fix: 优化官网
This commit is contained in:
@@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
<!-- 网站信息 -->
|
<!-- 网站信息 -->
|
||||||
<meta name="generator" content="Vue.js">
|
<meta name="generator" content="Vue.js">
|
||||||
<meta name="theme-color" content="#3498db">
|
<meta name="theme-color" content="#2563eb">
|
||||||
<meta name="msapplication-TileColor" content="#3498db">
|
<meta name="msapplication-TileColor" content="#2563eb">
|
||||||
|
|
||||||
<!-- Open Graph / Facebook -->
|
<!-- Open Graph / Facebook -->
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
|
|||||||
21
src/assets/css/design_tokens.less
Normal file
21
src/assets/css/design_tokens.less
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
:root {
|
||||||
|
--color-bg: #ffffff;
|
||||||
|
--color-bg-muted: #f6f8fb;
|
||||||
|
--color-surface: #ffffff;
|
||||||
|
--color-ink: #101828;
|
||||||
|
--color-text: #344054;
|
||||||
|
--color-text-muted: #667085;
|
||||||
|
--color-border: #e4e7ec;
|
||||||
|
--color-primary: #2563eb;
|
||||||
|
--color-primary-strong: #1d4ed8;
|
||||||
|
--color-primary-soft: #eef4ff;
|
||||||
|
--color-dark: #0f172a;
|
||||||
|
--space-section: 96px;
|
||||||
|
--space-section-mobile: 64px;
|
||||||
|
--radius-card: 8px;
|
||||||
|
--radius-control: 4px;
|
||||||
|
--shadow-card: 0 16px 40px rgba(16, 24, 40, 0.06);
|
||||||
|
--shadow-card-hover: 0 22px 50px rgba(16, 24, 40, 0.1);
|
||||||
|
--motion-fast: 0.2s ease;
|
||||||
|
--motion-base: 0.25s ease;
|
||||||
|
}
|
||||||
@@ -7,11 +7,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
name: 'icontent'
|
||||||
return {
|
|
||||||
msg: "Welcome to Your Vue.js App"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -8,19 +8,11 @@
|
|||||||
<div class="footer-logo">
|
<div class="footer-logo">
|
||||||
<img :src="require('@/assets/img/logo.png')" alt="丙维科技" class="logo">
|
<img :src="require('@/assets/img/logo.png')" alt="丙维科技" class="logo">
|
||||||
<h3>上海丙维数字科技有限公司</h3>
|
<h3>上海丙维数字科技有限公司</h3>
|
||||||
<p class="company-desc">技术驱动未来,服务创造价值</p>
|
<p class="company-desc">AI 工程交付与企业数字化服务</p>
|
||||||
|
<router-link to="/index#contact" class="footer-cta">预约咨询</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-section">
|
|
||||||
<h4>关于我们</h4>
|
|
||||||
<ul class="footer-links">
|
|
||||||
<li v-for="item in aboutUsMenu" :key="item.name">
|
|
||||||
<router-link :to="item.url">{{ item.name }}</router-link>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="footer-section">
|
<div class="footer-section">
|
||||||
<h4>解决方案</h4>
|
<h4>解决方案</h4>
|
||||||
<ul class="footer-links">
|
<ul class="footer-links">
|
||||||
@@ -31,25 +23,34 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-section">
|
<div class="footer-section">
|
||||||
<h4>联系我们</h4>
|
<h4>联系咨询</h4>
|
||||||
<div class="contact-info">
|
<div class="contact-info">
|
||||||
<div class="contact-item">
|
<div class="contact-item">
|
||||||
<span class="contact-icon">🏢</span>
|
<span class="contact-icon" v-html="icons.phone"></span>
|
||||||
<span>上海市宝山区高逸路112-118号3幢6422室</span>
|
<a href="tel:13817819452">13817819452</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-item">
|
<div class="contact-item">
|
||||||
<span class="contact-icon">📱</span>
|
<span class="contact-icon" v-html="icons.mail"></span>
|
||||||
<span>13817819452</span>
|
<a href="mailto:bimwe@bimwe.com">bimwe@bimwe.com</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-item">
|
<div class="contact-item">
|
||||||
<span class="contact-icon">📧</span>
|
<span class="contact-icon" v-html="icons.globe"></span>
|
||||||
<span>bimwe@bimwe.com</span>
|
<router-link to="/index#contact">提交业务场景</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-item">
|
|
||||||
<span class="contact-icon">💻</span>
|
|
||||||
<span>www.bimwe.com</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-section">
|
||||||
|
<h4>合规信息</h4>
|
||||||
|
<ul class="footer-links">
|
||||||
|
<li><router-link to="/aboutUs">关于我们</router-link></li>
|
||||||
|
<li><router-link to="/legal/privacy">隐私政策</router-link></li>
|
||||||
|
<li><router-link to="/legal/terms">服务条款</router-link></li>
|
||||||
|
<li><router-link to="/legal/compliance">数据合规说明</router-link></li>
|
||||||
|
</ul>
|
||||||
|
<div class="footer-address">
|
||||||
|
上海市宝山区高逸路112-118号3幢6422室
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -57,11 +58,11 @@
|
|||||||
<div class="footer-bottom">
|
<div class="footer-bottom">
|
||||||
<div class="footer-bottom-content">
|
<div class="footer-bottom-content">
|
||||||
<div class="copyright">
|
<div class="copyright">
|
||||||
<p>© © 2025 上海丙维数字科技有限公司. 保留所有权利.</p>
|
<p>© 2025 上海丙维数字科技有限公司. 保留所有权利.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-extra">
|
<div class="footer-extra">
|
||||||
<div class="beian">
|
<div class="beian">
|
||||||
<span class="beian-icon">🔒</span>
|
<span class="beian-icon" v-html="icons.shield"></span>
|
||||||
<span>沪ICP备19005870号-1</span>
|
<span>沪ICP备19005870号-1</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,32 +72,41 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 返回顶部按钮 -->
|
<!-- 返回顶部按钮 -->
|
||||||
<div class="back-to-top" @click="scrollToTop" v-show="showBackToTop">
|
<button type="button" class="back-to-top" @click="scrollToTop" v-show="showBackToTop" aria-label="返回顶部">
|
||||||
<span class="arrow">↑</span>
|
<span class="arrow" v-html="icons.arrowUp"></span>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getFooterAboutUsMenu, getFooterSolutionsMenu } from '../config/menu'
|
import { getFooterSolutionsMenu } from '../config/menu'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ifooter',
|
name: 'ifooter',
|
||||||
data() {
|
data() {
|
||||||
|
const icon = (path) => `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">${path}</svg>`
|
||||||
return {
|
return {
|
||||||
showBackToTop: false,
|
showBackToTop: false,
|
||||||
aboutUsMenu: getFooterAboutUsMenu(),
|
solutionsMenu: getFooterSolutionsMenu(),
|
||||||
solutionsMenu: getFooterSolutionsMenu()
|
icons: {
|
||||||
|
phone: icon('<path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.4 19.4 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8.1 9.9a16 16 0 0 0 6 6l1.3-1.2a2 2 0 0 1 2.1-.5c.9.3 1.8.6 2.8.7a2 2 0 0 1 1.7 2Z"/>'),
|
||||||
|
mail: icon('<path d="M4 5h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2Z"/><path d="M22 7l-10 6L2 7"/>'),
|
||||||
|
globe: icon('<circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15.3 15.3 0 0 1 0 20M12 2a15.3 15.3 0 0 0 0 20"/>'),
|
||||||
|
shield: icon('<path d="M12 3l7 4v5c0 4.5-2.9 7.5-7 9-4.1-1.5-7-4.5-7-9V7l7-4Z"/><path d="M9 12l2 2 4-5"/>'),
|
||||||
|
arrowUp: icon('<path d="M12 19V5M6 11l6-6 6 6"/>')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initScrollListener()
|
window.addEventListener('scroll', this.handleScroll)
|
||||||
|
this.handleScroll()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('scroll', this.handleScroll)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initScrollListener() {
|
handleScroll() {
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
this.showBackToTop = window.pageYOffset > 300
|
this.showBackToTop = window.pageYOffset > 300
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToTop() {
|
scrollToTop() {
|
||||||
@@ -111,10 +121,9 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.footer {
|
.footer {
|
||||||
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
|
background: #111827;
|
||||||
color: white;
|
color: white;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: 80px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-content {
|
.footer-content {
|
||||||
@@ -150,7 +159,7 @@ export default {
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background: #3498db;
|
background: #60a5fa;
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +183,20 @@ export default {
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer-cta {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 38px;
|
||||||
|
margin-top: 18px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #2563eb;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* 链接列表 */
|
/* 链接列表 */
|
||||||
.footer-links {
|
.footer-links {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@@ -185,7 +208,8 @@ export default {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-links a {
|
.footer-links a,
|
||||||
|
.contact-item a {
|
||||||
color: #bdc3c7;
|
color: #bdc3c7;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
@@ -193,24 +217,12 @@ export default {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-links a:hover {
|
.footer-links a:hover,
|
||||||
color: #3498db;
|
.contact-item a:hover {
|
||||||
|
color: #93c5fd;
|
||||||
transform: translateX(5px);
|
transform: translateX(5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-links a::before {
|
|
||||||
content: '→';
|
|
||||||
position: absolute;
|
|
||||||
left: -20px;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-links a:hover::before {
|
|
||||||
opacity: 1;
|
|
||||||
left: -15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 联系信息 */
|
/* 联系信息 */
|
||||||
.contact-info {
|
.contact-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -227,9 +239,30 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contact-icon {
|
.contact-icon {
|
||||||
font-size: 1.2rem;
|
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: #93c5fd;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-address {
|
||||||
|
margin-top: 18px;
|
||||||
|
color: #7d8898;
|
||||||
|
font-size: 0.86rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-icon /deep/ svg,
|
||||||
|
.beian-icon /deep/ svg,
|
||||||
|
.back-to-top .arrow /deep/ svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
fill: none;
|
||||||
|
stroke: currentColor;
|
||||||
|
stroke-width: 1.8;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 页脚底部 */
|
/* 页脚底部 */
|
||||||
@@ -267,8 +300,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.beian-icon {
|
.beian-icon {
|
||||||
font-size: 1.2rem;
|
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #95a5a6;
|
color: #95a5a6;
|
||||||
}
|
}
|
||||||
@@ -280,26 +313,30 @@ export default {
|
|||||||
right: 30px;
|
right: 30px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
background: #2563eb;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
|
box-shadow: 0 12px 28px rgba(37, 99, 235, 0.28);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-to-top:hover {
|
.back-to-top:hover {
|
||||||
transform: translateY(-3px);
|
transform: translateY(-3px);
|
||||||
box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
|
background: #1d4ed8;
|
||||||
|
box-shadow: 0 16px 32px rgba(37, 99, 235, 0.34);
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-to-top .arrow {
|
.back-to-top .arrow {
|
||||||
|
display: block;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 响应式设计 */
|
/* 响应式设计 */
|
||||||
@@ -330,25 +367,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 动画效果 */
|
|
||||||
.footer-section {
|
|
||||||
animation: fadeInUp 0.6s ease forwards;
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(20px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-section:nth-child(1) { animation-delay: 0.1s; }
|
|
||||||
.footer-section:nth-child(2) { animation-delay: 0.2s; }
|
|
||||||
.footer-section:nth-child(3) { animation-delay: 0.3s; }
|
|
||||||
.footer-section:nth-child(4) { animation-delay: 0.4s; }
|
|
||||||
|
|
||||||
@keyframes fadeInUp {
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 悬停效果增强 */
|
/* 悬停效果增强 */
|
||||||
.footer-section:hover {
|
.footer-section:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
@@ -359,17 +377,4 @@ export default {
|
|||||||
transform: translateX(8px);
|
transform: translateX(8px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 渐变背景动画 */
|
|
||||||
.footer {
|
|
||||||
background-size: 200% 200%;
|
|
||||||
animation: gradientShift 10s ease infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes gradientShift {
|
|
||||||
0% { background-position: 0% 50%; }
|
|
||||||
50% { background-position: 100% 50%; }
|
|
||||||
100% { background-position: 0% 50%; }
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,39 @@
|
|||||||
<div class="bottom desktop">
|
<div class="bottom desktop">
|
||||||
<div class="nav-container">
|
<div class="nav-container">
|
||||||
<div class="logoCell">
|
<div class="logoCell">
|
||||||
|
<router-link to="/index" aria-label="返回首页">
|
||||||
<img class="logo" :src="image_paths.logo" alt="丙维科技">
|
<img class="logo" :src="image_paths.logo" alt="丙维科技">
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="mainMenuCell">
|
<div class="mainMenuCell">
|
||||||
<nav class="mainMenu">
|
<nav class="mainMenu">
|
||||||
<div class="nav-item" v-for="menu in menus" :key="menu.name">
|
<div
|
||||||
<router-link :to="menu.url" class="nav-link">
|
class="nav-item"
|
||||||
|
v-for="(menu, index) in menus"
|
||||||
|
:key="menu.name"
|
||||||
|
@mouseenter="openDropdown(index)"
|
||||||
|
@mouseleave="closeDropdown"
|
||||||
|
@focusin="openDropdown(index)"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="menu.url"
|
||||||
|
class="nav-link"
|
||||||
|
:aria-expanded="menu.child.length > 0 ? String(activeDropdownIndex === index) : null"
|
||||||
|
:aria-haspopup="menu.child.length > 0 ? 'true' : null"
|
||||||
|
@keydown.native.enter.prevent="handleNavEnter(menu, index)"
|
||||||
|
@keydown.native.esc.prevent="closeDropdown"
|
||||||
|
>
|
||||||
{{ menu.name }}
|
{{ menu.name }}
|
||||||
<span v-if="menu.child.length > 0" class="downCaret">▼</span>
|
<span v-if="menu.child.length > 0" class="downCaret"></span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="dropDown bottomShadowSegment" v-if="menu.child.length > 0">
|
<div
|
||||||
|
class="dropDown bottomShadowSegment"
|
||||||
|
:class="{ visible: activeDropdownIndex === index }"
|
||||||
|
v-if="menu.child.length > 0"
|
||||||
|
>
|
||||||
<router-link :to="sonMenu.url" v-for="sonMenu in menu.child" :key="sonMenu.name"
|
<router-link :to="sonMenu.url" v-for="sonMenu in menu.child" :key="sonMenu.name"
|
||||||
class="dropdown-item">
|
class="dropdown-item"
|
||||||
|
@keydown.native.esc.prevent="closeDropdown">
|
||||||
{{ sonMenu.name }}
|
{{ sonMenu.name }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,35 +53,53 @@
|
|||||||
<div class="bottom headerBottom mobile">
|
<div class="bottom headerBottom mobile">
|
||||||
<div class="mobile-nav">
|
<div class="mobile-nav">
|
||||||
<div class="logoCell">
|
<div class="logoCell">
|
||||||
|
<router-link to="/index" aria-label="返回首页" @click.native="closeMobileMenu">
|
||||||
<img class="logo" :src="image_paths.mobile_logo" alt="丙维科技">
|
<img class="logo" :src="image_paths.mobile_logo" alt="丙维科技">
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="mobileIconsCell">
|
<div class="mobileIconsCell">
|
||||||
<img :src="image_paths.hamburger" id="hamburger" alt="菜单">
|
<button
|
||||||
|
type="button"
|
||||||
|
id="hamburger"
|
||||||
|
class="mobile-menu-button"
|
||||||
|
ref="mobileMenuButton"
|
||||||
|
:aria-expanded="mobileMenuOpen ? 'true' : 'false'"
|
||||||
|
aria-controls="mobileMenu"
|
||||||
|
aria-label="打开或关闭菜单"
|
||||||
|
@click.stop="toggleMobileMenu"
|
||||||
|
>
|
||||||
|
<img :src="image_paths.hamburger" alt="">
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 移动端菜单 -->
|
<!-- 移动端菜单 -->
|
||||||
<div id="mobileMenu" class="headerMobileMenu bread">
|
<div id="mobileMenu" class="headerMobileMenu bread" :class="{ active: mobileMenuOpen }" @click.self="closeMobileMenu">
|
||||||
<div class="menuDummy"></div>
|
<div class="menuDummy" @click="closeMobileMenu"></div>
|
||||||
<div class="menuContent">
|
<div class="menuContent" @click.stop>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="menu in menus" :key="menu.name">
|
<li v-for="menu in menus" :key="menu.name">
|
||||||
<router-link :to="menu.url" v-if="menu.child.length === 0">{{ menu.name }}</router-link>
|
<router-link
|
||||||
<label v-else class="hasSubmenu" style="display:block;">{{ menu.name }}</label>
|
:to="menu.url"
|
||||||
|
v-if="menu.child.length === 0"
|
||||||
|
ref="mobileMenuLink"
|
||||||
|
@click.native="closeMobileMenu"
|
||||||
|
>{{ menu.name }}</router-link>
|
||||||
|
<span v-else class="menu-label hasSubmenu">{{ menu.name }}</span>
|
||||||
<ul class="subMenu" v-if="menu.child.length > 0">
|
<ul class="subMenu" v-if="menu.child.length > 0">
|
||||||
<li v-for="sonMenu in menu.child" :key="sonMenu.name">
|
<li v-for="sonMenu in menu.child" :key="sonMenu.name">
|
||||||
<router-link class="hasSubmenu" :to="sonMenu.url">{{ sonMenu.name }}</router-link>
|
<router-link class="hasSubmenu" :to="sonMenu.url" @click.native="closeMobileMenu">{{ sonMenu.name }}</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="goBack">
|
<div class="goBack">
|
||||||
<a href="JavaScript:void()" class="linkGoBack flexVerticalCenter">
|
<button type="button" class="linkGoBack flexVerticalCenter" @click="closeMobileMenuAndScrollTop">
|
||||||
<img :src="image_paths.arrow_back" alt="返回">
|
<img :src="image_paths.arrow_back" alt="" aria-hidden="true">
|
||||||
<span>返回</span>
|
<span>返回</span>
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -69,7 +108,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { common } from '../static/common'
|
|
||||||
import { getMainMenu } from '../config/menu'
|
import { getMainMenu } from '../config/menu'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -77,11 +115,12 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isMiniHeader: false,
|
isMiniHeader: false,
|
||||||
|
mobileMenuOpen: false,
|
||||||
|
activeDropdownIndex: null,
|
||||||
menus: getMainMenu()
|
menus: getMainMenu()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 统一管理图片路径,提高可维护性
|
|
||||||
image_paths() {
|
image_paths() {
|
||||||
return {
|
return {
|
||||||
logo: require('@/assets/img/logo.png'),
|
logo: require('@/assets/img/logo.png'),
|
||||||
@@ -92,136 +131,70 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initHeader()
|
window.addEventListener('scroll', this.handleScroll)
|
||||||
this.initScrollListener()
|
document.addEventListener('keydown', this.handleKeydown)
|
||||||
this.initMobileMenu()
|
this.handleScroll()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('scroll', this.handleScroll)
|
||||||
|
document.removeEventListener('keydown', this.handleKeydown)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 封装事件监听器创建,提高代码复用性
|
handleScroll() {
|
||||||
add_event_listener(selector, event_type, callback, use_id = false) {
|
this.isMiniHeader = window.pageYOffset > 200
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.addEventListener(event_type, callback);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
toggleMobileMenu() {
|
||||||
// 封装类名操作,提高代码复用性
|
this.mobileMenuOpen = !this.mobileMenuOpen
|
||||||
toggle_class(selector, class_name, use_id = false) {
|
if (this.mobileMenuOpen) {
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
this.$nextTick(() => {
|
||||||
if (element) {
|
const firstLink = this.$refs.mobileMenuLink && this.$refs.mobileMenuLink[0]
|
||||||
element.classList.toggle(class_name);
|
if (firstLink && firstLink.$el) {
|
||||||
return true;
|
firstLink.$el.focus()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
closeMobileMenu() {
|
||||||
// 封装类名添加,提高代码复用性
|
this.mobileMenuOpen = false
|
||||||
add_class(selector, class_name, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.classList.add(class_name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
closeMobileMenuAndRestoreFocus() {
|
||||||
// 封装类名移除,提高代码复用性
|
this.closeMobileMenu()
|
||||||
remove_class(selector, class_name, use_id = false) {
|
this.$nextTick(() => {
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
if (this.$refs.mobileMenuButton) {
|
||||||
if (element) {
|
this.$refs.mobileMenuButton.focus()
|
||||||
element.classList.remove(class_name);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
})
|
||||||
},
|
},
|
||||||
|
closeMobileMenuAndScrollTop() {
|
||||||
initHeader() {
|
this.closeMobileMenu()
|
||||||
// 点击logo返回首页
|
|
||||||
this.add_event_listener(".logoCell .logo", "click", () => {
|
|
||||||
if (window.location.href.indexOf("index") === -1) {
|
|
||||||
window.location.href = "#/index";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 移动端菜单切换
|
|
||||||
this.add_event_listener("hamburger", "click", () => {
|
|
||||||
this.toggle_class("mobileMenu", "active", true);
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
// 返回按钮
|
|
||||||
this.add_event_listener(".linkGoBack", "click", () => {
|
|
||||||
this.remove_class("mobileMenu", "active", true);
|
|
||||||
// 关闭移动端菜单后滚动到顶部
|
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
})
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
handleKeydown(e) {
|
||||||
initScrollListener() {
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
if (window.pageYOffset > 200) {
|
|
||||||
if (!this.isMiniHeader) {
|
|
||||||
this.isMiniHeader = true;
|
|
||||||
this.add_class('.header', 'mini');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.isMiniHeader) {
|
|
||||||
this.isMiniHeader = false;
|
|
||||||
this.remove_class('.header', 'mini');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 初始化移动端菜单
|
|
||||||
initMobileMenu() {
|
|
||||||
// 汉堡菜单点击事件
|
|
||||||
this.add_event_listener("hamburger", "click", () => {
|
|
||||||
this.toggle_class("mobileMenu", "active", true);
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
// 返回按钮点击事件
|
|
||||||
this.add_event_listener(".linkGoBack", "click", () => {
|
|
||||||
this.remove_class("mobileMenu", "active", true);
|
|
||||||
// 关闭移动端菜单后滚动到顶部
|
|
||||||
window.scrollTo({
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 点击菜单项后自动关闭菜单
|
|
||||||
const menuLinks = document.querySelectorAll('.headerMobileMenu a');
|
|
||||||
menuLinks.forEach(link => {
|
|
||||||
link.addEventListener('click', () => {
|
|
||||||
this.remove_class("mobileMenu", "active", true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 点击菜单外部区域关闭菜单
|
|
||||||
document.addEventListener('click', (e) => {
|
|
||||||
const mobileMenu = document.getElementById('mobileMenu');
|
|
||||||
const hamburger = document.getElementById('hamburger');
|
|
||||||
|
|
||||||
if (mobileMenu && mobileMenu.classList.contains('active') &&
|
|
||||||
!mobileMenu.contains(e.target) &&
|
|
||||||
!hamburger.contains(e.target)) {
|
|
||||||
this.remove_class("mobileMenu", "active", true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ESC键关闭菜单
|
|
||||||
document.addEventListener('keydown', (e) => {
|
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
this.remove_class("mobileMenu", "active", true);
|
this.closeDropdown()
|
||||||
|
if (this.mobileMenuOpen) {
|
||||||
|
this.closeMobileMenuAndRestoreFocus()
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
},
|
||||||
|
openDropdown(index) {
|
||||||
|
if (this.menus[index] && this.menus[index].child.length > 0) {
|
||||||
|
this.activeDropdownIndex = index
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeDropdown() {
|
||||||
|
this.activeDropdownIndex = null
|
||||||
|
},
|
||||||
|
handleNavEnter(menu, index) {
|
||||||
|
if (menu.child.length > 0) {
|
||||||
|
this.openDropdown(index)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$router.push(menu.url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,41 +207,41 @@ export default {
|
|||||||
.header table tbody,
|
.header table tbody,
|
||||||
.header table tbody tr,
|
.header table tbody tr,
|
||||||
.header table tbody tr td {
|
.header table tbody tr td {
|
||||||
display: block !important;
|
display: block;
|
||||||
width: auto !important;
|
width: auto;
|
||||||
height: auto !important;
|
height: auto;
|
||||||
border: none !important;
|
border: none;
|
||||||
padding: 0 !important;
|
padding: 0;
|
||||||
margin: 0 !important;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 头部基础样式 - 使用 !important 覆盖 common.css */
|
/* 头部基础样式 */
|
||||||
.header {
|
.header {
|
||||||
position: fixed !important;
|
position: fixed;
|
||||||
top: 0 !important;
|
top: 0;
|
||||||
left: 0 !important;
|
left: 0;
|
||||||
right: 0 !important;
|
right: 0;
|
||||||
z-index: 1000 !important;
|
z-index: 1000;
|
||||||
background: rgba(255, 255, 255, 0.95) !important;
|
background: rgba(255, 255, 255, 0.92);
|
||||||
backdrop-filter: blur(10px) !important;
|
backdrop-filter: blur(16px);
|
||||||
transition: all 0.3s ease !important;
|
transition: all 0.3s ease;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important;
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
/* 覆盖旧表格布局 */
|
/* 覆盖旧表格布局 */
|
||||||
display: block !important;
|
display: block;
|
||||||
height: auto !important;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header.mini {
|
.header.mini {
|
||||||
background: rgba(255, 255, 255, 0.98) !important;
|
background: rgba(255, 255, 255, 0.98);
|
||||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1) !important;
|
box-shadow: 0 12px 32px rgba(16, 24, 40, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 主要导航区域 - 覆盖旧样式 */
|
/* 主要导航区域 - 覆盖旧样式 */
|
||||||
.bottom {
|
.bottom {
|
||||||
padding: 15px 0 !important;
|
padding: 15px 0;
|
||||||
/* 覆盖旧表格布局 */
|
/* 覆盖旧表格布局 */
|
||||||
display: block !important;
|
display: block;
|
||||||
height: auto !important;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
@@ -288,6 +261,11 @@ export default {
|
|||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logoCell a {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.logoCell .logo:hover {
|
.logoCell .logo:hover {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
@@ -312,20 +290,20 @@ export default {
|
|||||||
|
|
||||||
.nav-link {
|
.nav-link {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 15px 25px;
|
padding: 14px 22px;
|
||||||
color: #2c3e50;
|
color: #1f2937;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
border-radius: 8px;
|
border-radius: 6px;
|
||||||
position: relative;
|
position: relative;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link:hover {
|
.nav-link:hover {
|
||||||
color: #3498db;
|
color: #2563eb;
|
||||||
background: rgba(52, 152, 219, 0.1);
|
background: rgba(37, 99, 235, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link::after {
|
.nav-link::after {
|
||||||
@@ -335,7 +313,7 @@ export default {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background: #3498db;
|
background: #2563eb;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
@@ -352,7 +330,7 @@ export default {
|
|||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 18px 42px rgba(16, 24, 40, 0.14);
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -362,7 +340,9 @@ export default {
|
|||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover .dropDown {
|
.nav-item:hover .dropDown,
|
||||||
|
.nav-item:focus-within .dropDown,
|
||||||
|
.dropDown.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
transform: translateX(-50%) translateY(0);
|
transform: translateX(-50%) translateY(0);
|
||||||
@@ -379,8 +359,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item:hover {
|
.dropdown-item:hover {
|
||||||
background: rgba(52, 152, 219, 0.1);
|
background: rgba(37, 99, 235, 0.08);
|
||||||
color: #3498db;
|
color: #2563eb;
|
||||||
padding-left: 30px;
|
padding-left: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,12 +368,17 @@ export default {
|
|||||||
.downCaret {
|
.downCaret {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
border-right: 1.5px solid currentColor;
|
||||||
|
border-bottom: 1.5px solid currentColor;
|
||||||
|
transform: rotate(45deg) translateY(-2px);
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
font-size: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover .downCaret {
|
.nav-item:hover .downCaret,
|
||||||
transform: rotate(180deg);
|
.nav-item:focus-within .downCaret {
|
||||||
|
transform: rotate(225deg) translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 移动端导航 */
|
/* 移动端导航 */
|
||||||
@@ -410,10 +395,19 @@ export default {
|
|||||||
#hamburger {
|
#hamburger {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#hamburger img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#hamburger:hover {
|
#hamburger:hover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
@@ -434,7 +428,13 @@ export default {
|
|||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menuDummy {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.menuContent {
|
.menuContent {
|
||||||
|
position: relative;
|
||||||
background: white;
|
background: white;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -452,7 +452,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menuContent a,
|
.menuContent a,
|
||||||
.menuContent label {
|
.menuContent .menu-label {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
@@ -463,9 +463,9 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menuContent a:hover,
|
.menuContent a:hover,
|
||||||
.menuContent label:hover {
|
.menuContent .menu-label:hover {
|
||||||
background: rgba(52, 152, 219, 0.1);
|
background: rgba(37, 99, 235, 0.08);
|
||||||
color: #3498db;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subMenu {
|
.subMenu {
|
||||||
@@ -484,45 +484,50 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.linkGoBack:hover {
|
.linkGoBack:hover {
|
||||||
color: #3498db;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 响应式设计 */
|
/* 响应式设计 */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.desktop {
|
.desktop {
|
||||||
display: none !important;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile {
|
.mobile {
|
||||||
display: block !important;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .content {
|
.header .content {
|
||||||
padding: 0 1em !important;
|
padding: 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding-top: 100px !important;
|
padding-top: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
gap: 1rem !important;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 769px) {
|
@media (min-width: 769px) {
|
||||||
.mobile {
|
.mobile {
|
||||||
display: none !important;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.desktop {
|
.desktop {
|
||||||
display: block !important;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
@@ -554,7 +559,7 @@ export default {
|
|||||||
|
|
||||||
/* 确保内容不被遮挡 */
|
/* 确保内容不被遮挡 */
|
||||||
body {
|
body {
|
||||||
padding-top: 120px !important;
|
padding-top: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 使用逻辑属性实现更好的间距 */
|
/* 使用逻辑属性实现更好的间距 */
|
||||||
@@ -564,6 +569,6 @@ body {
|
|||||||
|
|
||||||
/* 使用逻辑属性实现更好的边框 */
|
/* 使用逻辑属性实现更好的边框 */
|
||||||
.header {
|
.header {
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important;
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -11,12 +11,7 @@ export const menuConfig = {
|
|||||||
child: []
|
child: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '关于我们',
|
name: '解决方案',
|
||||||
url: '/aboutUs',
|
|
||||||
child: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '我们的方案',
|
|
||||||
url: '/ourPlan',
|
url: '/ourPlan',
|
||||||
child: [
|
child: [
|
||||||
{ name: 'AI集成', url: '/ourPlan/aiSolutions' },
|
{ name: 'AI集成', url: '/ourPlan/aiSolutions' },
|
||||||
@@ -25,6 +20,21 @@ export const menuConfig = {
|
|||||||
{ name: '设施管理', url: '/ourPlan/facilityManagement' },
|
{ name: '设施管理', url: '/ourPlan/facilityManagement' },
|
||||||
{ name: '系统集成', url: '/ourPlan/technologyIntegration' }
|
{ name: '系统集成', url: '/ourPlan/technologyIntegration' }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '案例',
|
||||||
|
url: '/index#cases',
|
||||||
|
child: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '联系我们',
|
||||||
|
url: '/index#contact',
|
||||||
|
child: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '关于我们',
|
||||||
|
url: '/aboutUs',
|
||||||
|
child: []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -54,6 +64,6 @@ export const getFooterSolutionsMenu = () => menuConfig.footerMenu.solutions
|
|||||||
|
|
||||||
// 获取所有解决方案
|
// 获取所有解决方案
|
||||||
export const getAllSolutions = () => {
|
export const getAllSolutions = () => {
|
||||||
const solutionMenu = menuConfig.mainMenu.find(menu => menu.name === '我们的方案');
|
const solutionMenu = menuConfig.mainMenu.find(menu => menu.name === '解决方案');
|
||||||
return solutionMenu && solutionMenu.child ? solutionMenu.child : [];
|
return solutionMenu && solutionMenu.child ? solutionMenu.child : [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import './assets/css/cookieconsent.min.css'
|
import './assets/css/cookieconsent.min.css'
|
||||||
|
import './assets/css/design_tokens.less'
|
||||||
import './assets/css/common.less'
|
import './assets/css/common.less'
|
||||||
import './assets/css/content_pages.less'
|
import './assets/css/content_pages.less'
|
||||||
import './assets/css/animations.less'
|
import './assets/css/animations.less'
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import facilityManagement from './views/ourPlan/facilityManagement'
|
|||||||
import iot from './views/ourPlan/iot'
|
import iot from './views/ourPlan/iot'
|
||||||
import aiSolutions from './views/ourPlan/aiSolutions'
|
import aiSolutions from './views/ourPlan/aiSolutions'
|
||||||
import technologyIntegration from './views/ourPlan/technologyIntegration'
|
import technologyIntegration from './views/ourPlan/technologyIntegration'
|
||||||
|
import LegalPage from './views/legal/LegalPage'
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
@@ -22,15 +23,27 @@ const router = new Router({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/index',
|
path: '/index',
|
||||||
component: index
|
component: index,
|
||||||
|
meta: {
|
||||||
|
title: '上海丙维数字科技有限公司 - AI工程交付与数字化解决方案',
|
||||||
|
description: '围绕企业真实业务场景,提供从需求拆解、系统集成到上线运维的一体化 AI 工程服务。'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/aboutUs',
|
path: '/aboutUs',
|
||||||
component: aboutUs
|
component: aboutUs,
|
||||||
|
meta: {
|
||||||
|
title: '关于丙维科技 - 上海丙维数字科技有限公司',
|
||||||
|
description: '了解丙维科技的公司简介、核心能力、发展里程碑与 AI 应用交付方法论。'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/ourPlan',
|
path: '/ourPlan',
|
||||||
component: ourPlan
|
component: ourPlan,
|
||||||
|
meta: {
|
||||||
|
title: '解决方案 - 上海丙维数字科技有限公司',
|
||||||
|
description: '覆盖 AI 集成、智能建筑、物联网、设施管理与系统集成等企业数字化场景。'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/ourPlan/estateManagement',
|
path: '/ourPlan/estateManagement',
|
||||||
@@ -52,6 +65,14 @@ const router = new Router({
|
|||||||
path: '/ourPlan/technologyIntegration',
|
path: '/ourPlan/technologyIntegration',
|
||||||
component: technologyIntegration
|
component: technologyIntegration
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/legal/:type',
|
||||||
|
component: LegalPage,
|
||||||
|
meta: {
|
||||||
|
title: '合规信息 - 上海丙维数字科技有限公司',
|
||||||
|
description: '查看隐私政策、服务条款与数据合规说明。'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '*',
|
path: '*',
|
||||||
redirect: '/index'
|
redirect: '/index'
|
||||||
@@ -61,18 +82,36 @@ const router = new Router({
|
|||||||
|
|
||||||
// 全局前置守卫 - 路由切换时自动滚动到顶部
|
// 全局前置守卫 - 路由切换时自动滚动到顶部
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
// 滚动到页面顶部
|
|
||||||
window.scrollTo({
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
behavior: 'smooth' // 平滑滚动效果
|
|
||||||
});
|
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 全局后置钩子 - 路由切换完成后触发动画重置
|
// 全局后置钩子 - 路由切换完成后触发动画重置
|
||||||
router.afterEach((to, from) => {
|
router.afterEach((to, from) => {
|
||||||
|
if (to.meta && to.meta.title) {
|
||||||
|
document.title = to.meta.title
|
||||||
|
}
|
||||||
|
|
||||||
|
const description = document.querySelector('meta[name="description"]')
|
||||||
|
if (description && to.meta && to.meta.description) {
|
||||||
|
description.setAttribute('content', to.meta.description)
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
if (to.hash) {
|
||||||
|
const target = document.querySelector(to.hash)
|
||||||
|
if (target) {
|
||||||
|
target.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
behavior: 'smooth'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// 触发自定义路由变化事件
|
// 触发自定义路由变化事件
|
||||||
window.dispatchEvent(new CustomEvent('routeChange', {
|
window.dispatchEvent(new CustomEvent('routeChange', {
|
||||||
detail: { to, from }
|
detail: { to, from }
|
||||||
|
|||||||
@@ -1,677 +1,47 @@
|
|||||||
var isMobile = null;
|
import { submitJsonForm } from './form_submit'
|
||||||
var wasMobile = isMobile;
|
|
||||||
var isMiniHeader = false;
|
|
||||||
|
|
||||||
// 移除 jQuery 导入,使用原生 JavaScript
|
export function isMobileUserAgent(userAgent = '') {
|
||||||
|
return /(iPhone|Android|Mobile)/i.test(userAgent)
|
||||||
class Common {
|
|
||||||
constructor(name, age) {
|
|
||||||
this.name = name;
|
|
||||||
this.age = age;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 封装原生 JavaScript 方法,提高代码复用性
|
export function normalizeBasePath(basePath = '/') {
|
||||||
add_event_listener(selector, event_type, callback, use_id = false) {
|
return basePath.replace(/\/?$/, '/')
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.addEventListener(event_type, callback);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle_class(selector, class_name, use_id = false) {
|
export function createSupportPayload(values = {}) {
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.classList.toggle(class_name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_class(selector, class_name, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.classList.add(class_name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_class(selector, class_name, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.classList.remove(class_name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
show_element(selector, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.style.display = 'block';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hide_element(selector, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.style.display = 'none';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_element_value(selector, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
return element ? element.value : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
set_element_value(selector, value, use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
element.value = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 滚动到页面顶部 - 支持平滑滚动
|
|
||||||
scroll_to_top(behavior = 'smooth') {
|
|
||||||
window.scrollTo({
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
behavior: behavior
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 滚动到指定元素 - 支持平滑滚动和偏移
|
|
||||||
scroll_to_element(selector, offset = 0, behavior = 'smooth', use_id = false) {
|
|
||||||
const element = use_id ? document.getElementById(selector) : document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
const elementTop = element.offsetTop - offset;
|
|
||||||
window.scrollTo({
|
|
||||||
top: elementTop,
|
|
||||||
left: 0,
|
|
||||||
behavior: behavior
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 滚动到指定位置 - 支持平滑滚动
|
|
||||||
scroll_to_position(top = 0, left = 0, behavior = 'smooth') {
|
|
||||||
window.scrollTo({
|
|
||||||
top: top,
|
|
||||||
left: left,
|
|
||||||
behavior: behavior
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前滚动位置
|
|
||||||
get_scroll_position() {
|
|
||||||
return {
|
return {
|
||||||
top: window.pageYOffset || document.documentElement.scrollTop,
|
subject: values.subject || '',
|
||||||
left: window.pageXOffset || document.documentElement.scrollLeft
|
company: values.company || '',
|
||||||
};
|
name: values.name || '',
|
||||||
}
|
email: values.email || '',
|
||||||
|
phone: values.phone || '',
|
||||||
// 检查是否在页面顶部
|
product: values.product || '',
|
||||||
is_at_top() {
|
comments: values.comments || ''
|
||||||
return window.pageYOffset === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否在页面底部
|
|
||||||
is_at_bottom() {
|
|
||||||
return window.innerHeight + window.pageYOffset >= document.documentElement.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建返回顶部按钮
|
|
||||||
create_back_to_top_button() {
|
|
||||||
// 检查是否已存在返回顶部按钮
|
|
||||||
if (document.getElementById('backToTopBtn')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const button = document.createElement('button');
|
|
||||||
button.id = 'backToTopBtn';
|
|
||||||
button.innerHTML = '↑';
|
|
||||||
button.title = '返回顶部';
|
|
||||||
button.className = 'back-to-top-btn';
|
|
||||||
|
|
||||||
// 添加样式
|
|
||||||
button.style.cssText = `
|
|
||||||
position: fixed;
|
|
||||||
bottom: 30px;
|
|
||||||
right: 30px;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
background: #3498db;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
font-size: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
z-index: 1000;
|
|
||||||
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.3);
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 悬停效果
|
|
||||||
button.addEventListener('mouseenter', () => {
|
|
||||||
button.style.background = '#2980b9';
|
|
||||||
button.style.transform = 'scale(1.1)';
|
|
||||||
});
|
|
||||||
|
|
||||||
button.addEventListener('mouseleave', () => {
|
|
||||||
button.style.background = '#3498db';
|
|
||||||
button.style.transform = 'scale(1)';
|
|
||||||
});
|
|
||||||
|
|
||||||
// 点击事件
|
|
||||||
button.addEventListener('click', () => {
|
|
||||||
this.scroll_to_top('smooth');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 添加到页面
|
|
||||||
document.body.appendChild(button);
|
|
||||||
|
|
||||||
// 监听滚动事件,控制按钮显示/隐藏
|
|
||||||
window.addEventListener('scroll', () => {
|
|
||||||
if (window.pageYOffset > 300) {
|
|
||||||
button.style.opacity = '1';
|
|
||||||
button.style.visibility = 'visible';
|
|
||||||
} else {
|
|
||||||
button.style.opacity = '0';
|
|
||||||
button.style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
isMobile = common.isMobile();
|
|
||||||
|
|
||||||
// 创建 resizeEnd 事件触发器,在事件完成后调用
|
|
||||||
let resizeTO;
|
|
||||||
window.addEventListener('resize', function() {
|
|
||||||
if (resizeTO) clearTimeout(resizeTO);
|
|
||||||
resizeTO = setTimeout(function() {
|
|
||||||
// 触发自定义 resizeEnd 事件
|
|
||||||
window.dispatchEvent(new CustomEvent('resizeEnd'));
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 确定屏幕类型并在窗口调整大小完成后调用样式函数
|
|
||||||
window.addEventListener('resizeEnd', function() {
|
|
||||||
self.adjustElementsForScreen();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 创建返回顶部按钮
|
|
||||||
this.create_back_to_top_button();
|
|
||||||
|
|
||||||
window.addEventListener('scroll', function() {
|
|
||||||
if (window.pageYOffset > 200) {
|
|
||||||
if (isMiniHeader === false && !self.isMobile()) {
|
|
||||||
common.add_class('.header', 'mini');
|
|
||||||
isMiniHeader = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isMiniHeader === true) {
|
|
||||||
common.remove_class('.header', 'mini');
|
|
||||||
isMiniHeader = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 滚动到元素的原生实现
|
|
||||||
this.scrollToElement = function(selector) {
|
|
||||||
const element = document.querySelector(selector);
|
|
||||||
if (element) {
|
|
||||||
const adjustment = isMiniHeader ? 35 : 0;
|
|
||||||
const header = document.querySelector('.header:first-child');
|
|
||||||
const headerHeight = header ? header.offsetHeight : 0;
|
|
||||||
const targetPosition = element.offsetTop - headerHeight - adjustment;
|
|
||||||
|
|
||||||
window.scrollTo({
|
|
||||||
top: targetPosition,
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
adjustElementsForScreen() {
|
|
||||||
isMobile = this.isMobile();
|
|
||||||
|
|
||||||
if (!this.isMobile()) {
|
|
||||||
const mobileContents = document.querySelectorAll(".mobileContent");
|
|
||||||
mobileContents.forEach(content => content.style.display = 'none');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMobile) wasMobile = true;
|
|
||||||
|
|
||||||
if (wasMobile && !isMobile) location.reload();
|
|
||||||
|
|
||||||
if (isMobile && isMiniHeader === true) {
|
|
||||||
common.remove_class('.header', 'mini');
|
|
||||||
isMiniHeader = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.adjustContentBannersForScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
initHeader() {
|
|
||||||
// 点击 logo 返回主页
|
|
||||||
this.add_event_listener(".logoCell .logo", "click", function() {
|
|
||||||
if (window.location.href.indexOf("index") === -1) {
|
|
||||||
window.location.href = "#/index";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示/隐藏主导航下拉菜单(悬停)
|
|
||||||
const mainMenuItems = document.querySelectorAll(".mainMenu > tbody > tr > td");
|
|
||||||
mainMenuItems.forEach(item => {
|
|
||||||
item.addEventListener("mouseenter", function(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
const dropDowns = document.querySelectorAll(".dropDown");
|
|
||||||
dropDowns.forEach(dd => dd.style.display = 'none');
|
|
||||||
|
|
||||||
const selectedItems = document.querySelectorAll("table.mainMenu > tbody > tr > td.selected");
|
|
||||||
selectedItems.forEach(selected => selected.style.boxShadow = 'none');
|
|
||||||
|
|
||||||
const currentDropDown = this.querySelector(".dropDown");
|
|
||||||
if (currentDropDown) {
|
|
||||||
currentDropDown.classList.add("droppedDown");
|
|
||||||
currentDropDown.style.display = 'block';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
item.addEventListener("mouseleave", function(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
const currentDropDown = this.querySelector(".dropDown");
|
|
||||||
if (currentDropDown) {
|
|
||||||
currentDropDown.classList.remove("droppedDown");
|
|
||||||
currentDropDown.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedItems = document.querySelectorAll("table.mainMenu > tbody > tr > td.selected");
|
|
||||||
selectedItems.forEach(selected => selected.style.boxShadow = '0 -3px 0 #ff0000 inset');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initListeners() {
|
|
||||||
// 汉堡菜单点击事件
|
|
||||||
this.add_event_listener("hamburger", "click", function() {
|
|
||||||
const mobileLanguageMenu = document.getElementById("mobileLanguageMenu");
|
|
||||||
if (mobileLanguageMenu && mobileLanguageMenu.classList.contains("showing")) {
|
|
||||||
common.hide_element("mobileLanguageMenu", true);
|
|
||||||
common.remove_class("mobileLanguageMenu", "showing", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mobileMenu = document.getElementById("mobileMenu");
|
|
||||||
if (mobileMenu && mobileMenu.classList.contains("showing")) {
|
|
||||||
common.hideMobileMenu();
|
|
||||||
} else {
|
|
||||||
common.showMobileMenu();
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
// 移动端语言菜单点击事件
|
|
||||||
this.add_event_listener("mobileLanguage", "click", function() {
|
|
||||||
const mobileMenu = document.getElementById("mobileMenu");
|
|
||||||
if (mobileMenu && mobileMenu.classList.contains("showing")) {
|
|
||||||
common.hide_element("mobileMenu", true);
|
|
||||||
common.remove_class("mobileMenu", "showing", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mobileLanguageMenu = document.getElementById("mobileLanguageMenu");
|
|
||||||
if (mobileLanguageMenu && !mobileLanguageMenu.classList.contains("showing")) {
|
|
||||||
common.showMobileLanguageMenu();
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
// 屏幕覆盖层和返回按钮点击事件
|
|
||||||
const screenOverlay = document.getElementById("screenOverlayBehindHeader");
|
|
||||||
const goBackLinks = document.querySelectorAll(".linkGoBack");
|
|
||||||
|
|
||||||
if (screenOverlay) {
|
|
||||||
screenOverlay.addEventListener("click", function() {
|
|
||||||
const mobileMenu = document.getElementById("mobileMenu");
|
|
||||||
if (mobileMenu && mobileMenu.classList.contains("showing")) {
|
|
||||||
common.hideMobileMenu();
|
|
||||||
}
|
|
||||||
const mobileLanguageMenu = document.getElementById("mobileLanguageMenu");
|
|
||||||
if (mobileLanguageMenu && mobileLanguageMenu.classList.contains("showing")) {
|
|
||||||
common.hideMobileLanguageMenu();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
goBackLinks.forEach(link => {
|
|
||||||
link.addEventListener("click", function() {
|
|
||||||
const mobileMenu = document.getElementById("mobileMenu");
|
|
||||||
if (mobileMenu && mobileMenu.classList.contains("showing")) {
|
|
||||||
common.hideMobileMenu();
|
|
||||||
}
|
|
||||||
const mobileLanguageMenu = document.getElementById("mobileLanguageMenu");
|
|
||||||
if (mobileLanguageMenu && mobileLanguageMenu.classList.contains("showing")) {
|
|
||||||
common.hideMobileLanguageMenu();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 移动端语言菜单链接点击事件
|
|
||||||
const mobileLanguageMenuLinks = document.querySelectorAll("#mobileLanguageMenu a");
|
|
||||||
mobileLanguageMenuLinks.forEach(link => {
|
|
||||||
link.addEventListener("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示支持表单
|
|
||||||
const supportLinks = document.querySelectorAll("a.linkSupport");
|
|
||||||
supportLinks.forEach(link => {
|
|
||||||
link.addEventListener("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
common.showForm("support");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示联系表单
|
|
||||||
const contactLinks = document.querySelectorAll("a.linkContactUs");
|
|
||||||
contactLinks.forEach(link => {
|
|
||||||
link.addEventListener("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
common.showForm("contact");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 滚动到盒子容器
|
|
||||||
const scrollToBoxes = document.getElementById("scrollToBoxes");
|
|
||||||
if (scrollToBoxes) {
|
|
||||||
scrollToBoxes.addEventListener("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
common.scrollToElement("#pageBoxesContainer");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cookie 信息按钮点击事件
|
|
||||||
const cookieButtons = document.querySelectorAll('.cookiesInfo input[type="button"]');
|
|
||||||
cookieButtons.forEach(button => {
|
|
||||||
button.addEventListener("click", function() {
|
|
||||||
const parent = this.parentElement;
|
|
||||||
if (parent) {
|
|
||||||
parent.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initMobileMenu() {
|
|
||||||
// 移动端菜单标签点击事件
|
|
||||||
const mobileMenuLabels = document.querySelectorAll("#mobileMenu label");
|
|
||||||
mobileMenuLabels.forEach(label => {
|
|
||||||
label.addEventListener("click", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const subMenus = document.querySelectorAll("#mobileMenu .subMenu");
|
|
||||||
subMenus.forEach(subMenu => {
|
|
||||||
if (subMenu !== this.nextElementSibling) {
|
|
||||||
subMenu.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const hasSubmenuElements = document.querySelectorAll(".hasSubmenu");
|
|
||||||
hasSubmenuElements.forEach(element => {
|
|
||||||
if (element !== this) {
|
|
||||||
element.style.fontWeight = "normal";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.style.fontWeight = "bold";
|
|
||||||
const currentSubMenu = this.parentElement.querySelector(".subMenu");
|
|
||||||
if (currentSubMenu) {
|
|
||||||
currentSubMenu.style.display = 'block';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 移动端菜单链接点击事件
|
|
||||||
const mobileMenuLinks = document.querySelectorAll("#mobileMenu a");
|
|
||||||
mobileMenuLinks.forEach(link => {
|
|
||||||
link.addEventListener("click", function() {
|
|
||||||
common.hideMobileMenu();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initForms() {
|
|
||||||
// 退出表单按钮
|
|
||||||
const quitButtons = document.querySelectorAll(".btnQuitForm");
|
|
||||||
quitButtons.forEach(button => {
|
|
||||||
button.addEventListener("click", function() {
|
|
||||||
common.hide_element("#forms", true);
|
|
||||||
common.hide_element("#screenOverlay", true);
|
|
||||||
common.hide_element("#formContactContainer", true);
|
|
||||||
common.hide_element("#formSupportContainer", true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 支持表单提交
|
|
||||||
const supportForm = document.getElementById("formSupport");
|
|
||||||
if (supportForm) {
|
|
||||||
supportForm.addEventListener("submit", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
common.submitSupportForm(this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 联系表单提交
|
|
||||||
const contactForm = document.getElementById("formContact");
|
|
||||||
if (contactForm) {
|
|
||||||
contactForm.addEventListener("submit", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
common.submitContactForm(this);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showForm(formName) {
|
export function createContactPayload(values = {}) {
|
||||||
common.show_element("#forms", true);
|
return {
|
||||||
common.show_element("#screenOverlay", true);
|
name: values.name || '',
|
||||||
|
email: values.email || '',
|
||||||
const contactTable = document.querySelector(".contactTable");
|
phone: values.phone || '',
|
||||||
const formInputContainer = document.querySelector(".formInputContainer");
|
comments: values.comments || ''
|
||||||
const formResultContainer = document.querySelector(".formResultContainer");
|
|
||||||
|
|
||||||
if (contactTable) contactTable.style.display = 'table';
|
|
||||||
if (formInputContainer) formInputContainer.style.display = 'block';
|
|
||||||
if (formResultContainer) formResultContainer.style.display = 'none';
|
|
||||||
|
|
||||||
if (formName === "contact") {
|
|
||||||
const conCommentsTitle = document.querySelector("label[for='conComments']");
|
|
||||||
if (conCommentsTitle) {
|
|
||||||
const contactLinkElement = document.querySelector(".contentTableRight [data-contact-link]");
|
|
||||||
if (contactLinkElement && contactLinkElement.dataset.contactLink) {
|
|
||||||
conCommentsTitle.innerHTML = "Berätta vad du vill veta mer om gällande " +
|
|
||||||
contactLinkElement.dataset.contactLink + ": *";
|
|
||||||
} else {
|
|
||||||
conCommentsTitle.innerHTML = "Vad vill du veta mer om: ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
common.show_element("#formContactContainer", true);
|
|
||||||
} else if (formName === "support") {
|
|
||||||
common.show_element("#formSupportContainer", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
common.scrollToTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
submitSupportForm() {
|
|
||||||
// 使用原生 fetch API 替代 jQuery.post
|
|
||||||
const formData = {
|
|
||||||
subject: common.get_element_value("#supSubject", true),
|
|
||||||
company: common.get_element_value("#supCompany", true),
|
|
||||||
name: common.get_element_value("#supName", true),
|
|
||||||
email: common.get_element_value("#supEmail", true),
|
|
||||||
phone: common.get_element_value("#supPhone", true),
|
|
||||||
product: common.get_element_value("#supProduct", true),
|
|
||||||
comments: common.get_element_value("#supComments", true)
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch("http://biz199.inmotionhosting.com/~rustyt6/pythagoras/php/submit_support_form.php", {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(formData)
|
|
||||||
})
|
|
||||||
.then(response => response.text())
|
|
||||||
.then(data => {
|
|
||||||
console.log(data);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
common.hide_element("#formInputContainer", true);
|
|
||||||
common.show_element("#formResultContainer", true);
|
|
||||||
common.scrollToTop();
|
|
||||||
|
|
||||||
// 清空表单
|
|
||||||
common.set_element_value("#supSubject", "", true);
|
|
||||||
common.set_element_value("#supCompany", "", true);
|
|
||||||
common.set_element_value("#supName", "", true);
|
|
||||||
common.set_element_value("#supEmail", "", true);
|
|
||||||
common.set_element_value("#supPhone", "", true);
|
|
||||||
common.set_element_value("#supProduct", "", true);
|
|
||||||
common.set_element_value("#supComments", "", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
submitContactForm() {
|
|
||||||
// 使用原生 fetch API 替代 jQuery.post
|
|
||||||
const formData = {
|
|
||||||
name: common.get_element_value("#conName", true),
|
|
||||||
email: common.get_element_value("#conEmail", true),
|
|
||||||
phone: common.get_element_value("#conPhone", true),
|
|
||||||
comments: common.get_element_value("#conComments", true)
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch("http://biz199.inmotionhosting.com/~rustyt6/pythagoras/php/submit_contact_form.php", {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(formData)
|
|
||||||
})
|
|
||||||
.then(response => response.text())
|
|
||||||
.then(data => {
|
|
||||||
console.log(data);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
});
|
|
||||||
|
|
||||||
common.hide_element(".contactTable");
|
|
||||||
common.show_element("#formResultContainer", true);
|
|
||||||
common.scrollToTop();
|
|
||||||
|
|
||||||
// 清空表单
|
|
||||||
common.set_element_value("#conName", "", true);
|
|
||||||
common.set_element_value("#conEmail", "", true);
|
|
||||||
common.set_element_value("#conPhone", "", true);
|
|
||||||
common.set_element_value("#conComments", "", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
adjustContentBannersForScreen() {
|
|
||||||
if (this.isMobile()) {
|
|
||||||
const banner1 = document.getElementById("pageBannerImage1");
|
|
||||||
const banner2 = document.getElementById("pageBannerImage2");
|
|
||||||
const banner3 = document.getElementById("pageBannerImage3");
|
|
||||||
|
|
||||||
if (banner1) banner1.src = "images/banner_page_mobile_solutions_mobile.jpg";
|
|
||||||
if (banner2) banner2.src = "images/banner_page_ifrs16_mobile.jpg";
|
|
||||||
if (banner3) banner3.src = "images/banner_page_gdpr_mobile.jpg";
|
|
||||||
} else {
|
|
||||||
const banner1 = document.getElementById("pageBannerImage1");
|
|
||||||
const banner2 = document.getElementById("pageBannerImage2");
|
|
||||||
const banner3 = document.getElementById("pageBannerImage3");
|
|
||||||
|
|
||||||
if (banner1) banner1.src = "images/banner_page_mobile_solutions.jpg";
|
|
||||||
if (banner2) banner2.src = "images/banner_page_ifrs16.jpg";
|
|
||||||
if (banner3) banner3.src = "images/banner_page_gdpr.jpg";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showMobileMenu() {
|
export function submitSupportPayload(values, endpoint = process.env.VUE_APP_SUPPORT_FORM_ENDPOINT) {
|
||||||
common.show_element("#screenOverlayBehindHeader", true);
|
return submitJsonForm(endpoint, createSupportPayload(values))
|
||||||
const mobileMenu = document.getElementById("mobileMenu");
|
|
||||||
if (mobileMenu) {
|
|
||||||
mobileMenu.style.display = 'block';
|
|
||||||
common.add_class("mobileMenu", "showing", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hideMobileMenu() {
|
export function submitContactPayload(values, endpoint = process.env.VUE_APP_CONTACT_FORM_ENDPOINT) {
|
||||||
const mobileMenu = document.getElementById("mobileMenu");
|
return submitJsonForm(endpoint, createContactPayload(values))
|
||||||
if (mobileMenu) {
|
|
||||||
mobileMenu.style.display = 'none';
|
|
||||||
common.hide_element("#screenOverlayBehindHeader", true);
|
|
||||||
common.remove_class("mobileMenu", "showing", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showMobileLanguageMenu() {
|
export const common = {
|
||||||
common.show_element("#screenOverlayBehindHeader", true);
|
isMobileUserAgent,
|
||||||
const mobileLanguageMenu = document.getElementById("mobileLanguageMenu");
|
normalizeBasePath,
|
||||||
if (mobileLanguageMenu) {
|
createSupportPayload,
|
||||||
mobileLanguageMenu.style.display = 'block';
|
createContactPayload,
|
||||||
common.add_class("mobileLanguageMenu", "showing", true);
|
submitSupportPayload,
|
||||||
|
submitContactPayload
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hideMobileLanguageMenu() {
|
|
||||||
const mobileLanguageMenu = document.getElementById("mobileLanguageMenu");
|
|
||||||
if (mobileLanguageMenu) {
|
|
||||||
mobileLanguageMenu.style.display = 'none';
|
|
||||||
common.hide_element("#screenOverlayBehindHeader", true);
|
|
||||||
common.remove_class("mobileLanguageMenu", "showing", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToTop() {
|
|
||||||
window.scrollTo({
|
|
||||||
top: 0,
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isMobile() {
|
|
||||||
var ua = navigator.userAgent;
|
|
||||||
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
|
|
||||||
isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
|
|
||||||
isAndroid = ua.match(/(Android)\s+([\d.]+)/),
|
|
||||||
isMobile = isIphone || isAndroid;
|
|
||||||
|
|
||||||
return isMobile;
|
|
||||||
}
|
|
||||||
|
|
||||||
isPhone() {
|
|
||||||
var ua = navigator.userAgent;
|
|
||||||
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
|
|
||||||
var isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
|
|
||||||
return isIphone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const common = new Common();
|
|
||||||
27
src/static/form_submit.js
Normal file
27
src/static/form_submit.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
export function submitJsonForm(endpoint, formData) {
|
||||||
|
if (!endpoint || !/^https:\/\//i.test(endpoint)) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: false,
|
||||||
|
status: 'missing_endpoint',
|
||||||
|
message: 'Form endpoint must be configured with an HTTPS URL.'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(formData)
|
||||||
|
})
|
||||||
|
.then(response => response.text().then(text => ({
|
||||||
|
ok: response.ok,
|
||||||
|
status: response.ok ? 'success' : 'error',
|
||||||
|
message: text
|
||||||
|
})))
|
||||||
|
.catch(error => ({
|
||||||
|
ok: false,
|
||||||
|
status: 'error',
|
||||||
|
message: error.message
|
||||||
|
}))
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
1265
src/views/index.vue
1265
src/views/index.vue
File diff suppressed because it is too large
Load Diff
156
src/views/legal/LegalPage.vue
Normal file
156
src/views/legal/LegalPage.vue
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<template>
|
||||||
|
<div class="legal-page">
|
||||||
|
<ihead></ihead>
|
||||||
|
<main>
|
||||||
|
<section class="legal-hero">
|
||||||
|
<div class="container">
|
||||||
|
<h1>{{ page.title }}</h1>
|
||||||
|
<p>{{ page.description }}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="legal-content">
|
||||||
|
<div class="container narrow">
|
||||||
|
<article v-for="section in page.sections" :key="section.title" class="legal-section">
|
||||||
|
<h2>{{ section.title }}</h2>
|
||||||
|
<p>{{ section.text }}</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<ifooter></ifooter>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ihead from '@/components/ihead.vue'
|
||||||
|
import ifooter from '@/components/ifooter.vue'
|
||||||
|
|
||||||
|
const pages = {
|
||||||
|
privacy: {
|
||||||
|
title: '隐私政策',
|
||||||
|
description: '本页面说明我们如何处理通过官网产生的基本联系信息。',
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
title: '信息收集',
|
||||||
|
text: '当您通过电话、邮箱或咨询入口与我们联系时,我们可能会接收姓名、联系方式、公司信息和业务需求描述。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '使用目的',
|
||||||
|
text: '相关信息仅用于需求沟通、方案评估、项目联系和必要的客户服务,不用于无关用途。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '信息保护',
|
||||||
|
text: '我们会采取合理的访问控制和内部管理措施,降低信息未经授权访问、披露或滥用的风险。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
terms: {
|
||||||
|
title: '服务条款',
|
||||||
|
description: '本页面说明官网内容和咨询服务的基本使用边界。',
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
title: '内容说明',
|
||||||
|
text: '官网展示的案例、收益和方案说明用于介绍服务能力,具体交付范围以双方确认的项目文件为准。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '咨询沟通',
|
||||||
|
text: '初步咨询用于判断业务场景与技术路径,不构成最终承诺或完整实施方案。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '知识产权',
|
||||||
|
text: '官网文字、图片、标识和页面设计受相关法律保护,未经授权不得复制、改编或用于商业传播。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
compliance: {
|
||||||
|
title: '数据合规说明',
|
||||||
|
description: '本页面说明我们在数据处理和系统交付中的基本合规原则。',
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
title: '最小必要',
|
||||||
|
text: '项目实施中优先使用达成目标所需的最小数据范围,并在方案设计阶段明确数据边界。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '权限控制',
|
||||||
|
text: '系统集成与应用交付会结合客户现有权限体系设计访问控制、日志记录和操作留痕。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '交付留痕',
|
||||||
|
text: '关键配置、接口、模型调用和运维动作尽量形成可追踪记录,便于复盘、审计和持续优化。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LegalPage',
|
||||||
|
components: {
|
||||||
|
ihead,
|
||||||
|
ifooter
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
page() {
|
||||||
|
return pages[this.$route.params.type] || pages.privacy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.legal-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1180px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.narrow {
|
||||||
|
max-width: 820px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-hero {
|
||||||
|
padding: 154px 0 76px;
|
||||||
|
background: #0f172a;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-hero h1 {
|
||||||
|
margin: 0 0 16px;
|
||||||
|
font-size: 44px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-hero p {
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 0;
|
||||||
|
color: rgba(255, 255, 255, 0.76);
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-content {
|
||||||
|
padding: 72px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section {
|
||||||
|
padding: 28px 0;
|
||||||
|
border-bottom: 1px solid #e4e7ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section h2 {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
color: #101828;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section p {
|
||||||
|
margin: 0;
|
||||||
|
color: #667085;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<div class="content-section">
|
<div class="content-section">
|
||||||
<h3 class="section-title">AI技术优势</h3>
|
<h3 class="section-title">AI技术优势</h3>
|
||||||
<p class="section-text">
|
<p class="section-text">
|
||||||
我们运用最前沿的人工智能技术,为企业提供智能化解决方案。通过机器学习、深度学习、自然语言处理等AI技术,帮助企业实现数字化转型,提升运营效率。
|
我们围绕业务流程、数据质量和系统集成条件设计智能应用方案,帮助企业把知识检索、数据分析、自动化处理等能力接入现有业务。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -26,22 +26,22 @@
|
|||||||
<h3 class="section-title">核心AI服务</h3>
|
<h3 class="section-title">核心AI服务</h3>
|
||||||
<div class="ai-services">
|
<div class="ai-services">
|
||||||
<div class="service-item">
|
<div class="service-item">
|
||||||
<div class="service-icon">📊</div>
|
<div class="service-icon">DA</div>
|
||||||
<h4>智能数据分析</h4>
|
<h4>智能数据分析</h4>
|
||||||
<p>利用AI算法分析海量数据,挖掘商业价值,为决策提供数据支撑。</p>
|
<p>利用AI算法分析海量数据,挖掘商业价值,为决策提供数据支撑。</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="service-item">
|
<div class="service-item">
|
||||||
<div class="service-icon">💬</div>
|
<div class="service-icon">CS</div>
|
||||||
<h4>智能客服系统</h4>
|
<h4>智能客服系统</h4>
|
||||||
<p>基于NLP技术的智能客服,24/7全天候服务,提升客户体验。</p>
|
<p>基于NLP技术的智能客服,24/7全天候服务,提升客户体验。</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="service-item">
|
<div class="service-item">
|
||||||
<div class="service-icon">🔮</div>
|
<div class="service-icon">PM</div>
|
||||||
<h4>预测性维护</h4>
|
<h4>预测性维护</h4>
|
||||||
<p>通过AI预测设备故障,实现预防性维护,降低维护成本。</p>
|
<p>通过AI预测设备故障,实现预防性维护,降低维护成本。</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="service-item">
|
<div class="service-item">
|
||||||
<div class="service-icon">👁️</div>
|
<div class="service-icon">CV</div>
|
||||||
<h4>智能图像识别</h4>
|
<h4>智能图像识别</h4>
|
||||||
<p>计算机视觉技术,实现自动化检测、质量控制和安防监控。</p>
|
<p>计算机视觉技术,实现自动化检测、质量控制和安防监控。</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<div class="services-grid">
|
<div class="services-grid">
|
||||||
<div class="service-card">
|
<div class="service-card">
|
||||||
<div class="service-icon">🏢</div>
|
<div class="service-icon">BLD</div>
|
||||||
<h3>建筑维护</h3>
|
<h3>建筑维护</h3>
|
||||||
<p>定期检查、预防性维护、应急响应,确保建筑设施始终处于最佳状态</p>
|
<p>定期检查、预防性维护、应急响应,确保建筑设施始终处于最佳状态</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,13 +30,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="service-card">
|
<div class="service-card">
|
||||||
<div class="service-icon">📊</div>
|
<div class="service-icon">DAT</div>
|
||||||
<h3>数据分析</h3>
|
<h3>数据分析</h3>
|
||||||
<p>运营数据收集、性能分析、优化建议,数据驱动的决策支持</p>
|
<p>运营数据收集、性能分析、优化建议,数据驱动的决策支持</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="service-card">
|
<div class="service-card">
|
||||||
<div class="service-icon">👥</div>
|
<div class="service-icon">OPS</div>
|
||||||
<h3>人员管理</h3>
|
<h3>人员管理</h3>
|
||||||
<p>工作流程优化、任务分配、绩效评估,提升团队工作效率</p>
|
<p>工作流程优化、任务分配、绩效评估,提升团队工作效率</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -86,12 +86,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
ihead,
|
ihead,
|
||||||
ifooter
|
ifooter
|
||||||
},
|
}
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
msg: 'Welcome to Your Vue.js App',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,6 @@ export default {
|
|||||||
ihead,
|
ihead,
|
||||||
ifooter
|
ifooter
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
msg: 'Welcome to Your Vue.js App',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {},
|
mounted() {},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -23,14 +23,14 @@
|
|||||||
<h3 class="section-title">核心服务</h3>
|
<h3 class="section-title">核心服务</h3>
|
||||||
<div class="services-grid">
|
<div class="services-grid">
|
||||||
<div class="service-card">
|
<div class="service-card">
|
||||||
<div class="service-icon">🏗️</div>
|
<div class="service-icon">BIM</div>
|
||||||
<h4>AI智能建筑</h4>
|
<h4>AI智能建筑</h4>
|
||||||
<p>运用AI技术打造智能化建筑,通过机器学习优化建筑管理效率和用户体验。</p>
|
<p>运用AI技术打造智能化建筑,通过机器学习优化建筑管理效率和用户体验。</p>
|
||||||
<router-link to="/ourPlan/estateManagement" class="service-link">了解更多</router-link>
|
<router-link to="/ourPlan/estateManagement" class="service-link">了解更多</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="service-card">
|
<div class="service-card">
|
||||||
<div class="service-icon">🌐</div>
|
<div class="service-icon">IoT</div>
|
||||||
<h4>AI物联网</h4>
|
<h4>AI物联网</h4>
|
||||||
<p>构建AI驱动的物联网生态系统,实现智能设备互联互通和自动化控制。</p>
|
<p>构建AI驱动的物联网生态系统,实现智能设备互联互通和自动化控制。</p>
|
||||||
<router-link to="/ourPlan/iot" class="service-link">了解更多</router-link>
|
<router-link to="/ourPlan/iot" class="service-link">了解更多</router-link>
|
||||||
@@ -69,16 +69,16 @@
|
|||||||
<h3 class="section-title">为什么选择我们?</h3>
|
<h3 class="section-title">为什么选择我们?</h3>
|
||||||
<div class="features">
|
<div class="features">
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
<h4>AI专家团队</h4>
|
<h4>场景评估清晰</h4>
|
||||||
<p>拥有丰富的AI项目经验和深度学习技术能力</p>
|
<p>先确认数据、流程和系统边界,再确定可交付范围</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
<h4>前沿AI技术</h4>
|
<h4>系统对接可控</h4>
|
||||||
<p>持续关注AI前沿技术,提供最新智能解决方案</p>
|
<p>围绕现有业务系统设计接口、权限和运行监控</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
<h4>AI全流程服务</h4>
|
<h4>结果指标明确</h4>
|
||||||
<p>从AI咨询到实施落地,确保智能化转型成功</p>
|
<p>以效率、工时、响应时长等指标验收交付效果</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<h2>集成方案</h2>
|
<h2>集成方案</h2>
|
||||||
<div class="methods-grid">
|
<div class="methods-grid">
|
||||||
<div class="method-card">
|
<div class="method-card">
|
||||||
<div class="method-icon">🔌</div>
|
<div class="method-icon">API</div>
|
||||||
<h3>API集成</h3>
|
<h3>API集成</h3>
|
||||||
<p>提供标准化的RESTful API接口,支持多种数据格式,实现系统间的无缝连接</p>
|
<p>提供标准化的RESTful API接口,支持多种数据格式,实现系统间的无缝连接</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="method-card">
|
<div class="method-card">
|
||||||
<div class="method-icon">🌐</div>
|
<div class="method-icon">MID</div>
|
||||||
<h3>中间件集成</h3>
|
<h3>中间件集成</h3>
|
||||||
<p>基于企业级中间件技术,实现复杂业务系统的深度集成</p>
|
<p>基于企业级中间件技术,实现复杂业务系统的深度集成</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="method-card">
|
<div class="method-card">
|
||||||
<div class="method-icon">📱</div>
|
<div class="method-icon">ETL</div>
|
||||||
<h3>数据集成</h3>
|
<h3>数据集成</h3>
|
||||||
<p>实现多源数据的统一采集、清洗和同步,构建企业数据中台</p>
|
<p>实现多源数据的统一采集、清洗和同步,构建企业数据中台</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
<h2>服务优势</h2>
|
<h2>服务优势</h2>
|
||||||
<div class="features-list">
|
<div class="features-list">
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
<div class="feature-icon">☁️</div>
|
<div class="feature-icon">CLD</div>
|
||||||
<div class="feature-content">
|
<div class="feature-content">
|
||||||
<h4>云端部署</h4>
|
<h4>云端部署</h4>
|
||||||
<p>基于云原生架构,支持弹性扩展,确保系统高可用性和稳定性</p>
|
<p>基于云原生架构,支持弹性扩展,确保系统高可用性和稳定性</p>
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
<div class="feature-icon">🔒</div>
|
<div class="feature-icon">SEC</div>
|
||||||
<div class="feature-content">
|
<div class="feature-content">
|
||||||
<h4>安全可靠</h4>
|
<h4>安全可靠</h4>
|
||||||
<p>多层次安全防护,支持企业级权限管理,确保数据安全和系统稳定</p>
|
<p>多层次安全防护,支持企业级权限管理,确保数据安全和系统稳定</p>
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
<div class="feature-icon">📊</div>
|
<div class="feature-icon">OPS</div>
|
||||||
<div class="feature-content">
|
<div class="feature-content">
|
||||||
<h4>统一管理</h4>
|
<h4>统一管理</h4>
|
||||||
<p>提供统一的系统管理界面,简化运维操作,提升管理效率</p>
|
<p>提供统一的系统管理界面,简化运维操作,提升管理效率</p>
|
||||||
@@ -100,12 +100,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
ihead,
|
ihead,
|
||||||
ifooter
|
ifooter
|
||||||
},
|
}
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
msg: 'Welcome to Your Vue.js App',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user