Compare commits
10 Commits
1c99cb6c75
...
91bb3cd5d8
| Author | SHA1 | Date | |
|---|---|---|---|
| 91bb3cd5d8 | |||
| f4c896fefd | |||
| 7ee5633d14 | |||
| 4e5d6980eb | |||
| 05ed7dad8a | |||
| 0582339969 | |||
| 6853a60112 | |||
| ddd8f091e0 | |||
| e11e20790d | |||
| c1c60a5313 |
@ -1,2 +1,4 @@
|
||||
# .env.development (开发环境)
|
||||
VITE_API_BASE_URL = 'http://health.ufutx.net'
|
||||
# VITE_API_BASE_URL = 'http://health.ufutx.net'
|
||||
|
||||
VITE_API_BASE_URL = 'https://health.ufutx.com'
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
lint-staged
|
||||
2
components.d.ts
vendored
2
components.d.ts
vendored
@ -9,6 +9,8 @@ export {}
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCarousel: typeof import('element-plus/es')['ElCarousel']
|
||||
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
|
||||
26
index.html
26
index.html
@ -6,6 +6,31 @@
|
||||
<!-- <link href="https://cdn.jsdelivr.net/npm/element-plus@2.4.10/dist/index.min.css" rel="stylesheet">-->
|
||||
<!-- <link href="https://cdn.jsdelivr.net/npm/element-plus@2.4.10/dist/index.min.css" rel="stylesheet">-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<!-- 基础信息:标题(分享卡片标题) -->
|
||||
<meta property="og:title" content="这是分享的标题" />
|
||||
|
||||
<!-- 描述(分享卡片副标题) -->
|
||||
<meta property="og:description" content="这是分享的详细描述,会显示在标题下方" />
|
||||
|
||||
<!-- 分享图片(卡片主图) -->
|
||||
<meta property="og:image" content="https://images.health.ufutx.com/202507/14/cc651222ac2e5f63185dec1f31d176ae.png" />
|
||||
|
||||
<!-- 分享链接(点击卡片跳转的 URL,默认是当前页面 URL) -->
|
||||
<meta property="og:url" content="https://www.ufutx.com/web/#/" />
|
||||
|
||||
<!-- 类型(固定为 website) -->
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
<!-- 微信特定标签(增强兼容性) -->
|
||||
<meta name="description" content="这是分享的详细描述(微信 fallback 用)" />
|
||||
<meta name="thumbnail" content="https://images.health.ufutx.com/202507/14/be87f139c2c1a98f259db1fb3c82de6b.png" /> <!-- 微信缩略图 -->
|
||||
|
||||
<!-- index.html 的 <head> 中添加 -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
<meta name="format-detection" content="telephone=no"> <!-- 避免手机号被默认识别为链接 -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"> <!-- 适配 iOS 微信 -->
|
||||
<!-- 修复后的viewport,适配安卓X5内核 -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi">
|
||||
<title>友福同享官网</title>
|
||||
</head>
|
||||
<body>
|
||||
@ -14,5 +39,6 @@
|
||||
<!--<script src="https://cdn.jsdelivr.net/npm/element-plus@2.4.10/dist/index.full.min.js"></script>-->
|
||||
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -30,11 +30,11 @@
|
||||
"@vueuse/core": "^13.4.0",
|
||||
"@vueuse/motion": "^3.0.3",
|
||||
"axios": "^1.9.0",
|
||||
"core-js": "^3.45.1",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.10.1",
|
||||
"motion-v": "^1.3.1",
|
||||
"pinia": "^2.1.7",
|
||||
"postcss-px-to-viewport": "^1.1.1",
|
||||
"regenerator-runtime": "^0.14.1",
|
||||
"swiper": "^11.2.10",
|
||||
"vue": "^3.5.13",
|
||||
"vue-i18n": "^9.8.0",
|
||||
@ -65,6 +65,7 @@
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup-plugin-visualizer": "^6.0.3",
|
||||
"sass": "^1.89.2",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tw-animate-css": "^1.3.4",
|
||||
@ -74,7 +75,6 @@
|
||||
"unplugin-vue-components": "^28.7.0",
|
||||
"vite": "^5.4.19",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-imagemin": "^0.6.1",
|
||||
"vite-ssg": "^27.0.1",
|
||||
"vue-tsc": "1.8.14"
|
||||
}
|
||||
|
||||
BIN
src/assets/images/logo-mini.png
Normal file
BIN
src/assets/images/logo-mini.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 11 KiB |
@ -64,22 +64,50 @@ const updateAnimation = () => {
|
||||
const style = document.createElement('style')
|
||||
style.id = 'marquee-keyframes'
|
||||
style.textContent = `
|
||||
@keyframes marquee {
|
||||
0% { transform: translateX(var(--initial-offset)); }
|
||||
100% { transform: translateX(calc(var(--initial-offset) - ${originalWidth.value}px)); }
|
||||
}
|
||||
`
|
||||
@keyframes marquee {
|
||||
0% { transform: translateX(var(--initial-offset)); }
|
||||
/* 滚动距离 = 原始内容宽度,确保克隆内容衔接 */
|
||||
100% { transform: translateX(calc(var(--initial-offset) - ${originalWidth.value}px)); }
|
||||
}
|
||||
`
|
||||
|
||||
// 替换旧关键帧
|
||||
const existingStyle = document.head.querySelector('#marquee-keyframes')
|
||||
if (existingStyle) document.head.removeChild(existingStyle)
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
// 图片加载完成后重新计算宽度
|
||||
const watchImagesLoad = () => {
|
||||
if (!originalRef.value) return
|
||||
// 获取插槽中的所有图片
|
||||
const images = originalRef.value.querySelectorAll('img')
|
||||
if (images.length === 0) return
|
||||
|
||||
// 监听所有图片加载完成
|
||||
let loadedCount = 0
|
||||
images.forEach(img => {
|
||||
// 图片已加载完成
|
||||
if (img.complete) {
|
||||
loadedCount++
|
||||
} else {
|
||||
// 图片加载完成后触发
|
||||
img.addEventListener('load', () => {
|
||||
loadedCount++
|
||||
if (loadedCount === images.length) {
|
||||
nextTick(calculateWidth) // 所有图片加载后重新计算宽度
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 初始化与监听
|
||||
onMounted(() => {
|
||||
calculateWidth()
|
||||
updateAnimation()
|
||||
nextTick(() => {
|
||||
// 确保DOM渲染完成
|
||||
calculateWidth()
|
||||
watchImagesLoad() // 监听图片加载
|
||||
updateAnimation()
|
||||
})
|
||||
})
|
||||
watchEffect(() => {
|
||||
calculateWidth()
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
<div class="navbar-container">
|
||||
<!-- Logo -->
|
||||
<div class="navbar-logo">
|
||||
<img src="@/assets/images/logo.png" alt="友福同享Logo" />
|
||||
<img src="@/assets/images/logo.png" alt="友福同享Logo" class="navbar-logo-icon" />
|
||||
<img src="@/assets/images/logo-mini.png" alt="友福同享Logo" class="navbar-logo-mini" />
|
||||
<!-- <span>友福同享</span>-->
|
||||
</div>
|
||||
|
||||
@ -23,7 +24,7 @@
|
||||
<!-- 语言切换 -->
|
||||
<!-- <div class="language-switch"><span>中文</span></div>-->
|
||||
<div class="language-switch" @click="changeLanguage">
|
||||
<span>English</span> | <span>中文</span> | <span>繁體</span>
|
||||
<!-- <span>English</span> | <span>中文</span> | <span>繁體</span>-->
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@ -92,6 +93,15 @@ const isActive = (path: string) => {
|
||||
//left: 0;
|
||||
}
|
||||
|
||||
.navbar-logo-mini {
|
||||
display: none;
|
||||
//width: 72px;
|
||||
//height: 72px;
|
||||
//position: absolute;
|
||||
//top: 0;
|
||||
//left: 0;
|
||||
}
|
||||
|
||||
// 导航容器(居中)
|
||||
.navbar-container {
|
||||
width: 100%;
|
||||
@ -157,9 +167,22 @@ const isActive = (path: string) => {
|
||||
}
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 1200px) {
|
||||
//@media (max-width: @tablet-breakpoint) {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.navbar-container {
|
||||
width: 90%;
|
||||
height: 56px;
|
||||
.navbar-logo-icon {
|
||||
display: none;
|
||||
}
|
||||
.navbar-logo-mini {
|
||||
display: inline-block;
|
||||
}
|
||||
.navbar-logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
122
src/data/caseImage.ts
Normal file
122
src/data/caseImage.ts
Normal file
@ -0,0 +1,122 @@
|
||||
export interface RealCase {
|
||||
username: string
|
||||
case: string // 案例描述
|
||||
avatar: string // 用户头像
|
||||
result: string // 案例结果
|
||||
caseImage: string // 新增:案例相关图片(如场景图、产品使用图等)
|
||||
}
|
||||
|
||||
export const newRealCasesWithImage: RealCase[] = [
|
||||
{
|
||||
username: '林婉清',
|
||||
case: '高中班主任用「课堂专注度」功能分析学生听课数据,AI识别走神高频时段并推送互动课件。商城买的护嗓麦克风收音清晰,课后用「作业批改助手」自动统计错题率,节省2小时工作时间。',
|
||||
avatar: 'https://picsum.photos/id/601/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/f3ccdd27d2000e3f9255a7e3e2c48800.jpeg', // 课堂场景图(学生听课+课件屏幕)
|
||||
result: '学生课堂走神率从35%降至12%,班级月考平均分提升15分,个人嗓子嘶哑频率减少80%。'
|
||||
},
|
||||
{
|
||||
username: '陈浩宇',
|
||||
case: '糖尿病患者用「血糖波动曲线」记录餐前餐后数据,App智能提醒胰岛素注射时间。商城买的血糖仪免采血且误差<0.5mmol/L,同步推送低糖食谱和「餐后散步20分钟」计划。',
|
||||
avatar: 'https://picsum.photos/id/602/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/156005c5baf40ff51a327f1c34f2975b.jpeg', // 血糖仪+低糖食谱场景图
|
||||
result: '空腹血糖从8.5mmol/L降至6.2mmol/L,低血糖发作次数从每月4次降至0次,糖化血红蛋白从7.8%降至6.5%。'
|
||||
},
|
||||
{
|
||||
username: '苏雨薇',
|
||||
case: '留学生在海外用「翻译问诊」功能与当地医生沟通,AI实时翻译症状描述。商城买的便携体温计支持多语言播报,感冒时通过「海外药房导航」找到附近中文服务药店。',
|
||||
avatar: 'https://picsum.photos/id/603/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/799bad5a3b514f096e69bbc4a7896cd9.jpeg', // 海外诊所+翻译App界面图
|
||||
result: '就医沟通效率提升90%,感冒康复周期缩短2天,成功适配3种语言的医疗服务场景。'
|
||||
},
|
||||
{
|
||||
username: '赵健峰',
|
||||
case: '健身教练用「体成分分析」功能为学员定制增肌计划,AI识别肌肉量薄弱部位。商城买的弹力带防滑且承重50kg,通过「班级打卡」功能监督学员训练,同步推送高蛋白食谱。',
|
||||
avatar: 'https://picsum.photos/id/604/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/032b2cc936860b03048302d991c3498f.jpeg', // 健身房训练+弹力带使用图
|
||||
result: '学员平均肌肉量增加3.2kg,体脂率下降5.8%,课程续费率从65%提升至92%。'
|
||||
},
|
||||
{
|
||||
username: '吴欣怡',
|
||||
case: '花店店主用「花粉过敏预警」功能调整进货品类,避开高致敏花卉。商城买的保鲜喷雾延长玫瑰花期5天,通过「会员健康标签」为过敏顾客推荐低敏花束,减少退货率。',
|
||||
avatar: 'https://picsum.photos/id/605/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/d0096ec6c83575373e3a21d129ff8fef.jpeg', // 花店陈列+低敏花束图
|
||||
result: '顾客过敏投诉从每月8起降至1起,花卉损耗率减少30%,会员复购率提升45%。'
|
||||
},
|
||||
{
|
||||
username: '马子轩',
|
||||
case: '程序员用「久坐提醒」功能每50分钟弹窗拉伸提示,App分析代码时长与颈椎压力关联。商城买的人体工学椅腰托可调节,配合「眼疲劳监测」每2小时强制远眺,同步记录睡眠质量。',
|
||||
avatar: 'https://picsum.photos/id/606/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/28c03d3961c2e936cc6234f52d82e965.jpeg', // 程序员工位+工学椅+拉伸提醒图
|
||||
result: '颈椎疼痛频率从每周5次降至1次,视力从4.7恢复至4.9,深度睡眠时间延长1.5小时。'
|
||||
},
|
||||
{
|
||||
username: '郑思琪',
|
||||
case: '哺乳期妈妈用「奶量预测」功能根据宝宝月龄调整吸奶时间,AI识别供需失衡风险。商城买的吸奶器静音且吸力可调,通过「辅食营养库」匹配宝宝过敏体质,推送低敏食谱。',
|
||||
avatar: 'https://picsum.photos/id/607/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/af9b82a1b9683d5734db895886c002c0.jpeg', // 母婴场景+吸奶器+辅食图
|
||||
result: '奶量供需平衡率从60%提升至95%,宝宝湿疹发作次数减少70%,夜间连续睡眠时长从3小时增至6小时。'
|
||||
},
|
||||
{
|
||||
username: '王浩明',
|
||||
case: '退休老人用「语音记事」功能记录血压、用药时间,App自动生成周健康报告。商城买的智能水杯提醒每日饮水1500ml,通过「子女共享」功能让子女实时查看健康数据,减少担忧。',
|
||||
avatar: 'https://picsum.photos/id/608/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/59aa235ebd97e78a23210c5a618e3633.jpeg', // 老人居家+智能水杯+血压仪图
|
||||
result: '每日饮水量达标率从40%提升至90%,漏服药次数从每月6次降至0次,子女远程关怀响应时间缩短至5分钟内。'
|
||||
},
|
||||
{
|
||||
username: '李雨桐',
|
||||
case: '舞蹈老师用「动作矫正」功能通过手机摄像头识别学员肢体角度,AI标注错误动作。商城买的舞蹈把杆稳固且可折叠,通过「课程回放」功能让学员课后复习,重点标注纠错片段。',
|
||||
avatar: 'https://picsum.photos/id/609/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/b89c4cc90e26a826ef04a7adfea8c40d.jpeg', // 舞蹈教室+把杆+手机矫正界面图
|
||||
result: '学员动作标准率从55%提升至88%,课程学习效率提升40%,家长满意度评分从3.2分升至4.8分。'
|
||||
},
|
||||
{
|
||||
username: '张博文',
|
||||
case: '货车司机用「疲劳驾驶监测」通过方向盘震动提醒,连续驾驶4小时强制休息。商城买的车载腰靠贴合腰椎曲线,离线地图提前预警施工路段,同步记录油耗与胎压数据。',
|
||||
avatar: 'https://picsum.photos/id/610/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/734a4c7ff726c7e7aeadf15773e060ff.jpeg', // 货车驾驶舱+腰靠+导航界面图
|
||||
result: '疲劳驾驶风险事件从每月3次降至0次,油耗降低12%,轮胎异常磨损率减少60%。'
|
||||
},
|
||||
{
|
||||
username: '刘雅菲',
|
||||
case: '鼻炎患者用「花粉浓度地图」避开高风险区域,App推送每日鼻腔冲洗提醒。商城买的洗鼻器喷头柔软且水流可调,通过「过敏原记录」识别尘螨过敏,推荐防螨床品。',
|
||||
avatar: 'https://picsum.photos/id/611/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/280a6001ab93c8eea794f0fdf899c4ad.jpeg', // 洗鼻器+花粉地图+防螨床品图
|
||||
result: '鼻炎发作频率从每周4次降至1次,打喷嚏次数从每日20次减至5次,睡眠质量评分从60分升至85分。'
|
||||
},
|
||||
{
|
||||
username: '陈宇轩',
|
||||
case: '咖啡店店主用「员工健康打卡」功能记录体温、核酸状态,到期自动提醒体检。商城买的手部消毒机感应灵敏,通过「客流健康分析」调整高峰时段员工排班,减少交叉感染风险。',
|
||||
avatar: 'https://picsum.photos/id/612/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/c7b9fe05ece7c3068309677eb788d520.jpeg', // 咖啡店吧台+消毒机+打卡界面图
|
||||
result: '员工健康异常率从8%降至1%,顾客投诉率减少50%,门店卫生评分从B级升至A级。'
|
||||
},
|
||||
{
|
||||
username: '高思远',
|
||||
case: '备考公务员用「专注计时」功能屏蔽娱乐软件,AI分析学习效率高峰时段。商城买的护眼台灯可调节色温,通过「错题本同步」功能整理高频考点,推送相似题型练习。',
|
||||
avatar: 'https://picsum.photos/id/613/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/45fca35bf2e29ddb2e49305da1c813d6.jpeg', // 学习桌+护眼台灯+错题本App图
|
||||
result: '日均有效学习时长从5小时增至7.5小时,错题重复率从40%降至15%,笔试成绩提升28分。'
|
||||
},
|
||||
{
|
||||
username: '周雨薇',
|
||||
case: '早产儿妈妈用「生长曲线监测」每周记录宝宝体重、身高,AI对比标准曲线预警异常。商城买的婴儿体重秤精度达10g,通过「母乳成分分析」调整饮食,提升乳汁营养密度。',
|
||||
avatar: 'https://picsum.photos/id/614/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/15a7bfcf08d4a38fad6d798e02461165.jpeg', // 婴儿体重秤+生长曲线App+母乳检测图
|
||||
result: '宝宝生长达标率从65%提升至98%,纠正月龄后体重追平同龄婴儿,医生随访满意度达100%。'
|
||||
},
|
||||
{
|
||||
username: '吴浩明',
|
||||
case: '工地安全员用「噪音监测」功能记录施工环境分贝,超过85dB自动推送防护提醒。商城买的防噪音耳塞降噪率达35dB,通过「安全培训视频」定期考核工人,同步记录防护装备佩戴情况。',
|
||||
avatar: 'https://picsum.photos/id/615/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/e47f1edd5ca04227b115fe4b47786b85.jpeg', // 工地场景+噪音监测仪+耳塞图
|
||||
result: '工人听力损伤风险降低70%,安全考核通过率从75%升至96%,工伤事故次数减少80%。'
|
||||
},
|
||||
{
|
||||
username: '郑雅琳',
|
||||
case: '瑜伽教练用「呼吸节奏监测」功能纠正学员呼吸与动作配合,AI识别憋气时段。商城买的瑜伽垫防滑系数达0.8,通过「会员体态报告」生成个性化矫正计划,推送居家练习视频。',
|
||||
avatar: 'https://picsum.photos/id/616/200/200',
|
||||
caseImage: 'https://images.health.ufutx.com/202509/18/72eec5023144990dc4b80e31d8a0a6e0.jpeg', // 瑜伽馆+瑜伽垫+呼吸监测App图
|
||||
result: '学员呼吸配合准确率从50%提升至90%,体态不良改善率达85%,私教课程续费率提升50%。'
|
||||
}
|
||||
]
|
||||
22
src/lib/device.ts
Normal file
22
src/lib/device.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 判断是否为移动端设备
|
||||
* @returns boolean
|
||||
*/
|
||||
export const isMobile = (): boolean => {
|
||||
// 1. UA 检测:匹配常见移动设备关键词
|
||||
const mobileUA = /Android|iPhone|iPad|iPod|BlackBerry|Windows Phone|SymbianOS/i.test(navigator.userAgent)
|
||||
// 2. 屏幕宽度辅助判断(适配部分平板/PC 小窗口场景)
|
||||
const mobileWidth = window.innerWidth < 768
|
||||
|
||||
// 满足任一条件即视为移动端
|
||||
return mobileUA || mobileWidth
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前页面是否已在移动端 H5 页面
|
||||
* @param mobileDomain 移动端页面域名(如 'm.xxx.com')
|
||||
* @returns boolean
|
||||
*/
|
||||
export const isInMobilePage = (mobileDomain: string): boolean => {
|
||||
return window.location.hostname === mobileDomain
|
||||
}
|
||||
@ -1,4 +1,7 @@
|
||||
// src/main.ts
|
||||
import 'core-js/stable/structured-clone' // 专门为 structuredClone 打补丁
|
||||
import 'regenerator-runtime/runtime' // 若项目用了 async/await,需加这行
|
||||
|
||||
import { ViteSSG } from 'vite-ssg'
|
||||
import { createWebHashHistory } from 'vue-router'
|
||||
import App from './App.vue'
|
||||
|
||||
@ -6,8 +6,10 @@ import routes from './routes'
|
||||
// const history = isProduction
|
||||
// ? createWebHashHistory() // 线上:带#
|
||||
// : createWebHistory() // 本地:无#
|
||||
|
||||
const routerBase = import.meta.env.MODE === 'production' ? '/web/' : '/'
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
history: createWebHashHistory(routerBase),
|
||||
routes,
|
||||
scrollBehavior(_to, _from, savedPosition) {
|
||||
// 添加下划线标记未使用参数
|
||||
|
||||
@ -33,7 +33,9 @@ export const openNewWindow = (to: RouteLocationRaw) => {
|
||||
// 使用导入的 router 实例调用 resolve
|
||||
const routeLocation = router.resolve(to)
|
||||
// 拼接完整URL(当前域名 + 路由路径)
|
||||
const fullUrl = `${window.location.origin}${routeLocation.href}`
|
||||
const fullUrl = `${window.location.origin}/${import.meta.env.MODE === 'production' ? '/web/' : '/'}${routeLocation.href}`
|
||||
console.log(window.location)
|
||||
console.log(fullUrl)
|
||||
// 新窗口打开
|
||||
window.open(fullUrl, '_blank', 'noopener,noreferrer')
|
||||
} catch (error) {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<MissionVision />
|
||||
<!-- 合作伙伴-->
|
||||
<Partners />
|
||||
<!-- <FooterContact />-->
|
||||
<!-- <FooterContact />-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -139,6 +139,9 @@
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner-bg {
|
||||
height: auto !important;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
|
||||
@ -275,22 +275,219 @@ watch(activeIndex, () => {
|
||||
position: relative; /* 作为地图的定位容器 */
|
||||
z-index: 10; /* 父容器层级,控制整体显示优先级 */
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="less">
|
||||
.branch-section {
|
||||
background-color: #fff;
|
||||
padding: 50px 192px 50px;
|
||||
border-top: 50px solid #f6f8fe;
|
||||
|
||||
/* 响应式适配 */
|
||||
@media (max-width: 1200px) {
|
||||
.branch-section {
|
||||
padding: 60px 40px;
|
||||
// 【移动端基础适配】缩小整体内边距和顶部边框
|
||||
@media (max-width: 768px) {
|
||||
padding: 30px 16px; // 小屏仅留16px左右边距
|
||||
border-top-width: 20px; // 减少顶部留白
|
||||
}
|
||||
.branch-wrapper {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: @font-size-xxl;
|
||||
font-weight: bold;
|
||||
color: @text-color;
|
||||
margin-bottom: 10px;
|
||||
|
||||
// 【移动端标题】缩小字体
|
||||
@media (max-width: 768px) {
|
||||
font-size: 24px; // 原xxl(通常32px+)改24px
|
||||
}
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 20px;
|
||||
color: @text-color-secondary;
|
||||
margin-bottom: 40px;
|
||||
|
||||
// 【移动端副标题】缩小字体+减少底部间距
|
||||
@media (max-width: 768px) {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.branch-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin-top: 50px;
|
||||
|
||||
// 【核心】移动端从“左右分栏”改“垂直堆叠”
|
||||
@media (max-width: 768px) {
|
||||
flex-direction: column; // 垂直排列
|
||||
align-items: center;
|
||||
margin-top: 20px; // 减少顶部间距
|
||||
}
|
||||
}
|
||||
|
||||
/* 左侧切换区 - 移动端适配 */
|
||||
.branch-left {
|
||||
margin-top: 110px;
|
||||
padding: 16px 16px 16px 0;
|
||||
text-align: left;
|
||||
width: 496px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%; // 占满屏幕宽度
|
||||
margin-top: 0; // 取消顶部大间距
|
||||
padding: 0; // 清除左右内边距
|
||||
}
|
||||
|
||||
.branch-icon {
|
||||
width: 56px;
|
||||
height: 52px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 40px;
|
||||
height: 38px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.branch-title {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: @text-color;
|
||||
margin-bottom: 24px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tabs容器 - 移动端关键优化(避免超出屏幕) */
|
||||
.branch-tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
background: #f6f8fe;
|
||||
padding: 6px;
|
||||
width: 463px; // 桌面端固定宽度
|
||||
border-radius: 100px;
|
||||
position: relative;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%; // 移动端占满宽度
|
||||
gap: 5px; // 缩小tab间距
|
||||
padding: 4px; // 减少内边距
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 平移滑块 - 适配移动端Tabs尺寸 */
|
||||
.tab-slider {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
bottom: 6px;
|
||||
border-radius: 100px;
|
||||
color: #fff;
|
||||
background-color: #165dff;
|
||||
z-index: 1;
|
||||
transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
|
||||
@media (max-width: 768px) {
|
||||
top: 4px; // 与Tabs容器padding匹配
|
||||
bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tab按钮 - 移动端缩小尺寸,避免换行 */
|
||||
.branch-tab {
|
||||
padding: 12px 30px;
|
||||
border-radius: 100px;
|
||||
color: @text-color-secondary;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
transition: color 0.3s ease;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
padding: 8px 15px; // 大幅减少内边距
|
||||
font-size: 14px; // 缩小字体
|
||||
}
|
||||
|
||||
&.active,
|
||||
.branch-tabs:hover &:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* 详情区 - 移动端缩小字体和行高 */
|
||||
.branch-details {
|
||||
.detail-item {
|
||||
font-size: 20px;
|
||||
color: @text-color-secondary;
|
||||
line-height: 40px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 14px;
|
||||
line-height: 28px; // 减少行高,避免占用过多高度
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-icon {
|
||||
width: 20px;
|
||||
height: 18px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
margin-bottom: 1px;
|
||||
vertical-align: middle; // 对齐文字
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 右侧地图区 - 移动端关键适配(高度自适应) */
|
||||
.branch-right {
|
||||
width: 870px;
|
||||
height: 850px; // 桌面端固定高度
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
margin-left: 60px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%; // 占满屏幕宽度
|
||||
height: 300px; // 固定小屏高度(或用min-height: 50vh自适应)
|
||||
margin-left: 0; // 取消左侧间距
|
||||
margin-top: 20px; // 与左侧区域留间距
|
||||
}
|
||||
}
|
||||
|
||||
/* 平板过渡态(768px~1200px)- 补充中间尺寸适配 */
|
||||
@media (min-width: 769px) and (max-width: 1200px) {
|
||||
.branch-section {
|
||||
padding: 40px 30px;
|
||||
}
|
||||
|
||||
.branch-left {
|
||||
margin-bottom: 40px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.branch-tabs {
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.branch-right {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<p class="card-desc">友福同享—<br />AI精准健康的领航者</p>
|
||||
<p class="card-text">
|
||||
友福同享(深圳)智能科技有限公司以人工智能为核心驱动力,专注于生命科学与AI技术融合,打造主动式精准健康管理平台。<br />
|
||||
公司依托先进的算法模型与多维度数据体系,为个人提供精准预测与个性化健康方案,业务覆盖全球20+国家和地区,同时深度赋能企业、政府及医疗健康机构,提供标准化、场景化的AI健康解决方案,构建健康产业新生态。
|
||||
公司依托先进的算法模型与多维度数据体系,为个人提供精准预测与个性化健康方案,业务覆盖全球13+国家和70+城市,同时深度赋能企业、政府及医疗健康机构,提供标准化、场景化的AI健康解决方案,构建健康产业新生态。
|
||||
</p>
|
||||
</div>
|
||||
<div class="team-info">
|
||||
@ -95,16 +95,22 @@
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
padding: 40px 20px;
|
||||
.intro-content {
|
||||
flex-direction: column;
|
||||
|
||||
.intro-card {
|
||||
order: 2;
|
||||
.card-text {
|
||||
line-height: 12px !important;
|
||||
}
|
||||
|
||||
.team-info {
|
||||
order: 1;
|
||||
margin-bottom: 40px;
|
||||
.team-list {
|
||||
line-height: 14px !important;
|
||||
}
|
||||
//flex-direction: column;
|
||||
//
|
||||
//.intro-card {
|
||||
// order: 2;
|
||||
//}
|
||||
//
|
||||
//.team-info {
|
||||
// order: 1;
|
||||
// margin-bottom: 40px;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,11 @@
|
||||
|
||||
<!-- 时间轴容器(控制曲线、飞机、阶段定位) -->
|
||||
<section class="timeline-section">
|
||||
<img
|
||||
src="https://images.health.ufutx.com/202506/20/26691a92ed7a9b632cd635c08e35fb17.png"
|
||||
class="timeline-section-bgImage"
|
||||
alt=""
|
||||
/>
|
||||
<div class="timeline-container">
|
||||
<!-- 发展阶段 -->
|
||||
<div v-for="(item, index) in timelineData" :key="index" class="timeline-stage" :class="`stage-${index}`">
|
||||
@ -70,7 +75,7 @@ const timelineData = [
|
||||
padding: 80px 20px;
|
||||
border-top: 50px solid #f5f7fe;
|
||||
text-align: center;
|
||||
|
||||
//height: auto;
|
||||
// 标题区样式
|
||||
.timeline-header {
|
||||
margin-bottom: 50px;
|
||||
@ -89,15 +94,23 @@ const timelineData = [
|
||||
.timeline-section {
|
||||
padding: 50px 0px;
|
||||
margin: 0 192px;
|
||||
background-image: url('https://images.health.ufutx.com/202506/20/26691a92ed7a9b632cd635c08e35fb17.png');
|
||||
background-position: top;
|
||||
height: 955px; // 固定高度承载绝对定位
|
||||
background-size: contain;
|
||||
//background-image: url('https://images.health.ufutx.com/202506/20/26691a92ed7a9b632cd635c08e35fb17.png');
|
||||
//background-position: top;
|
||||
//background-repeat: no-repeat;
|
||||
height: auto; // 固定高度承载绝对定位
|
||||
//background-size: contain;
|
||||
position: relative;
|
||||
.timeline-section-bgImage {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
//background: red;
|
||||
}
|
||||
// 核心容器:提供定位参考
|
||||
.timeline-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: 944px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
// 阶段通用样式
|
||||
@ -219,21 +232,100 @@ const timelineData = [
|
||||
}
|
||||
|
||||
// 响应式适配(移动端垂直排列)
|
||||
// 响应式适配(彻底解决高度撑开问题)
|
||||
@media (max-width: 768px) {
|
||||
.timeline-container {
|
||||
height: auto; // 取消固定高度
|
||||
padding: 40px 0;
|
||||
// 1. 重置最外层容器样式
|
||||
.company-timeline {
|
||||
padding: 40px 16px;
|
||||
border-top-width: 20px; // 缩小顶部边框,适配移动端
|
||||
}
|
||||
|
||||
//.timeline-stage {
|
||||
// position: relative; // 重置定位
|
||||
// margin: 40px auto; // 垂直分布
|
||||
// width: 80%; // 适配小屏宽度
|
||||
// left: auto;
|
||||
// right: auto;
|
||||
// top: auto;
|
||||
// bottom: auto;
|
||||
// transform: none; // 清除变换
|
||||
//}
|
||||
// 2. 关键:彻底取消.timeline-section的固定高度,强制由内容决定
|
||||
::v-deep .timeline-section {
|
||||
margin: 0 16px !important;
|
||||
padding: 20px 0 !important;
|
||||
height: auto !important; /* 强制覆盖桌面端的955px固定高度 */
|
||||
min-height: auto !important; /* 清除可能存在的最小高度限制 */
|
||||
background-size: 100% auto !important;
|
||||
background-position: top center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
overflow: visible !important; /* 确保内容不被截断 */
|
||||
}
|
||||
|
||||
// 3. 重置容器高度,确保继承内容高度
|
||||
::v-deep .timeline-container {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
height: auto !important; /* 彻底取消100%继承的固定高度 */
|
||||
padding: 20px 0 !important;
|
||||
overflow: visible !important; /* 允许内容撑开高度 */
|
||||
display: block !important; /* 确保是块级元素,能计算内容高度 */
|
||||
}
|
||||
|
||||
// 4. 阶段元素完全回归文档流,确保参与高度计算
|
||||
::v-deep .timeline-stage {
|
||||
position: static !important; /* 强制取消绝对定位,必须带!important */
|
||||
width: 100% !important;
|
||||
max-width: 300px !important;
|
||||
margin: 0 auto 60px !important; /* 增加底部间距,确保内容不重叠 */
|
||||
padding: 10px 0 !important; /* 增加内边距,避免内容紧贴 */
|
||||
display: grid !important;
|
||||
justify-items: center !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
// 5. 隐藏桌面端线条,避免干扰高度
|
||||
::v-deep .stage-0:after,
|
||||
::v-deep .stage-1:after,
|
||||
::v-deep .stage-2:after,
|
||||
::v-deep .stage-3:after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// 6. 调整内容样式,确保内容有足够高度
|
||||
::v-deep .stage-period {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
::v-deep .stage-line {
|
||||
margin: 0 auto 12px !important; /* 居中显示线条,增加间距 */
|
||||
}
|
||||
|
||||
::v-deep .stage-title {
|
||||
font-size: 24px !important;
|
||||
margin: 12px 0 16px !important; /* 增加上下间距,提升高度贡献 */
|
||||
}
|
||||
|
||||
::v-deep .stage-content {
|
||||
width: 100% !important;
|
||||
padding: 0 10px !important; /* 增加左右内边距,避免内容过宽 */
|
||||
li {
|
||||
font-size: 14px !important;
|
||||
line-height: 26px !important; /* 增加行高,确保内容高度 */
|
||||
margin-bottom: 8px !important; /* 增加列表项间距 */
|
||||
text-align: left !important;
|
||||
padding-left: 16px !important;
|
||||
&::before {
|
||||
content: '·';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: #4b89dc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 7. 标题区适配,避免挤压内容
|
||||
.timeline-header {
|
||||
margin-bottom: 30px !important;
|
||||
.main-title {
|
||||
font-size: 24px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
.sub-title {
|
||||
font-size: 16px !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
<template>
|
||||
<section class="app-scenes">
|
||||
<h3 class="app-title">应用场景</h3>
|
||||
<!-- <div class="scenes-tabs">-->
|
||||
<!-- <span v-for="(tab, i) in tabs" :key="i" :class="{ active: currentTab === i }" @click="currentTab = i">{{-->
|
||||
<!-- tab-->
|
||||
<!-- }}</span>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- 标签切换(友福动态 / 媒体报道) -->
|
||||
<!-- 标签切换 -->
|
||||
<el-tabs v-model="activeTab" class="news-tabs" @tab-click="handleTabClick">
|
||||
<el-tab-pane v-for="(tab, index) in valueTabs" :key="index" :label="tab.title" :name="tab.name">
|
||||
<template #label>
|
||||
<p class="scene-label">{{ tab.title }}</p>
|
||||
</template>
|
||||
<div v-show="currentTabIndex === index" class="scenes-content">
|
||||
<div class="scene-desc">
|
||||
<div class="speech-title">
|
||||
@ -74,34 +72,33 @@ const valueTabs = [
|
||||
image: 'https://images.health.ufutx.com/202506/20/ba5d18e65df7d1fef4d9be2fdb185c23.png'
|
||||
}
|
||||
]
|
||||
const activeTab = ref(valueTabs[0].name) // 默认选中第一个标签
|
||||
const currentTabIndex = ref(0) // 当前选中标签的下标
|
||||
// 计算属性:当前选中的标签数据
|
||||
// const currentTab = computed(() => {
|
||||
// return valueTabs[currentTabIndex.value] || valueTabs[0]
|
||||
// })
|
||||
const handleTabClick = (tab: any, event: Event) => {
|
||||
console.log(tab.props.name, event)
|
||||
currentTabIndex.value = valueTabs.findIndex(item => item.name === tab.props.name)
|
||||
const activeTab = ref(valueTabs[0].name)
|
||||
const currentTabIndex = ref(0)
|
||||
|
||||
console.log(currentTabIndex.value)
|
||||
// currentPage.value = 1 // 切换标签时重置页码
|
||||
const handleTabClick = (tab: any) => {
|
||||
currentTabIndex.value = valueTabs.findIndex(item => item.name === tab.props.name)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
/* 标签切换样式(还原设计的蓝色下划线) */
|
||||
/* 基础样式保持不变 */
|
||||
.news-tabs {
|
||||
.pt(50px);
|
||||
width: 93vw;
|
||||
padding-top: 50px;
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
width: 100%;
|
||||
.el-tabs__nav {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
:deep(.el-tabs__nav-wrap) {
|
||||
//margin-bottom: 1.04167vw;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
width: 100%;
|
||||
height: 0.5px;
|
||||
background-color: #b5b5b5;
|
||||
z-index: var(--el-index-normal);
|
||||
@ -109,10 +106,9 @@ const handleTabClick = (tab: any, event: Event) => {
|
||||
}
|
||||
|
||||
:deep(.el-tabs__active-bar) {
|
||||
background-color: @primary-dark; // 下划线颜色
|
||||
background-color: @primary-dark;
|
||||
height: 3px;
|
||||
bottom: -10px !important;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
@ -122,30 +118,20 @@ const handleTabClick = (tab: any, event: Event) => {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
gap: 100px;
|
||||
gap: 100px; /* 桌面端标签间距 */
|
||||
|
||||
.el-tabs__item {
|
||||
font-size: @font-size-lg;
|
||||
color: @text-color-secondary;
|
||||
|
||||
&.is-active {
|
||||
color: @primary-dark; // 激活态文字颜色
|
||||
color: @primary-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.news-tabs {
|
||||
// 关键:让选项卡居中
|
||||
:deep(.el-tabs__header) {
|
||||
width: 100%; // 占满容器宽度,为居中提供基础
|
||||
.el-tabs__nav {
|
||||
justify-content: center; // 水平居中对齐
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-scenes {
|
||||
text-align: center;
|
||||
padding: 50px 0;
|
||||
@ -154,62 +140,32 @@ const handleTabClick = (tab: any, event: Event) => {
|
||||
color: @text-color;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
line-height: 32px; /* 100% */
|
||||
line-height: 32px;
|
||||
letter-spacing: 0.32px;
|
||||
//.mb(50px);
|
||||
}
|
||||
|
||||
.scenes-tabs {
|
||||
margin-bottom: 40px;
|
||||
|
||||
span {
|
||||
margin: 0 20px;
|
||||
font-size: @font-size-md;
|
||||
color: @text-color-secondary;
|
||||
cursor: pointer;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 2px solid transparent;
|
||||
|
||||
&.active {
|
||||
color: @primary-color;
|
||||
border-bottom: 2px solid @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scenes-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 192px;
|
||||
margin: 0 192px; /* 桌面端左右边距 */
|
||||
padding: 80px 30px 30px 30px;
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(180deg, rgba(250, 250, 250, 0) 0%, #fafafa 100%);
|
||||
//background: #00acc1;
|
||||
&:after {
|
||||
position: absolute;
|
||||
left: 500px;
|
||||
bottom: 7px;
|
||||
content: ' ';
|
||||
width: 360px;
|
||||
height: 360px;
|
||||
background-image: url('https://images.health.ufutx.com/202506/20/fc55ef830c38d03501fb37bc9f111b71.png');
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.scene-desc {
|
||||
width: 600px;
|
||||
width: 600px; /* 桌面端描述宽度 */
|
||||
text-align: left;
|
||||
//padding: 0 40px;
|
||||
|
||||
.speech-title {
|
||||
color: @text-color;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
display: flex; // 启用 Flex 布局
|
||||
align-items: center; // 子元素垂直居中
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
.mb(20px);
|
||||
margin-bottom: 20px;
|
||||
|
||||
.icon {
|
||||
width: 18px;
|
||||
@ -221,32 +177,116 @@ const handleTabClick = (tab: any, event: Event) => {
|
||||
.speech-subtitle {
|
||||
color: @text-color;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
._text {
|
||||
margin-bottom: 10px;
|
||||
color: @text-color;
|
||||
font-size: 14px;
|
||||
._text {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scene-img {
|
||||
text-align: center;
|
||||
width: 600px;
|
||||
|
||||
width: 600px; /* 桌面端图片宽度 */
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
flex-direction: column;
|
||||
.scene-desc {
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
margin-bottom: 20px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端适配(768px以下,核心优化) */
|
||||
@media (max-width: 768px) {
|
||||
.app-scenes {
|
||||
padding: 30px 15px; /* 缩小整体内边距,避免贴边 */
|
||||
|
||||
.app-title {
|
||||
font-size: 24px; /* 缩小标题字体 */
|
||||
line-height: 1.5; /* 优化行高,避免拥挤 */
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.scenes-content {
|
||||
flex-direction: column; /* 垂直堆叠布局,替代左右分栏 */
|
||||
margin: 0; /* 取消桌面端192px边距 */
|
||||
padding: 30px 15px; /* 内边距适配小屏 */
|
||||
gap: 20px; /* 描述与图片间距 */
|
||||
|
||||
.scene-desc {
|
||||
width: 100%; /* 占满屏幕宽度 */
|
||||
margin-bottom: 0; /* 取消冗余间距,用gap控制 */
|
||||
|
||||
.speech-title {
|
||||
font-size: 16px; /* 缩小标题 */
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.speech-subtitle {
|
||||
font-size: 13px; /* 缩小内容字体 */
|
||||
|
||||
._text {
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.5; /* 适配小屏行高 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scene-img {
|
||||
width: 100%; /* 图片占满宽度 */
|
||||
max-width: 400px; /* 限制最大宽度,避免大屏拉伸 */
|
||||
margin: 0 auto; /* 居中显示 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 标签页核心适配(解决溢出问题) */
|
||||
.news-tabs {
|
||||
padding-top: 20px;
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
.el-tabs__nav {
|
||||
gap: 25px; /* 缩小标签间距,避免溢出 */
|
||||
overflow-x: auto; /* 允许横向滚动,适配多标签 */
|
||||
padding: 0 5px; /* 左右留白,避免贴边 */
|
||||
scrollbar-width: none; /* 隐藏火狐滚动条 */
|
||||
&::-webkit-scrollbar {
|
||||
/* 隐藏Chrome滚动条 */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
font-size: 14px; /* 缩小标签字体 */
|
||||
white-space: nowrap; /* 防止标签换行 */
|
||||
padding: 0 5px; /* 标签内边距优化 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-tabs__active-bar) {
|
||||
bottom: -8px !important; /* 调整下划线位置,避免错位 */
|
||||
height: 2px; /* 缩小下划线,适配小屏 */
|
||||
}
|
||||
|
||||
/* 自定义标签文本适配 */
|
||||
.scene-label {
|
||||
font-size: 14px; /* 与el-tabs__item字体统一 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 平板过渡态(769px~1024px)- 避免中间尺寸断裂 */
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
.app-scenes .scenes-content {
|
||||
margin: 0 50px;
|
||||
gap: 30px;
|
||||
|
||||
.scene-desc,
|
||||
.scene-img {
|
||||
width: 45%; /* 左右分栏但缩小宽度 */
|
||||
}
|
||||
}
|
||||
|
||||
.news-tabs :deep(.el-tabs__nav) {
|
||||
gap: 50px; /* 标签间距过渡 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="mv-content">
|
||||
<div class="mv-text">
|
||||
<h2 class="mv-title">使命与愿景</h2>
|
||||
<p class="mv-desc">使命-提升人类生命质量 —— 愿景-成为健康生活方式的引领者</p>
|
||||
<p class="mv-desc">使命-提升人类生命质量 —— 愿景-做健康生活方式的引领者</p>
|
||||
</div>
|
||||
<!-- <div class="mv-img">-->
|
||||
<!-- <img-->
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<!-- 模板部分保持不变 -->
|
||||
<section class="qualification">
|
||||
<h2 class="section-title">资质认证</h2>
|
||||
<p class="section-subtitle">成立至今获得多项荣誉</p>
|
||||
@ -7,7 +8,8 @@
|
||||
<div class="certificate-section">
|
||||
<div class="certificate-list">
|
||||
<Marquee
|
||||
:duration="60"
|
||||
v-if="certificateImgs.length > 0"
|
||||
:duration="300"
|
||||
:reverse="false"
|
||||
repeatCount="3"
|
||||
pause-on-hover
|
||||
@ -18,15 +20,12 @@
|
||||
v-for="(src, index) in certificateImgs"
|
||||
:key="index"
|
||||
class="certificate-item"
|
||||
:class="{ 'scale-up': activeIndex === index }"
|
||||
@mouseenter="activeIndex = index"
|
||||
@mouseleave="activeIndex = -1"
|
||||
>
|
||||
<el-image
|
||||
:ref="
|
||||
(el: any) => {
|
||||
imageRefs[index] = el
|
||||
}
|
||||
"
|
||||
:ref="(el: any) => (imageRefs[index] = el)"
|
||||
:src="src"
|
||||
alt="certificate"
|
||||
class="certificate-image"
|
||||
@ -34,8 +33,8 @@
|
||||
:preview-src-list="certificateImgs"
|
||||
show-progress
|
||||
preview-teleported
|
||||
fit="cover"
|
||||
:initial-index="index"
|
||||
:class="{ 'scale-up': activeIndex === index }"
|
||||
/>
|
||||
<div
|
||||
v-show="activeIndex === index"
|
||||
@ -55,33 +54,53 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import Marquee from '@/components/Marquee.vue'
|
||||
import type { ImageInstance } from 'element-plus'
|
||||
// 创建数组ref存储每个图片实例
|
||||
import request from '@/utils/request.ts'
|
||||
|
||||
const certificateImgs = ref<string[]>([])
|
||||
const imageRefs = ref<(ImageInstance | null)[]>([])
|
||||
|
||||
const certificateImgs = [
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png',
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png',
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png', // 中间证书
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png',
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png',
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png',
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png',
|
||||
'https://images.health.ufutx.com/202506/20/6972bf0f5da9af6ec4f2b8fba404d59e.png'
|
||||
]
|
||||
|
||||
const activeIndex = ref(-1)
|
||||
// 点击处理函数(接收索引参数)
|
||||
|
||||
// 生成当前日期(YYYY-MM-DD格式)
|
||||
const getCurrentDate = () => {
|
||||
const date = new Date()
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始,补零
|
||||
const day = String(date.getDate()).padStart(2, '0') // 日期补零
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
// 动态生成secret(当前日期 + 固定后缀)
|
||||
const currentDate = getCurrentDate()
|
||||
const secret = `${currentDate}-ufutx`
|
||||
|
||||
// 注意:路径中的:plat需要替换为实际平台值(如web)
|
||||
const plat = 'web' // 实际平台标识,根据需求修改
|
||||
const response = await request.get(`/go/api/${plat}/v1/assets/list?secret=${secret}`)
|
||||
|
||||
// 解析接口响应(根据实际格式调整)
|
||||
|
||||
const imgList = response.data.data
|
||||
.filter((item: any) => item.file) // 过滤掉没有file或file为空的项
|
||||
.map((item: any) => item.file) // 只提取file字段的值
|
||||
certificateImgs.value = imgList
|
||||
console.log(imgList)
|
||||
} catch (error) {
|
||||
console.error('资质图片加载失败:', error)
|
||||
}
|
||||
})
|
||||
|
||||
const handleClick = (index: number) => {
|
||||
const image = imageRefs.value[index]
|
||||
if (image) {
|
||||
image.showPreview() // 调用对应图片的预览方法
|
||||
image.showPreview()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.qualification {
|
||||
text-align: center;
|
||||
@ -139,7 +158,7 @@ const handleClick = (index: number) => {
|
||||
//background: red;
|
||||
}
|
||||
.certificate-section {
|
||||
padding: 122px 0px;
|
||||
padding: 100px 0px;
|
||||
|
||||
&&::before {
|
||||
content: '';
|
||||
@ -161,6 +180,7 @@ const handleClick = (index: number) => {
|
||||
height: 460px;
|
||||
align-items: center;
|
||||
//background: red;
|
||||
padding-top: 32px;
|
||||
margin: 0 auto;
|
||||
//margin-left: 100px;
|
||||
box-sizing: border-box;
|
||||
@ -172,6 +192,7 @@ const handleClick = (index: number) => {
|
||||
}
|
||||
|
||||
.certificate-item {
|
||||
width: 288px; /* 固定宽度,确保能在一行放下多个 */
|
||||
width: 288px; /* 固定宽度,确保能在一行放下多个 */
|
||||
flex-shrink: 0; /* 禁止收缩,保证宽度不变 */
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); /* 增加轻微阴影,提升视觉层次 */
|
||||
@ -179,12 +200,25 @@ const handleClick = (index: number) => {
|
||||
cursor: pointer; /* 提示可交互 */
|
||||
position: relative;
|
||||
transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); /* 卡片整体过渡 */
|
||||
|
||||
width: 288px;
|
||||
height: 384px;
|
||||
background-image: url('https://images.health.ufutx.com/202507/08/e83e520b3e3098d5b7331f627042a1f2.png');
|
||||
background-size: cover;
|
||||
transform-origin: bottom center; /* 核心:设置缩放原点为底部中心 */
|
||||
transition:
|
||||
transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94),
|
||||
border-color 0.3s ease;
|
||||
.certificate-image {
|
||||
width: 288px;
|
||||
transform-origin: bottom center; /* 核心:设置缩放原点为底部中心 */
|
||||
transition:
|
||||
transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94),
|
||||
border-color 0.3s ease;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
//opacity: 0;
|
||||
|
||||
width: 260px;
|
||||
height: 356px;
|
||||
margin-top: 14px;
|
||||
//transform: scale(0.9);
|
||||
//border: 12px solid #fff;
|
||||
}
|
||||
.certificate-preview {
|
||||
position: absolute;
|
||||
@ -231,6 +265,9 @@ const handleClick = (index: number) => {
|
||||
}
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.qualification {
|
||||
height: auto;
|
||||
}
|
||||
.certificate-list {
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
@ -10,6 +10,9 @@
|
||||
<!-- 标签切换(友福动态 / 媒体报道) -->
|
||||
<el-tabs v-model="activeTab" class="news-tabs">
|
||||
<el-tab-pane v-for="scene in scenes" :key="scene.name" :label="scene.title" :name="scene.name">
|
||||
<template #label>
|
||||
<p class="scene-label">{{ scene.title }}</p>
|
||||
</template>
|
||||
<div class="scenes-content">
|
||||
<!-- 文字描述区 -->
|
||||
<div class="scene-desc">
|
||||
@ -131,6 +134,30 @@ const activeTab = ref(scenes.value[0].name)
|
||||
justify-content: center; // 水平居中对齐
|
||||
}
|
||||
}
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
//flex-direction: column;
|
||||
.scene-label {
|
||||
font-size: @font-size-sm;
|
||||
}
|
||||
.speech-title {
|
||||
p {
|
||||
font-size: @font-size-sm;
|
||||
}
|
||||
}
|
||||
.speech-content li {
|
||||
font-size: 14px;
|
||||
color: @text-color-secondary;
|
||||
line-height: 25px;
|
||||
position: relative;
|
||||
padding-left: 12px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.scene-desc {
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-scenes {
|
||||
@ -213,15 +240,6 @@ const activeTab = ref(scenes.value[0].name)
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
flex-direction: column;
|
||||
.scene-desc {
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.speech-content {
|
||||
@ -244,4 +262,100 @@ const activeTab = ref(scenes.value[0].name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------- 移动端适配(max-width: 768px) ------------------- */
|
||||
@media (max-width: 768px) {
|
||||
/* 页面整体适配 */
|
||||
.app-scenes {
|
||||
padding: 0 15px; /* 取消192px边距,改为小屏留白 */
|
||||
|
||||
.app-title {
|
||||
font-size: 24px; /* 缩小标题字体 */
|
||||
line-height: 1.5;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* 场景内容区:垂直堆叠 */
|
||||
.scenes-content {
|
||||
flex-direction: column; /* 横向→垂直 */
|
||||
padding: 20px 10px;
|
||||
gap: 20px; /* 缩小间距 */
|
||||
|
||||
/* 隐藏移动端不需要的装饰伪元素 */
|
||||
&:after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 文字描述区:占满宽度 */
|
||||
.scene-desc {
|
||||
width: 100%; /* 取消600px固定宽度 */
|
||||
text-align: left;
|
||||
padding: 0 5px;
|
||||
|
||||
.speech-title {
|
||||
font-size: 16px; /* 缩小标题 */
|
||||
margin-bottom: 15px;
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 图片区:占满宽度+限制最大尺寸 */
|
||||
.scene-img {
|
||||
width: 100%; /* 取消600px固定宽度 */
|
||||
max-width: 400px; /* 避免大屏手机拉伸 */
|
||||
margin: 0 auto; /* 居中 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 标签栏:解决溢出+优化交互 */
|
||||
.news-tabs {
|
||||
padding: 30px 0 20px;
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
.el-tabs__nav {
|
||||
gap: 30px; /* 缩小标签间距,避免溢出 */
|
||||
overflow-x: auto; /* 允许横向滚动 */
|
||||
padding: 0 5px; /* 左右留白 */
|
||||
scrollbar-width: none; /* 隐藏火狐滚动条 */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
/* 隐藏Chrome滚动条 */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
font-size: 14px; /* 缩小标签字体 */
|
||||
white-space: nowrap; /* 防止标签换行 */
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 调整下划线位置,避免错位 */
|
||||
:deep(.el-tabs__active-bar) {
|
||||
bottom: -8px !important;
|
||||
height: 2px; /* 缩小下划线 */
|
||||
}
|
||||
|
||||
/* 自定义标签文本适配 */
|
||||
.scene-label {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 列表样式:优化小屏阅读 */
|
||||
.speech-content li {
|
||||
line-height: 28px; /* 略微增加行高,提升可读性 */
|
||||
padding-left: 15px;
|
||||
|
||||
&::before {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<section class="banner">
|
||||
<div v-motion-fade-visible class="banner-bg">
|
||||
<!-- 替换为实际背景图路径 -->
|
||||
<img src="https://images.health.ufutx.com/202506/13/19ee6e89c397511fef5ba05d9798cc76.png" alt="Banner背景" />
|
||||
<img src="https://images.health.ufutx.com/202509/26/9986d47439b87108c3cbb01ddf2a853d.jpeg" alt="Banner背景" />
|
||||
</div>
|
||||
<div class="news-panel">
|
||||
<div
|
||||
@ -139,6 +139,9 @@ const newsList = [
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner {
|
||||
height: auto !important;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
@ -151,5 +154,8 @@ const newsList = [
|
||||
padding: 10px 24px;
|
||||
}
|
||||
}
|
||||
.news-panel {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -117,4 +117,18 @@
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
/* -------------- 移动端适配(768px以下)-------------- */
|
||||
@media (max-width: 768px) {
|
||||
.app-promotion {
|
||||
//padding-top: 30px; /* 缩小顶部留白 */
|
||||
.app-download {
|
||||
}
|
||||
.app-item {
|
||||
margin-top: 50px;
|
||||
height: 52px;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -253,6 +253,7 @@ const handleSelect = (index: number) => {
|
||||
.device-info {
|
||||
.device-desc {
|
||||
max-width: 100%;
|
||||
line-height: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,14 +262,14 @@ const handleSelect = (index: number) => {
|
||||
/* 响应式适配 */
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
.feature-nav {
|
||||
gap: 40px;
|
||||
gap: 20px;
|
||||
.nav-item {
|
||||
&:not(:first-child)::before {
|
||||
left: -20px;
|
||||
left: -12px;
|
||||
height: 8px;
|
||||
}
|
||||
.nav-text {
|
||||
font-size: @font-size-sm;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,6 +128,7 @@ const openReport = () => {
|
||||
.device-info {
|
||||
.device-desc {
|
||||
max-width: 100%;
|
||||
line-height: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,8 +90,8 @@ const openReport = () => {
|
||||
}
|
||||
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
flex-direction: column;
|
||||
padding: 40px 20px;
|
||||
//flex-direction: column;
|
||||
//padding: 40px 20px;
|
||||
|
||||
.speech-content {
|
||||
flex-direction: column;
|
||||
@ -100,6 +100,7 @@ const openReport = () => {
|
||||
.speech-info {
|
||||
.speech-desc {
|
||||
max-width: 100%;
|
||||
line-height: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +139,9 @@
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner {
|
||||
height: auto !important;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
|
||||
@ -58,7 +58,7 @@ const points = [
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
border-radius: 16px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
//background: rgba(255, 255, 255, 0.6);
|
||||
|
||||
/* 底部导航 0.8透模糊 */
|
||||
backdrop-filter: blur(25px);
|
||||
@ -77,12 +77,12 @@ const points = [
|
||||
gap: 20px;
|
||||
margin: 0 auto;
|
||||
.pb(20px);
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
@media (max-width: @mobile-breakpoint) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
//@media (max-width: @tablet-breakpoint) {
|
||||
// grid-template-columns: repeat(2, 1fr);
|
||||
//}
|
||||
//@media (max-width: @mobile-breakpoint) {
|
||||
// grid-template-columns: 1fr;
|
||||
//}
|
||||
}
|
||||
|
||||
.point-card {
|
||||
|
||||
@ -139,6 +139,9 @@
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner-bg {
|
||||
height: auto !important;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
|
||||
@ -67,7 +67,7 @@ const navItems = [
|
||||
title: '共享万亿市场机遇',
|
||||
desc:
|
||||
'携手友福同享,共同分享AI智能健康产业的巨大红利,实现区域市场的快速增长。\n' +
|
||||
'我们期待与您携手,将AI智能健康理念带到更多城市,共同提升人类生命质量,成为健康生活方式的引领者。',
|
||||
'我们期待与您携手,将AI智能健康理念带到更多城市,共同提升人类生命质量,做健康生活方式的引领者。',
|
||||
icon: 'https://images.health.ufutx.com/202506/20/d780da8996bc4a771e70300456e4eb5d.png',
|
||||
illustration: 'https://images.health.ufutx.com/202506/23/152ab9d119dbab87bbfc8bc496cc3e98.png'
|
||||
}
|
||||
@ -231,7 +231,12 @@ const currentIdx = ref(0)
|
||||
//.nav-bar {
|
||||
// gap: 30px;
|
||||
//}
|
||||
|
||||
.text {
|
||||
margin-top: 22px !important;
|
||||
}
|
||||
.desc {
|
||||
line-height: 12px !important;
|
||||
}
|
||||
.content {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
|
||||
@ -38,6 +38,7 @@ const openCooperationDialog = () => {
|
||||
text-align: left;
|
||||
background-image: url('https://images.health.ufutx.com/202506/20/c60d98038ab065c2e92dc67b938d45e2.png');
|
||||
background-size: cover;
|
||||
background-position: top;
|
||||
|
||||
.consult-content {
|
||||
max-width: 1066px;
|
||||
@ -64,4 +65,12 @@ const openCooperationDialog = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端适配(768px以下) */
|
||||
@media (max-width: 768px) {
|
||||
.consult-btn {
|
||||
width: 60px !important;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -100,11 +100,11 @@ defineExpose({
|
||||
display: flex;
|
||||
padding: 16px 50px;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid var(--1060-ff, #1060ff);
|
||||
color: var(--1060-ff, #1060ff);
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@ -112,6 +112,16 @@ defineExpose({
|
||||
background: var(--1060-ff, #1060ff);
|
||||
color: #fff;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.confirmButtonClass {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.confirmButtonClass {
|
||||
background: var(--1060-ff, #1060ff);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="less">
|
||||
:deep(.el-dialog) {
|
||||
@ -197,4 +207,96 @@ defineExpose({
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 移动端适配(768px以下)
|
||||
@media (max-width: 768px) {
|
||||
:deep(.el-dialog) {
|
||||
border-radius: 20px;
|
||||
padding: 50px 70px;
|
||||
|
||||
.form-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
line-height: 14px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.el-input__wrapper,
|
||||
.el-textarea__inner {
|
||||
display: flex;
|
||||
padding: 18px 16px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-self: stretch;
|
||||
border-radius: 10px;
|
||||
border: 0.5px solid #b2b3b5;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 在你的全局样式文件中 */
|
||||
|
||||
.el-input__inner::placeholder,
|
||||
.el-textarea__inner::placeholder {
|
||||
color: var(--b-2-b-3-b-5, #b2b3b5);
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.el-textarea__inner {
|
||||
min-height: 142px !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog) {
|
||||
width: 90% !important; /* 弹框宽度占屏幕90% */
|
||||
padding: 20px 15px; /* 减小内边距 */
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 15px; /* 减小表单项间距 */
|
||||
}
|
||||
|
||||
.el-input__wrapper,
|
||||
.el-textarea__inner {
|
||||
padding: 12px 14px; /* 减小输入框内边距 */
|
||||
}
|
||||
|
||||
.el-textarea__inner {
|
||||
min-height: 100px !important; /* 减小文本域高度 */
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-header {
|
||||
font-size: 18px; /* 减小标题字体 */
|
||||
padding-bottom: 25px; /* 减小标题底部间距 */
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
gap: 15px; /* 减小按钮间距 */
|
||||
|
||||
.cancel-btn,
|
||||
.confirm-btn {
|
||||
width: 45%; /* 按钮宽度平分 */
|
||||
height: 44px; /* 减小按钮高度 */
|
||||
padding: 10px 0; /* 垂直居中文字 */
|
||||
font-size: 14px; /* 减小按钮文字 */
|
||||
}
|
||||
}
|
||||
|
||||
// 确保输入框和按钮不超出容器
|
||||
:deep(.el-input),
|
||||
:deep(.el-textarea),
|
||||
.dialog-footer > div {
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -197,6 +197,9 @@ const resetHighlight = () => {
|
||||
gap: 20px;
|
||||
.health-item {
|
||||
border-radius: 8px !important;
|
||||
.item-desc {
|
||||
line-height: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.sector-img-container {
|
||||
|
||||
@ -24,7 +24,7 @@ const cooperations = [
|
||||
{
|
||||
icon: 'https://images.health.ufutx.com/202506/19/f3c8ac06eca308002736e3e42e026265.png',
|
||||
title: '丰富的市场验证与成功案例',
|
||||
desc: '已服务16+国家、70+地区客户,数千例客户成功案例'
|
||||
desc: '已服务13+国家、70+地区客户,数千例客户成功案例'
|
||||
},
|
||||
{
|
||||
icon: 'https://images.health.ufutx.com/202506/19/f3c8ac06eca308002736e3e42e026265.png',
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<section class="banner">
|
||||
<div v-motion-fade-visible class="banner-bg">
|
||||
<!-- 替换为实际背景图路径 -->
|
||||
<img src="https://images.health.ufutx.com/202506/12/e6ea04327d2b5dbd9e4ae441431018df.png" alt="Banner背景" />
|
||||
<img src="https://images.health.ufutx.com/202507/08/a8e9e05faedce4f60b6a97e3bbcb6d1d.png" alt="Banner背景" />
|
||||
</div>
|
||||
<div class="news-panel">
|
||||
<div
|
||||
@ -142,9 +142,11 @@ const newsList = [
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner {
|
||||
height: auto !important;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
@ -157,5 +159,8 @@ const newsList = [
|
||||
padding: 10px 24px;
|
||||
}
|
||||
}
|
||||
.news-panel {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -8,6 +8,23 @@
|
||||
<!-- 循环渲染所有模块 -->
|
||||
<div v-for="item in modules" :key="item.id" :class="['module', `module-${item.id}`]">
|
||||
<div
|
||||
class="center-module"
|
||||
:class="{
|
||||
'hover-delay': isHover === item.id
|
||||
}"
|
||||
@mouseenter="handleMouseEnter(item.id)"
|
||||
@mouseleave="handleMouseLeave(item.id)"
|
||||
>
|
||||
<div class="center-icon">
|
||||
<img :src="item.icon" alt="center icon" />
|
||||
</div>
|
||||
<div class="center-title">{{ item.title }}</div>
|
||||
<div class="center-desc">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="isHover !== item.id"
|
||||
class="module-content"
|
||||
:class="{
|
||||
hover: isHover === item.id,
|
||||
@ -20,14 +37,11 @@
|
||||
<img :src="item.icon" :alt="item.title" />
|
||||
</div>
|
||||
<div class="text">{{ item.title }}</div>
|
||||
<div
|
||||
v-if="isHover === item.id && isDelay[item.id]"
|
||||
class="desc"
|
||||
:class="{ show: isHover === item.id && isDelay[item.id] }"
|
||||
>
|
||||
<div v-if="isHover === item.id && isDelay[item.id]" class="desc">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <!– 中心模块 –>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -80,6 +94,7 @@ const modules = [
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
}
|
||||
]
|
||||
// const date = new Date()
|
||||
|
||||
// 控制当前悬浮的模块(0为无悬浮)
|
||||
const isHover = ref<number>(0)
|
||||
@ -158,7 +173,7 @@ const handleMouseLeave = (moduleId: number) => {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
transform-origin: center center;
|
||||
transition:
|
||||
height 0.2s ease,
|
||||
opacity 0.1s ease,
|
||||
width 0.3s ease,
|
||||
transform 1s ease;
|
||||
|
||||
@ -206,28 +221,19 @@ const handleMouseLeave = (moduleId: number) => {
|
||||
|
||||
// hover基础动画
|
||||
&.hover {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
transform: translateX(-20%);
|
||||
.text {
|
||||
overflow: auto;
|
||||
text-overflow: ellipsis;
|
||||
white-space: pre-wrap;
|
||||
width: 100%;
|
||||
}
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
// 延迟布局样式
|
||||
&.hover-delay {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
align-items: start;
|
||||
justify-items: center;
|
||||
border-radius: 16px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
//&.hover-delay {
|
||||
// display: grid;
|
||||
// grid-template-rows: auto 1fr auto;
|
||||
// align-items: start;
|
||||
// justify-items: center;
|
||||
// border-radius: 16px;
|
||||
// background: #fff;
|
||||
// padding: 20px;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,43 +265,98 @@ const handleMouseLeave = (moduleId: number) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.center-module {
|
||||
transform: translateX(-20%) !important;
|
||||
text-align: center;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
width: 300px;
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
transform-origin: center center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 99;
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.core-value {
|
||||
padding: 60px 0;
|
||||
transition:
|
||||
max-height 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),
|
||||
opacity 0.6s cubic-bezier(0.34, 1.56, 0.64, 1),
|
||||
transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// 关键修改:将 .hover 类选择器改为 :hover 伪类
|
||||
&.hover-delay {
|
||||
max-height: 500px; /* 设一个足够大的值(大于内容实际高度) */
|
||||
height: auto !important;
|
||||
opacity: 1;
|
||||
}
|
||||
.center-icon {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto 10px auto;
|
||||
|
||||
.container {
|
||||
.section-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.diagram-wrapper {
|
||||
height: auto;
|
||||
padding-bottom: 150%;
|
||||
|
||||
.module {
|
||||
.module-content {
|
||||
width: 150px;
|
||||
height: 60px;
|
||||
|
||||
.icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
width: 250px;
|
||||
height: auto;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.center-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: @text-color;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.center-desc {
|
||||
color: @text-color-secondary;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 25px; /* 178.571% */
|
||||
}
|
||||
}
|
||||
// 响应式适配
|
||||
//@media (max-width: 768px) {
|
||||
// .core-value {
|
||||
// padding: 60px 0;
|
||||
//
|
||||
// .container {
|
||||
// .section-title {
|
||||
// font-size: 28px;
|
||||
// }
|
||||
//
|
||||
// .diagram-wrapper {
|
||||
// height: auto;
|
||||
// padding-bottom: 150%;
|
||||
//
|
||||
// .module {
|
||||
// .module-content {
|
||||
// width: 150px;
|
||||
// height: 60px;
|
||||
//
|
||||
// .icon {
|
||||
// width: 40px;
|
||||
// height: 40px;
|
||||
// }
|
||||
// .text {
|
||||
// font-size: 16px;
|
||||
// }
|
||||
//
|
||||
// &.hover {
|
||||
// width: 250px;
|
||||
// height: auto;
|
||||
// transform: scale(1.05);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
</style>
|
||||
|
||||
@ -5,130 +5,30 @@
|
||||
<p class="section-desc">友福同享AI健康解决方案应用场景</p>
|
||||
|
||||
<div class="diagram-wrapper" :style="{ backgroundImage: `url(${diagramBg})` }">
|
||||
<!-- 模块1:AI赋能精准决策 -->
|
||||
<div class="module module-1">
|
||||
<!-- 循环渲染所有模块 -->
|
||||
<div v-for="item in modules" :key="item.id" :class="['module', `module-${item.id}`]">
|
||||
<div
|
||||
class="module-content"
|
||||
:class="{ hover: isHover === 1, 'hover-delay': isHover === 1 && isDelay[1] }"
|
||||
@mouseenter="handleMouseEnter(1)"
|
||||
@mouseleave="handleMouseLeave(1)"
|
||||
:class="{
|
||||
hover: isHover === item.id,
|
||||
'hover-delay': isHover === item.id && isDelay[item.id]
|
||||
}"
|
||||
@mouseenter="handleMouseEnter(item.id)"
|
||||
@mouseleave="handleMouseLeave(item.id)"
|
||||
>
|
||||
<div class="icon">
|
||||
<img src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png" alt="icon" />
|
||||
<img :src="item.icon" :alt="item.title" />
|
||||
</div>
|
||||
<div class="text">AI赋能精准决策</div>
|
||||
<div v-if="isHover === 1 && isDelay[1]" class="desc" :class="{ show: isHover === 1 && isDelay[1] }">
|
||||
基于海量数据分析,提供精准的健康风险评估与干预建议。
|
||||
</div>
|
||||
<!-- <div class="desc" :class="{ show: isHover === 1 && isDelay[1] }" v-show="isHover === 1">-->
|
||||
<!-- 基于海量数据分析,提供精准的健康风险评估与干预建议。-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模块2:创新七大核心 -->
|
||||
<div class="module module-2">
|
||||
<div
|
||||
class="module-content"
|
||||
:class="{ hover: isHover === 2, 'hover-delay': isHover === 2 && isDelay[2] }"
|
||||
@mouseenter="handleMouseEnter(2)"
|
||||
@mouseleave="handleMouseLeave(2)"
|
||||
>
|
||||
<div class="icon">
|
||||
<img src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png" alt="icon" />
|
||||
</div>
|
||||
<div class="text">创新七大核心...</div>
|
||||
<div class="desc" :class="{ show: isHover === 2 && isDelay[2] }">
|
||||
七大核心技术支撑,构建全场景健康服务体系。
|
||||
<div class="text">{{ item.title }}</div>
|
||||
<div
|
||||
v-if="isHover === item.id && isDelay[item.id]"
|
||||
class="desc"
|
||||
:class="{ show: isHover === item.id && isDelay[item.id] }"
|
||||
>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模块3:全方位的AI健... -->
|
||||
<div class="module module-3">
|
||||
<div
|
||||
class="module-content"
|
||||
:class="{ hover: isHover === 3, 'hover-delay': isHover === 3 && isDelay[3] }"
|
||||
@mouseenter="handleMouseEnter(3)"
|
||||
@mouseleave="handleMouseLeave(3)"
|
||||
>
|
||||
<div class="icon">
|
||||
<img src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png" alt="icon" />
|
||||
</div>
|
||||
<div class="text">全方位的AI健...</div>
|
||||
<div class="desc" :class="{ show: isHover === 3 && isDelay[3] }">
|
||||
覆盖全生命周期,提供一站式AI健康管理服务。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模块4:双重认证教练... -->
|
||||
<div class="module module-4">
|
||||
<div
|
||||
class="module-content"
|
||||
:class="{ hover: isHover === 4, 'hover-delay': isHover === 4 && isDelay[4] }"
|
||||
@mouseenter="handleMouseEnter(4)"
|
||||
@mouseleave="handleMouseLeave(4)"
|
||||
>
|
||||
<div class="icon">
|
||||
<img src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png" alt="icon" />
|
||||
</div>
|
||||
<div class="text">双重认证教练...</div>
|
||||
<div class="desc" :class="{ show: isHover === 4 && isDelay[4] }">
|
||||
专业认证教练团队,提供个性化健康指导方案。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模块5:构建健康产业... -->
|
||||
<div class="module module-5">
|
||||
<div
|
||||
class="module-content"
|
||||
:class="{ hover: isHover === 5, 'hover-delay': isHover === 5 && isDelay[5] }"
|
||||
@mouseenter="handleMouseEnter(5)"
|
||||
@mouseleave="handleMouseLeave(5)"
|
||||
>
|
||||
<div class="icon">
|
||||
<img src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png" alt="icon" />
|
||||
</div>
|
||||
<div class="text">构建健康产业...</div>
|
||||
<div class="desc" :class="{ show: isHover === 5 && isDelay[5] }">
|
||||
整合产业资源,打造闭环健康服务生态系统。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模块6:中间模块 -->
|
||||
<div class="module module-6">
|
||||
<div
|
||||
class="module-content"
|
||||
:class="{ hover: isHover === 6, 'hover-delay': isHover === 6 && isDelay[6] }"
|
||||
@mouseenter="handleMouseEnter(6)"
|
||||
@mouseleave="handleMouseLeave(6)"
|
||||
>
|
||||
<div class="icon">
|
||||
<img src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png" alt="icon" />
|
||||
</div>
|
||||
<div class="text">创新模式-身心双指标评估</div>
|
||||
<div class="desc" :class="{ show: isHover === 6 && isDelay[6] }">
|
||||
结合生理与心理健康数据,生成个性化评估方案。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <!– 中心模块 –>-->
|
||||
<!-- <div class="center-module">-->
|
||||
<!-- <div class="center-icon">-->
|
||||
<!-- <img-->
|
||||
<!-- src="https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png"-->
|
||||
<!-- alt="center icon"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="center-title">创新模式-身心双指标评估,生成精准个性化方案</div>-->
|
||||
<!-- <div class="center-desc">-->
|
||||
<!-- 整合个人身理+心理健康数据、健康行为、个人及家族疾病史及生活方式等,多维度数据,全方面分析精准个性化方案-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -140,6 +40,47 @@ import { ref } from 'vue'
|
||||
// 底图地址
|
||||
const diagramBg = 'https://images.health.ufutx.com/202507/04/3b6a1b49d79c1cd13a59187e58c614a7.png'
|
||||
|
||||
// 模块数据(统一管理)
|
||||
const modules = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'AI赋能精准决策',
|
||||
description: '基于海量数据分析,提供精准的健康风险评估与干预建议。',
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '创新七大核心要素更新人体全局系统',
|
||||
description: '自愈力、免疫力、抵抗力、平衡力、代谢力、情绪力及认知力。',
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '全方位的AI健康管理系统',
|
||||
description: '精准营养方案+心理疏导陪伴+饮食方案+关键要素指导。',
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '双重认证教练团队全程支持',
|
||||
description: '国家卫健委《营养指导员》+营养师协会《身心健康管理师》双证教练服务指导。',
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '构建健康产业生态',
|
||||
description: '整合产业链协同,链接多方资源,打造开放共赢的智慧健康生态系统。',
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: '创新模式-身心双指标评估,生成精准个性化方案',
|
||||
description:
|
||||
'整合个人身理+心理健康数据、健康行为、个人及家族疾病史及生活方式等多维度数据,全方面分析精准个性化方案。',
|
||||
icon: 'https://images.health.ufutx.com/202507/04/4a47a0db6e60853dedfcfdf08a5ca249.png'
|
||||
}
|
||||
]
|
||||
|
||||
// 控制当前悬浮的模块(0为无悬浮)
|
||||
const isHover = ref<number>(0)
|
||||
// 控制每个模块的延迟状态
|
||||
@ -203,8 +144,7 @@ const handleMouseLeave = (moduleId: number) => {
|
||||
.module {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
/* 移除模块本身的偏移,避免影响子元素定位 */
|
||||
// 模块内容容器(核心样式)
|
||||
|
||||
.module-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -216,31 +156,19 @@ const handleMouseLeave = (moduleId: number) => {
|
||||
width: 190px;
|
||||
height: 70px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
transform-origin: center center; /* 基于自身中心变换 */
|
||||
transition: all 0.8s ease;
|
||||
// hover基础动画(尺寸和缩放)
|
||||
&.hover {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
transform: translateX(-20%); /* 基于中心放大1.1倍,无偏移 */
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
transform-origin: center center;
|
||||
transition:
|
||||
height 0.2s ease,
|
||||
width 0.3s ease,
|
||||
transform 1s ease;
|
||||
|
||||
// 延迟布局样式(hover后0.4s生效,切换为网格布局)
|
||||
&.hover-delay {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto; /* 图标区 | 空白区 | 描述区 */
|
||||
align-items: start;
|
||||
justify-items: center;
|
||||
border-radius: 16px;
|
||||
background: #fff;
|
||||
padding: 20px; /* 增加内边距,避免内容贴边 */
|
||||
}
|
||||
/* 统一过渡时间和缓动函数 */
|
||||
//transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
// 图标样式
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
flex-shrink: 0; /* 防止图标缩小 */
|
||||
flex-shrink: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
@ -253,150 +181,121 @@ const handleMouseLeave = (moduleId: number) => {
|
||||
.text {
|
||||
width: 130px;
|
||||
font-size: 18px;
|
||||
color: @text-color;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// 描述文本(默认隐藏,hover后显示在底部)
|
||||
// 描述文本
|
||||
.desc {
|
||||
width: 90%; /* 限制宽度,避免超出容器 */
|
||||
width: 90%;
|
||||
opacity: 1;
|
||||
visibility: hidden;
|
||||
font-size: 14px;
|
||||
color: @text-color-secondary;
|
||||
color: #666;
|
||||
line-height: 25px;
|
||||
text-align: center;
|
||||
//transition:
|
||||
//opacity 0.3s ease 0.2s,
|
||||
//visibility 0.3s ease 0.2s;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
// hover基础动画
|
||||
&.hover {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
transform: translateX(-20%);
|
||||
.text {
|
||||
overflow: auto;
|
||||
text-overflow: ellipsis;
|
||||
white-space: pre-wrap;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 延迟布局样式
|
||||
&.hover-delay {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
align-items: start;
|
||||
justify-items: center;
|
||||
border-radius: 16px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 各模块定位(根据设计图微调,确保初始位置正确)
|
||||
// 各模块定位(与数据ID对应)
|
||||
.module-1 {
|
||||
bottom: 482px;
|
||||
left: 521px;
|
||||
}
|
||||
.module-2 {
|
||||
top: 288px;
|
||||
right: 521px;
|
||||
bottom: 482px;
|
||||
left: 1185px;
|
||||
}
|
||||
.module-3 {
|
||||
top: 530px;
|
||||
bottom: 240px;
|
||||
left: 376px;
|
||||
}
|
||||
.module-4 {
|
||||
top: 530px;
|
||||
right: 376px;
|
||||
bottom: 240px;
|
||||
left: 1328px;
|
||||
}
|
||||
.module-5 {
|
||||
top: 687px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%); /* 水平居中 */
|
||||
bottom: 83px;
|
||||
left: 852px;
|
||||
}
|
||||
.module-6 {
|
||||
bottom: 381px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%); /* 水平居中 */
|
||||
&.hover {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
transform: translateX(-50%) !important; /* 基于中心放大1.1倍,无偏移 */
|
||||
}
|
||||
}
|
||||
|
||||
// 中心模块
|
||||
.center-module {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
width: 300px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
|
||||
.center-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin: 0 auto 16px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.center-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.center-desc {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
left: 842px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.core-value {
|
||||
padding: 60px 0;
|
||||
|
||||
.container {
|
||||
.section-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.diagram-wrapper {
|
||||
height: auto;
|
||||
padding-bottom: 150%; /* 自适应高度 */
|
||||
|
||||
.module {
|
||||
.module-content {
|
||||
width: 150px;
|
||||
height: 60px;
|
||||
|
||||
.icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
width: 250px;
|
||||
height: 220px;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center-module {
|
||||
width: 80%;
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//@media (max-width: 768px) {
|
||||
// .core-value {
|
||||
// padding: 60px 0;
|
||||
//
|
||||
// .container {
|
||||
// .section-title {
|
||||
// font-size: 28px;
|
||||
// }
|
||||
//
|
||||
// .diagram-wrapper {
|
||||
// height: auto;
|
||||
// padding-bottom: 150%;
|
||||
//
|
||||
// .module {
|
||||
// .module-content {
|
||||
// width: 150px;
|
||||
// height: 60px;
|
||||
//
|
||||
// .icon {
|
||||
// width: 40px;
|
||||
// height: 40px;
|
||||
// }
|
||||
// .text {
|
||||
// font-size: 16px;
|
||||
// }
|
||||
//
|
||||
// &.hover {
|
||||
// width: 250px;
|
||||
// height: auto;
|
||||
// transform: scale(1.05);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
</style>
|
||||
|
||||
@ -216,14 +216,14 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
}
|
||||
}
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.feedback-section {
|
||||
padding: 0 20px 60px; /* 缩小移动端内边距 */
|
||||
}
|
||||
.feedback-card {
|
||||
width: 220px; /* 移动端缩小卡片宽度 */
|
||||
}
|
||||
}
|
||||
//@media (max-width: 768px) {
|
||||
// .feedback-section {
|
||||
// padding: 0 20px 60px; /* 缩小移动端内边距 */
|
||||
// }
|
||||
// .feedback-card {
|
||||
// width: 220px; /* 移动端缩小卡片宽度 */
|
||||
// }
|
||||
//}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
@ -265,4 +265,6 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
//@media (max-width: @tablet-breakpoint) { }
|
||||
</style>
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
<section class="global-service">
|
||||
<div class="container">
|
||||
<h3 class="section-title">我们全球服务覆盖范围</h3>
|
||||
<p class="section-desc">覆盖国家/地区:65+ · 客户产业覆盖范围:18+</p>
|
||||
<!-- <p class="section-desc">65+ 国家/地区覆盖 | 13+ 产业领域服务</p>-->
|
||||
<p class="section-desc">业务已拓展至 13+ 个国家,覆盖全国 70+ 个城市</p>
|
||||
<!-- 替换为实际地图路径 -->
|
||||
<img
|
||||
src="https://images.health.ufutx.com/202506/12/2acedc9535b108d6cd079b34bb01e78e.jpeg"
|
||||
|
||||
@ -177,6 +177,9 @@ const selectedIndex = ref(defaultIndex)
|
||||
}
|
||||
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
.scene-section {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
.scene-item {
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
|
||||
@ -41,6 +41,9 @@ const openReport = () => {
|
||||
.pt(36px);
|
||||
.pb(36px);
|
||||
background-image: url('https://images.health.ufutx.com/202506/18/e403f857ad7385ea660987cbcbdcf198.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.section-title {
|
||||
font-weight: bold;
|
||||
@ -123,4 +126,24 @@ const openReport = () => {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
.scene-list {
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
gap: @space-lg;
|
||||
}
|
||||
.scene-item {
|
||||
height: 280px;
|
||||
}
|
||||
.app-promotion {
|
||||
//padding-top: 30px; /* 缩小顶部留白 */
|
||||
.app-download {
|
||||
}
|
||||
.app-item {
|
||||
margin-top: 50px;
|
||||
height: 52px;
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -178,6 +178,9 @@ const newsList = [
|
||||
}
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner {
|
||||
height: auto !important;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
@ -190,5 +193,8 @@ const newsList = [
|
||||
padding: 10px 24px;
|
||||
}
|
||||
}
|
||||
.news-panel {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,117 +1,106 @@
|
||||
<template>
|
||||
<section class="feedback-section">
|
||||
<div class="feedback-title">真实客户案例</div>
|
||||
<div class="feedback-desc">友福智能健康-用AI重塑人类健康未来</div>
|
||||
<div class="feedback-list">
|
||||
<Marquee
|
||||
:duration="360"
|
||||
:reverse="false"
|
||||
repeatCount="3"
|
||||
pause-on-hover
|
||||
container-class="h-56 bg-white rounded-lg shadow-sm p-4"
|
||||
:initial-offset="0"
|
||||
<el-carousel
|
||||
ref="carouselRef"
|
||||
trigger="click"
|
||||
height="460px"
|
||||
arrow="always"
|
||||
interval="3800"
|
||||
@change="carouselChange"
|
||||
>
|
||||
<!-- 内容卡片:直接作为Marquee的子元素,不嵌套额外div -->
|
||||
<div v-for="(item, index) in feedbackList[0]" :key="`${item.username}-${index}`" class="feedback-card">
|
||||
<el-popover placement="right-end" :width="320" trigger="hover" popper-class="custom-popover">
|
||||
<template #default>
|
||||
<div class="_userinfo">
|
||||
<div class="_userPic"><img :src="item.avatar" alt="avatar" class="avatar" /></div>
|
||||
<div class="_username">{{ item.username }}</div>
|
||||
<el-carousel-item v-for="(itemList, index) in feedbackList" :key="index" :name="index">
|
||||
<div v-for="(item, idx) in itemList" :key="`${item.username}-${idx}`" class="feedback-card">
|
||||
<div class="popover-container">
|
||||
<div class="avatar-container">
|
||||
<el-image
|
||||
:ref="(el: any) => (imageRefs[idx] = el)"
|
||||
:src="item.caseImage"
|
||||
alt="certificate"
|
||||
class="certificate-image"
|
||||
:zoom-rate="1"
|
||||
scale="0.8"
|
||||
:hide-on-click-modal="true"
|
||||
:preview-src-list="[item.caseImage]"
|
||||
show-progress
|
||||
preview-teleported
|
||||
fit="contain"
|
||||
:initial-index="idx"
|
||||
/>
|
||||
</div>
|
||||
<div class="_comment">{{ item.case }}</div>
|
||||
</template>
|
||||
<template #reference>
|
||||
<div class="popover-container">
|
||||
<div class="avatar-container">
|
||||
<img :src="item.avatar" alt="avatar" class="avatar" />
|
||||
</div>
|
||||
<div class="feedback-info">
|
||||
<!-- <p class="username">{{ item.username }}</p>-->
|
||||
<p class="comment">{{ item.result }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</Marquee>
|
||||
</div>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
<div class="feedback-list" style="margin-top: 40px">
|
||||
<Marquee
|
||||
:duration="360"
|
||||
:reverse="false"
|
||||
repeatCount="3"
|
||||
pause-on-hover
|
||||
container-class="h-56 bg-white rounded-lg shadow-sm p-4"
|
||||
:initial-offset="-300"
|
||||
>
|
||||
<!-- 内容卡片:直接作为Marquee的子元素,不嵌套额外div -->
|
||||
<div v-for="(item, index) in feedbackList[1]" :key="`${item.username}-${index}`" class="feedback-card">
|
||||
<el-popover placement="right-end" :width="320" trigger="hover" popper-class="custom-popover">
|
||||
<template #default>
|
||||
<div class="_userinfo">
|
||||
<div class="_userPic"><img :src="item.avatar" alt="avatar" class="avatar" /></div>
|
||||
<div class="_username">{{ item.username }}</div>
|
||||
</div>
|
||||
<div class="_comment">{{ item.case }}</div>
|
||||
</template>
|
||||
<template #reference>
|
||||
<div class="popover-container">
|
||||
<div class="avatar-container">
|
||||
<img :src="item.avatar" alt="avatar" class="avatar" />
|
||||
</div>
|
||||
<div class="feedback-info">
|
||||
<!-- <p class="username">{{ item.username }}</p>-->
|
||||
<p class="comment">{{ item.result }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</Marquee>
|
||||
<div class="el-timeline__dot">
|
||||
<div
|
||||
v-for="(_, index) in feedbackList"
|
||||
:key="index"
|
||||
class="el-item__dot"
|
||||
:class="{ 'el-item__dot--active': index === currentIndex }"
|
||||
@click="handleSwitch(index)"
|
||||
></div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 模拟假数据(头像统一使用你提供的链接)
|
||||
// import TextGenerateEffect from '@/components/TextGenerateEffect.vue'
|
||||
import Marquee from '@/components/Marquee.vue'
|
||||
import { realCases } from '@/data/realCases.ts'
|
||||
import { ref, reactive } from 'vue'
|
||||
import type { CarouselInstance, ImageInstance } from 'element-plus'
|
||||
import { newRealCasesWithImage } from '@/data/caseImage.ts'
|
||||
|
||||
// 添加泛型类型 T 表示数组元素的类型
|
||||
function splitArrayRandomly<T>(arr: T[], ratio = 0.5): [T[], T[]] {
|
||||
// 复制原数组避免修改
|
||||
// 定义案例数据类型
|
||||
type CaseItem = {
|
||||
username: string
|
||||
case: string
|
||||
avatar: string
|
||||
result: string
|
||||
caseImage: string
|
||||
}
|
||||
|
||||
// 图片引用集合
|
||||
const imageRefs = ref<(ImageInstance | null)[]>([])
|
||||
// Carousel 实例引用(指定类型)
|
||||
const carouselRef = ref<CarouselInstance | null>(null)
|
||||
// 当前激活的轮播索引
|
||||
const currentIndex = ref(0)
|
||||
|
||||
// 切换轮播项
|
||||
const handleSwitch = (target: number) => {
|
||||
if (carouselRef.value) {
|
||||
carouselRef.value.setActiveItem(target)
|
||||
}
|
||||
}
|
||||
|
||||
// 轮播切换时更新索引
|
||||
const carouselChange = (newIndex: number) => {
|
||||
currentIndex.value = newIndex
|
||||
}
|
||||
|
||||
// 数组按3个一组随机拆分
|
||||
function splitIntoGroupsOfThree<T>(arr: T[]): T[][] {
|
||||
const shuffled = [...arr]
|
||||
|
||||
// Fisher-Yates 洗牌算法
|
||||
// Fisher-Yates 洗牌(随机打乱数组)
|
||||
for (let i = shuffled.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
|
||||
}
|
||||
|
||||
// 计算分割点(默认为 50%)
|
||||
const splitIndex = Math.round(shuffled.length * ratio)
|
||||
|
||||
// 分割数组
|
||||
return [shuffled.slice(0, splitIndex), shuffled.slice(splitIndex)]
|
||||
// 按3个一组拆分
|
||||
const groups: T[][] = []
|
||||
for (let i = 0; i < shuffled.length; i += 3) {
|
||||
groups.push(shuffled.slice(i, i + 3))
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
const feedbackList = reactive(splitArrayRandomly(realCases))
|
||||
|
||||
console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
// 处理案例数据为分组形式
|
||||
const feedbackList = reactive<CaseItem[][]>(splitIntoGroupsOfThree(newRealCasesWithImage))
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
// 基础变量(可继承项目全局样式)
|
||||
@bg-color: #f9fbff;
|
||||
@card-bg: #ffffff;
|
||||
@radius: 12px;
|
||||
@padding: 16px;
|
||||
@gap: 50px;
|
||||
@avatar-size: 60px;
|
||||
@subtext-color: #999;
|
||||
@transition: all 0.3s ease;
|
||||
|
||||
// 基础变量
|
||||
@bg-color: #f9fbff;
|
||||
@card-bg: #ffffff;
|
||||
@ -120,14 +109,13 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
@avatar-size: 60px;
|
||||
@subtext-color: #999;
|
||||
@transition: all 0.3s ease;
|
||||
|
||||
.feedback-section {
|
||||
background-color: @bg-color;
|
||||
padding: 0 0 100px 0; /* 改用标准padding写法,避免自定义.px()可能的问题 */
|
||||
padding: 0 0 100px 0;
|
||||
text-align: center;
|
||||
//background: bisque;
|
||||
position: relative;
|
||||
&&::before {
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -135,76 +123,87 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
width: 60px;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
&&::before {
|
||||
left: 100px;
|
||||
background: linear-gradient(to right, #f9fbff, transparent);
|
||||
}
|
||||
.feedback-title {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
padding: 100px 0 60px;
|
||||
}
|
||||
|
||||
// 跑马灯容器:关键修改——禁止换行,确保内容单行滚动
|
||||
.feedback-title {
|
||||
padding: 50px 0 0;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.feedback-desc {
|
||||
font-size: 20px;
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
||||
.el-timeline__dot {
|
||||
width: auto;
|
||||
display: inline-flex;
|
||||
height: 36px;
|
||||
padding: 8px 20px;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
border-radius: 100px;
|
||||
background: #f5f7fe;
|
||||
margin-top: 20px;
|
||||
|
||||
.el-item__dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 100px;
|
||||
opacity: 0.2;
|
||||
background: var(--313-fa-8, #313fa8);
|
||||
}
|
||||
|
||||
.el-item__dot--active {
|
||||
width: 20px;
|
||||
border-radius: 100px;
|
||||
opacity: 1;
|
||||
background: var(--313-fa-8, #313fa8);
|
||||
}
|
||||
}
|
||||
|
||||
.feedback-list {
|
||||
//width: 100vw;
|
||||
max-width: 1820px;
|
||||
margin: 0 auto;
|
||||
margin-left: 100px;
|
||||
box-sizing: border-box;
|
||||
// 关键:强制水平布局,禁止换行
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: row; /* 明确水平方向 */
|
||||
flex-wrap: nowrap; /* 禁止换行 */
|
||||
overflow: hidden; /* 隐藏超出容器的部分 */
|
||||
flex-direction: row;
|
||||
}
|
||||
// 反馈卡片:固定宽度,确保排列整齐
|
||||
|
||||
.feedback-card {
|
||||
width: 362px; /* 固定宽度,确保能在一行放下多个 */
|
||||
//max-width: 320px;
|
||||
flex-shrink: 0; /* 禁止收缩,保证宽度不变 */
|
||||
border-radius: 100px;
|
||||
background: #f3f5f7;
|
||||
//transition: @transition;
|
||||
//box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); /* 增加轻微阴影,提升视觉层次 */
|
||||
margin-right: 60px;
|
||||
cursor: pointer; /* 提示可交互 */
|
||||
transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); /* 卡片整体过渡 */
|
||||
margin-top: 50px;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.popover-container {
|
||||
padding: @padding;
|
||||
display: flex; /* 卡片内部水平排列头像和文字 */
|
||||
flex-direction: row; /* 明确水平方向 */
|
||||
align-items: center;
|
||||
width: 492px;
|
||||
height: 352px;
|
||||
display: inline-block;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.avatar-container {
|
||||
flex-shrink: 0;
|
||||
margin-right: 20px;
|
||||
|
||||
.avatar {
|
||||
width: @avatar-size;
|
||||
height: @avatar-size;
|
||||
border-radius: 50%;
|
||||
.avatar-container {
|
||||
.certificate-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border: 2px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
.feedback-info {
|
||||
text-align: left;
|
||||
max-width: calc(100% - @avatar-size - 12px); /* 限制文本区域宽度 */
|
||||
max-width: calc(100% - @avatar-size - 12px);
|
||||
|
||||
.username {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 6px;
|
||||
white-space: nowrap; /* 用户名不换行 */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@ -214,18 +213,20 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
color: @text-color;
|
||||
line-height: 1.5;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2; /* 固定2行文本 */
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
/* 过渡动画:重点控制max-height */
|
||||
max-height: 42px; /* 14px*1.5*2=42px(刚好2行高度) */
|
||||
max-height: 42px;
|
||||
transition: max-height 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式适配
|
||||
:deep(.el-image-viewer__canvas) {
|
||||
height: 80vh;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.feedback-card {
|
||||
width: 100%;
|
||||
@ -236,22 +237,17 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
|
||||
<style lang="less">
|
||||
.custom-popover {
|
||||
/* 修改圆角(核心) */
|
||||
border-radius: 18px !important; /* 根据需求调整数值,如8px、16px */
|
||||
|
||||
/* 可选:修改边框 */
|
||||
border-radius: 18px !important;
|
||||
border: 1px solid #e5e7eb !important;
|
||||
|
||||
/* 可选:修改阴影 */
|
||||
box-shadow: 0 4px 16px rgba(79, 79, 79, 0.08) !important;
|
||||
|
||||
/* 可选:修改内部边距 */
|
||||
padding: 22px !important;
|
||||
|
||||
._userinfo {
|
||||
.flex();
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.mb(12px);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
._userPic {
|
||||
width: 62px;
|
||||
height: 62px;
|
||||
@ -259,16 +255,33 @@ console.log('数组1:', feedbackList[0]) // 例如: [3, 7, 2, 5]
|
||||
overflow: hidden;
|
||||
border: 4px solid #f3f5f7;
|
||||
box-shadow: 0 0 16px rgba(79, 79, 79, 0.08);
|
||||
.mr(10px);
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
._username {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
._comment {
|
||||
font-size: 16px;
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
.el-carousel {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.demonstration {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.el-carousel__item h3 {
|
||||
color: #475669;
|
||||
opacity: 0.75;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -160,20 +160,61 @@ onMounted(() => {
|
||||
transform: translateY(-5px); // 描述文字上移
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
.scene-list {
|
||||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||||
gap: @space-lg;
|
||||
}
|
||||
.scene-item {
|
||||
height: 280px;
|
||||
}
|
||||
}
|
||||
/* ------------------- 移动端适配(max-width: 768px) ------------------- */
|
||||
@media (max-width: 768px) {
|
||||
.scene-section {
|
||||
padding-top: 40px; // 减少顶部留白
|
||||
height: auto; // 取消固定高度,内容自适应
|
||||
padding-bottom: 40px; // 增加底部留白,避免内容贴边
|
||||
overflow: visible; // 允许激活态自然显示
|
||||
}
|
||||
|
||||
@media (max-width: @mobile-breakpoint) {
|
||||
.scene-list {
|
||||
grid-template-columns: 1fr;
|
||||
// 网格改为单列布局
|
||||
.scene-list {
|
||||
grid-template-columns: 1fr; // 每个item占满宽度
|
||||
gap: 30px; // 增加垂直间距,避免拥挤
|
||||
padding: 0 15px; // 左右小边距,避免贴边
|
||||
max-width: 350px; // 限制最大宽度,避免大屏手机拉伸
|
||||
}
|
||||
|
||||
// 场景项适配
|
||||
.scene-item {
|
||||
// 触摸设备增加点击反馈
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.scene-inner {
|
||||
height: 120px;
|
||||
padding: 15px 0 20px; // 减少内边距
|
||||
|
||||
// 图标缩小,适配小屏
|
||||
.scene-icon {
|
||||
width: 100%;
|
||||
max-width: 200px; // 限制图标最大宽度
|
||||
height: auto; // 保持宽高比,避免拉伸
|
||||
}
|
||||
|
||||
// 名称字体缩小
|
||||
.scene-name {
|
||||
line-height: 12px !important;
|
||||
}
|
||||
|
||||
// 描述优化小屏显示
|
||||
.scene-desc {
|
||||
line-height: 12px !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 激活态:减小位移,避免过度上移
|
||||
&.active .scene-inner {
|
||||
transform: translateY(-20px); // 桌面端-42px → 移动端-20px
|
||||
}
|
||||
|
||||
// 描述最大高度适配小屏
|
||||
&.active .scene-desc {
|
||||
max-height: 80px; // 减少高度,避免占用过多空间
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
</div>
|
||||
|
||||
<!-- 正文内容(富文本渲染) -->
|
||||
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div class="article-body" v-html="article.content"></div>
|
||||
</div>
|
||||
@ -59,7 +58,33 @@ const article = ref({
|
||||
pic: '', // 封面图URL
|
||||
content: '' // 正文内容(HTML格式)
|
||||
})
|
||||
|
||||
const TinyMceFormatFn = (data: any) => {
|
||||
if (!data) return ''
|
||||
// 1. 移除 img 标签中的 width/height 属性(保留 style 和其他属性)
|
||||
// 原代码中处理图片的正则替换部分
|
||||
data = data.replace(/<img([^>]*)>/gi, (_: any, attrs: any) => {
|
||||
// 用 _ 代替 match
|
||||
// 移除 width 和 height 属性
|
||||
attrs = attrs.replace(/\s*width\s*=\s*["'][^"']*["']/gi, '')
|
||||
attrs = attrs.replace(/\s*height\s*=\s*["'][^"']*["']/gi, '')
|
||||
// 移除 align 属性(避免图片靠右)
|
||||
attrs = attrs.replace(/\s*align\s*=\s*["'](left|right|center)["']/gi, '')
|
||||
// 处理原有的 style 属性
|
||||
const newStyle = 'max-width:100%;height:auto;display: block;margin:16px 0;'
|
||||
if (attrs.match(/\s*style\s*=\s*["']/i)) {
|
||||
// 用 _ 代替 m(第二个未使用的参数)
|
||||
attrs = attrs.replace(/\s*style\s*=\s*["']([^"']*)["']/i, (_: any, existingStyle: any) => {
|
||||
return ` style="${existingStyle}${newStyle}"`
|
||||
})
|
||||
} else {
|
||||
attrs = ` style="${newStyle}"${attrs}`
|
||||
}
|
||||
return `<img${attrs}>`
|
||||
})
|
||||
// 2. 处理 video 标签(保持原有逻辑)
|
||||
data = data.replace(/<video([^>]*)>/gi, '<video style="max-width:100%;height:auto;display: block;"$1>')
|
||||
return data
|
||||
}
|
||||
// 从接口获取文章详情
|
||||
const fetchArticleDetail = async () => {
|
||||
loading.value = true
|
||||
@ -73,6 +98,7 @@ const fetchArticleDetail = async () => {
|
||||
const data = res.data
|
||||
// 赋值到响应式变量
|
||||
article.value = data
|
||||
data.content = TinyMceFormatFn(data.content)
|
||||
} else {
|
||||
throw new Error(res.message || '获取文章详情失败')
|
||||
}
|
||||
@ -174,27 +200,30 @@ onMounted(() => {
|
||||
|
||||
// 正文内容(富文本样式适配)
|
||||
.article-body {
|
||||
font-weight: 400;
|
||||
line-height: 35px;
|
||||
p {
|
||||
//font-weight: 400;
|
||||
//line-height: 35px;
|
||||
:deep(p) {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
line-height: 1.8;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 24px;
|
||||
text-indent: 2em;
|
||||
:deep img {
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 适配富文本中的图片
|
||||
img {
|
||||
:deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 16px 0;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
// 适配富文本中的标题
|
||||
h2,
|
||||
h3 {
|
||||
margin: 24px 0 16px;
|
||||
//margin: 24px 0 16px;
|
||||
color: @text-color;
|
||||
}
|
||||
}
|
||||
@ -202,7 +231,32 @@ onMounted(() => {
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
padding: 40px 20px;
|
||||
.article-body {
|
||||
:deep(p) {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
line-height: 1.8;
|
||||
margin-bottom: 24px;
|
||||
text-indent: 2em;
|
||||
:deep img {
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 适配富文本中的图片
|
||||
:deep img {
|
||||
max-width: 100%; // 图片宽度自适应
|
||||
height: auto;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
// 适配富文本中的标题
|
||||
h2,
|
||||
h3 {
|
||||
margin: 24px 0 16px;
|
||||
color: @text-color;
|
||||
}
|
||||
}
|
||||
.article-header {
|
||||
.article-title {
|
||||
font-size: 24px;
|
||||
|
||||
@ -112,7 +112,7 @@ const fetchCategories = async () => {
|
||||
activeTab.value = categories.value[0].name
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(res.message || '获取分类失败')
|
||||
// ElMessage.error(res.message || '获取分类失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('获取分类列表失败', error)
|
||||
@ -271,6 +271,9 @@ onMounted(async () => {
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: @tablet-breakpoint) {
|
||||
.categories-label {
|
||||
font-size: @font-size-lg;
|
||||
}
|
||||
:deep(.el-tabs__item) {
|
||||
margin-right: @space-md;
|
||||
font-size: @font-size-lg;
|
||||
@ -311,6 +314,7 @@ onMounted(async () => {
|
||||
height: 260px;
|
||||
object-fit: cover;
|
||||
border-radius: @border-radius-md;
|
||||
flex-shrink: 0; /* 禁止收缩,保证宽度不变 */
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
@ -409,7 +413,20 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
.news-info .news-label {
|
||||
margin-bottom: @space-md;
|
||||
font-size: @font-size-sm;
|
||||
}
|
||||
|
||||
.news-info .view-btn {
|
||||
font-size: @font-size-xs;
|
||||
}
|
||||
}
|
||||
.news-date {
|
||||
.icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
p {
|
||||
font-size: @font-size-xs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +139,12 @@ const newsList = [
|
||||
|
||||
// 响应式适配
|
||||
@media (max-width: 768px) {
|
||||
.banner {
|
||||
height: auto !important;
|
||||
}
|
||||
.news-panel {
|
||||
display: none;
|
||||
}
|
||||
.banner-content {
|
||||
.main-title {
|
||||
font-size: 32px;
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"src/**/*.vue", "src/auto-imports.d.ts", // 必须包含这行!
|
||||
"vite.config.ts",
|
||||
"src/main.ts"
|
||||
]
|
||||
|
||||
106
vite.config.ts
106
vite.config.ts
@ -1,22 +1,27 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import path from 'path' // 引入 path 模块
|
||||
import path from 'path'
|
||||
|
||||
import viteImagemin from 'vite-plugin-imagemin' // 新插件
|
||||
// import viteImagemin from 'vite-plugin-imagemin'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
// 引入 ElementPlus 相关解析器
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
// import ElementPlus from 'unplugin-element-plus/vite'
|
||||
import { visualizer } from 'rollup-plugin-visualizer'
|
||||
import legacy from '@vitejs/plugin-legacy'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
// ElementPlus(),
|
||||
vue(),
|
||||
export default defineConfig(({ mode }) => ({
|
||||
// 新增:指定打包基础路径为 /web/
|
||||
// base: '/web/', // 所有资源引用会以 /web/ 为前缀(如静态资源路径变为 /web/static/js/xxx.js)
|
||||
base: mode === 'production' ? '/web/' : '/',
|
||||
|
||||
// 仅在生产环境启用 legacy 插件
|
||||
plugins: [
|
||||
visualizer({
|
||||
filename: './node_modules/.cache/visualizer/stats.html',
|
||||
open: true,
|
||||
gzipSize: true,
|
||||
brotliSize: true
|
||||
}),
|
||||
vue(),
|
||||
...(process.env.NODE_ENV === 'production'
|
||||
? [
|
||||
legacy({
|
||||
@ -27,47 +32,39 @@ export default defineConfig({
|
||||
]
|
||||
: []),
|
||||
AutoImport({
|
||||
imports: ['vue', 'vue-router'], // 自动导入 Vue、Vue Router API
|
||||
// 自动导入 Vue 相关函数,以及 ElementPlus 的相关函数等
|
||||
resolvers: [
|
||||
ElementPlusResolver({
|
||||
importStyle: false, // 关闭自动导入样式(手动引入 index.css)
|
||||
directives: true // 导入 Element Plus 指令(如 v-loading)
|
||||
})
|
||||
// ElementPlusResolver({
|
||||
// importStyle: 'sass',
|
||||
// directives: true // 导入指令
|
||||
// })
|
||||
// 1. 自动导入的 API 来源(Vue 核心 API + Vue Router 等)
|
||||
imports: [
|
||||
'vue', // 自动导入 Vue 组合式 API(ref、reactive、onMounted 等)
|
||||
'vue-router' // 可选:自动导入 Vue Router API(useRouter 等)
|
||||
// 其他来源(如 Pinia)可按需添加
|
||||
],
|
||||
dts: true // 生成 auto-imports.d.ts(让 ESLint 识别自动导入的 API)
|
||||
// 2. 生成类型声明文件(让 TypeScript 识别自动导入的 API)
|
||||
dts: 'src/auto-imports.d.ts', // 生成的类型文件路径(必须存在)
|
||||
// 3. 解决 ESLint 报错(可选,若 ESLint 提示“未定义变量”)
|
||||
eslintrc: {
|
||||
enabled: true, // 生成 ESLint 配置片段
|
||||
filepath: './.eslintrc-auto-import.json' // 生成的 ESLint 配置文件
|
||||
}
|
||||
}),
|
||||
Components({
|
||||
resolvers: [
|
||||
ElementPlusResolver({
|
||||
importStyle: false // 同上,避免与手动引入的样式冲突
|
||||
importStyle: false
|
||||
})
|
||||
], // 自动解析 Element Plus 组件
|
||||
dts: true, // 生成 components.d.ts(关键:让 ESLint 识别组件)
|
||||
include: [/\.vue$/, /\.vue\?vue/, /\.tsx$/], // 确保覆盖所有组件文件
|
||||
// 自动导入 ElementPlus 的组件
|
||||
// resolvers: [
|
||||
// ElementPlusResolver({
|
||||
// importStyle: 'sass',
|
||||
// directives: true
|
||||
// })
|
||||
// ],
|
||||
dirs: ['src/components'] // 自动扫描组件目录
|
||||
],
|
||||
dts: true,
|
||||
include: [/\.vue$/, /\.vue\?vue/, /\.tsx$/],
|
||||
dirs: ['src/components']
|
||||
}),
|
||||
// 开发环境暂时禁用图片压缩插件
|
||||
...(process.env.NODE_ENV !== 'development'
|
||||
? [
|
||||
viteImagemin({
|
||||
gifsicle: { optimizationLevel: 7 },
|
||||
optipng: { optimizationLevel: 7 },
|
||||
mozjpeg: { quality: 80 },
|
||||
pngquant: { quality: [0.8, 0.9] },
|
||||
svgo: { plugins: [{ name: 'removeViewBox' }] }
|
||||
})
|
||||
// viteImagemin({
|
||||
// gifsicle: { optimizationLevel: 7 },
|
||||
// optipng: { optimizationLevel: 7 },
|
||||
// mozjpeg: { quality: 80 },
|
||||
// pngquant: { quality: [0.8, 0.9] },
|
||||
// svgo: { plugins: [{ name: 'removeViewBox' }] }
|
||||
// })
|
||||
]
|
||||
: [])
|
||||
],
|
||||
@ -86,46 +83,45 @@ export default defineConfig({
|
||||
rewrite: path => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
// proxy: {
|
||||
// '^/dev-api': {
|
||||
// target: ''
|
||||
// }
|
||||
// }
|
||||
},
|
||||
optimizeDeps: {
|
||||
// include: ['element-plus'] // 预构建依赖
|
||||
// include: ['element-plus']
|
||||
},
|
||||
build: {
|
||||
chunkSizeWarningLimit: 1000, // 增大分块警告阈值
|
||||
chunkSizeWarningLimit: 1000,
|
||||
rollupOptions: {
|
||||
// external: ['element-plus', 'element-plus/dist/index.css'], // 排除 Element Plus
|
||||
// external: ['element-plus'], // 排除 Element Plus 从打包中
|
||||
output: {
|
||||
// manualChunks: undefined // 取消手动分割,使用 Vite 自动策略
|
||||
manualChunks(id) {
|
||||
if (id.includes('node_modules')) {
|
||||
// 将第三方库单独分包(如 axios、vue 等)
|
||||
return id.split('node_modules/')[1].split('/')[0]
|
||||
}
|
||||
}
|
||||
// chunkFileNames: 'static/js/[name]-[hash].js',
|
||||
// entryFileNames: 'static/js/[name]-[hash].js',
|
||||
// assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
|
||||
}
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
// 关键配置:强制 Sass 使用现代 API(二选一,推荐 modern-compiler)
|
||||
api: 'modern-compiler'
|
||||
// additionalData: `@import "@/styles/element-variables.scss";`
|
||||
// api: 'modern' // 轻量版,适合简单场景
|
||||
},
|
||||
less: {
|
||||
// 关键配置:自动注入 global.less
|
||||
additionalData: `@import "@/styles/global.less";`,
|
||||
|
||||
// 可选:如果需要自定义 Less 选项
|
||||
javascriptEnabled: true
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src') // 添加路径别名
|
||||
'@': path.resolve(__dirname, 'src')
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user