index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <template>
  2. <div class="home-index" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
  3. <div class="banner-wrap" @click="handleBannerClick">
  4. <img class="banner-img" :src="bannerObj?.media?.[0]" alt="" />
  5. <div class="banner-title">
  6. <span class="van-multi-ellipsis--l2">{{ bannerObj?.title }}</span>
  7. </div>
  8. </div>
  9. <!-- 天气遮罩 -->
  10. <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
  11. <!-- 天气 -->
  12. <weather-info
  13. ref="weatherInfoRef"
  14. class="weather-info"
  15. @weatherExpanded="weatherExpanded"
  16. :isGarden="false"
  17. @changeGarden="changeGarden"
  18. ></weather-info>
  19. <div class="farm-monitor-container" :class="{ 'farmer-role': userType == 2 }">
  20. <div class="farm-monitor-left" @click="handleCardClick(monitorCards.left)">
  21. <div class="title">
  22. <span>{{ monitorCards.left.title }}</span>
  23. <el-icon class="icon" v-if="userType == 2"><ArrowRightBold /></el-icon>
  24. </div>
  25. <div class="content">{{ monitorCards.left.content }}</div>
  26. <div class="arrow" v-if="userType != 2">
  27. <el-icon class="icon"><ArrowRightBold /></el-icon>
  28. </div>
  29. </div>
  30. <div class="farm-monitor-right">
  31. <div
  32. v-for="(item, index) in monitorCards.right"
  33. :key="index"
  34. class="right-item"
  35. :class="{ expert: index === 1 }"
  36. @click="handleCardClick(item)"
  37. >
  38. <div class="title">
  39. <span>{{ item.title }}</span>
  40. <el-icon class="icon"><ArrowRightBold /></el-icon>
  41. </div>
  42. <div class="content">{{ item.content }}</div>
  43. </div>
  44. </div>
  45. </div>
  46. <template v-if="userType == 2">
  47. <knowledge-card />
  48. </template>
  49. <template v-else>
  50. <AgriculturalDynamics />
  51. </template>
  52. </div>
  53. <tip-popup
  54. v-model:show="showTipPopup"
  55. type="warning"
  56. text="请设置"
  57. highlightText="种植方案"
  58. buttonText="去设置"
  59. @confirm="handleBtn"
  60. :closeOnClickOverlay="false"
  61. :zIndex="9999"
  62. />
  63. </template>
  64. <script setup>
  65. import { ref, computed, onActivated, onMounted } from "vue";
  66. import { useStore } from "vuex";
  67. import weatherInfo from "@/components/weatherInfo.vue";
  68. import AgriculturalDynamics from "./components/AgriculturalDynamics.vue";
  69. import { useRouter, useRoute } from "vue-router";
  70. import wx from "weixin-js-sdk";
  71. import tipPopup from "@/components/popup/tipPopup.vue";
  72. import knowledgeCard from "./components/knowledgeCard.vue";
  73. const store = useStore();
  74. const tabBarHeight = computed(() => store.state.home.tabBarHeight);
  75. const router = useRouter();
  76. const route = useRoute();
  77. const showTipPopup = ref(false);
  78. const handleBtn = () => {
  79. router.push("/plan?pageType=plant&headerTitle=请设置您的种植方案");
  80. };
  81. //判断是否存在可用方案
  82. async function checkExistsEnabledScheme() {
  83. const { data } = await VE_API.home.existsEnabledScheme({containerId:null});
  84. if(!data && localStorage.getItem("SET_USER_CUR_ROLE") == 2) {
  85. showTipPopup.value = true;
  86. }
  87. }
  88. const gardenId = ref(null);
  89. const isGarden = ref(false);
  90. const changeGarden = ({ id }) => {
  91. gardenId.value = id;
  92. getExpertByFarmId();
  93. };
  94. const expertInfo = ref({});
  95. const getExpertByFarmId = () => {
  96. VE_API.home.getExpertByFarmId({ farmId: gardenId.value }).then(({ data }) => {
  97. expertInfo.value = data || {};
  98. sessionStorage.setItem("expertId", data.appUserId);
  99. });
  100. };
  101. // 监测卡片数据
  102. const monitorCards = ref({
  103. left: {
  104. title: "农情采集",
  105. content: "精准监测 科学决策",
  106. route: "/pest",
  107. },
  108. right: [
  109. {
  110. title: "病虫识别",
  111. content: "智能识别 快速诊断",
  112. route: "/pest",
  113. },
  114. // {
  115. // title: "新增客户",
  116. // content: "农情先知 高效管理",
  117. // route: "/create_farm?type=client&isReload=true&from=home",
  118. // },
  119. ],
  120. });
  121. // 卡片点击事件
  122. const handleCardClick = (card) => {
  123. const dropdownGardenItem = ref({
  124. organId: 766,
  125. periodId: 1,
  126. name: "荔博园",
  127. });
  128. if (card.title === "农情采集") {
  129. dropdownGardenItem.value.page = "create_farm";
  130. wx.miniProgram.navigateTo({
  131. url: `/pages/subPages/new_recognize/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
  132. });
  133. } else if (card.title === "病虫识别") {
  134. dropdownGardenItem.value.page = "album_recognize";
  135. wx.miniProgram.navigateTo({
  136. url: `/pages/subPages/new_recognize/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
  137. });
  138. } else {
  139. router.push(card.route);
  140. }
  141. };
  142. onActivated(() => {
  143. getManagerList();
  144. checkExistsEnabledScheme()
  145. getBannerList();
  146. isGarden.value = Boolean(localStorage.getItem("isGarden"));
  147. // 检测是否从创建农场页面成功返回
  148. if (route.query.showSuccess === "true") {
  149. // 清除URL参数,避免刷新页面时再次显示弹窗
  150. router.replace({
  151. path: "/home",
  152. query: { reload: route.query.reload },
  153. });
  154. }
  155. });
  156. const userType = ref(localStorage.getItem("USER_TYPE"));
  157. onMounted(() => {
  158. if (userType.value != 2) {
  159. monitorCards.value.right.push({
  160. title: "新增客户",
  161. content: "农情先知 高效管理",
  162. route: "/create_farm?type=client&isReload=true&from=home",
  163. });
  164. }
  165. });
  166. // 查询当前农资店的成员列表(只保留有"任务接单"权限的成员)
  167. const getManagerList = async () => {
  168. const { data } = await VE_API.mine.listManagerList({ onlyExecutor: true });
  169. if (data && data.length > 0) {
  170. // 过滤 permissionList 中包含"任务接单"的成员,并过滤掉超管(role为1)
  171. const executorList = data.filter((item) => item.role !== 1);
  172. sessionStorage.setItem("executorList", JSON.stringify(executorList));
  173. }
  174. };
  175. const bannerObj = ref({});
  176. const getBannerList = () => {
  177. const params = {
  178. page: 1,
  179. limit: 1,
  180. topicId: 5,
  181. };
  182. VE_API.home.warningPageList(params).then(({ data }) => {
  183. bannerObj.value = data[0] || {};
  184. });
  185. };
  186. const isExpanded = ref(false);
  187. const weatherInfoRef = ref(null);
  188. const weatherExpanded = (isExpandedValue) => {
  189. isExpanded.value = isExpandedValue;
  190. };
  191. // 点击遮罩时收起天气
  192. const handleMaskClick = () => {
  193. if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
  194. weatherInfoRef.value.toggleExpand();
  195. }
  196. };
  197. const handleBannerClick = () => {
  198. router.push(`/warning_detail?id=${bannerObj.value.id}`);
  199. };
  200. </script>
  201. <style scoped lang="scss">
  202. .home-index {
  203. width: 100%;
  204. height: 100vh;
  205. overflow: auto;
  206. position: relative;
  207. background: linear-gradient(180deg, #f4f9fd 0%, #f9f9f9 100%);
  208. .banner-wrap {
  209. width: 100%;
  210. height: 200px;
  211. position: relative;
  212. z-index: 1;
  213. .banner-img {
  214. width: 100%;
  215. height: 100%;
  216. object-fit: cover;
  217. }
  218. .banner-title {
  219. position: absolute;
  220. bottom: 0;
  221. left: 0;
  222. width: 100%;
  223. padding: 10px 12px 34px 12px;
  224. box-sizing: border-box;
  225. background: linear-gradient(
  226. 180deg,
  227. rgba(102, 102, 102, 0) -64.3%,
  228. rgba(0, 0, 0, 0.0074) -1.43%,
  229. rgba(0, 0, 0, 0.684747) 39.67%,
  230. rgba(0, 0, 0, 0.74) 40.09%,
  231. rgba(0, 0, 0, 0.74) 83.2%
  232. );
  233. color: #fff;
  234. font-weight: bold;
  235. backdrop-filter: blur(2px);
  236. }
  237. }
  238. .weather-mask {
  239. position: fixed;
  240. top: 0;
  241. left: 0;
  242. width: 100%;
  243. height: 100%;
  244. background-color: rgba(0, 0, 0, 0.52);
  245. z-index: 2;
  246. }
  247. .weather-info {
  248. width: calc(100% - 20px);
  249. position: absolute;
  250. top: calc(200px - 28px);
  251. left: 10px;
  252. z-index: 3;
  253. }
  254. .farm-monitor-container {
  255. padding-top: 30px;
  256. display: flex;
  257. align-items: center;
  258. margin: 10px;
  259. gap: 6px;
  260. height: 134px;
  261. &.farmer-role {
  262. height: 104px;
  263. .farm-monitor-left {
  264. background: url("@/assets/img/home/farm-bg-4.png") no-repeat center center / 100% 100%;
  265. }
  266. .farm-monitor-right {
  267. .right-item {
  268. background: url("@/assets/img/home/farm-bg-5.png") no-repeat center center / 100% 100%;
  269. }
  270. }
  271. }
  272. .farm-monitor-left,
  273. .farm-monitor-right {
  274. .title {
  275. font-size: 16px;
  276. color: #1d2129;
  277. font-weight: 500;
  278. .icon {
  279. font-size: 12px;
  280. margin-left: 2px;
  281. }
  282. }
  283. .content {
  284. margin-top: 6px;
  285. font-size: 12px;
  286. color: rgba(29, 33, 41, 0.5);
  287. line-height: 1.5;
  288. }
  289. .arrow {
  290. border-radius: 5px;
  291. background: #fff;
  292. display: flex;
  293. align-items: center;
  294. justify-content: center;
  295. width: 34px;
  296. height: 25px;
  297. margin-top: 10px;
  298. font-size: 11px;
  299. }
  300. }
  301. .farm-monitor-left {
  302. flex: 1;
  303. height: 100%;
  304. margin-top: 2px;
  305. padding: 25px 12px;
  306. box-sizing: border-box;
  307. max-width: 170px;
  308. background: url("@/assets/img/home/farm-bg-1.png") no-repeat center center / 105% 106%;
  309. }
  310. .farm-monitor-right {
  311. flex: 1;
  312. height: 100%;
  313. display: flex;
  314. flex-direction: column;
  315. .right-item {
  316. padding: 10px 12px;
  317. box-sizing: border-box;
  318. display: flex;
  319. flex-direction: column;
  320. justify-content: center;
  321. flex: 1;
  322. background: url("@/assets/img/home/farm-bg-2.png") no-repeat center center / 100% 100%;
  323. }
  324. .expert {
  325. background: url("@/assets/img/home/farm-bg-3.png") no-repeat center center / 100% 100%;
  326. }
  327. }
  328. }
  329. }
  330. </style>