index.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <template>
  2. <div class="entry-information-page" :class="{ 'is-dark-step': isDarkStep }">
  3. <custom-header
  4. name="录入信息"
  5. bgColor="#fff"
  6. :isClose="hideBack"
  7. :showClose="false"
  8. ></custom-header>
  9. <div class="entry-information-body">
  10. <service-information v-if="currentStep === 1 && isServiceEntry" @next="handleNext" />
  11. <ba-information v-else-if="currentStep === 1" @next="handleNext" />
  12. <select-category v-else-if="currentStep === 2" :multiple="isServiceEntry" @prev="handlePrev" @next="handleNext" />
  13. <select-equipment
  14. v-else-if="showEquipmentStep"
  15. :key="equipmentScope || 'farmer'"
  16. :is-service="isServiceEntry"
  17. :is-last-step="equipmentIsLastStep"
  18. :equipment-scope="equipmentScope"
  19. :total-steps="totalSteps"
  20. @prev="handlePrev"
  21. @next="handleNext"
  22. @confirm="handleConfirm"
  23. />
  24. <manual-farming-service
  25. v-else-if="showManualStep"
  26. :has-field="hasFieldSelected"
  27. :has-fruit="hasFruitSelected"
  28. @prev="handlePrev"
  29. @next="handleNext"
  30. @confirm="handleConfirm"
  31. />
  32. </div>
  33. </div>
  34. </template>
  35. <script setup>
  36. import { computed, onActivated, onMounted, ref, watch } from "vue";
  37. import { useRoute, useRouter } from "vue-router";
  38. import customHeader from "@/components/customHeader.vue";
  39. import baInformation from "./components/baInformation.vue";
  40. import serviceInformation from "./components/serviceInformation.vue";
  41. import selectCategory from "./components/selectCategory.vue";
  42. import selectEquipment from "./components/selectEquipment.vue";
  43. import manualFarmingService from "./components/manualFarmingService.vue";
  44. const STEP_KEY = "ENTRY_INFORMATION_STEP";
  45. const INVITE_TYPE_KEY = "ENTRY_INVITE_TYPE";
  46. const CATEGORY_SESSION_KEY = "ENTRY_SELECTED_CATEGORY";
  47. const ADMIN_ID_KEY = "ENTRY_ADMIN_ID";
  48. const router = useRouter();
  49. const route = useRoute();
  50. /** 无农场从登录页进入时隐藏返回箭头 */
  51. const hideBack = computed(
  52. () => route.query.isClose === "1" || route.query.isClose === "true"
  53. );
  54. function readStep() {
  55. const step = Number(sessionStorage.getItem(STEP_KEY));
  56. return step >= 1 && step <= 5 ? step : 1;
  57. }
  58. function readInviteType() {
  59. const fromQuery = route.query.inviteType;
  60. if (fromQuery === "service" || fromQuery === "farmer") {
  61. sessionStorage.setItem(INVITE_TYPE_KEY, fromQuery);
  62. return fromQuery;
  63. }
  64. return sessionStorage.getItem(INVITE_TYPE_KEY) || "farmer";
  65. }
  66. function syncAdminIdFromQuery() {
  67. const fromQuery = route.query.adminId;
  68. if (fromQuery != null && fromQuery !== "") {
  69. sessionStorage.setItem(ADMIN_ID_KEY, String(fromQuery));
  70. }
  71. }
  72. const currentStep = ref(readStep());
  73. const inviteType = ref(readInviteType());
  74. const isServiceEntry = computed(() => inviteType.value === "service");
  75. /** 农户录入:位置确认 / 作物品种页为深色 */
  76. const isDarkStep = computed(
  77. () => !isServiceEntry.value && (currentStep.value === 1 || currentStep.value === 2)
  78. );
  79. const hasFieldSelected = ref(false);
  80. const hasFruitSelected = ref(false);
  81. const isBothCrops = computed(() => hasFieldSelected.value && hasFruitSelected.value);
  82. /** 农户:位置 → 作物+品种 → 设备(共 3 步) */
  83. const totalSteps = computed(() => {
  84. if (!isServiceEntry.value) return 3;
  85. return isBothCrops.value ? 6 : 4;
  86. });
  87. const maxStep = computed(() => {
  88. if (!isServiceEntry.value) return 3;
  89. return isBothCrops.value ? 5 : 4;
  90. });
  91. const showEquipmentStep = computed(() => {
  92. if (!isServiceEntry.value) return currentStep.value === 3;
  93. if (hasFieldSelected.value && currentStep.value === 3) return true;
  94. if (isBothCrops.value && currentStep.value === 5) return true;
  95. if (hasFruitSelected.value && !hasFieldSelected.value && currentStep.value === 4) return true;
  96. return false;
  97. });
  98. const equipmentScope = computed(() => {
  99. if (!isServiceEntry.value) return "";
  100. if (!hasFieldSelected.value) return "fruit";
  101. return currentStep.value === 5 ? "fruit" : "field";
  102. });
  103. const equipmentIsLastStep = computed(() => {
  104. if (!isServiceEntry.value) return true;
  105. return equipmentScope.value === "fruit";
  106. });
  107. const showManualStep = computed(() => {
  108. if (!isServiceEntry.value) return false;
  109. if (hasFieldSelected.value) return currentStep.value === 4;
  110. return hasFruitSelected.value && currentStep.value === 3;
  111. });
  112. function refreshHasField() {
  113. try {
  114. const list = JSON.parse(sessionStorage.getItem(CATEGORY_SESSION_KEY) || "[]");
  115. const items = Array.isArray(list) ? list : [];
  116. hasFieldSelected.value = items.some(
  117. (item) => item?.firstCrop === "大田" || item?.majorKey === "field"
  118. );
  119. hasFruitSelected.value = items.some(
  120. (item) => item?.firstCrop === "果树" || item?.majorKey === "fruit"
  121. );
  122. } catch {
  123. hasFieldSelected.value = false;
  124. hasFruitSelected.value = false;
  125. }
  126. }
  127. function clampStep() {
  128. if (currentStep.value > maxStep.value) {
  129. currentStep.value = maxStep.value;
  130. }
  131. }
  132. function syncEntryState() {
  133. inviteType.value = readInviteType();
  134. syncAdminIdFromQuery();
  135. currentStep.value = readStep();
  136. refreshHasField();
  137. clampStep();
  138. }
  139. onMounted(syncEntryState);
  140. onActivated(syncEntryState);
  141. watch(
  142. currentStep,
  143. (step) => {
  144. sessionStorage.setItem(STEP_KEY, String(step));
  145. },
  146. { immediate: true }
  147. );
  148. const handleNext = () => {
  149. refreshHasField();
  150. if (isServiceEntry.value && hasFieldSelected.value && currentStep.value === 3) {
  151. sessionStorage.removeItem("ENTRY_MANUAL_VIEW");
  152. }
  153. if (currentStep.value < maxStep.value) {
  154. currentStep.value += 1;
  155. }
  156. };
  157. const handlePrev = () => {
  158. if (currentStep.value > 1) {
  159. currentStep.value -= 1;
  160. }
  161. };
  162. const handleConfirm = () => {
  163. router.replace("/growth_report");
  164. };
  165. </script>
  166. <style lang="scss" scoped>
  167. .entry-information-page {
  168. height: 100vh;
  169. background: linear-gradient(270deg, rgba(218, 195, 255, 0.59) 0%, #E6F2FF 0.01%, #8FC5FE 100%);
  170. display: flex;
  171. flex-direction: column;
  172. &.is-dark-step {
  173. background: #0f0f0f;
  174. }
  175. }
  176. .entry-information-body {
  177. height: 100%;
  178. display: flex;
  179. flex-direction: column;
  180. overflow: hidden;
  181. }
  182. </style>