agriculturalDetail.vue 4.5 KB

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