diff --git a/f/web-kboss/src/assets/less/news/news.less b/f/web-kboss/src/assets/less/news/news.less
index a70e549..d66c293 100644
--- a/f/web-kboss/src/assets/less/news/news.less
+++ b/f/web-kboss/src/assets/less/news/news.less
@@ -1,7 +1,10 @@
.news-view-page {
position: relative;
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
min-height: 100vh;
- overflow-x: hidden;
+ overflow-x: clip;
color: #1f2937;
background:
radial-gradient(circle at 78% 18%, rgba(236, 72, 153, 0.07) 0%, rgba(236, 72, 153, 0) 32%),
@@ -12,13 +15,15 @@
.news-shell {
position: relative;
z-index: 1;
- max-width: 1280px;
+ box-sizing: border-box;
+ width: 100%;
+ max-width: 1400px;
margin: 0 auto;
padding: 0 24px;
}
.orb {
- position: fixed;
+ position: absolute;
z-index: 0;
border-radius: 50%;
filter: blur(110px);
@@ -196,6 +201,8 @@
.news-featured,
.news-item {
position: relative;
+ width: 100%;
+ max-width: 100%;
overflow: hidden;
cursor: pointer;
background: #fff;
@@ -253,11 +260,19 @@
.news-featured-inner {
display: grid;
- grid-template-columns: 1fr 2fr;
- min-height: 180px;
+ grid-template-columns: minmax(280px, 380px) minmax(0, 1fr);
+ align-items: stretch;
+ width: 100%;
+ min-height: 280px;
}
-
- .news-featured-img,
+
+ .news-featured-img {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ min-height: 280px;
+ }
+
.news-item-img {
position: relative;
overflow: hidden;
@@ -280,6 +295,8 @@
display: flex;
flex-direction: column;
justify-content: center;
+ min-width: 0;
+ width: 100%;
padding: 24px 40px;
}
@@ -484,13 +501,22 @@
.news-hero {
padding: 120px 0 56px;
}
-
+
.hero-title-row {
flex-direction: column;
gap: 10px;
align-items: flex-start;
}
-
+
+ .news-featured-inner {
+ grid-template-columns: 1fr;
+ }
+
+ .news-featured-img {
+ width: 100%;
+ min-height: 220px;
+ }
+
.filter-tabs {
display: flex;
border-radius: 20px;
@@ -501,16 +527,11 @@
padding: 8px 16px;
font-size: 14px;
}
-
- .news-featured-inner,
+
.news-grid {
grid-template-columns: 1fr;
}
-
- .news-featured-img {
- height: 220px;
- }
-
+
.news-featured-body {
padding: 24px;
}
diff --git a/f/web-kboss/src/i18n/lang/en-US.js b/f/web-kboss/src/i18n/lang/en-US.js
index 3514dc2..823fd09 100644
--- a/f/web-kboss/src/i18n/lang/en-US.js
+++ b/f/web-kboss/src/i18n/lang/en-US.js
@@ -401,5 +401,59 @@ export default {
openedDecision: 'The Investment Strategy Agent page has been opened.
Anything else you would like to know?',
openedPage: 'The related page has been opened. Anything else you would like to know?'
},
+ loginDialog: {
+ welcomeLogin: 'Welcome',
+ createAccount: 'Create Account',
+ signIn: 'Sign In',
+ signUp: 'Sign Up',
+ signInWithPassword: 'Password',
+ signInWithCode: 'Verification Code',
+ enterAccount: 'Enter account',
+ enterPassword: 'Enter password',
+ enterMobile: 'Enter mobile number',
+ enterVerificationCode: 'Enter verification code',
+ enterAccountName: 'Enter account name',
+ forgotPassword: 'Forgot password?',
+ noAccountSignUp: 'No account? Sign Up',
+ signInNow: 'Sign In',
+ getVerificationCode: 'Get Verification Code',
+ agreePrefix: 'I have read and agree to the ',
+ userAgreement: 'User Agreement',
+ agreeAnd: ' and ',
+ privacyPolicy: 'Privacy Policy',
+ signUpNow: 'Sign Up',
+ hasAccountSignIn: 'Already have an account? Sign In',
+ signingIn: 'Signing in...',
+ signingUp: 'Signing up...',
+ resendCode: 'Resend {seconds}s',
+ mobileRequired: 'Enter mobile number',
+ mobileInvalid: 'Please enter a valid mobile number',
+ accountRequired: 'Enter account',
+ passwordRequired: 'Enter password',
+ codeRequired: 'Enter verification code',
+ accountNameRequired: 'Enter account name',
+ agreeRequired: 'Please read and agree to the agreements first',
+ codeSent: 'Verification code sent',
+ codeSendFail: 'Failed to get verification code',
+ loginFail: 'Sign in failed',
+ loginSuccess: 'Signed in successfully',
+ registerSuccess: 'Registration successful. Please sign in.',
+ registerFail: 'Registration failed',
+ registerRetry: 'Registration failed. Please try again.',
+ resetPassword: 'Reset Password',
+ resetPasswordDesc: 'Verify identity via mobile verification code to set a new password',
+ mobileLabel: 'Mobile Number',
+ newPasswordLabel: 'New Password',
+ verificationCodeLabel: 'Verification Code',
+ enterBoundMobile: 'Enter bound mobile number',
+ enterNewPassword: 'Enter new password',
+ cancel: 'Cancel',
+ confirmReset: 'Confirm Reset',
+ newPasswordRequired: 'Enter new password',
+ getCodeFirst: 'Please get the verification code first',
+ resetSuccess: 'Password reset successfully',
+ resetFail: 'Password reset failed',
+ codeSentCheck: 'Verification code sent. Please check your messages.'
+ },
...autoMessages
}
diff --git a/f/web-kboss/src/i18n/lang/zh-CN.js b/f/web-kboss/src/i18n/lang/zh-CN.js
index 09ec8bd..4925636 100644
--- a/f/web-kboss/src/i18n/lang/zh-CN.js
+++ b/f/web-kboss/src/i18n/lang/zh-CN.js
@@ -401,5 +401,59 @@ export default {
openedDecision: '已为您打开投策智能体页面 📊
还有其他想了解的吗?',
openedPage: '已为您打开相关页面。还有其他想了解的吗?'
},
+ loginDialog: {
+ welcomeLogin: '欢迎登录',
+ createAccount: '创建账号',
+ signIn: '登录',
+ signUp: '注册',
+ signInWithPassword: '密码登录',
+ signInWithCode: '验证码登录',
+ enterAccount: '请输入账户',
+ enterPassword: '请输入密码',
+ enterMobile: '请输入手机号',
+ enterVerificationCode: '请输入验证码',
+ enterAccountName: '请输入账户名',
+ forgotPassword: '忘记密码?',
+ noAccountSignUp: '没有账号?去注册',
+ signInNow: '立即登录',
+ getVerificationCode: '获取验证码',
+ agreePrefix: '我已阅读并同意',
+ userAgreement: '《用户协议》',
+ agreeAnd: '、',
+ privacyPolicy: '《隐私政策》',
+ signUpNow: '立即注册',
+ hasAccountSignIn: '已有账号?前往登录',
+ signingIn: '登录中...',
+ signingUp: '注册中...',
+ resendCode: '重新发送 {seconds}s',
+ mobileRequired: '请输入手机号',
+ mobileInvalid: '请输入正确的手机号',
+ accountRequired: '请输入账户',
+ passwordRequired: '请输入密码',
+ codeRequired: '请输入验证码',
+ accountNameRequired: '请输入账户名',
+ agreeRequired: '请先阅读并同意相关协议',
+ codeSent: '验证码已发送',
+ codeSendFail: '验证码获取失败',
+ loginFail: '登录失败',
+ loginSuccess: '登录成功',
+ registerSuccess: '注册成功,请登录',
+ registerFail: '注册失败',
+ registerRetry: '注册失败,请重试',
+ resetPassword: '重置密码',
+ resetPasswordDesc: '通过手机号验证码验证身份后设置新密码',
+ mobileLabel: '手机号',
+ newPasswordLabel: '新密码',
+ verificationCodeLabel: '验证码',
+ enterBoundMobile: '请输入绑定手机号',
+ enterNewPassword: '请输入新密码',
+ cancel: '取消',
+ confirmReset: '确认重置',
+ newPasswordRequired: '请输入新密码',
+ getCodeFirst: '请先获取验证码',
+ resetSuccess: '密码重置成功',
+ resetFail: '密码重置失败',
+ codeSentCheck: '验证码已发送,请注意查收。'
+ },
...autoMessages
}
diff --git a/f/web-kboss/src/main.js b/f/web-kboss/src/main.js
index 384c4fb..58e0453 100644
--- a/f/web-kboss/src/main.js
+++ b/f/web-kboss/src/main.js
@@ -12,6 +12,7 @@ import 'xterm/css/xterm.css'
// import 'lib-flexible/flexible'
import '@/styles/index.scss' // global css
+import '@/assets/less/news/news.less'
import globalMixin from '@/mixin/globalMixin'; // 替换为实际的文件路径
diff --git a/f/web-kboss/src/router/index.js b/f/web-kboss/src/router/index.js
index 0af589b..8e21726 100644
--- a/f/web-kboss/src/router/index.js
+++ b/f/web-kboss/src/router/index.js
@@ -1,6 +1,9 @@
import Vue from 'vue'
import Router from 'vue-router'
import store from '@/store'
+import { scheduleHomePageLayoutReset, resetHomePageLayout } from '@/utils/resetHomePageLayout'
+
+const HOME_ROUTE_RE = /^\/(homePage|ncmatchHome)(\/|$)/
/* Layout */
import Layout from '@/layout'
import GpuProduct from '@/views/product/productHome/capitalOnline/productItem/GpuProduct/index.vue'
@@ -2618,10 +2621,18 @@ const router = createRouter()
// 在beforeRouteLeave导航守卫中清空面包屑状态
router.beforeEach((to, from, next) => {
- // 清空面包屑状态的代码
- // store.commit('tagsView/resetBreadcrumbState');
+ if (HOME_ROUTE_RE.test(to.path) || HOME_ROUTE_RE.test(from.path)) {
+ resetHomePageLayout()
+ }
next()
})
+
+router.afterEach((to) => {
+ if (!HOME_ROUTE_RE.test(to.path)) return
+ scheduleHomePageLayoutReset()
+ window.setTimeout(() => scheduleHomePageLayoutReset(), 900)
+})
+
window.addEventListener('beforeunload', function() {
// 清空面包屑状态的代码
store.commit('tagsView/resetBreadcrumbState')
diff --git a/f/web-kboss/src/styles/home-page-shell.scss b/f/web-kboss/src/styles/home-page-shell.scss
new file mode 100644
index 0000000..f53027a
--- /dev/null
+++ b/f/web-kboss/src/styles/home-page-shell.scss
@@ -0,0 +1,140 @@
+// 官网 shell:html/body 不滚动,仅 #homeOut 内部纵向滚动,彻底避免 SPA 跳转后 scrollLeft 残留
+
+html.home-page-shell-active,
+body.home-page-shell-active {
+ width: 100% !important;
+ max-width: 100% !important;
+ height: 100% !important;
+ overflow: hidden !important;
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+html.home-page-shell-active #app,
+body.home-page-shell-active #app {
+ width: 100% !important;
+ max-width: 100% !important;
+ min-width: 0 !important;
+ height: 100% !important;
+ overflow: hidden !important;
+}
+
+.home-page-shell {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
+ height: 100vh;
+ height: 100dvh;
+ overflow: hidden;
+ position: relative;
+ isolation: isolate;
+}
+
+.home-page-shell > #topBox,
+.home-page-shell > #topBox.top-nav,
+#topBox.top-nav {
+ flex: 0 0 auto;
+ min-width: 0 !important;
+ max-width: 100% !important;
+ width: 100% !important;
+}
+
+.home-page-shell #homeOut {
+ flex: 1 1 auto;
+ width: 100% !important;
+ max-width: 100% !important;
+ min-width: 0 !important;
+ min-height: 0 !important;
+ overflow-x: hidden !important;
+ overflow-y: auto !important;
+ overscroll-behavior-x: none;
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+.home-page-shell .home-route-stage,
+.home-page-shell .home-router-view {
+ width: 100% !important;
+ max-width: 100% !important;
+ min-width: 0 !important;
+ overflow-x: hidden !important;
+ box-sizing: border-box;
+}
+
+.home-page-shell .home-router-view > * {
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
+ box-sizing: border-box;
+}
+
+.home-page-shell .train-page,
+.home-page-shell .agent-store-page,
+.home-page-shell .jd-homepage,
+.home-page-shell .product-service-page,
+.home-page-shell .news-view-page,
+.home-page-shell .about-page,
+.home-page-shell .home-main-page {
+ overflow-x: hidden;
+}
+
+.home-page-shell .about-page,
+.home-page-shell .about-container {
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
+ box-sizing: border-box;
+}
+
+.home-page-shell .grid-bg {
+ width: 100% !important;
+ max-width: 100% !important;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
+.home-page-shell .product-service-page.single-product-page {
+ height: auto !important;
+ min-height: calc(100vh - 82px);
+ overflow-y: visible !important;
+ overflow-x: hidden !important;
+}
+
+.home-page-shell .nav-container {
+ max-width: 100%;
+}
+
+.home-page-shell .news-shell {
+ width: 100%;
+ max-width: 1400px;
+ margin-left: auto;
+ margin-right: auto;
+ box-sizing: border-box;
+}
+
+.home-page-shell .news-featured-inner {
+ display: grid !important;
+ grid-template-columns: minmax(280px, 380px) minmax(0, 1fr);
+ align-items: stretch;
+ width: 100%;
+ min-height: 280px;
+}
+
+.home-page-shell .news-featured-body {
+ width: 100%;
+ min-width: 0;
+}
+
+.home-page-shell .news-featured,
+.home-page-shell .news-item {
+ width: 100%;
+ max-width: 100%;
+}
+
+.home-page-shell .footer {
+ width: 100%;
+ max-width: 100%;
+ box-sizing: border-box;
+}
diff --git a/f/web-kboss/src/utils/resetHomePageLayout.js b/f/web-kboss/src/utils/resetHomePageLayout.js
new file mode 100644
index 0000000..4295f12
--- /dev/null
+++ b/f/web-kboss/src/utils/resetHomePageLayout.js
@@ -0,0 +1,182 @@
+const HOME_SHELL_CLASS = 'home-page-shell-active'
+const RESET_TARGETS = [
+ '.home-page-shell',
+ '#homeOut',
+ '.home-route-stage',
+ '.home-router-view'
+]
+
+let scrollLockBound = false
+let homeOutObserver = null
+
+function attachHomeOutScrollListener() {
+ const homeOut = getHomeOut()
+ if (!homeOut || homeOut.dataset.scrollLockBound === '1') return
+ homeOut.dataset.scrollLockBound = '1'
+ homeOut.addEventListener('scroll', lockHomeOutHorizontalScroll, { passive: true })
+}
+
+export function enableHomePageBodyScroll() {
+ document.documentElement.classList.add(HOME_SHELL_CLASS)
+ document.body.classList.add(HOME_SHELL_CLASS)
+ bindHomeOutScrollLock()
+ bindHomeOutResizeObserver()
+ attachHomeOutScrollListener()
+}
+
+export function disableHomePageBodyScroll() {
+ document.documentElement.classList.remove(HOME_SHELL_CLASS)
+ document.body.classList.remove(HOME_SHELL_CLASS)
+ if (homeOutObserver) {
+ homeOutObserver.disconnect()
+ homeOutObserver = null
+ }
+}
+
+function getHomeOut() {
+ return document.getElementById('homeOut')
+}
+
+function getHomeScroller() {
+ return getHomeOut() || document.documentElement
+}
+
+function clearInlineLayoutStyles(element) {
+ if (!element || !element.style) return
+ element.style.removeProperty('width')
+ element.style.removeProperty('max-width')
+ element.style.removeProperty('min-width')
+ element.style.removeProperty('transform')
+ element.style.removeProperty('margin-left')
+ element.style.removeProperty('left')
+}
+
+function resetElementScroll(element, resetVertical = true) {
+ if (!element) return
+ element.scrollLeft = 0
+ if (resetVertical) {
+ element.scrollTop = 0
+ }
+}
+
+function resetScrollableDescendants(root) {
+ if (!root || !root.querySelectorAll) return
+ root.querySelectorAll('*').forEach((element) => {
+ if (element.scrollLeft) {
+ element.scrollLeft = 0
+ }
+ })
+}
+
+function lockHomeOutHorizontalScroll() {
+ const homeOut = getHomeOut()
+ if (!homeOut) return
+
+ if (homeOut.scrollLeft !== 0) {
+ homeOut.scrollLeft = 0
+ }
+
+ resetElementScroll(document.documentElement, false)
+ resetElementScroll(document.body, false)
+
+ if (window.scrollX !== 0) {
+ window.scrollTo(0, 0)
+ }
+}
+
+export function resetHomePageLayout(resetVertical = true) {
+ const homeOut = getHomeOut()
+
+ RESET_TARGETS.forEach((selector) => {
+ document.querySelectorAll(selector).forEach((element) => {
+ resetElementScroll(element, resetVertical)
+ clearInlineLayoutStyles(element)
+ })
+ })
+
+ if (homeOut) {
+ resetElementScroll(homeOut, resetVertical)
+ clearInlineLayoutStyles(homeOut)
+ resetScrollableDescendants(homeOut)
+ }
+
+ resetElementScroll(document.documentElement, resetVertical)
+ resetElementScroll(document.body, resetVertical)
+ window.scrollTo(0, 0)
+ lockHomeOutHorizontalScroll()
+}
+
+export function scheduleHomePageLayoutReset(resetVertical = true) {
+ attachHomeOutScrollListener()
+ resetHomePageLayout(resetVertical)
+ window.requestAnimationFrame(() => resetHomePageLayout(resetVertical))
+ window.setTimeout(() => resetHomePageLayout(resetVertical), 0)
+ window.setTimeout(() => resetHomePageLayout(resetVertical), 80)
+ window.setTimeout(() => resetHomePageLayout(resetVertical), 200)
+ window.setTimeout(() => resetHomePageLayout(resetVertical), 500)
+ window.setTimeout(() => resetHomePageLayout(resetVertical), 900)
+}
+
+export function scrollHomeSection(id, offset = 82) {
+ const homeOut = getHomeOut()
+ const element = document.getElementById(id)
+ if (!element) return false
+
+ lockHomeOutHorizontalScroll()
+
+ if (homeOut) {
+ const top = element.getBoundingClientRect().top - homeOut.getBoundingClientRect().top + homeOut.scrollTop - offset
+ homeOut.scrollTo({
+ left: 0,
+ top: Math.max(top, 0),
+ behavior: 'smooth'
+ })
+ return true
+ }
+
+ const top = element.getBoundingClientRect().top + window.pageYOffset - offset
+ window.scrollTo({
+ left: 0,
+ top: Math.max(top, 0),
+ behavior: 'smooth'
+ })
+ return true
+}
+
+export function bindHomeOutScrollLock() {
+ if (scrollLockBound) return
+ scrollLockBound = true
+
+ document.addEventListener('scroll', (event) => {
+ if (!document.body.classList.contains(HOME_SHELL_CLASS)) return
+ if (event.target === getHomeOut()) {
+ lockHomeOutHorizontalScroll()
+ }
+ }, true)
+
+ window.addEventListener('resize', () => scheduleHomePageLayoutReset(true), { passive: true })
+}
+
+export function bindHomeOutResizeObserver() {
+ if (homeOutObserver || typeof ResizeObserver === 'undefined') return
+
+ homeOutObserver = new ResizeObserver(() => {
+ if (!document.body.classList.contains(HOME_SHELL_CLASS)) return
+ lockHomeOutHorizontalScroll()
+ })
+
+ const observe = () => {
+ const homeOut = getHomeOut()
+ if (homeOut) homeOutObserver.observe(homeOut)
+ }
+
+ observe()
+ window.setTimeout(observe, 0)
+}
+
+export const bindHomeHorizontalScrollLock = bindHomeOutScrollLock
+export const bindHomeOutHorizontalScrollLock = bindHomeOutScrollLock
+
+export function getHomeScrollContainer() {
+ return getHomeScroller()
+}
diff --git a/f/web-kboss/src/views/LoginDialog/LoginDialog.vue b/f/web-kboss/src/views/LoginDialog/LoginDialog.vue
index ec5920c..707e64e 100644
--- a/f/web-kboss/src/views/LoginDialog/LoginDialog.vue
+++ b/f/web-kboss/src/views/LoginDialog/LoginDialog.vue
@@ -13,31 +13,31 @@