index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <el-dialog
  3. v-model="visible"
  4. :title="title"
  5. :close-on-click-modal="false"
  6. :show-close="false"
  7. width="500px"
  8. class="hardware-check-dialog"
  9. >
  10. <div class="hardware-check-container">
  11. <el-timeline>
  12. <!-- Step 1 -->
  13. <el-timeline-item
  14. :type="'primary'"
  15. :hollow="true">
  16. <template #dot>
  17. <img src="@/assets/images/check/icon1.png" class="custom-timeline-icon" />
  18. </template>
  19. <div class="step-content">
  20. <div class="step-title">
  21. <template v-if="checkLoading">正在初始化检测硬件......</template>
  22. <template v-else-if="checkSuccess">硬件检测完成</template>
  23. <template v-else>初始化检测硬件失败</template>
  24. </div>
  25. <el-progress
  26. :percentage="checkInfoStore.getProgress"
  27. :colors="['#2FB0FF', '#B863FB']"
  28. :stroke-width="8"
  29. v-if="checkLoading"
  30. ></el-progress>
  31. <div class="check-error-result" v-else-if="!checkSuccess">失败的原因,{{ checkInfoStore.getErrorMsg }}</div>
  32. </div>
  33. </el-timeline-item>
  34. <!-- Step 2 -->
  35. <el-timeline-item
  36. :type="'primary'"
  37. :hollow="true">
  38. <template #dot>
  39. <img src="@/assets/images/check/icon2.png" class="custom-timeline-icon" />
  40. </template>
  41. <div class="step-content">
  42. <div class="step-title">自我检查</div>
  43. <div class="check-result">
  44. <p>补光灯电源和链接器是否正常连上。</p>
  45. <p>请检查红外线器是否正常显示。</p>
  46. </div>
  47. </div>
  48. </el-timeline-item>
  49. </el-timeline>
  50. </div>
  51. <template #footer v-if="!checkLoading">
  52. <div class="flex" v-if="!checkSuccess">
  53. <div class="check-btn cu-p" @click="reCheck">重新监测</div>
  54. </div>
  55. <div class="flex" v-else>
  56. <div class="check-btn cu-p" style="width: 180px" @click="confirm()">正常,开始下一步</div>
  57. </div>
  58. </template>
  59. </el-dialog>
  60. </template>
  61. <script setup>
  62. import { ref, computed, watch, onBeforeUnmount, nextTick, watchEffect } from 'vue';
  63. import useUserInfo from "@/stores/modules/user";
  64. import checkInfo from "@/stores/modules/check";
  65. import client from "@/stores/modules/client";
  66. const clientStore = client();
  67. /**
  68. * 定义组件的 props。
  69. * @param {Object} props
  70. * @param {Boolean} props.modelValue - 控制对话框显示状态的双向绑定值,默认为 false。
  71. * @param {String} props.title - 对话框标题,默认为 '检测硬件'。
  72. */
  73. const props = defineProps({
  74. modelValue: {
  75. type: Boolean,
  76. default: false
  77. },
  78. title: {
  79. type: String,
  80. default: '检测硬件'
  81. }
  82. });
  83. // 初始化用户信息状态管理
  84. const useUserInfoStore = useUserInfo()
  85. const checkInfoStore = checkInfo()
  86. // 检测是否成功的状态
  87. const checkSuccess = ref(false);
  88. // 检测加载状态
  89. const checkLoading = ref(true);
  90. // 定义事件发射器,用于更新父组件的 modelValue 和触发 confirm 事件
  91. const emit = defineEmits(['update:modelValue', 'confirm']);
  92. // 检测次数计数器
  93. const checkCount = ref(0);
  94. // 进度条的当前进度值
  95. // 定时器变量,用于控制进度条的递增
  96. let timer = null;
  97. // 控制组件可见性的状态
  98. const visible = ref(false);
  99. /**
  100. * 开始进度条的递增逻辑。
  101. * 该函数会重置进度条并启动定时器,逐步增加进度值直到达到 80。
  102. */
  103. function startProgress() {
  104. checkLoading.value = true;
  105. checkInfoStore.reCheckAction()
  106. }
  107. /**
  108. * 重新执行检测逻辑。
  109. * 调用 startProgress 函数以重新开始进度条。
  110. */
  111. function reCheck() {
  112. startProgress()
  113. // checkInfoStore.reCheckAction()
  114. }
  115. // 初始化客户端状态管理
  116. /**
  117. * 监听用户信息和检测次数的变化,自动触发相关逻辑。
  118. * 当用户信息存在且检测次数为 0 时,设置组件可见性为 true,
  119. * 并尝试连接 WebSocket 和发送消息。
  120. */
  121. watchEffect(async ()=>{
  122. if( useUserInfoStore.userInfo.id && checkCount.value === 0){
  123. if(clientStore.isClient){
  124. visible.value = true
  125. //python 启动有延时,延迟2秒执行
  126. setTimeout(()=>{
  127. startProgress()
  128. },2000)
  129. }
  130. checkCount.value++;
  131. }
  132. })
  133. watchEffect(async ()=>{
  134. if(checkInfoStore.getProgress === 100 ){
  135. checkLoading.value = false;
  136. checkSuccess.value = true;
  137. }
  138. })
  139. watchEffect(async ()=>{
  140. if( checkInfoStore.getErrorMsg){
  141. checkLoading.value = false;
  142. checkSuccess.value = false;
  143. }
  144. })
  145. watchEffect(async ()=>{
  146. if( checkInfoStore.getProgress === 1){
  147. checkLoading.value = false;
  148. checkSuccess.value = true;
  149. }
  150. })
  151. function confirm(){
  152. visible.value = false;
  153. emit('confirm')
  154. }
  155. </script>
  156. <style lang="scss" scoped>
  157. .hardware-check-container {
  158. padding: 20px 0;
  159. }
  160. .step-content {
  161. flex: 1;
  162. }
  163. .step-title {
  164. font-weight: 600;
  165. font-size: 14px;
  166. color: #000000;
  167. margin-bottom: 15px;
  168. padding-top: 4px;
  169. text-align: left;
  170. }
  171. .progress-text {
  172. text-align: right;
  173. margin-top: 5px;
  174. color: #606266;
  175. }
  176. .check-result {
  177. color: rgba(0,0,0,0.45);
  178. text-align: left;
  179. p {
  180. margin: 8px 0;
  181. }
  182. }
  183. :deep(.el-progress-bar__inner) {
  184. background-image: linear-gradient(to right, #409EFF, #7e57c2);
  185. }
  186. .custom-timeline-icon{
  187. width: 24px;
  188. height: 24px;
  189. position: relative;
  190. left: -7px;
  191. }
  192. .check-btn{
  193. width: 100px;
  194. height: 40px;
  195. background: linear-gradient( 135deg, #2FB0FF 0%, #B863FB 100%);
  196. border-radius: 4px;
  197. font-weight: 400;
  198. font-size: 16px;
  199. color: #FFFFFF;
  200. text-align: center;
  201. line-height: 40px;
  202. }
  203. .check-error-result{
  204. font-size: 14px;
  205. text-align: left;
  206. color: #FF4C00;
  207. }
  208. </style>