11<script setup>
22import {ref , onMounted , watch , computed } from ' vue' ;
33import { useStats } from ' ../composables/useStats.js' ;
4-
4+ import { formatTime } from " ../composables/formatTime.js "
55import RecentApps from " ./RecentApps.vue" ;
66import UsageDetails from " ./UsageDetails.vue" ;
77import AppUsageChart from " ./charts/AppUsageChart.vue" ;
88import TimeUsageChart from " ./charts/TimeUsageChart.vue" ;
99import AISummary from " ./AISummary.vue" ;
10+ import EyeTimeStats from " ./EyeTimeStats.vue" ;
1011
1112const props = defineProps ({
1213 deviceId: {
@@ -63,18 +64,6 @@ const calculateRunningTime = () => {
6364 return Math .floor ((now - startTime) / 60000 );
6465};
6566
66- // 格式化时间
67- const formatTime = (minutes ) => {
68- const totalMinutes = parseFloat (minutes);
69- if (totalMinutes < 60 ) {
70- return ` ${ totalMinutes .toFixed (2 )} 分` ;
71- } else {
72- const hours = Math .floor (totalMinutes / 60 );
73- const remainingMinutes = Math .round (totalMinutes % 60 );
74- return ` ${ hours} 时${ remainingMinutes} 分` ;
75- }
76- };
77-
7867// 获取设备统计信息
7968const getDeviceStats = () => {
8069 const defaultStats = {
@@ -153,7 +142,7 @@ watch(stats, (newStats) => {
153142 <p class =" text-xl md:text-2xl font-bold" >{{ getDeviceStats().appCount }}</p >
154143 </div >
155144 <div class =" bg-green-50 hover:bg-green-100 transition-colors duration-200 p-4 rounded-lg shadow-md dark:bg-green-950 dark:hover:bg-green-900" >
156- <p class =" text-sm text-green-700" >总时间 </p >
145+ <p class =" text-sm text-green-700" >应用总时间 </p >
157146 <p class =" text-xl md:text-2xl font-bold whitespace-nowrap" >{{ formatTime(getDeviceStats().totalUsageMinutes) }}</p >
158147 </div >
159148 <div class =" bg-yellow-50 hover:bg-yellow-100 transition-colors duration-200 p-4 rounded-lg shadow-md dark:bg-yellow-950 dark:hover:bg-yellow-900" >
@@ -168,32 +157,49 @@ watch(stats, (newStats) => {
168157 </div >
169158 </div >
170159
171- <!-- 当前使用情况 -->
172- <div class =" mb-6" >
173- <div class =" bg-blue-50 hover:bg-blue-100 transition-colors duration-200 p-4 rounded-lg shadow-md dark:bg-[#1d1f20] dark:hover:bg-blue-900/30" >
174- <div class =" flex items-center justify-between" >
175- <div >
176- <p class =" text-sm text-blue-800" >{{ deviceInfo?.running ? '当前应用' : '上次应用' }}</p >
177- <p class =" text-xl font-bold" >{{ deviceInfo?.currentApp }}</p >
178- </div >
179- <div >
180- <p class =" text-sm text-blue-800" >状态</p >
181- <p class =" text-xl font-bold" >{{ deviceInfo?.running ? '运行中' : '已停止' }}</p >
182- </div >
183- <div >
184- <p class =" text-sm text-blue-800" >已运行时间</p >
185- <p class =" text-xl font-bold" >{{ calculateRunningTime() }} 分钟</p >
160+ <!-- 当前使用情况和用眼时间的切换容器 -->
161+ <div class =" relative mb-6" >
162+ <Transition name =" slide-fade" mode =" out-in" >
163+ <!-- 当前使用情况 -->
164+ <div v-if =" deviceInfo?.device !== 'summary'" key =" current-app" >
165+ <div class =" bg-blue-50 hover:bg-blue-100 transition-colors duration-200 p-4 rounded-lg shadow-md dark:bg-[#1d1f20] dark:hover:bg-blue-900/30" >
166+ <div class =" flex items-center justify-between" >
167+ <div >
168+ <p class =" text-sm text-blue-800" >{{ deviceInfo?.running ? '当前应用' : '上次应用' }}</p >
169+ <p class =" text-xl font-bold" >{{ deviceInfo?.currentApp }}</p >
170+ </div >
171+ <div >
172+ <p class =" text-sm text-blue-800" >状态</p >
173+ <p class =" text-xl font-bold" >{{ deviceInfo?.running ? '运行中' : '已停止' }}</p >
174+ </div >
175+ <div >
176+ <p class =" text-sm text-blue-800" >已运行时间</p >
177+ <p class =" text-xl font-bold" >{{ calculateRunningTime() }} 分钟</p >
178+ </div >
179+ </div >
186180 </div >
187181 </div >
188- </div >
182+
183+ <!-- 用眼时间 -->
184+ <div v-else key =" eye-time" >
185+ <EyeTimeStats
186+ :statsType =" props.statsType"
187+ :timeOffset =" props.timeOffset"
188+ :date =" props.date"
189+ />
190+ </div >
191+ </Transition >
189192 </div >
190193
191194 <!-- AI总结组件 - 支持双向绑定展开状态 -->
192- <AISummary
193- v-if =" showAiSummary"
194- :device-id =" deviceId"
195- v-model:is-expanded =" isAISummaryExpanded"
196- />
195+ <Transition name =" slide-fade" mode =" out-in" >
196+ <AISummary
197+ v-show =" showAiSummary && deviceInfo?.device !== 'summary'"
198+ :device-id =" deviceId"
199+ v-model:is-expanded =" isAISummaryExpanded"
200+ />
201+ </Transition >
202+
197203
198204 <!-- 图表组件 -->
199205 <div class =" grid grid-cols-1 md:grid-cols-2 gap-6 mb-6" >
@@ -212,6 +218,47 @@ watch(stats, (newStats) => {
212218 <UsageDetails :stats =" stats || {}" :show-limit =" 10" />
213219
214220 <!-- 最近使用的APP组件 -->
215- <RecentApps v-show =" props.statsType === 'daily'" :deviceId =" deviceId" />
221+ <RecentApps v-show =" props.statsType === 'daily' && deviceInfo?.device !== 'summary' " :deviceId =" deviceId" />
216222 </div >
217- </template >
223+ </template >
224+
225+ <style scoped>
226+ /* Transition动画:同时进行淡入淡出,并保持布局流动 */
227+ .slide-fade-enter-active {
228+ transition : opacity 0.3s ease-out , transform 0.3s ease-out , max-height 0.3s ease-out ;
229+ }
230+
231+ .slide-fade-leave-active {
232+ transition : opacity 0.3s ease-out , transform 0.3s ease-out , max-height 0.3s ease-out ;
233+ overflow : hidden ;
234+ }
235+
236+ /* 为左侧整体容器添加平滑过渡 */
237+ .space-y-6 > * {
238+ transition : transform 0.3s ease , opacity 0.3s ease ;
239+ }
240+
241+ .slide-fade-enter-from {
242+ opacity : 0 ;
243+ transform : translateY (-20px );
244+ max-height : 0 ;
245+ }
246+
247+ .slide-fade-leave-to {
248+ opacity : 0 ;
249+ transform : translateY (-20px );
250+ max-height : 0 ;
251+ }
252+
253+ .slide-fade-enter-to ,
254+ .slide-fade-leave-from {
255+ opacity : 1 ;
256+ transform : translateY (0 );
257+ max-height : 500px ; /* 根据实际内容高度调整 */
258+ }
259+
260+ /* 让容器在动画期间也有过渡效果 */
261+ .relative.mb-6 {
262+ transition : height 0.3s ease-out ;
263+ }
264+ </style >
0 commit comments