index.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <template>
  2. <div class="motion-detection">
  3. <div class="section">
  4. <div class="section-title">Manual Alarm Control</div>
  5. <div class="section-content">
  6. <div class="alarm-status-row">
  7. <span class="label">Current Status:</span>
  8. <el-tag :type="alarmActive ? 'danger' : 'info'" size="large">
  9. {{ alarmActive ? 'Alarm Active' : 'Alarm Inactive' }}
  10. </el-tag>
  11. </div>
  12. </div>
  13. </div>
  14. <el-divider class="short-divider"/>
  15. <div class="section">
  16. <div class="section-title">Alarm Actions</div>
  17. <div class="alarm-actions">
  18. <el-button
  19. type="primary"
  20. round
  21. @click="handleAlarm"
  22. :loading="loading"
  23. >
  24. Enable Manual Alarm
  25. </el-button>
  26. <el-button
  27. type="info"
  28. round
  29. @click="handleCloseAlarm"
  30. :loading="disableLoading"
  31. >
  32. Disable Manual Alarm
  33. </el-button>
  34. </div>
  35. </div>
  36. <el-divider class="short-divider"/>
  37. <div class="section">
  38. <div class="section-title">Notes</div>
  39. <div class="alarm-tip">
  40. <el-icon class="tip-icon"><InfoFilled/></el-icon>
  41. <span>Alarm will remain active for 1 minute after activation.</span>
  42. </div>
  43. </div>
  44. </div>
  45. </template>
  46. <script setup lang="ts">
  47. import {ref} from 'vue'
  48. import {ElMessage} from 'element-plus'
  49. import {InfoFilled} from '@element-plus/icons-vue'
  50. import {cameraAlarm} from '@/api/setting'
  51. const loading = ref(false)
  52. const disableLoading = ref(false)
  53. const alarmActive = ref(false)
  54. async function handleCloseAlarm() {
  55. if (disableLoading.value) return
  56. disableLoading.value = true
  57. try {
  58. const res = await cameraAlarm({AlarmSettings: 0}) as { data: string }
  59. if (res.data === 'ok\n') {
  60. alarmActive.value = false
  61. ElMessage.success('Manual Alarm Deactivated Successfully')
  62. } else {
  63. ElMessage.warning('Manual Alarm Deactivation Error')
  64. }
  65. } catch {
  66. ElMessage.error('Manual Alarm Deactivation Error')
  67. } finally {
  68. disableLoading.value = false
  69. }
  70. }
  71. async function handleAlarm() {
  72. if (loading.value) return
  73. loading.value = true
  74. try {
  75. const res = await cameraAlarm({AlarmSettings: 1}) as { data: string }
  76. if (res.data === 'ok\n') {
  77. alarmActive.value = true
  78. ElMessage.success('Manual alarm activated successfully. It will remain active for 1 minute.')
  79. } else {
  80. ElMessage.warning('Manual Alarm Activation Error')
  81. }
  82. } catch {
  83. ElMessage.error('Failed to Activate Manual Alarm.')
  84. } finally {
  85. loading.value = false
  86. }
  87. }
  88. </script>
  89. <style scoped lang="scss">
  90. .motion-detection {
  91. padding: 20px;
  92. .short-divider {
  93. max-width: 700px;
  94. margin: 16px 0;
  95. }
  96. .section {
  97. margin: 16px 0;
  98. .section-title {
  99. font-size: 14px;
  100. font-weight: 500;
  101. color: #333;
  102. margin-bottom: 12px;
  103. }
  104. .section-content {
  105. display: flex;
  106. gap: 100px;
  107. }
  108. }
  109. .alarm-status-row {
  110. display: flex;
  111. align-items: center;
  112. .label {
  113. font-size: 14px;
  114. color: #333;
  115. flex-shrink: 0;
  116. }
  117. }
  118. .alarm-actions {
  119. display: flex;
  120. gap: 16px;
  121. }
  122. .alarm-tip {
  123. display: flex;
  124. align-items: center;
  125. gap: 6px;
  126. font-size: 13px;
  127. color: #909399;
  128. .tip-icon {
  129. font-size: 15px;
  130. color: #909399;
  131. }
  132. }
  133. }
  134. </style>