2025-08-15

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>智能家居控制面板</title>
    <link rel="stylesheet"  />
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      }

      body {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
        padding: 20px;
      }

      .container {
        width: 100%;
        max-width: 500px;
        background-color: rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(10px);
        border-radius: 20px;
        padding: 30px;
        box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3);
        border: 1px solid rgba(255, 255, 255, 0.1);
      }

      h1 {
        text-align: center;
        color: white;
        margin-bottom: 30px;
        font-weight: 600;
        text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
      }

      .status-container {
        display: flex;
        justify-content: space-between;
        margin-bottom: 40px;
        gap: 20px;
      }

      .status-card {
        flex: 1;
        background: rgba(255, 255, 255, 0.15);
        border-radius: 15px;
        padding: 20px;
        text-align: center;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
        transition: transform 0.3s ease;
      }

      .status-card:hover {
        transform: translateY(-5px);
      }

      .status-icon {
        font-size: 50px;
        margin-bottom: 15px;
      }

      .door-icon {
        color: #ff9a8b;
      }

      .window-icon {
        color: #8bd3ff;
      }

      .status-name {
        font-size: 18px;
        color: white;
        margin-bottom: 10px;
        font-weight: 500;
      }

      .status-value {
        font-size: 22px;
        font-weight: 700;
        color: #ffd700;
        text-transform: uppercase;
      }

      .closed {
        color: #4caf50;
      }

      .open {
        color: #f44336;
      }

      .control-btn {
        display: block;
        width: 100%;
        padding: 18px;
        background: linear-gradient(to right, #ff416c, #ff4b2b);
        color: white;
        border: none;
        border-radius: 50px;
        font-size: 20px;
        font-weight: 600;
        cursor: pointer;
        transition: all 0.3s ease;
        box-shadow: 0 5px 15px rgba(255, 75, 43, 0.4);
        margin-bottom: 30px;
      }

      .control-btn:hover {
        transform: translateY(-3px);
        box-shadow: 0 8px 20px rgba(255, 75, 43, 0.6);
      }

      .control-btn:active {
        transform: translateY(1px);
      }

      .control-btn:disabled {
        background: linear-gradient(to right, #8e9eab, #eef2f3);
        cursor: not-allowed;
        transform: none;
        box-shadow: none;
      }

      .toast-container {
        position: fixed;
        bottom: 30px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 1000;
      }

      .toast {
        background-color: #323232;
        color: white;
        padding: 18px 25px;
        border-radius: 10px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        display: flex;
        align-items: center;
        max-width: 90vw;
        animation: slideIn 0.3s, fadeOut 0.5s 2.5s;
      }

      .toast i {
        margin-right: 15px;
        font-size: 24px;
      }

      .toast.success i {
        color: #4caf50;
      }

      .toast.error i {
        color: #f44336;
      }

      .toast-content {
        flex: 1;
      }

      .toast-title {
        font-weight: 600;
        margin-bottom: 5px;
      }

      @keyframes slideIn {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      @keyframes fadeOut {
        from {
          opacity: 1;
        }
        to {
          opacity: 0;
        }
      }
     .loading {
        display: inline-block;
        width: 20px;
        height: 20px;
        border: 3px solid rgba(255, 255, 255, 0.3);
        border-radius: 50%;
        border-top-color: white;
        animation: spin 1s linear infinite;
        margin-right: 10px;
      }

      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }

      .log-container {
        background: rgba(0, 0, 0, 0.2);
        border-radius: 10px;
        padding: 15px;
        margin-top: 20px;
        max-height: 200px;
        overflow-y: auto;
      }

      .log-title {
        color: white;
        font-size: 16px;
        margin-bottom: 10px;
        text-align: center;
      }

      .log-entry {
        color: rgba(255, 255, 255, 0.8);
        font-size: 14px;
        padding: 5px 0;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1><i class="fas fa-home"></i> 智能家居控制面板</h1>

      <div class="status-container">
        <div class="status-card">
          <div class="status-icon door-icon">
            <i class="fas fa-door-open"></i>
          </div>
          <div class="status-name">門狀態(tài)</div>
          <div class="status-value open" id="door-status">開(kāi)啟</div>
        </div>

        <div class="status-card">
          <div class="status-icon window-icon">
            <i class="fas fa-window-maximize"></i>
          </div>
          <div class="status-name">窗狀態(tài)</div>
          <div class="status-value open" id="window-status">開(kāi)啟</div>
        </div>
      </div>

      <button class="control-btn" id="close-all-btn"><i class="fas fa-power-off"></i> 一鍵關(guān)閉所有</button>

      <div class="log-container">
        <div class="log-title">操作日志</div>
        <div id="log-entries"></div>
      </div>
    </div>

    <div class="toast-container" id="toast-container"></div>
    <script>
      // DOM 元素
      const closeAllBtn = document.getElementById('close-all-btn')
      const doorStatus = document.getElementById('door-status')
      const windowStatus = document.getElementById('window-status')
      const toastContainer = document.getElementById('toast-container')
      const logEntries = document.getElementById('log-entries')

      // 初始狀態(tài)
      let doorOpen = true
      let windowOpen = true

      // 添加日志條目
      function addLogEntry(message) {
        const now = new Date()
        const timeString = now.toLocaleTimeString()
        const logEntry = document.createElement('div')
        logEntry.className = 'log-entry'
        logEntry.innerHTML = `<span style="color: #FFD700;">[${timeString}]</span> ${message}`
        logEntries.prepend(logEntry)
      }

      // 顯示 toast 消息
      function showToast(type, title, message) {
        const toast = document.createElement('div')
        toast.className = `toast ${type}`

        const icon = type === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle'

        toast.innerHTML = `
                <i class="fas ${icon}"></i>
                <div class="toast-content">
                    <div class="toast-title">${title}</div>
                    <div>${message}</div>
                </div>
            `

        toastContainer.innerHTML = ''
        toastContainer.appendChild(toast)

        // 5秒后移除 toast
        setTimeout(() => {
          toast.style.animation = 'fadeOut 0.5s forwards'
          setTimeout(() => {
            if (toastContainer.contains(toast)) {
              toastContainer.removeChild(toast)
            }
          }, 500)
        }, 2500)
      }

      // 模擬關(guān)門接口
      function closeDoor() {
        return new Promise((resolve, reject) => {
          // 模擬網(wǎng)絡(luò)延遲
          const delay = 800 + Math.random() * 1200

          setTimeout(() => {
            // 模擬80%成功率
            const success = Math.random() > 0.2

            if (success) {
              doorOpen = false
              doorStatus.textContent = '已關(guān)閉'
              doorStatus.className = 'status-value closed'
              resolve('門已成功關(guān)閉')
            } else {
              reject('關(guān)門失?。涸O(shè)備未響應(yīng)')
            }
          }, delay)
        })
      }

      // 模擬關(guān)窗接口
      function closeWindow() {
        return new Promise((resolve, reject) => {
          // 模擬網(wǎng)絡(luò)延遲
          const delay = 1000 + Math.random() * 1500

          setTimeout(() => {
            // 模擬70%成功率
            const success = Math.random() > 0.3

            if (success) {
              windowOpen = false
              windowStatus.textContent = '已關(guān)閉'
              windowStatus.className = 'status-value closed'
              resolve('窗已成功關(guān)閉')
            } else {
              reject('關(guān)窗失?。簜鞲衅鞴收?)
            }
          }, delay)
        })
      }

      // 一鍵關(guān)閉所有
      async function closeAll() {
        // 禁用按鈕防止重復(fù)點(diǎn)擊
        closeAllBtn.disabled = true
        closeAllBtn.innerHTML = '<span class="loading"></span> 正在關(guān)閉中...'
        addLogEntry('開(kāi)始執(zhí)行一鍵關(guān)閉操作...')
        try {
          // 同時(shí)調(diào)用兩個(gè)接口
          const results = await Promise.allSettled([closeDoor(), closeWindow()])

          const doorResult = results[0]
          const windowResult = results[1]

          // 收集失敗信息
          const errors = []
          console.log("doorResult",doorResult);//{"status": "rejected", "reason": "關(guān)門失?。涸O(shè)備未響應(yīng)"}
          console.log("windowResult",windowResult);//{"status": "fulfilled", "reason": "窗已成功關(guān)閉"}
          if (doorResult.status === 'rejected') {
            errors.push(doorResult.reason)
            doorStatus.textContent = '開(kāi)啟'
            doorStatus.className = 'status-value open'
          }

          if (windowResult.status === 'rejected') {
            errors.push(windowResult.reason)
            windowStatus.textContent = '開(kāi)啟'
            windowStatus.className = 'status-value open'
          }
          console.log("errors",errors);

          if (errors.length === 0) {
            // 兩個(gè)都成功
            showToast('success', '操作成功', '門和窗都已成功關(guān)閉!')
            addLogEntry('一鍵關(guān)閉操作成功:門和窗都已關(guān)閉')
          } else {
            // 一個(gè)或兩個(gè)失敗
            const errorMessage = errors.join(';')
            showToast('error', '操作失敗', errorMessage)
            addLogEntry(`一鍵關(guān)閉操作失?。?{errorMessage}`)
          }
        } catch (error) {
          // 這里理論上不會(huì)執(zhí)行,因?yàn)槭褂昧?allSettled
          showToast('error', '系統(tǒng)錯(cuò)誤', '發(fā)生意外錯(cuò)誤')
          addLogEntry(`系統(tǒng)錯(cuò)誤:${error.message}`)
        } finally {
          // 重新啟用按鈕
          closeAllBtn.disabled = false
          closeAllBtn.innerHTML = '<i class="fas fa-power-off"></i> 一鍵關(guān)閉所有'
        }
      }

      // 事件監(jiān)聽(tīng)
      closeAllBtn.addEventListener('click', closeAll)

      // 初始日志
      addLogEntry('系統(tǒng)已就緒,等待操作...')
    </script>
  </body>
</html>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 做更好的人 最近幾天中午都沒(méi)有回去,今天太陽(yáng)又大,沒(méi)有想要回去的,早上就和 我說(shuō)了他沒(méi)有時(shí)間中午,我還告訴他讓他點(diǎn)...
    64fbe1876343閱讀 23評(píng)論 0 0
  • 紅巖讀后感 “在東方的地平線上,漸漸透出一派紅光,閃爍的綠草的嘉陵江上。湛藍(lán)的...
    Lxr_db8f閱讀 106評(píng)論 0 0
  • 這一章主要講述的是可能性效應(yīng)和確定性效應(yīng)之間的不對(duì)稱性。 決策權(quán)重 只有在確定的情況下,人們的決策和概率一致。其它...
    燕歸來(lái)2021閱讀 185評(píng)論 0 0
  • 1,本軟件停止更新,請(qǐng)下載新系統(tǒng)使用,謝謝配合
    草沒(méi)味u閱讀 114評(píng)論 0 0
  • 題清-八大山人 《彩筆山水圖》 山石如鐵木似戟, 天地籠罩蕭煞氣。 夢(mèng)中乾坤一空亭, 遺世獨(dú)立破壓抑。
    19f31e7d61ed閱讀 25評(píng)論 0 0

友情鏈接更多精彩內(nèi)容