This commit is contained in:
fuenmao
2026-10-09 16:46:35 +08:00
parent 4925c4c74d
commit 563836f789
60 changed files with 4729 additions and 2047 deletions
+140
View File
@@ -0,0 +1,140 @@
<script setup lang="ts">
import { toRefs } from 'vue'
import { Button as VanButton, Slider as VanSlider } from 'vant'
import type { HomeAssistantDiscoveredDevice } from '../../services/health'
import { useDeviceControlContext } from '../../devices/controlContext'
import { useDeviceCardState } from '../../devices/useDeviceCardState'
const props = defineProps<{ device: HomeAssistantDiscoveredDevice }>()
const { device: fragranceDevice } = toRefs(props)
const { localParams, operationBusy, switchingDeviceId, isDeviceTurnedOn, toggleDevice, applyParam, settingParam } = useDeviceControlContext()
const state = useDeviceCardState(() => props.device)
</script>
<template>
<section class="device-card" v-if="fragranceDevice">
<div class="device-head">
<div class="dev-info">
<span class="category-tag">香氛助眠</span>
<h3>{{ fragranceDevice.name }}</h3>
<span class="status-dot" :class="{ online: fragranceDevice.online }">
{{ fragranceDevice.online ? '设备在线' : '设备离线' }}
</span>
</div>
<VanButton
size="small"
round
:type="isDeviceTurnedOn(fragranceDevice) ? 'primary' : 'default'"
:color="isDeviceTurnedOn(fragranceDevice) ? '#0c5045' : ''"
:loading="switchingDeviceId === fragranceDevice.deviceId"
:disabled="operationBusy || !state.powerAvailable()"
@click="toggleDevice(fragranceDevice)"
>
{{ state.powerLabel('释放中', '已关闭') }}
</VanButton>
</div>
<small class="p-tip">上方“释放中/已关闭”只表示香薰主开关;感应夜灯在下方单独显示和控制。</small>
<div class="params-body">
<div class="param-row">
<div class="param-header">
<span class="p-title">单次出香时长</span>
<strong class="p-val">{{ state.display('fragrance_duration', localParams.fragranceDuration, ' 秒') }}</strong>
</div>
<VanSlider
v-model="localParams.fragranceDuration"
:min="2"
:max="6"
:step="1"
:disabled="operationBusy || !state.available('fragrance_duration')"
@change="applyParam(fragranceDevice.deviceId, 'fragrance_duration', localParams.fragranceDuration)"
/>
<div class="range-labels"><span>2 秒</span><span>4 秒</span><span>6 秒</span></div>
</div>
<div class="param-row">
<div class="param-header">
<span class="p-title">自动出香间隔</span>
<strong class="p-val">{{ state.display('fragrance_interval', localParams.fragranceInterval, ' 分钟') }}</strong>
</div>
<VanSlider
v-model="localParams.fragranceInterval"
:min="10"
:max="20"
:step="5"
:disabled="operationBusy || !state.available('fragrance_interval')"
@change="applyParam(fragranceDevice.deviceId, 'fragrance_interval', localParams.fragranceInterval)"
/>
<div class="range-labels"><span>10 分钟</span><span>15 分钟</span><span>20 分钟</span></div>
</div>
<div class="param-row inline-row">
<div>
<div class="p-title">香薰氛围灯</div>
<small class="p-tip">与香薰释放独立控制</small>
</div>
<button
class="mini-toggle"
:class="{ active: state.readable('fragrance_light') && localParams.fragranceLight }"
:disabled="operationBusy || !state.available('fragrance_light')"
@click="localParams.fragranceLight = !localParams.fragranceLight; applyParam(fragranceDevice.deviceId, 'fragrance_light', localParams.fragranceLight)"
>{{ state.display('fragrance_light', localParams.fragranceLight ? '已开启' : '已关闭') }}</button>
</div>
<div class="param-row inline-row">
<div>
<div class="p-title">人来增香</div>
<small class="p-tip">检测到有人活动时自动增香</small>
</div>
<button
class="mini-toggle"
:class="{ active: state.readable('fragrance_auto_release') && localParams.fragranceAutoRelease }"
:disabled="operationBusy || !state.available('fragrance_auto_release')"
@click="localParams.fragranceAutoRelease = !localParams.fragranceAutoRelease; applyParam(fragranceDevice.deviceId, 'fragrance_auto_release', localParams.fragranceAutoRelease)"
>{{ state.display('fragrance_auto_release', localParams.fragranceAutoRelease ? '已开启' : '已关闭') }}</button>
</div>
<div class="param-row inline-row">
<div>
<div class="p-title">感应夜灯</div>
<small class="p-tip">有人移动时自动开启柔光</small>
</div>
<button
class="mini-toggle"
:class="{ active: state.readable('fragrance_auto_light') && localParams.fragranceAutoLight }"
:disabled="operationBusy || !state.available('fragrance_auto_light')"
@click="localParams.fragranceAutoLight = !localParams.fragranceAutoLight; applyParam(fragranceDevice.deviceId, 'fragrance_auto_light', localParams.fragranceAutoLight)"
>{{ state.display('fragrance_auto_light', localParams.fragranceAutoLight ? '已开启' : '已关闭') }}</button>
</div>
<div class="param-row inline-row">
<div>
<div class="p-title">无人时自动关灯</div>
<small class="p-tip">关闭时氛围灯保持常亮</small>
</div>
<button
class="mini-toggle"
:class="{ active: state.readable('fragrance_light_auto_off') && localParams.fragranceLightAutoOff }"
:disabled="operationBusy || !state.available('fragrance_light_auto_off')"
@click="localParams.fragranceLightAutoOff = !localParams.fragranceLightAutoOff; applyParam(fragranceDevice.deviceId, 'fragrance_light_auto_off', localParams.fragranceLightAutoOff)"
>{{ state.display('fragrance_light_auto_off', localParams.fragranceLightAutoOff ? '已开启' : '已关闭') }}</button>
</div>
<div class="param-row inline-row">
<div>
<div class="p-title">立即出香</div>
<small class="p-tip">{{ state.available('fragrance_quick_release') ? '手动触发一次当前时长的香氛释放' : '快速出香能力当前不可用' }}</small>
</div>
<VanButton
size="small"
round
plain
color="#0c5045"
:loading="settingParam === `${fragranceDevice.deviceId}_fragrance_quick_release`"
:disabled="operationBusy || !state.available('fragrance_quick_release')"
@click="applyParam(fragranceDevice.deviceId, 'fragrance_quick_release', true)"
>{{ state.available('fragrance_quick_release') ? '快速出香' : '暂不可用' }}</VanButton>
</div>
</div>
</section>
</template>