feat(客户端): 添加兑换服务和任务交互功能
实现兑换服务弹窗和任务接单功能,包括: 1. 添加兑换服务弹窗及兑换逻辑 2. 实现任务列表平滑滚动和接单功能 3. 在Dashboard中添加语音通话、用药提醒和召唤机器人弹窗 4. 优化UI交互和动画效果
This commit is contained in:
@@ -11,6 +11,11 @@ const routes = [
|
|||||||
name: 'Login',
|
name: 'Login',
|
||||||
component: () => import('../views/LoginPage.vue')
|
component: () => import('../views/LoginPage.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/whitepaper',
|
||||||
|
name: 'Whitepaper',
|
||||||
|
component: () => import('../views/Whitepaper.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/client',
|
path: '/client',
|
||||||
component: () => import('../layouts/ClientLayout.vue'),
|
component: () => import('../layouts/ClientLayout.vue'),
|
||||||
|
|||||||
@@ -25,9 +25,9 @@
|
|||||||
<button @click="router.push('/login')" class="px-8 py-4 bg-blue-600 hover:bg-blue-500 text-white rounded-xl font-bold text-lg shadow-lg shadow-blue-600/30 transition-all transform hover:-translate-y-1">
|
<button @click="router.push('/login')" class="px-8 py-4 bg-blue-600 hover:bg-blue-500 text-white rounded-xl font-bold text-lg shadow-lg shadow-blue-600/30 transition-all transform hover:-translate-y-1">
|
||||||
立即启动系统
|
立即启动系统
|
||||||
</button>
|
</button>
|
||||||
<a href="#" class="px-8 py-4 bg-slate-800/50 hover:bg-slate-800 text-white rounded-xl font-semibold text-lg border border-slate-700 backdrop-blur transition-all">
|
<button @click="router.push('/whitepaper')" class="px-8 py-4 bg-slate-800/50 hover:bg-slate-800 text-white rounded-xl font-semibold text-lg border border-slate-700 backdrop-blur transition-all">
|
||||||
查看技术白皮书
|
查看技术白皮书
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-3 gap-6 pt-8 border-t border-slate-700/50">
|
<div class="grid grid-cols-3 gap-6 pt-8 border-t border-slate-700/50">
|
||||||
|
|||||||
332
src/views/Whitepaper.vue
Normal file
332
src/views/Whitepaper.vue
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
<template>
|
||||||
|
<div class="min-h-screen bg-slate-50">
|
||||||
|
<!-- Navigation Bar -->
|
||||||
|
<nav class="sticky top-0 z-50 bg-white/80 backdrop-blur-md border-b border-slate-200">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div class="flex justify-between h-16 items-center">
|
||||||
|
<div class="flex items-center space-x-3 cursor-pointer" @click="router.push('/')">
|
||||||
|
<div class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold">智</div>
|
||||||
|
<span class="text-xl font-black text-slate-900 tracking-tight">智护链 <span class="text-blue-600">Technical Whitepaper</span></span>
|
||||||
|
</div>
|
||||||
|
<button @click="router.push('/')" class="text-sm font-bold text-slate-500 hover:text-blue-600 transition-colors">返回首页</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-12">
|
||||||
|
|
||||||
|
<!-- Sidebar Navigation -->
|
||||||
|
<div class="hidden lg:block lg:col-span-1">
|
||||||
|
<div class="sticky top-28 space-y-1">
|
||||||
|
<h3 class="text-xs font-black text-slate-400 uppercase tracking-widest mb-4 px-3">目录</h3>
|
||||||
|
<a v-for="section in sections" :key="section.id" :href="'#' + section.id"
|
||||||
|
class="block px-3 py-2 text-sm font-bold rounded-lg transition-all"
|
||||||
|
:class="activeSection === section.id ? 'bg-blue-50 text-blue-600' : 'text-slate-600 hover:bg-slate-100'">
|
||||||
|
{{ section.title }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div class="lg:col-span-3 space-y-24 pb-24">
|
||||||
|
|
||||||
|
<!-- Introduction -->
|
||||||
|
<section id="abstract" class="scroll-mt-24">
|
||||||
|
<h1 class="text-4xl font-black text-slate-900 mb-6">1. 摘要 (Abstract)</h1>
|
||||||
|
<div class="prose prose-slate prose-lg max-w-none text-slate-600 leading-relaxed">
|
||||||
|
<p>
|
||||||
|
随着全球人口老龄化的加剧,传统的养老服务模式面临着信任成本高、隐私保护难、资源分配不均等严峻挑战。
|
||||||
|
<strong>智护链 (SmartCare Chain)</strong> 是一套基于区块链、边缘计算与隐私计算技术的下一代智慧养老协作网络。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
本白皮书详细阐述了智护链的技术架构、核心算法及其在实际养老场景中的应用逻辑,旨在构建一个“以人为中心,以行为为存证”的可信养老生态。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Architecture -->
|
||||||
|
<section id="architecture" class="scroll-mt-24">
|
||||||
|
<h2 class="text-3xl font-black text-slate-900 mb-8 flex items-center">
|
||||||
|
<span class="w-8 h-8 bg-slate-900 text-white rounded-lg flex items-center justify-center mr-4 text-sm">2</span>
|
||||||
|
技术架构 (Technical Architecture)
|
||||||
|
</h2>
|
||||||
|
<div class="bg-white rounded-3xl border border-slate-200 p-8 shadow-sm">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
|
<div v-for="layer in architectureLayers" :key="layer.name" class="p-6 rounded-2xl bg-slate-50 border border-slate-100">
|
||||||
|
<div class="text-blue-600 font-black mb-2">{{ layer.layer }}</div>
|
||||||
|
<h4 class="text-lg font-bold text-slate-900 mb-4">{{ layer.name }}</h4>
|
||||||
|
<ul class="space-y-2 text-sm text-slate-600 font-medium">
|
||||||
|
<li v-for="item in layer.items" :key="item" class="flex items-center">
|
||||||
|
<span class="w-1.5 h-1.5 bg-blue-400 rounded-full mr-2"></span>
|
||||||
|
{{ item }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-8 p-6 bg-blue-600 rounded-2xl text-white">
|
||||||
|
<h4 class="font-bold mb-2">架构核心逻辑:</h4>
|
||||||
|
<p class="text-sm opacity-90 leading-relaxed">
|
||||||
|
系统采用“云-边-端”协同架构。前端采集设备(端)进行数据脱敏,边缘网关(边)执行实时AI识别与决策,云端区块链(云)进行确权与审计。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Blockchain -->
|
||||||
|
<section id="blockchain" class="scroll-mt-24">
|
||||||
|
<h2 class="text-3xl font-black text-slate-900 mb-8 flex items-center">
|
||||||
|
<span class="w-8 h-8 bg-slate-900 text-white rounded-lg flex items-center justify-center mr-4 text-sm">3</span>
|
||||||
|
区块链核心 (Blockchain Core)
|
||||||
|
</h2>
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<div class="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm">
|
||||||
|
<h4 class="font-black text-slate-900 mb-4 flex items-center">
|
||||||
|
<span class="mr-2">⛓️</span> 共识机制与底层
|
||||||
|
</h4>
|
||||||
|
<p class="text-sm text-slate-600 leading-relaxed">
|
||||||
|
智护链底层基于 <strong>FISCO BCOS</strong> 企业级协作平台,采用 PBFT (Practical Byzantine Fault Tolerance) 共识算法,
|
||||||
|
实现秒级区块确认,确保养老记录的高可用性与强一致性。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm">
|
||||||
|
<h4 class="font-black text-slate-900 mb-4 flex items-center">
|
||||||
|
<span class="mr-2">📜</span> 智能合约治理
|
||||||
|
</h4>
|
||||||
|
<p class="text-sm text-slate-600 leading-relaxed">
|
||||||
|
所有业务逻辑通过 Solidity 编写的智能合约执行。包括:身份认证 (DID)、服务质量对赌 (SLA)、时间银行通证分发等,
|
||||||
|
实现“法典即代码 (Code is Law)”。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-slate-900 rounded-2xl p-8 text-white font-mono text-sm overflow-hidden relative">
|
||||||
|
<div class="absolute top-0 right-0 p-4 opacity-10 text-6xl">{}</div>
|
||||||
|
<div class="text-blue-400 mb-4">// 核心合约:养老服务存证</div>
|
||||||
|
<div class="space-y-1 opacity-80">
|
||||||
|
<div><span class="text-purple-400">contract</span> <span class="text-yellow-400">CareRecord</span> {</div>
|
||||||
|
<div class="pl-4"><span class="text-purple-400">struct</span> <span class="text-yellow-400">Record</span> {</div>
|
||||||
|
<div class="pl-8">address elder;</div>
|
||||||
|
<div class="pl-8">uint256 timestamp;</div>
|
||||||
|
<div class="pl-8">bytes32 dataHash; <span class="text-slate-500">// 加密后的护理数据哈希</span></div>
|
||||||
|
<div class="pl-8">uint8 level; <span class="text-slate-500">// 紧急程度 L1-L4</span></div>
|
||||||
|
<div class="pl-4">}</div>
|
||||||
|
<div class="pl-4"><span class="text-purple-400">mapping</span>(uint256 => Record) <span class="text-purple-400">public</span> records;</div>
|
||||||
|
<div>}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Privacy -->
|
||||||
|
<section id="privacy" class="scroll-mt-24">
|
||||||
|
<h2 class="text-3xl font-black text-slate-900 mb-8 flex items-center">
|
||||||
|
<span class="w-8 h-8 bg-slate-900 text-white rounded-lg flex items-center justify-center mr-4 text-sm">4</span>
|
||||||
|
隐私计算 (Privacy Computing)
|
||||||
|
</h2>
|
||||||
|
<div class="prose prose-slate prose-lg max-w-none text-slate-600">
|
||||||
|
<p>
|
||||||
|
智护链解决的核心痛点是“既要数据协同,又要隐私安全”。我们引入了以下关键技术:
|
||||||
|
</p>
|
||||||
|
<ul class="list-none p-0 grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<li class="bg-white p-6 rounded-2xl border border-slate-200">
|
||||||
|
<strong class="text-slate-900 block mb-2">1. 零知识证明 (ZKP)</strong>
|
||||||
|
家属在不泄露老人具体健康指标的前提下,通过 ZKP 向保险机构证明老人符合理赔条件。
|
||||||
|
</li>
|
||||||
|
<li class="bg-white p-6 rounded-2xl border border-slate-200">
|
||||||
|
<strong class="text-slate-900 block mb-2">2. 可信执行环境 (TEE)</strong>
|
||||||
|
敏感的 AI 识别逻辑运行在边缘侧的硬件安全隔离区,原始视频流不离开设备,仅输出识别结果。
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Edge AI -->
|
||||||
|
<section id="edge-ai" class="scroll-mt-24">
|
||||||
|
<h2 class="text-3xl font-black text-slate-900 mb-8 flex items-center">
|
||||||
|
<span class="w-8 h-8 bg-slate-900 text-white rounded-lg flex items-center justify-center mr-4 text-sm">5</span>
|
||||||
|
边缘 AI 决策 (Edge AI Logic)
|
||||||
|
</h2>
|
||||||
|
<div class="bg-slate-50 rounded-3xl p-8 border border-slate-200">
|
||||||
|
<h4 class="font-bold text-slate-900 mb-6">告警分级决策模型 (L1-L4)</h4>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div v-for="level in aiLevels" :key="level.id" class="flex items-start space-x-6 p-4 rounded-xl bg-white border border-slate-100 transition-all hover:shadow-md">
|
||||||
|
<div class="w-12 h-12 rounded-lg flex items-center justify-center font-black shrink-0" :class="level.color">
|
||||||
|
{{ level.id }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-bold text-slate-900">{{ level.title }}</div>
|
||||||
|
<p class="text-sm text-slate-500 mt-1">{{ level.desc }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Tokenomics -->
|
||||||
|
<section id="tokenomics" class="scroll-mt-24">
|
||||||
|
<h2 class="text-3xl font-black text-slate-900 mb-8 flex items-center">
|
||||||
|
<span class="w-8 h-8 bg-slate-900 text-white rounded-lg flex items-center justify-center mr-4 text-sm">6</span>
|
||||||
|
通证经济:时间银行 (Time Bank)
|
||||||
|
</h2>
|
||||||
|
<div class="bg-gradient-to-br from-blue-600 to-indigo-700 rounded-3xl p-10 text-white shadow-xl relative overflow-hidden">
|
||||||
|
<div class="absolute top-0 right-0 w-64 h-64 bg-white/10 rounded-full -mr-32 -mt-32 blur-3xl"></div>
|
||||||
|
<div class="relative z-10 grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||||
|
<div>
|
||||||
|
<h4 class="text-2xl font-black mb-6">双通证治理模型</h4>
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div class="flex items-start space-x-4">
|
||||||
|
<div class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center text-xl shrink-0">🪙</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-bold">智护通证 (Care Token)</div>
|
||||||
|
<p class="text-sm opacity-80 mt-1">激励层。用户通过提供互助服务获得,可兑换专业护理服务或耗材。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start space-x-4">
|
||||||
|
<div class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center text-xl shrink-0">⚖️</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-bold">治理积分 (Gov Point)</div>
|
||||||
|
<p class="text-sm opacity-80 mt-1">权益层。基于信用评价体系,影响节点在协作网络中的决策权重。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white/10 backdrop-blur-md rounded-2xl p-6 border border-white/20">
|
||||||
|
<div class="text-center mb-6">
|
||||||
|
<div class="text-sm opacity-60 uppercase tracking-widest">通证循环路径</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="flex justify-between items-center bg-white/5 p-3 rounded-lg border border-white/10">
|
||||||
|
<span>提供互助服务</span>
|
||||||
|
<span class="text-green-300 font-bold">+Token</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center py-2">⬇️</div>
|
||||||
|
<div class="flex justify-between items-center bg-white/5 p-3 rounded-lg border border-white/10">
|
||||||
|
<span>链上共识确认</span>
|
||||||
|
<span class="text-blue-300 font-bold">Audit</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center py-2">⬇️</div>
|
||||||
|
<div class="flex justify-between items-center bg-white/5 p-3 rounded-lg border border-white/10">
|
||||||
|
<span>兑换专业服务</span>
|
||||||
|
<span class="text-orange-300 font-bold">-Token</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Conclusion -->
|
||||||
|
<section id="conclusion" class="scroll-mt-24">
|
||||||
|
<h2 class="text-3xl font-black text-slate-900 mb-8 flex items-center">
|
||||||
|
<span class="w-8 h-8 bg-slate-900 text-white rounded-lg flex items-center justify-center mr-4 text-sm">7</span>
|
||||||
|
未来展望 (Future Roadmap)
|
||||||
|
</h2>
|
||||||
|
<div class="prose prose-slate prose-lg max-w-none text-slate-600">
|
||||||
|
<p>
|
||||||
|
智护链不仅是一个技术平台,更是一个社会化治理实验。未来我们将持续探索:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>多模态大模型集成</strong>:实现更自然的老人情感陪护。</li>
|
||||||
|
<li><strong>跨链互操作性</strong>:与医疗机构、社区民政系统的区块链实现底层互通。</li>
|
||||||
|
<li><strong>硬件标准开源</strong>:联合更多硬件厂商共同构建可信养老硬件标准。</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="bg-slate-900 text-slate-400 py-12">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 text-center">
|
||||||
|
<div class="text-white font-black text-xl mb-4">SmartCare Chain</div>
|
||||||
|
<p class="text-sm">© 2026 智护链技术委员会. All Rights Reserved.</p>
|
||||||
|
<div class="mt-6 flex justify-center space-x-6 text-xs font-bold uppercase tracking-widest">
|
||||||
|
<a href="#" class="hover:text-white transition-colors">隐私政策</a>
|
||||||
|
<a href="#" class="hover:text-white transition-colors">服务条款</a>
|
||||||
|
<a href="#" class="hover:text-white transition-colors">开源协议</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const activeSection = ref('abstract')
|
||||||
|
|
||||||
|
const sections = [
|
||||||
|
{ id: 'abstract', title: '1. 摘要' },
|
||||||
|
{ id: 'architecture', title: '2. 技术架构' },
|
||||||
|
{ id: 'blockchain', title: '3. 区块链核心' },
|
||||||
|
{ id: 'privacy', title: '4. 隐私计算' },
|
||||||
|
{ id: 'edge-ai', title: '5. 边缘AI决策' },
|
||||||
|
{ id: 'tokenomics', title: '6. 通证经济' },
|
||||||
|
{ id: 'conclusion', title: '7. 未来展望' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const architectureLayers = [
|
||||||
|
{
|
||||||
|
layer: 'L1',
|
||||||
|
name: '感知层 (Perception)',
|
||||||
|
items: ['多模态视觉采集', '毫米波雷达感应', '环境传感器网格', '穿戴式生理监测']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
layer: 'L2',
|
||||||
|
name: '计算层 (Computing)',
|
||||||
|
items: ['边缘计算节点 (Edge)', 'Pose Estimation 算法', '行为意图识别', '隐私计算 TEE 隔离']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
layer: 'L3',
|
||||||
|
name: '信任层 (Trust)',
|
||||||
|
items: ['FISCO BCOS 底层链', '智能合约业务逻辑', '跨机构分布式账本', 'DID 身份体系']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const aiLevels = [
|
||||||
|
{ id: 'L1', title: '日常监测', desc: '正常行为识别,心跳、步态数据定期脱敏上链。', color: 'bg-blue-100 text-blue-600' },
|
||||||
|
{ id: 'L2', title: '异常趋势', desc: '识别久坐、食欲减退等负面趋势,通过智能合约触发家属提醒。', color: 'bg-yellow-100 text-yellow-600' },
|
||||||
|
{ id: 'L3', title: '即时告警', desc: '识别剧烈咳嗽、迷路等行为,立即激活就近机器人前往。', color: 'bg-orange-100 text-orange-600' },
|
||||||
|
{ id: 'L4', title: '紧急响应', desc: '确认跌倒、昏迷。系统自动锁定链上证据,调度救护资源与护理端。', color: 'bg-red-100 text-red-600' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
const sectionElements = sections.map(s => document.getElementById(s.id))
|
||||||
|
const scrollPosition = window.scrollY + 100
|
||||||
|
|
||||||
|
for (let i = sectionElements.length - 1; i >= 0; i--) {
|
||||||
|
const el = sectionElements[i]
|
||||||
|
if (el && el.offsetTop <= scrollPosition) {
|
||||||
|
activeSection.value = sections[i].id
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('scroll', handleScroll)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.prose blockquote {
|
||||||
|
border-left-color: #3b82f6;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
background: #eff6ff;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -47,15 +47,15 @@
|
|||||||
|
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<div class="grid grid-cols-3 gap-4 w-full mt-8">
|
<div class="grid grid-cols-3 gap-4 w-full mt-8">
|
||||||
<button class="flex flex-col items-center justify-center p-3 rounded-xl bg-gray-50 hover:bg-orange-50 text-gray-600 hover:text-vitality-orange transition-colors">
|
<button @click="handleVoiceCall" class="flex flex-col items-center justify-center p-3 rounded-xl bg-gray-50 hover:bg-orange-50 text-gray-600 hover:text-vitality-orange transition-colors">
|
||||||
<span class="text-xl mb-1">📞</span>
|
<span class="text-xl mb-1">📞</span>
|
||||||
<span class="text-xs">语音通话</span>
|
<span class="text-xs">语音通话</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="flex flex-col items-center justify-center p-3 rounded-xl bg-gray-50 hover:bg-orange-50 text-gray-600 hover:text-vitality-orange transition-colors">
|
<button @click="handleRemindMedication" class="flex flex-col items-center justify-center p-3 rounded-xl bg-gray-50 hover:bg-orange-50 text-gray-600 hover:text-vitality-orange transition-colors">
|
||||||
<span class="text-xl mb-1">💊</span>
|
<span class="text-xl mb-1">💊</span>
|
||||||
<span class="text-xs">提醒吃药</span>
|
<span class="text-xs">提醒吃药</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="flex flex-col items-center justify-center p-3 rounded-xl bg-gray-50 hover:bg-orange-50 text-gray-600 hover:text-vitality-orange transition-colors">
|
<button @click="handleSummonRobot" class="flex flex-col items-center justify-center p-3 rounded-xl bg-gray-50 hover:bg-orange-50 text-gray-600 hover:text-vitality-orange transition-colors">
|
||||||
<span class="text-xl mb-1">🤖</span>
|
<span class="text-xl mb-1">🤖</span>
|
||||||
<span class="text-xs">召唤机器人</span>
|
<span class="text-xs">召唤机器人</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -63,6 +63,129 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Voice Call Modal -->
|
||||||
|
<div v-if="showCallModal" class="fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4 backdrop-blur-sm">
|
||||||
|
<div class="bg-white rounded-3xl w-full max-w-sm shadow-2xl animate-bounce-in overflow-hidden border border-gray-100">
|
||||||
|
<div class="p-8 text-center">
|
||||||
|
<div class="w-20 h-20 bg-blue-50 text-blue-600 rounded-full flex items-center justify-center mx-auto mb-6 text-3xl">
|
||||||
|
📞
|
||||||
|
</div>
|
||||||
|
<h3 class="text-xl font-black text-gray-900 mb-2">语音/视频通话</h3>
|
||||||
|
|
||||||
|
<div v-if="!isLoggedIn" class="space-y-4">
|
||||||
|
<p class="text-sm text-gray-500 leading-relaxed">
|
||||||
|
您当前处于演示模式,请登录后查看完整通话功能。
|
||||||
|
</p>
|
||||||
|
<div class="bg-orange-50 p-3 rounded-xl border border-orange-100 text-[11px] text-orange-700 font-bold">
|
||||||
|
💡 提示:正式用户可直接接入养老院呼机大屏或室内机器人摄像头。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="space-y-6">
|
||||||
|
<div class="bg-gray-50 p-4 rounded-2xl border border-gray-100">
|
||||||
|
<div class="text-[10px] text-gray-400 font-black uppercase tracking-widest mb-1">老人绑定号码</div>
|
||||||
|
<div class="text-2xl font-black text-gray-800 font-mono">138-****-5521</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<button @click="copyNumber" class="py-3 px-4 bg-gray-100 text-gray-600 rounded-xl font-bold text-sm hover:bg-gray-200 transition-all">复制号码</button>
|
||||||
|
<button @click="startCall" class="py-3 px-4 bg-green-500 text-white rounded-xl font-bold text-sm hover:bg-green-600 shadow-lg shadow-green-100 transition-all">立即呼叫</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pt-4 border-t border-gray-100">
|
||||||
|
<button @click="connectCamera" class="w-full py-4 bg-blue-600 text-white rounded-2xl font-bold flex items-center justify-center shadow-xl shadow-blue-100 hover:bg-blue-700 transition-all">
|
||||||
|
<span class="mr-2">📹</span> 接入机器人摄像头
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-4 bg-gray-50 border-t border-gray-100 text-center">
|
||||||
|
<button @click="showCallModal = false" class="text-sm font-bold text-gray-400 hover:text-gray-600">关闭</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Medication Modal -->
|
||||||
|
<div v-if="showMedModal" class="fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4 backdrop-blur-sm">
|
||||||
|
<div class="bg-white rounded-3xl w-full max-w-sm shadow-2xl animate-bounce-in overflow-hidden border border-gray-100">
|
||||||
|
<div class="p-8 text-center">
|
||||||
|
<div class="w-20 h-20 bg-orange-50 text-orange-500 rounded-full flex items-center justify-center mx-auto mb-6 text-3xl">
|
||||||
|
💊
|
||||||
|
</div>
|
||||||
|
<h3 class="text-xl font-black text-gray-900 mb-2">智能用药提醒</h3>
|
||||||
|
<p class="text-sm text-gray-500 mb-6">设置后 AI 助手将通过机器人和手环定时提醒老人吃药。</p>
|
||||||
|
|
||||||
|
<div class="space-y-4 text-left">
|
||||||
|
<div class="bg-blue-50 p-4 rounded-2xl border border-blue-100">
|
||||||
|
<div class="flex items-center mb-2">
|
||||||
|
<span class="text-blue-600 mr-2 text-sm">🤖</span>
|
||||||
|
<span class="text-xs font-bold text-blue-800">AI 智能提示功能</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-[11px] text-blue-600/80 leading-relaxed">
|
||||||
|
您可以手动设置用药时间,AI 将在规定时间前 5 分钟自动通过语音引导机器人前往老人身边,并在手环上发出震动。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-gray-50 p-4 rounded-2xl space-y-3">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-sm font-bold text-gray-700">下次用药</span>
|
||||||
|
<span class="text-xs bg-gray-200 text-gray-500 px-2 py-0.5 rounded">未设置</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 bg-gray-50 border-t border-gray-100 grid grid-cols-2 gap-3">
|
||||||
|
<button @click="showMedModal = false" class="py-3 text-sm font-bold text-gray-400 hover:text-gray-600">取消</button>
|
||||||
|
<button @click="setMedication" class="py-3 text-sm font-bold bg-orange-500 text-white rounded-xl shadow-lg shadow-orange-100 hover:bg-orange-600">立即设置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Summon Robot Modal -->
|
||||||
|
<div v-if="showSummonModal" class="fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4 backdrop-blur-sm">
|
||||||
|
<div class="bg-white rounded-3xl w-full max-w-sm shadow-2xl animate-bounce-in overflow-hidden border border-gray-100">
|
||||||
|
<div class="p-8 text-center">
|
||||||
|
<div class="w-24 h-24 mx-auto mb-6 relative">
|
||||||
|
<div class="absolute inset-0 bg-blue-100 rounded-full animate-ping opacity-30"></div>
|
||||||
|
<div class="relative w-24 h-24 bg-blue-50 text-blue-600 rounded-full flex items-center justify-center text-4xl shadow-inner border border-blue-100">
|
||||||
|
🤖
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="text-xl font-black text-gray-900 mb-2">召唤机器人</h3>
|
||||||
|
|
||||||
|
<div class="space-y-4 mt-6">
|
||||||
|
<div v-if="!isRobotComing" class="space-y-4">
|
||||||
|
<p class="text-sm text-gray-500">机器人将立即前往老人当前所在位置({{ store.robotStatus.location }})。</p>
|
||||||
|
<button @click="startSummon" class="w-full py-4 bg-blue-600 text-white rounded-2xl font-bold shadow-xl shadow-blue-100 hover:bg-blue-700 transition-all active:scale-95">
|
||||||
|
立即确认召唤
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="space-y-6">
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="text-blue-600 font-black text-lg animate-pulse mb-2">机器人正在来的路上...</div>
|
||||||
|
<div class="w-full bg-gray-100 h-2 rounded-full overflow-hidden">
|
||||||
|
<div class="bg-blue-500 h-full animate-[progress_3s_ease-in-out_infinite]"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-gray-50 p-4 rounded-2xl border border-gray-100 text-left">
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<span class="text-xs font-bold text-gray-400 uppercase">实时位置</span>
|
||||||
|
<span class="text-xs font-black text-blue-600">2楼 走廊 C区</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-[11px] text-gray-500">预计 45 秒后到达王大爷身边。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-4 bg-gray-50 border-t border-gray-100 text-center">
|
||||||
|
<button @click="showSummonModal = false" class="text-sm font-bold text-gray-400 hover:text-gray-600">返回</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Blockchain Evidence List -->
|
<!-- Blockchain Evidence List -->
|
||||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-100">
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100">
|
||||||
<div class="p-4 border-b border-gray-100">
|
<div class="p-4 border-b border-gray-100">
|
||||||
@@ -102,6 +225,48 @@ import { useGlobalStore } from '../../stores/global'
|
|||||||
|
|
||||||
const store = useGlobalStore()
|
const store = useGlobalStore()
|
||||||
|
|
||||||
|
// UI State
|
||||||
|
const isLoggedIn = ref(false) // 演示模式
|
||||||
|
const showCallModal = ref(false)
|
||||||
|
const showMedModal = ref(false)
|
||||||
|
const showSummonModal = ref(false)
|
||||||
|
const isRobotComing = ref(false)
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
const handleVoiceCall = () => {
|
||||||
|
showCallModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRemindMedication = () => {
|
||||||
|
showMedModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSummonRobot = () => {
|
||||||
|
showSummonModal.value = true
|
||||||
|
isRobotComing.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const copyNumber = () => {
|
||||||
|
alert('号码 138-0013-5521 已复制到剪贴板')
|
||||||
|
}
|
||||||
|
|
||||||
|
const startCall = () => {
|
||||||
|
alert('正在呼叫王大爷的移动终端...')
|
||||||
|
}
|
||||||
|
|
||||||
|
const connectCamera = () => {
|
||||||
|
alert('正在接入室内机器人摄像头,请稍候...')
|
||||||
|
}
|
||||||
|
|
||||||
|
const setMedication = () => {
|
||||||
|
alert('设置成功!AI 助手已接管提醒任务。')
|
||||||
|
showMedModal.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const startSummon = () => {
|
||||||
|
isRobotComing.value = true
|
||||||
|
}
|
||||||
|
|
||||||
// Computed Status based on Global Store
|
// Computed Status based on Global Store
|
||||||
const isCritical = computed(() => store.robotStatus.level === 'L4')
|
const isCritical = computed(() => store.robotStatus.level === 'L4')
|
||||||
|
|
||||||
@@ -135,3 +300,19 @@ const statusDesc = computed(() => {
|
|||||||
return map[store.robotStatus.level]
|
return map[store.robotStatus.level]
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@keyframes progress {
|
||||||
|
0% { width: 0%; }
|
||||||
|
100% { width: 100%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce-in {
|
||||||
|
0% { transform: scale(0.95); opacity: 0; }
|
||||||
|
70% { transform: scale(1.02); opacity: 1; }
|
||||||
|
100% { transform: scale(1); }
|
||||||
|
}
|
||||||
|
.animate-bounce-in {
|
||||||
|
animation: bounce-in 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -7,33 +7,81 @@
|
|||||||
<div class="text-sm opacity-90 mb-1">我的智护通证 (Token)</div>
|
<div class="text-sm opacity-90 mb-1">我的智护通证 (Token)</div>
|
||||||
<div class="text-4xl font-bold font-mono tracking-tight">1,250.00</div>
|
<div class="text-4xl font-bold font-mono tracking-tight">1,250.00</div>
|
||||||
<div class="mt-6 flex space-x-3">
|
<div class="mt-6 flex space-x-3">
|
||||||
<button class="flex-1 bg-white/20 hover:bg-white/30 backdrop-blur py-2 rounded-lg text-sm font-medium transition-colors">
|
<button @click="showExchangeModal = true" class="flex-1 bg-white/20 hover:bg-white/30 backdrop-blur py-2 rounded-lg text-sm font-medium transition-colors">
|
||||||
兑换服务
|
兑换服务
|
||||||
</button>
|
</button>
|
||||||
<button class="flex-1 bg-white text-orange-600 hover:bg-orange-50 py-2 rounded-lg text-sm font-medium transition-colors shadow-sm">
|
<button @click="scrollToTasks" class="flex-1 bg-white text-orange-600 hover:bg-orange-50 py-2 rounded-lg text-sm font-medium transition-colors shadow-sm">
|
||||||
去赚取
|
去赚取
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tasks List -->
|
<!-- Exchange Services Modal -->
|
||||||
|
<div v-if="showExchangeModal" class="fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4 backdrop-blur-sm">
|
||||||
|
<div class="bg-white rounded-3xl w-full max-w-md shadow-2xl animate-bounce-in overflow-hidden border border-gray-100 max-h-[80vh] flex flex-col">
|
||||||
|
<div class="p-6 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-lg font-bold text-gray-800 mb-4 px-1">社区互助任务</h3>
|
<h3 class="text-xl font-black text-gray-900">兑换服务</h3>
|
||||||
|
<p class="text-xs text-gray-400 font-bold mt-1 flex items-center">
|
||||||
|
<span class="mr-1">💰</span> 当前余额: 1,250.00 Token
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button @click="showExchangeModal = false" class="text-gray-400 hover:text-gray-600 p-2">✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-1 overflow-y-auto p-4 space-y-3">
|
||||||
|
<div v-for="service in services" :key="service.id"
|
||||||
|
class="p-4 rounded-2xl border border-gray-100 hover:border-orange-200 hover:bg-orange-50/30 transition-all group flex items-center justify-between">
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="w-14 h-14 rounded-2xl bg-gray-50 flex items-center justify-center text-3xl shadow-inner border border-gray-100 group-hover:bg-white transition-colors">
|
||||||
|
{{ service.icon }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-black text-gray-900">{{ service.title }}</div>
|
||||||
|
<div class="text-[11px] text-gray-400 font-bold mt-0.5">{{ service.desc }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-right">
|
||||||
|
<div class="text-orange-500 font-black">{{ service.price }} <span class="text-[10px]">Token</span></div>
|
||||||
|
<button @click="handleExchange(service)" class="mt-1 px-4 py-1.5 bg-gray-900 text-white text-[11px] font-bold rounded-xl hover:bg-orange-500 transition-colors">兑换</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 bg-gray-50 border-t border-gray-100 text-center">
|
||||||
|
<p class="text-[10px] text-gray-400 font-bold mb-0">区块链通证兑换将实时记录并进行哈希上链存证</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tasks List -->
|
||||||
|
<div id="tasks-section" class="scroll-mt-6">
|
||||||
|
<h3 class="text-lg font-bold text-gray-800 mb-4 px-1 flex items-center justify-between">
|
||||||
|
<span>社区互助任务</span>
|
||||||
|
<span class="text-xs font-bold text-orange-500 bg-orange-50 px-2 py-1 rounded-lg">附近 {{ tasks.length }} 个任务</span>
|
||||||
|
</h3>
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<div v-for="task in tasks" :key="task.id" class="bg-white p-4 rounded-xl shadow-sm border border-gray-100 flex justify-between items-center">
|
<div v-for="task in tasks" :key="task.id"
|
||||||
<div class="flex items-center space-x-3">
|
class="bg-white p-5 rounded-2xl shadow-sm border border-gray-100 flex justify-between items-center hover:shadow-md transition-shadow group">
|
||||||
<div class="w-10 h-10 rounded-full bg-gray-100 flex items-center justify-center text-xl">
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="w-12 h-12 rounded-2xl bg-gray-50 flex items-center justify-center text-2xl group-hover:bg-orange-50 transition-colors">
|
||||||
{{ task.icon }}
|
{{ task.icon }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="font-medium text-gray-900">{{ task.title }}</div>
|
<div class="font-black text-gray-900">{{ task.title }}</div>
|
||||||
<div class="text-xs text-gray-500">{{ task.distance }} • {{ task.time }}</div>
|
<div class="text-xs text-gray-400 font-bold mt-1 flex items-center space-x-2">
|
||||||
|
<span class="flex items-center">📍 {{ task.distance }}</span>
|
||||||
|
<span>•</span>
|
||||||
|
<span class="flex items-center">⏱️ {{ task.time }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-end">
|
<div class="flex flex-col items-end">
|
||||||
<span class="text-vitality-orange font-bold text-lg">+{{ task.reward }}</span>
|
<div class="text-orange-500 font-black text-xl">+{{ task.reward }}</div>
|
||||||
<button class="px-3 py-1 bg-gray-900 text-white text-xs rounded-md mt-1 hover:bg-gray-700">接单</button>
|
<button @click="handleAcceptTask(task)" class="px-5 py-2 bg-gray-900 text-white text-xs font-bold rounded-xl mt-2 hover:bg-orange-500 shadow-sm transition-all active:scale-95">
|
||||||
|
立即接单
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,9 +92,48 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const showExchangeModal = ref(false)
|
||||||
|
|
||||||
|
const services = ref([
|
||||||
|
{ id: 1, title: '专业助浴', icon: '🛁', desc: '由专业护理员提供入户助浴服务', price: 150 },
|
||||||
|
{ id: 2, title: '全屋深度保洁', icon: '🧹', desc: '2小时专业家政深度清洁', price: 300 },
|
||||||
|
{ id: 3, title: '陪诊服务', icon: '🏥', desc: '陪同前往医院挂号、取药、就诊', price: 200 },
|
||||||
|
{ id: 4, title: '理发修甲', icon: '✂️', desc: '上门提供基础生活护理', price: 80 },
|
||||||
|
{ id: 5, title: '代办跑腿', icon: '🏃', desc: '代取快递、代办医保等事务', price: 50 },
|
||||||
|
])
|
||||||
|
|
||||||
const tasks = ref([
|
const tasks = ref([
|
||||||
{ id: 1, title: '陪伴李奶奶聊天', icon: '👵', distance: '300m', time: '30分钟', reward: 50 },
|
{ id: 1, title: '陪伴李奶奶聊天', icon: '👵', distance: '300m', time: '30分钟', reward: 50 },
|
||||||
{ id: 2, title: '协助购买日用品', icon: '🛒', distance: '500m', time: '1小时', reward: 100 },
|
{ id: 2, title: '协助购买日用品', icon: '🛒', distance: '500m', time: '1小时', reward: 100 },
|
||||||
{ id: 3, title: '教张大爷使用手机', icon: '📱', distance: '1.2km', time: '45分钟', reward: 80 },
|
{ id: 3, title: '教张大爷使用手机', icon: '📱', distance: '1.2km', time: '45分钟', reward: 80 },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const handleExchange = (service) => {
|
||||||
|
if (confirm(`确定消耗 ${service.price} Token 兑换 "${service.title}" 吗?\n兑换成功后将由平台为您指派专业服务人员。`)) {
|
||||||
|
alert(`兑换成功!\n\n区块链存证摘要已生成:\nHash: 0x${Math.random().toString(16).slice(2, 10)}...${Math.random().toString(16).slice(2, 6)}\n\n工作人员将在 30 分钟内与您联系。`)
|
||||||
|
showExchangeModal.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAcceptTask = (task) => {
|
||||||
|
alert(`成功接单:${task.title}!\n\n请准时前往任务地点。任务完成后,${task.reward} Token 将自动记入您的智护通证。`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollToTasks = () => {
|
||||||
|
const element = document.getElementById('tasks-section')
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@keyframes bounce-in {
|
||||||
|
0% { transform: scale(0.95); opacity: 0; }
|
||||||
|
70% { transform: scale(1.02); opacity: 1; }
|
||||||
|
100% { transform: scale(1); }
|
||||||
|
}
|
||||||
|
.animate-bounce-in {
|
||||||
|
animation: bounce-in 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user