7.31更新

This commit is contained in:
hrx 2026-07-31 16:09:44 +08:00
parent c1bacfd965
commit 08cc6e012b
4 changed files with 66 additions and 77 deletions

View File

@ -1,5 +1,5 @@
<template>
<div class="contract-case-page" :class="{ 'has-fixed-tabs': isTabsFixed }">
<div class="contract-case-page">
<div class="decor decor--blue"></div>
<div class="decor decor--purple"></div>
@ -14,7 +14,7 @@
</div>
</section>
<section ref="caseTabs" class="case-tabs" :class="{ 'is-fixed': isTabsFixed }">
<section class="case-tabs">
<div class="case-container">
<button
v-for="tab in tabs"
@ -237,7 +237,6 @@
</section>
</main>
</div>
</template>
@ -247,8 +246,6 @@ export default {
data() {
return {
activeTab: 'scenarios',
isTabsFixed: false,
tabsOriginTop: 0,
bannerImg: require('@/assets/image/bgimg.png'),
tabs: [
{ id: 'scenarios', label: '应用场景' },
@ -338,7 +335,6 @@ export default {
this.$nextTick(() => {
const scroller = this.getScrollContainer()
this.resetScrollTop(scroller)
this.refreshTabsOrigin()
scroller.addEventListener('scroll', this.handlePageScroll, { passive: true })
this.handlePageScroll()
})
@ -356,15 +352,6 @@ export default {
} else {
scroller.scrollTop = 0
}
this.isTabsFixed = false
},
refreshTabsOrigin() {
const scroller = this.getScrollContainer()
this.tabsOriginTop = this.getElementTopInScroller(this.$refs.caseTabs, scroller)
},
getScrollOffset() {
const tabs = this.$el.querySelector('.case-tabs')
return (tabs ? tabs.offsetHeight : 0) + 12
},
getElementTopInScroller(element, scroller) {
if (scroller === window) {
@ -380,14 +367,13 @@ export default {
const element = this.$el.querySelector(`#${sectionName}`)
if (!element) return
const scroller = this.getScrollContainer()
const top = this.getElementTopInScroller(element, scroller) - this.getScrollOffset()
const top = this.getElementTopInScroller(element, scroller)
scroller.scrollTo({ top, behavior: 'smooth' })
},
handlePageScroll() {
const scroller = this.getScrollContainer()
const scrollerTop = this.getScrollerTop(scroller)
this.isTabsFixed = scrollerTop >= this.tabsOriginTop
const offsetTop = scrollerTop + this.getScrollOffset() + 24
const offsetTop = scrollerTop + 24
const currentTab = this.tabs
.map(tab => {
const element = this.$el.querySelector(`#${tab.id}`)
@ -493,27 +479,12 @@ export default {
}
.case-tabs {
position: sticky;
top: 0;
z-index: 80;
height: 60px;
background: #fff;
border-bottom: 1px solid #e5e7eb;
box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06);
}
.case-tabs.is-fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
}
.contract-case-page.has-fixed-tabs .case-main {
padding-top: 60px;
}
.case-tabs .case-container {
display: flex;
align-items: center;

View File

@ -1,12 +1,12 @@
<template>
<div class="decision-case-page" :class="{ 'has-fixed-tabs': isTabsFixed }">
<div class="decision-case-page">
<div class="decor decor--blue"></div>
<div class="decor decor--purple"></div>
<div class="decor decor--deep-blue"></div>
<div class="decor decor--deep-purple"></div>
<section class="case-hero">
<img class="case-hero__bg" :src="bannerImg" alt="" @load="refreshTabsOrigin">
<img class="case-hero__bg" :src="bannerImg" alt="">
<div class="case-container">
<div class="case-hero__content">
<h1>投策智能体</h1>
@ -17,7 +17,7 @@
</div>
</section>
<section ref="caseTabs" class="case-tabs" :class="{ 'is-fixed': isTabsFixed }">
<section class="case-tabs">
<div class="case-container">
<button
v-for="tab in tabs"
@ -156,8 +156,6 @@ export default {
data() {
return {
activeTab: 'scenarios',
isTabsFixed: false,
tabsOriginTop: 0,
tabs: [
{ id: 'scenarios', label: '应用场景' },
{ id: 'solution', label: '解决方案' },
@ -238,7 +236,6 @@ export default {
this.$nextTick(() => {
const scroller = this.getScrollContainer()
this.resetScrollTop(scroller)
this.refreshTabsOrigin()
scroller.addEventListener('scroll', this.handlePageScroll, { passive: true })
this.handlePageScroll()
})
@ -256,16 +253,6 @@ export default {
} else {
scroller.scrollTop = 0
}
this.isTabsFixed = false
},
refreshTabsOrigin() {
const scroller = this.getScrollContainer()
this.tabsOriginTop = this.getElementTopInScroller(this.$refs.caseTabs, scroller)
},
getScrollOffset() {
const tabs = this.$el.querySelector('.case-tabs')
const tabsHeight = tabs ? tabs.offsetHeight : 0
return tabsHeight + 12
},
getElementTopInScroller(element, scroller) {
if (scroller === window) {
@ -281,16 +268,14 @@ export default {
const element = this.$el.querySelector(`#${sectionName}`)
if (element) {
const scroller = this.getScrollContainer()
const offset = this.getScrollOffset()
const top = this.getElementTopInScroller(element, scroller) - offset
const top = this.getElementTopInScroller(element, scroller)
scroller.scrollTo({ top, behavior: 'smooth' })
}
},
handlePageScroll() {
const scroller = this.getScrollContainer()
const scrollerTop = this.getScrollerTop(scroller)
this.isTabsFixed = scrollerTop >= this.tabsOriginTop
const offsetTop = scrollerTop + this.getScrollOffset() + 24
const offsetTop = scrollerTop + 24
const currentTab = this.tabs
.map(tab => {
const element = this.$el.querySelector(`#${tab.id}`)
@ -441,27 +426,12 @@ export default {
}
.case-tabs {
position: sticky;
top: 0;
z-index: 80;
background: #fff;
height: 60px;
border-bottom: 1px solid #e5e7eb;
box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06);
}
.case-tabs.is-fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
}
.decision-case-page.has-fixed-tabs .case-main {
padding-top: 60px;
}
.case-tabs .case-container {
display: flex;
align-items: center;

View File

@ -8,7 +8,7 @@
<section class="home-hero">
<div class="home-hero__inner animate-in">
<div class="hero-title-row">
<h1>{{ $t('home.heroTitle') }}</h1>
<h1 :class="{ 'home-hero__title--english': isEnglish }">{{ $t('home.heroTitle') }}</h1>
</div>
<h2 v-if="$t('home.heroSubtitle')">{{ $t('home.heroSubtitle') }}</h2>
<!-- <p>{{ $t('home.heroSlogan') }}</p> -->
@ -339,6 +339,9 @@ export default {
showTalkVisible() {
return this.$store.state.product.showTalk
},
isEnglish() {
return this.$i18n && this.$i18n.locale === 'en-US'
},
localizedSolutionCards() {
const keyMap = {
'群智协作': 'collaboration',
@ -659,6 +662,12 @@ body.dark-theme .bg-orb {
letter-spacing: 0.02em;
}
.home-hero__title--english {
font-size: clamp(40px, 5vw, 58px);
letter-spacing: 0.01em;
white-space: nowrap;
}
h2 {
margin: 20px 0 0;
font-size: 72px;
@ -690,6 +699,13 @@ body.dark-theme .bg-orb {
flex-wrap: wrap;
}
@media (max-width: 768px) {
.home-hero__inner .home-hero__title--english {
font-size: clamp(32px, 9vw, 48px);
white-space: normal;
}
}
.hero-actions {
display: flex;
align-items: center;

View File

@ -123,7 +123,7 @@
<el-input v-model.trim="english.title" placeholder="Enter article title" />
</div>
<div class="language-field language-field--wide">
<label>English Summary</label>
<label>Intro</label>
<el-input
v-model.trim="english.summary"
type="textarea"
@ -172,7 +172,7 @@
<div class="language-richtext">
<div class="language-richtext__head">
<span>English Content</span>
<small>Rich text editor</small>
</div>
<div v-if="dialogVisible" class="wang-editor-wrap wang-editor-wrap--english">
<Toolbar
@ -220,7 +220,7 @@
<div slot="footer" class="article-editor-footer">
<span class="editor-status">{{ dirty ? '未保存' : '已同步' }}</span>
<div>
<div class="editor-footer-buttons">
<el-button size="small" @click="requestClose">取消</el-button>
<el-button size="small" @click="handleSave('0')">保存草稿</el-button>
<el-button type="primary" size="small" @click="handlePublishConfirm">保存并发布</el-button>
@ -282,7 +282,7 @@ export default {
}
},
englishEditorConfig: {
placeholder: 'Start writing the English version of your article...',
placeholder: 'Please enter article content…',
MENU_CONF: {
uploadImage: {
customUpload: async(file, insertFn) => {
@ -705,13 +705,18 @@ export default {
margin-right: 4px;
}
::v-deep .article-editor-dialog {
--article-editor-radius: 8px;
margin: 0 !important;
height: 100vh;
display: flex;
flex-direction: column;
flex-shrink: 0;
padding:0 24px!important;
padding-top: 16px;
border-bottom: 1px solid #edf0f5;
}
::v-deep .article-editor-dialog .el-dialog__header {
::v-deep .el-dialog__header {
flex-shrink: 0;
padding: 16px 24px;
border-bottom: 1px solid #edf0f5;
@ -735,7 +740,7 @@ export default {
font-size: 13px;
background: #fff;
border: 1px solid #d8e0ec;
border-radius: 999px;
border-radius: var(--article-editor-radius);
cursor: pointer;
transition: all 0.2s ease;
}
@ -754,11 +759,20 @@ export default {
}
::v-deep .article-editor-dialog .el-dialog__footer {
width: 100%;
height: 60px;
min-height: 60px;
flex-shrink: 0;
padding: 14px 24px;
padding: 0 24px !important;
display: flex;
align-items: center;
box-sizing: border-box;
border-top: 1px solid #edf0f5;
}
::v-deep .article-editor-dialog .el-button {
border-radius: var(--article-editor-radius);
}
.article-editor {
height: 100%;
display: flex;
@ -1032,7 +1046,7 @@ export default {
color: #94a3b8;
font-size: 12px;
background: #fff;
border: 1px solid #dcdfe6;
/* border: 1px solid #dcdfe6; */
border-radius: 4px;
}
@ -1249,13 +1263,31 @@ export default {
}
.article-editor-footer {
width: 100%;
height: 100%;
min-height: 0;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
}
.editor-status {
color: #9ca3af;
font-size: 12px;
}
.editor-footer-buttons {
display: flex;
align-items: center;
padding: 0;
gap: 10px;
.el-button {
min-height: 32px;
margin-left: 0 !important;
border-radius: var(--article-editor-radius);
}
}
</style>