home修改

This commit is contained in:
wintsa 2026-04-09 09:59:38 +08:00
parent bbc9ad13fe
commit 860bd0161b
3 changed files with 76 additions and 0 deletions

View File

@ -104,6 +104,20 @@ const projectIndustryLabel = computed(() => {
if (!target) return '' if (!target) return ''
return getIndustryDisplayName(target, locale.value) || '' return getIndustryDisplayName(target, locale.value) || ''
}) })
const heroBrandName = computed(() => t('home.cards.heroBrand'))
const heroBrandMessages = computed(() => [
t('home.cards.heroBrandMessage1'),
t('home.cards.heroBrandMessage2'),
t('home.cards.heroBrandMessage3'),
t('home.cards.heroBrandMessage4'),
t('home.cards.heroBrandMessage5')
].filter(Boolean))
const heroBrandMessageIndex = ref(0)
const activeHeroBrandMessage = computed(() => {
const options = heroBrandMessages.value
if (!options.length) return ''
return options[((heroBrandMessageIndex.value % options.length) + options.length) % options.length]
})
const localeBadge = computed(() => (locale.value === 'en-US' ? 'EN' : '中')) const localeBadge = computed(() => (locale.value === 'en-US' ? 'EN' : '中'))
const toggleLocale = () => { const toggleLocale = () => {
const next = locale.value === 'en-US' ? 'zh-CN' : 'en-US' const next = locale.value === 'en-US' ? 'zh-CN' : 'en-US'
@ -393,10 +407,29 @@ const handleHomeVisibilityChange = () => {
handleHomeWindowFocus() handleHomeWindowFocus()
} }
let heroBrandMessageTimer: ReturnType<typeof setInterval> | null = null
const stopHeroBrandMessageRotation = () => {
if (heroBrandMessageTimer == null) return
clearInterval(heroBrandMessageTimer)
heroBrandMessageTimer = null
}
const startHeroBrandMessageRotation = () => {
stopHeroBrandMessageRotation()
if (heroBrandMessages.value.length <= 1) return
heroBrandMessageTimer = setInterval(() => {
const total = heroBrandMessages.value.length
if (total <= 1) return
heroBrandMessageIndex.value = (heroBrandMessageIndex.value + 1) % total
}, 2400)
}
onMounted(() => { onMounted(() => {
void refreshExistingProjects() void refreshExistingProjects()
void loadProjectDefaults() void loadProjectDefaults()
void loadQuickDefaults() void loadQuickDefaults()
startHeroBrandMessageRotation()
window.addEventListener('focus', handleHomeWindowFocus) window.addEventListener('focus', handleHomeWindowFocus)
document.addEventListener('visibilitychange', handleHomeVisibilityChange) document.addEventListener('visibilitychange', handleHomeVisibilityChange)
try { try {
@ -421,6 +454,7 @@ onMounted(() => {
onBeforeUnmount(() => { onBeforeUnmount(() => {
stopExistingProjectPolling() stopExistingProjectPolling()
stopHeroBrandMessageRotation()
window.removeEventListener('focus', handleHomeWindowFocus) window.removeEventListener('focus', handleHomeWindowFocus)
document.removeEventListener('visibilitychange', handleHomeVisibilityChange) document.removeEventListener('visibilitychange', handleHomeVisibilityChange)
}) })
@ -467,6 +501,13 @@ onBeforeUnmount(() => {
</div> </div>
<h2 class="relative mt-8 text-2xl font-semibold leading-tight tracking-tight lg:text-3xl">{{ t('home.cards.heroTitle') }}</h2> <h2 class="relative mt-8 text-2xl font-semibold leading-tight tracking-tight lg:text-3xl">{{ t('home.cards.heroTitle') }}</h2>
<p class="relative mt-2 text-sm text-red-200/90">{{ t('home.cards.heroSubTitle') }}</p> <p class="relative mt-2 text-sm text-red-200/90">{{ t('home.cards.heroSubTitle') }}</p>
<div class="relative mt-4 inline-flex max-w-full items-center gap-3 rounded-full border border-white/15 bg-white/10 px-4 py-2 text-xs text-white/90 backdrop-blur-sm">
<span class="shrink-0 font-semibold tracking-[0.28em] text-white">{{ heroBrandName }}</span>
<span class="h-3.5 w-px shrink-0 bg-white/25" />
<Transition name="hero-brand-message" mode="out-in">
<span :key="`${locale}-${heroBrandMessageIndex}`" class="truncate text-white/90">{{ activeHeroBrandMessage }}</span>
</Transition>
</div>
<div class="relative mt-6 h-px bg-white/20" /> <div class="relative mt-6 h-px bg-white/20" />
<p class="relative mt-4 text-xs leading-5 text-red-200/60">{{ t('home.cards.heroDesc') }}</p> <p class="relative mt-4 text-xs leading-5 text-red-200/60">{{ t('home.cards.heroDesc') }}</p>
</div> </div>
@ -582,6 +623,13 @@ onBeforeUnmount(() => {
</div> </div>
</Card> </Card>
</div> </div>
<div class="home-slogan-row mt-5 flex items-center justify-center">
<div class="flex w-full flex-wrap items-center justify-center gap-x-4 gap-y-1 px-4 py-2 text-center">
<span class="text-lg font-semibold tracking-[0.18em] text-slate-900 sm:text-xl">{{ t('home.cards.heroFooterTitle') }}</span>
<span class="text-slate-300">|</span>
<span class="text-sm tracking-[0.08em] text-slate-500 sm:text-base">{{ t('home.cards.heroFooterSubTitle') }}</span>
</div>
</div>
</div> </div>
</div> </div>
@ -738,6 +786,9 @@ onBeforeUnmount(() => {
.home-entry-item { .home-entry-item {
animation: fade-up 0.45s cubic-bezier(0.22, 1, 0.36, 1) both; animation: fade-up 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
} }
.home-slogan-row {
animation: fade-up 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.6s both;
}
.home-entry-item--1 { animation-delay: 0.2s; } .home-entry-item--1 { animation-delay: 0.2s; }
.home-entry-item--2 { animation-delay: 0.3s; } .home-entry-item--2 { animation-delay: 0.3s; }
.home-entry-item--3 { animation-delay: 0.4s; } .home-entry-item--3 { animation-delay: 0.4s; }
@ -819,4 +870,13 @@ onBeforeUnmount(() => {
from { opacity: 0; transform: translateY(16px); } from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); } to { opacity: 1; transform: translateY(0); }
} }
.hero-brand-message-enter-active,
.hero-brand-message-leave-active {
transition: opacity 0.22s ease, transform 0.22s ease;
}
.hero-brand-message-enter-from,
.hero-brand-message-leave-to {
opacity: 0;
transform: translateY(6px);
}
</style> </style>

View File

@ -26,6 +26,14 @@ export const enUS = {
cards: { cards: {
heroTitle: 'One-Click Smart Budget', heroTitle: 'One-Click Smart Budget',
heroSubTitle: 'Accelerate standards adoption', heroSubTitle: 'Accelerate standards adoption',
heroFooterTitle: 'Instant Cost Intelligence',
heroFooterSubTitle: 'Leave your time for creation',
heroBrand: 'Huizhongyi',
heroBrandMessage1: 'So easy',
heroBrandMessage2: 'Fee calc made easy',
heroBrandMessage3: 'No late nights for fees',
heroBrandMessage4: 'No heavy lifting for fees',
heroBrandMessage5: 'No late nights, no heavy lifting',
heroDesc: 'Cost consulting fee calculator for transport construction projects', heroDesc: 'Cost consulting fee calculator for transport construction projects',
projectBudget: 'Project Budget', projectBudget: 'Project Budget',
projectBudgetDesc: 'For full project-level calculation across multiple contracts with import/export support', projectBudgetDesc: 'For full project-level calculation across multiple contracts with import/export support',

View File

@ -26,6 +26,14 @@ export const zhCN = {
cards: { cards: {
heroTitle: '智能预算一键生成', heroTitle: '智能预算一键生成',
heroSubTitle: '助力《规范》高效落地', heroSubTitle: '助力《规范》高效落地',
heroFooterTitle: '智算费用 即点即出',
heroFooterSubTitle: '您的时间留给创造',
heroBrand: '慧众易',
heroBrandMessage1: '真容易',
heroBrandMessage2: '算费真容易',
heroBrandMessage3: '算费不熬夜',
heroBrandMessage4: '算费不费力',
heroBrandMessage5: '不熬夜,不费力',
heroDesc: '交通建设项目工程造价咨询服务费计算', heroDesc: '交通建设项目工程造价咨询服务费计算',
projectBudget: '项目预算', projectBudget: '项目预算',
projectBudgetDesc: '适用于多合同段、项目级整体计算,支持导出/导入完整项目数据', projectBudgetDesc: '适用于多合同段、项目级整体计算,支持导出/导入完整项目数据',