droneConsultPopup.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <popup v-model:show="showValue" round class="drone-consult-popup" :close-on-click-overlay="true" teleport="body">
  3. <div class="popup-content">
  4. <!-- 无人机咨询:飞鸟购买 -->
  5. <template v-if="type === 'droneConsult'">
  6. <div class="top-text">{{ $t('未监测您果园有配套的无人机,您可咨询飞鸟购买') }}</div>
  7. <div class="code-wrap">
  8. <img class="code-img" src="@/assets/img/home/qrcode.png" alt="">
  9. </div>
  10. <div class="hint-bubble">{{ $t('长按可添加客服,咨询相关问题') }}</div>
  11. <div class="action-btn" @click="handleCopy">{{ $t('一键复制微信号') }}</div>
  12. </template>
  13. <!-- 地形/建模航线 -->
  14. <template v-else-if="type === 'terrainRoute'">
  15. <div class="top-text">
  16. <div>{{ $t('需要获取精细的地形信息才可以规划航') }}</div>
  17. <div>{{ $t('线,点击获取建模航线') }}</div>
  18. </div>
  19. <div class="action-btn" @click="handleConfirm">{{ $t('立即获取') }}</div>
  20. </template>
  21. <!-- 航线已生成(兼容图片 UI:中间区域不展示,仅文案 + 我知道了) -->
  22. <template v-else-if="type === 'terrainRouteSuccess'">
  23. <div class="top-text">{{ $t('果园三维建模航线已经生成,航线已经推送到遥控器上,请您按照规划的航线起飞即可') }}</div>
  24. <div class="video-wrap"></div>
  25. <div class="action-btn" @click="handleConfirm">{{ $t('我知道了') }}</div>
  26. </template>
  27. </div>
  28. </popup>
  29. </template>
  30. <script setup>
  31. import { Popup } from "vant";
  32. import { computed } from "vue";
  33. const props = defineProps({
  34. show: {
  35. type: Boolean,
  36. default: false,
  37. },
  38. /** 弹窗类型:droneConsult 无人机咨询 | terrainRoute 地形/建模航线 | terrainRouteSuccess 航线已生成(兼容图片 UI,中间区域不展示) */
  39. type: {
  40. type: String,
  41. default: "droneConsult",
  42. },
  43. /** 要复制的微信号(仅 type=droneConsult 时有效),不传则复制默认客服号 */
  44. wechatId: {
  45. type: String,
  46. default: "",
  47. },
  48. });
  49. const emit = defineEmits(["update:show", "copy", "confirm"]);
  50. const showValue = computed({
  51. get: () => props.show,
  52. set: (value) => emit("update:show", value),
  53. });
  54. const handleCopy = async () => {
  55. const id = props.wechatId || "feiniao-kefu";
  56. try {
  57. await navigator.clipboard.writeText(id);
  58. emit("copy", id);
  59. emit("update:show", false);
  60. } catch (e) {
  61. console.error("复制失败", e);
  62. emit("copy", id);
  63. emit("update:show", false);
  64. }
  65. };
  66. const handleConfirm = () => {
  67. emit("confirm");
  68. emit("update:show", false);
  69. };
  70. </script>
  71. <style scoped lang="scss">
  72. .drone-consult-popup {
  73. width: 89%;
  74. padding: 20px 16px;
  75. .popup-content {
  76. display: flex;
  77. flex-direction: column;
  78. align-items: center;
  79. }
  80. .top-text {
  81. font-size: 16px;
  82. color: #333;
  83. text-align: left;
  84. line-height: 1.6;
  85. margin-bottom: 20px;
  86. width: 100%;
  87. }
  88. .code-wrap{
  89. width: 186px;
  90. height: 186px;
  91. background: #f5f5f5;
  92. border-radius: 4px;
  93. border: 0.86px solid rgba(33, 153, 248, 0.2);
  94. background: rgba(33, 153, 248, 0.04);
  95. display: flex;
  96. align-items: center;
  97. justify-content: center;
  98. .code-img{
  99. width: 176px;
  100. height: 176px;
  101. object-fit: cover;
  102. }
  103. }
  104. .hint-bubble {
  105. padding: 12px;
  106. color: #2199f8;
  107. background: rgba(33, 153, 248, 0.1);
  108. padding: 3px 9px 9px;
  109. border-radius: 8px;
  110. position: relative;
  111. margin-top: 5px;
  112. margin: 16px 0;
  113. // 三角形小尖尖
  114. &::before {
  115. content: "";
  116. position: absolute;
  117. top: -8px;
  118. left: 20px;
  119. width: 0;
  120. height: 0;
  121. border-left: 15px solid transparent;
  122. border-right: 2px solid transparent;
  123. border-bottom: 8px solid rgba(33, 153, 248, 0.1);
  124. }
  125. }
  126. .video-wrap{
  127. width: 100%;
  128. height: 220px;
  129. background: rgba(33, 153, 248, 0.05);
  130. border-radius: 5px;
  131. border: 1px solid rgba(33, 153, 248, 0.2);
  132. margin-bottom: 16px;
  133. }
  134. .action-btn {
  135. width: 100%;
  136. box-sizing: border-box;
  137. font-size: 16px;
  138. background: #2199f8;
  139. color: #fff;
  140. text-align: center;
  141. padding: 8px;
  142. border-radius: 4px;
  143. }
  144. .top-text > div {
  145. margin-bottom: 0;
  146. }
  147. }
  148. </style>