AgriculturalInteractionCard.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <template>
  2. <!-- 只封装时间轴区域 -->
  3. <div class="timeline">
  4. <div class="timeline-item" v-for="timelineItem in item.timelineList" :key="timelineItem.id">
  5. <div class="timeline-left">
  6. <div class="dot"></div>
  7. <div class="line"></div>
  8. </div>
  9. <div class="timeline-right">
  10. <div class="date">
  11. <span class="work-name">{{ timelineItem.farmWorkName }}</span>
  12. <!-- <span v-show="timelineItem.expectedRisk">({{ timelineItem.expectedRisk }})</span> -->
  13. <span class="ignore-btn" v-if="hasPlanPermission" @click="handleIgnore(item,timelineItem)"> 忽略 </span>
  14. </div>
  15. <div class="text">
  16. 预计报价<span class="price">{{ timelineItem.estimatedCost }}元</span>
  17. <span class="action-detail" @click="toDetail(timelineItem, item)"
  18. >查看详情</span
  19. >
  20. <!-- <span class="action-detail" @click="showPriceSheetPopup(timelineItem.farmWorkId, item)">查看报价单</span> -->
  21. </div>
  22. </div>
  23. <div class="timeline-action" @click="handleTimelineAction(timelineItem, item.farmId)">转入农事任务</div>
  24. </div>
  25. </div>
  26. <!-- 新增:激活上传弹窗 -->
  27. <active-upload-popup ref="activeUploadPopupRef" @handleUploadSuccess="handleUploadSuccess"></active-upload-popup>
  28. <!-- 服务报价单 -->
  29. <price-sheet-popup ref="priceSheetPopupRef"></price-sheet-popup>
  30. <popup v-model:show="showTaskPopup" round class="task-tips-popup">
  31. <img class="create-farm-icon" src="@/assets/img/home/create-farm-icon.png" alt="" />
  32. <div class="create-farm-text">
  33. <div>
  34. 您确认忽略 <span class="main-text">{{ currentTask?.farmName }}</span> 的
  35. <span class="main-text">{{ currentTask?.farmWorkName }}</span> 农事吗
  36. </div>
  37. </div>
  38. <div class="create-farm-btn" @click="handlePopupBtn">确认忽略</div>
  39. </popup>
  40. </template>
  41. <script setup>
  42. import { Popup } from "vant";
  43. import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
  44. import priceSheetPopup from "@/components/popup/priceSheetPopup.vue";
  45. import { computed, onMounted, ref } from "vue";
  46. import { ElMessage } from "element-plus";
  47. import { useRouter } from "vue-router";
  48. const router = useRouter();
  49. const props = defineProps({
  50. item: {
  51. type: Object,
  52. required: true,
  53. default: () => ({}),
  54. },
  55. });
  56. // 检查是否有"转入农事"权限
  57. const hasPlanPermission = computed(() => {
  58. try {
  59. const userInfoStr = localStorage.getItem("localUserInfo");
  60. if (!userInfoStr) return false;
  61. const userInfo = JSON.parse(userInfoStr);
  62. const permissions = userInfo.agriculturalPermissions || [];
  63. return permissions.includes("转入农事");
  64. } catch (error) {
  65. console.error("解析用户信息失败:", error);
  66. return false;
  67. }
  68. });
  69. const executorList = ref(JSON.parse(sessionStorage.getItem("executorList")) || []);
  70. const activeUploadPopupRef = ref(null);
  71. const handleTimelineAction = (timelineItem, farmId) => {
  72. if (hasPlanPermission.value) {
  73. activeUploadPopupRef.value.showPopup({
  74. gardenIdVal: farmId,
  75. needExecutorVal: true,
  76. problemTitleVal: "请选择 " + timelineItem.farmWorkName + " 执行截止时间",
  77. imgDescVal: "请上传凭证(转入农事任务凭证)",
  78. arrangeIdVal: timelineItem.arrangeId,
  79. executorListVal: executorList.value || [],
  80. farmWorkIdVal: timelineItem.farmWorkId,
  81. schemeIdVal: timelineItem.schemeId,
  82. });
  83. } else {
  84. ElMessage.warning("您暂无权限操作");
  85. }
  86. };
  87. const emits = defineEmits(["updateList"]);
  88. const handleUploadSuccess = async () => {
  89. emits("updateList");
  90. };
  91. const toDetail = (timelineItem, item) => {
  92. console.log(timelineItem, item);
  93. router.push({
  94. path: "/detail_work",
  95. query: { miniJson: JSON.stringify({ id: timelineItem.farmWorkId, arrangeId: timelineItem.arrangeId, farmId: item.farmId, }), },
  96. });
  97. };
  98. // 忽略农事库
  99. const currentTask = ref(null);
  100. const showTaskPopup = ref(false);
  101. const handleIgnore = (item, timelineItem) => {
  102. currentTask.value = { ...item, ...timelineItem };
  103. showTaskPopup.value = true;
  104. };
  105. const handlePopupBtn = () => {
  106. VE_API.home.ignoreFarmWorkLib({ farmWorkLibId: currentTask.value.farmWorkId }).then(({ code }) => {
  107. if (code === 0) {
  108. showTaskPopup.value = false;
  109. ElMessage.success("忽略成功");
  110. handleUploadSuccess();
  111. }
  112. });
  113. };
  114. const priceSheetPopupRef = ref(null);
  115. const showPriceSheetPopup = (id, item) => {
  116. priceSheetPopupRef.value.handleShowPopup({ id, farmId: item.farmId, agriculturalId: item.agriculturalStoreId });
  117. };
  118. </script>
  119. <style scoped lang="scss">
  120. .timeline {
  121. margin-left: -5px;
  122. margin-top: 8px;
  123. .timeline-item {
  124. display: flex;
  125. align-items: flex-start;
  126. font-size: 14px;
  127. color: #ffffff;
  128. line-height: 22px;
  129. & + .timeline-item {
  130. margin-top: 10px;
  131. }
  132. .timeline-left {
  133. width: 22px;
  134. display: flex;
  135. flex-direction: column;
  136. align-items: center;
  137. .dot {
  138. width: 6px;
  139. height: 6px;
  140. border-radius: 50%;
  141. background: #a2d5fd;
  142. margin-top: 6px;
  143. }
  144. .line {
  145. border-left: 1px dashed #a2d5fd;
  146. margin-top: 4px;
  147. height: 28px;
  148. }
  149. }
  150. .timeline-right {
  151. padding-left: 5px;
  152. flex: 1;
  153. .date {
  154. color: #1d2129;
  155. font-weight: 500;
  156. font-size: 14px;
  157. line-height: 22px;
  158. }
  159. .text {
  160. font-size: 12px;
  161. color: #d7d7d7;
  162. .price {
  163. padding-left: 4px;
  164. }
  165. .action-detail {
  166. margin-left: 6px;
  167. color: #2199f8;
  168. border-bottom: 1px solid;
  169. }
  170. }
  171. .work-name {
  172. padding-left: 4px;
  173. }
  174. .ignore-btn {
  175. margin-left: 6px;
  176. color: rgba(29, 33, 41, 0.4);
  177. font-size: 13px;
  178. }
  179. }
  180. .timeline-action {
  181. align-self: center;
  182. height: 28px;
  183. line-height: 28px;
  184. flex: none;
  185. background: rgba(33, 153, 248, 0.1);
  186. color: #2199f8;
  187. font-size: 12px;
  188. padding: 0px 11px;
  189. border-radius: 20px;
  190. }
  191. }
  192. }
  193. .task-tips-popup {
  194. z-index: 1000 !important;
  195. width: 90%;
  196. padding: 28px 28px 20px;
  197. display: flex;
  198. flex-direction: column;
  199. align-items: center;
  200. justify-content: center;
  201. .create-farm-icon {
  202. width: 52px;
  203. height: 52px;
  204. margin-bottom: 12px;
  205. }
  206. .create-farm-text {
  207. font-size: 19px;
  208. font-weight: 500;
  209. margin-bottom: 32px;
  210. text-align: center;
  211. }
  212. .main-text {
  213. color: #2199f8;
  214. }
  215. .create-farm-btn {
  216. width: 100%;
  217. box-sizing: border-box;
  218. padding: 8px;
  219. border-radius: 25px;
  220. font-size: 16px;
  221. background: #2199f8;
  222. color: #fff;
  223. text-align: center;
  224. }
  225. }
  226. </style>