agriculturalDetail.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <div class="agricultural-detail">
  3. <custom-header name="农事详情"></custom-header>
  4. <div class="detail-content">
  5. <!-- 采样信息卡片 -->
  6. <div class="card-wrap">
  7. <div class="card-box sampling-card">
  8. <div class="sampling-title">采样时间: {{ imgInfo.samplingTime }}</div>
  9. <div class="sampling-desc">本次采样{{ imgInfo.regions }},拍摄了 {{ imgInfo.total }} 棵树</div>
  10. </div>
  11. </div>
  12. <!-- 农情照片卡片 -->
  13. <div class="card-wrap">
  14. <div class="card-box photo-card">
  15. <div class="card-title">农情照片</div>
  16. <div class="ratio-tip">{{ route.query.content }}</div>
  17. <div class="photo-grid">
  18. <div
  19. v-for="(photo, index) in imgInfo.imageList"
  20. :key="photo.id"
  21. class="photo-item"
  22. @click="handlePhotoClick(index)"
  23. >
  24. <img :src="photo.url" alt="农情照片" />
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. </template>
  32. <script setup>
  33. import { useRoute } from "vue-router";
  34. import { ref, onActivated, computed } from "vue";
  35. import customHeader from "@/components/customHeader.vue";
  36. import { showImagePreview } from 'vant';
  37. const route = useRoute();
  38. const previewImages = computed(() => {
  39. const list = imgInfo.value?.imageList || [];
  40. return list.map((item) => item?.url).filter(Boolean);
  41. });
  42. const handlePhotoClick = (index) => {
  43. const images = previewImages.value;
  44. const safeIndex = Math.min(Math.max(Number(index) || 0, 0), Math.max(images.length - 1, 0));
  45. showImagePreview({
  46. images,
  47. startPosition: safeIndex,
  48. closeable: true,
  49. showIndex: true,
  50. });
  51. };
  52. onActivated(() => {
  53. getFarmImagePage();
  54. });
  55. const imgInfo = ref({});
  56. const getFarmImagePage = () => {
  57. VE_API.monitor.getFarmImagePage({
  58. id: route.query.id
  59. }).then((res) => {
  60. if (res.code === 0) {
  61. imgInfo.value = res.data;
  62. }
  63. });
  64. };
  65. </script>
  66. <style lang="scss" scoped>
  67. .agricultural-detail {
  68. min-height: 100vh;
  69. width: 100%;
  70. background: #f2f3f5;
  71. .detail-content {
  72. padding: 12px;
  73. padding-bottom: 24px;
  74. box-sizing: border-box;
  75. .card-wrap {
  76. margin-bottom: 12px;
  77. .card-box {
  78. background: #fff;
  79. border-radius: 8px;
  80. padding: 12px 16px;
  81. box-sizing: border-box;
  82. }
  83. .sampling-card {
  84. .sampling-title {
  85. font-size: 16px;
  86. font-weight: 500;
  87. color: #333;
  88. margin-bottom: 6px;
  89. }
  90. .sampling-desc {
  91. font-size: 14px;
  92. color: rgba(0, 0, 0, 0.5);
  93. }
  94. }
  95. .photo-card {
  96. .card-title {
  97. font-size: 16px;
  98. font-weight: bold;
  99. color: #333;
  100. margin-bottom: 12px;
  101. }
  102. .ratio-tip {
  103. font-size: 14px;
  104. color: #2199f8;
  105. padding: 10px 12px;
  106. background: rgba(33, 153, 248, 0.08);
  107. border-radius: 8px;
  108. }
  109. .photo-grid {
  110. margin-top: 12px;
  111. display: grid;
  112. grid-template-columns: repeat(4, 1fr);
  113. grid-gap: 6px;
  114. .photo-item {
  115. position: relative;
  116. width: 100%;
  117. padding-bottom: 100%;
  118. border-radius: 8px;
  119. overflow: hidden;
  120. background: #e5f5e5;
  121. img {
  122. position: absolute;
  123. inset: 0;
  124. width: 100%;
  125. height: 100%;
  126. object-fit: cover;
  127. display: block;
  128. }
  129. }
  130. }
  131. }
  132. }
  133. }
  134. }
  135. .image-popup {
  136. width: 327px;
  137. border-radius: 8px;
  138. .popup-content {
  139. width: 100%;
  140. }
  141. }
  142. </style>