index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <List key="id" :data="list" class="scene-list">
  3. <template #action>
  4. <slot name="action" />
  5. </template>
  6. <template #atom="{ item }">
  7. <div
  8. v-if="item.raw === fuseModel"
  9. @click="updateCurrent(item.raw)"
  10. class="all-scene-model-list"
  11. >
  12. <ModelList
  13. :class="{ active: current === fuseModel }"
  14. :title="getModelTypeDesc(fuseModel as any)"
  15. :show-content="showModelList"
  16. >
  17. <template #action>
  18. <ui-icon
  19. :type="`pull-${showModelList ? 'up' : 'down'}`"
  20. @click="showModelList = !showModelList"
  21. ctrl
  22. />
  23. </template>
  24. </ModelList>
  25. </div>
  26. <div
  27. class="scene"
  28. :class="{ disabled: item.raw.status !== SceneStatus.SUCCESS }"
  29. @click="updateCurrent(item.raw)"
  30. v-else
  31. >
  32. <div>
  33. <p>{{ item.raw.name }}</p>
  34. <p>
  35. {{ SceneTypeDesc[item.raw.type as SceneType] }}
  36. </p>
  37. </div>
  38. <Button
  39. size="small"
  40. type="primary"
  41. ghost
  42. style="float: right"
  43. v-if="canSync(item as Scene) && !voffline && currentLayout === RoutesName.show"
  44. @click.stop="sync(item as Scene)"
  45. >
  46. 同屏勘验
  47. </Button>
  48. </div>
  49. </template>
  50. </List>
  51. </template>
  52. <script lang="ts" setup>
  53. import { computed, nextTick, ref, watch } from "vue";
  54. import {
  55. scenes,
  56. SceneType,
  57. SceneTypeDesc,
  58. fuseModels,
  59. SceneStatus,
  60. getSWKKSyncLink,
  61. caseProject,
  62. } from "@/store";
  63. import List from "@/components/list/index.vue";
  64. import ModelList from "../model-list/index.vue";
  65. import { fuseModel, getModelTypeDesc } from "@/model";
  66. import { Button } from "ant-design-vue";
  67. import type { ModelType, FuseModelType } from "@/model";
  68. import type { Scene } from "@/store";
  69. import { currentLayout, RoutesName } from "@/router";
  70. const emit = defineEmits<{ (e: "update:current", data: ModelType): void }>();
  71. const props = defineProps<{ current: ModelType }>();
  72. const showModelList = ref(true);
  73. const voffline = offline;
  74. const canSync = (scene: Scene) =>
  75. [SceneType.SWKK, SceneType.SWKJ, SceneType.SWSSMX, SceneType.SWYDMX].includes(
  76. scene.raw.type
  77. );
  78. const sync = async (scene: Scene) => {
  79. const link = await getSWKKSyncLink(scene);
  80. window.open(link);
  81. };
  82. const list = computed(() => {
  83. const sceneList = true
  84. ? scenes.value.map((scene) => ({
  85. raw: scene,
  86. select:
  87. props.current !== fuseModel &&
  88. props.current.num === scene.num &&
  89. props.current.type === scene.type,
  90. }))
  91. : [];
  92. if (fuseModels.value.length) {
  93. return [{ raw: fuseModel }, ...sceneList];
  94. } else {
  95. return sceneList;
  96. }
  97. });
  98. const updateCurrent = (scene: FuseModelType | Scene) => {
  99. if (scene === fuseModel) {
  100. emit("update:current", scene);
  101. } else {
  102. emit("update:current", { type: scene.type, num: scene.num });
  103. }
  104. };
  105. const stopWatch = watch(
  106. list,
  107. () => {
  108. if (!list.value.some((model) => model.raw === fuseModel) && list.value.length) {
  109. updateCurrent(list.value[0].raw as any);
  110. nextTick(() => stopWatch());
  111. }
  112. },
  113. { immediate: true }
  114. );
  115. </script>
  116. <style lang="scss">
  117. .scene-list > .content > li {
  118. padding: 0 !important;
  119. }
  120. .scene {
  121. padding: 0 20px;
  122. display: flex;
  123. align-items: center;
  124. justify-content: space-between;
  125. > div {
  126. flex: 1;
  127. }
  128. p {
  129. height: 1.5em;
  130. overflow: hidden;
  131. text-overflow: ellipsis;
  132. word-break: keep-all;
  133. line-height: 1.5em;
  134. }
  135. }
  136. .all-scene-model-list .scene-model-list {
  137. margin-bottom: -20px;
  138. margin-top: -20px;
  139. .header {
  140. padding: 30px 20px 20px;
  141. h3 {
  142. font-size: 20px;
  143. font-weight: bold;
  144. color: #ffffff;
  145. }
  146. }
  147. &.active .header {
  148. background-color: rgba(0, 200, 175, 0.16);
  149. }
  150. .content li:last-child .atom-content {
  151. border: none;
  152. }
  153. }
  154. </style>