11111
This commit is contained in:
@@ -3,12 +3,14 @@ import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Button as VanButton, showToast } from 'vant'
|
||||
import { clearTokens } from '../services/auth'
|
||||
import { healthApi, type Dashboard } from '../services/health'
|
||||
import { healthApi, type Dashboard, type HomeAssistantDevice, type HomeAssistantStatus } from '../services/health'
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const generating = ref(false)
|
||||
const sceneRunning = ref<'sleep' | 'all-off'>()
|
||||
const dashboard = ref<Dashboard>()
|
||||
const homeAssistant = ref<HomeAssistantStatus>()
|
||||
const moduleNames: Record<string, string> = {
|
||||
sleep: '睡眠',
|
||||
exercise: '运动',
|
||||
@@ -20,11 +22,25 @@ const greeting = computed(() => {
|
||||
if (hour < 18) return '下午好'
|
||||
return '晚上好'
|
||||
})
|
||||
const availableDeviceCount = computed(() => homeAssistant.value?.devices.filter(item => item.isAvailable).length || 0)
|
||||
|
||||
function deviceState(item: HomeAssistantDevice) {
|
||||
if (!item.isAvailable) return '离线'
|
||||
if (item.code === 'dehumidifier' && item.value) return `${item.state === 'on' ? '运行中' : '已关闭'} · 当前湿度 ${item.value}${item.unit || ''}`
|
||||
if (item.state === 'on' || item.state === 'playing') return '已开启'
|
||||
if (item.state === 'off' || item.state === 'idle') return '已关闭'
|
||||
return item.value ? `${item.value}${item.unit || ''}` : item.state
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
try {
|
||||
dashboard.value = await healthApi.dashboard()
|
||||
const [dashboardResult, homeAssistantResult] = await Promise.all([
|
||||
healthApi.dashboard(),
|
||||
healthApi.homeAssistantStatus().catch(() => undefined)
|
||||
])
|
||||
dashboard.value = dashboardResult
|
||||
homeAssistant.value = homeAssistantResult
|
||||
} catch (error) {
|
||||
showToast(error instanceof Error ? error.message : '加载失败')
|
||||
} finally {
|
||||
@@ -32,6 +48,21 @@ async function load() {
|
||||
}
|
||||
}
|
||||
|
||||
async function executeScene(scene: 'sleep' | 'all-off') {
|
||||
sceneRunning.value = scene
|
||||
try {
|
||||
const result = scene === 'sleep'
|
||||
? await healthApi.executeSleepScene()
|
||||
: await healthApi.executeAllOffScene()
|
||||
showToast({ type: result.success ? 'success' : 'fail', message: result.message })
|
||||
homeAssistant.value = await healthApi.homeAssistantStatus()
|
||||
} catch (error) {
|
||||
showToast(error instanceof Error ? error.message : '场景执行失败')
|
||||
} finally {
|
||||
sceneRunning.value = undefined
|
||||
}
|
||||
}
|
||||
|
||||
async function generate() {
|
||||
generating.value = true
|
||||
try {
|
||||
@@ -106,13 +137,36 @@ onMounted(load)
|
||||
</section>
|
||||
|
||||
<section class="section-card smart-card">
|
||||
<div class="section-title"><span>健康空间</span><small class="status-dot">Home Assistant 待接入</small></div>
|
||||
<div class="section-title">
|
||||
<span>健康空间</span>
|
||||
<small class="status-dot" :class="{ online: homeAssistant?.connected }">
|
||||
{{ homeAssistant?.connected ? `Home Assistant 已连接 · ${availableDeviceCount}/${homeAssistant.devices.length} 在线` : (homeAssistant?.message || '正在连接 Home Assistant') }}
|
||||
</small>
|
||||
</div>
|
||||
<div v-if="homeAssistant?.devices.length" class="device-grid">
|
||||
<article v-for="item in homeAssistant.devices" :key="item.code" class="device-pill" :class="{ offline: !item.isAvailable }">
|
||||
<span></span>
|
||||
<div><strong>{{ item.name }}</strong><small>{{ deviceState(item) }}</small></div>
|
||||
</article>
|
||||
</div>
|
||||
<div class="scene-row">
|
||||
<div>
|
||||
<strong>舒睡模式</strong>
|
||||
<p>灯光 · 空调 · 香氛 · 除湿机</p>
|
||||
<p>除湿机 55% · 睡眠模式 · 低档风速 · 香氛 · 暖光</p>
|
||||
</div>
|
||||
<div class="scene-actions">
|
||||
<button type="button" :disabled="!homeAssistant?.connected || !!sceneRunning" @click="executeScene('sleep')">
|
||||
{{ sceneRunning === 'sleep' ? '执行中…' : '一键舒睡' }}
|
||||
</button>
|
||||
<button class="secondary" type="button" :disabled="!homeAssistant?.connected || !!sceneRunning" @click="executeScene('all-off')">
|
||||
{{ sceneRunning === 'all-off' ? '执行中…' : '全部关闭' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="homeAssistant?.environment.some(item => item.isAvailable)" class="environment-grid">
|
||||
<div v-for="item in homeAssistant.environment.filter(item => item.isAvailable)" :key="item.code">
|
||||
<small>{{ item.name }}</small><strong>{{ item.value }}{{ item.unit || '' }}</strong>
|
||||
</div>
|
||||
<button type="button">准备就绪</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user