You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.7 KiB

5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. <script setup lang="ts">
  2. import { getDeviceSelfTest } from 'apis/system'
  3. import FtDialog from 'components/common/FTDialog/index.vue'
  4. import { FtMessage } from 'libs/message'
  5. import { socket } from 'libs/socket'
  6. import { sendControl } from 'libs/utils'
  7. import { nextTick, onMounted, ref } from 'vue'
  8. const emits = defineEmits(['ok', 'cancel'])
  9. const okLoading = ref(false)
  10. const okHandle = () => {
  11. okLoading.value = true
  12. setTimeout(() => {
  13. okLoading.value = false
  14. FtMessage.success('保存成功')
  15. emits('ok')
  16. }, 300)
  17. }
  18. const list = ['x轴是否在原点', 'y轴是否在原点', 'z轴是否在原点']
  19. const status = ref<any>({})
  20. onMounted(async () => {
  21. socket.init(receiveMessage, 'cmd_response')
  22. await change()
  23. })
  24. const change = async () => {
  25. let num = 0
  26. await nextTick(() => {
  27. buttonCloseRef.value?.setLoading(true)
  28. })
  29. status.value = await getDeviceSelfTest()
  30. const interval = async () => {
  31. if (num < list.length) {
  32. await addTextToCheckList(list[num], num)
  33. num++
  34. await interval() // 递归调用 interval 处理下一条数据
  35. }
  36. }
  37. await interval()
  38. buttonCloseRef.value?.setLoading(false)
  39. closeVisible.value = false
  40. }
  41. const receiveMessage = (data: any) => {
  42. if (data.cmdId === cmdId) {
  43. if (data.status === 'success') {
  44. for (let i = 0; i < checkList.value.length; i++) {
  45. checkList.value[i].result = 'padding'
  46. setTimeout(() => {
  47. checkList.value[i].result = 'success'
  48. }, 500)
  49. }
  50. buttonRef.value.setLoading(false)
  51. closeVisible.value = true
  52. }
  53. else if (data.status === 'fail') {
  54. FtMessage.error('自检失败')
  55. change()
  56. buttonRef.value.setLoading(false)
  57. closeVisible.value = false
  58. }
  59. }
  60. }
  61. const cancel = () => {
  62. emits('cancel')
  63. }
  64. let cmdId = ''
  65. const motorXYZOrigin = async () => {
  66. buttonRef.value.setLoading(true)
  67. cmdId = Date.now().toString()
  68. const params = {
  69. cmdCode: 'device_self_test',
  70. cmdId,
  71. params: {},
  72. }
  73. await sendControl(params)
  74. }
  75. const checkList = ref<any>([])
  76. const buttonRef = ref()
  77. const buttonCloseRef = ref()
  78. const closeVisible = ref(true)
  79. const addTextToCheckList = async (text: string, id: number) => {
  80. // 检查 checkList 中是否存在该 id 的对象,如果不存在则初始化
  81. if (!checkList.value.some(item => item.id === id)) {
  82. checkList.value.push({ id, title: '', result: 'padding' })
  83. }
  84. let displayedText = ''
  85. return new Promise<void>((resolve) => {
  86. const interval = setInterval(() => {
  87. if (displayedText.length < text.length) {
  88. displayedText += text[displayedText.length]
  89. const itemIndex = checkList.value.findIndex(item => item.id === id)
  90. if (itemIndex !== -1) {
  91. checkList.value[itemIndex].title = displayedText
  92. }
  93. }
  94. else {
  95. clearInterval(interval)
  96. // 文字显示完毕后,设置 result 为 'success' 或 'failed' 以显示成功或失败图标
  97. const itemIndex = checkList.value.findIndex(item => item.id === id)
  98. if (itemIndex !== -1) {
  99. setTimeout(() => {
  100. checkList.value[itemIndex].result = status.value[['xAxisAtOrigin', 'yAxisAtOrigin', 'zAxisAtOrigin'][itemIndex]] ? 'success' : 'failed'
  101. resolve() // 解析 Promise,表示当前数据已完全展示
  102. }, Math.random() * 200) // 修改为随机数延时
  103. }
  104. }
  105. }, Math.random() * 100) // 修改为随机数延时
  106. })
  107. }
  108. </script>
  109. <template>
  110. <FtDialog visible title="自检" width="40%" @ok="okHandle" @cancel="cancel">
  111. <div v-for="item in checkList" :key="item.id" class="mask-box">
  112. <el-tag> {{ item.title }}</el-tag>
  113. <el-icon v-show="item.result === 'success'" color="green">
  114. <SuccessFilled />
  115. </el-icon>
  116. <el-icon v-show="item.result === 'failed'" color="red">
  117. <CircleCloseFilled />
  118. </el-icon>
  119. <el-icon v-show="item.result === 'padding'" color="gray" class="el-icon--loading">
  120. <Loading />
  121. </el-icon>
  122. </div>
  123. <template #footer>
  124. <ft-button v-if="closeVisible" ref="buttonCloseRef" @click="cancel">
  125. 关闭
  126. </ft-button>
  127. <ft-button v-else ref="buttonRef" type="primary" @click="motorXYZOrigin">
  128. 回原点
  129. </ft-button>
  130. </template>
  131. </FtDialog>
  132. </template>
  133. <style scoped lang="scss">
  134. .mask-box {
  135. display: flex;
  136. font-size: 35px;
  137. align-items: center;
  138. margin-bottom: 40px;
  139. .el-tag {
  140. margin-right: 20px;
  141. width: 100%;
  142. }
  143. }
  144. // 添加旋转动画
  145. @keyframes spin {
  146. 0% {
  147. transform: rotate(0deg);
  148. }
  149. 100% {
  150. transform: rotate(360deg);
  151. }
  152. }
  153. .el-icon.el-icon--loading {
  154. animation: spin 1s linear infinite; // 确保 Loading 图标应用 spin 动画
  155. }
  156. :deep(.el-tag) {
  157. padding: 30px 0;
  158. }
  159. </style>