farmDetails.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <template>
  2. <div class="farm-details-page">
  3. <custom-header name="农场详情"></custom-header>
  4. <div class="farm-details-content">
  5. <farm-info-card
  6. v-if="farmDetail.name"
  7. :data="{
  8. farmName: farmDetail.name || '',
  9. area: (farmDetail.mianji || 0) + '亩',
  10. variety: farmDetail.typeName || '',
  11. address: farmDetail.address || '',
  12. mapImage: '/map.png',
  13. maxWidth:'70px',
  14. }"
  15. >
  16. <template #right>
  17. <div @click="handleFarmInfo">基本信息</div>
  18. </template>
  19. </farm-info-card>
  20. <tabs v-model:active="activeTab" class="custom-tabs" scrollspy sticky offset-top="40" background="#f5f7fb">
  21. <tab title="农情互动" class="tab-item">
  22. <common-box title="农情互动">
  23. <template #right>
  24. <span @click="handleDetail('farm_list')">查看详情</span>
  25. </template>
  26. <template v-if="farmWorkData.quest">
  27. <div class="question-header">
  28. <img class="question-icon" src="@/assets/img/home/ask-icon.png" alt="" />
  29. <div class="question-title">{{ farmWorkData.quest }}</div>
  30. </div>
  31. <template v-if="farmWorkData.images.length">
  32. <div class="answer-content">
  33. 答:{{ farmWorkData.agriDate }} {{ farmWorkData.answerLabel }}出现{{
  34. farmWorkData.indicatorName
  35. }}
  36. </div>
  37. <div class="answer-img">
  38. <img v-for="image in farmWorkData.images" :key="image" :src="config.base_img_url2 + image.cloudFilename" alt="" />
  39. </div>
  40. </template>
  41. <div v-else class="answer-btn">
  42. <div class="answer-btn-item">转发给客户</div>
  43. <div class="answer-btn-item-group">
  44. <div class="answer-btn-item">否</div>
  45. <div class="answer-btn-item primary">是</div>
  46. </div>
  47. </div>
  48. </template>
  49. <empty
  50. v-else
  51. image="https://birdseye-img.sysuimars.com/birdseye-look-mini/custom-empty-image.png"
  52. image-size="80"
  53. description="暂无数据"
  54. class="empty-state"
  55. />
  56. </common-box>
  57. </tab>
  58. <tab title="农事服务" class="tab-item">
  59. <common-box title="农事服务">
  60. <template #right>
  61. <span @click="handleDetail('service_list')">查看详情</span>
  62. </template>
  63. <tab-list
  64. type="light"
  65. v-model="farmServiceActiveTab"
  66. :tabs="farmServiceTabs"
  67. @change="handleFarmServiceTabChange"
  68. />
  69. <stats-box :stats-data="serviceStatsData" />
  70. <div v-for="(section, index) in detailList" :key="index" class="content-section">
  71. <record-item
  72. :record-item-data="section"
  73. onlyRecipeName
  74. :content-mode="farmServiceActiveTab === 0 ? 'serviceDetail' : ''"
  75. title-mode="default"
  76. :title-right-text="farmServiceActiveTab === 0 ? '分享成果' : ''"
  77. :title-right-type="farmServiceActiveTab === 1 ? 'dot' : null"
  78. :title-right-dot-text="farmServiceActiveTab === 1 ? '2区' : ''"
  79. class="recipe-item"
  80. />
  81. </div>
  82. <empty
  83. v-if="detailList.length === 0"
  84. image="https://birdseye-img.sysuimars.com/birdseye-look-mini/custom-empty-image.png"
  85. image-size="80"
  86. description="暂无数据"
  87. class="empty-state"
  88. />
  89. </common-box>
  90. </tab>
  91. <tab title="农场报告" class="tab-item">
  92. <common-box title="农场报告">
  93. <template #right>
  94. <span @click="handleDetail('farm_report')">查看详情</span>
  95. </template>
  96. <span class="report-content"
  97. >果园面积共XX亩,共有XX棵生产树。果园面积共XX亩,共有XX棵生产树。果园面积共XX亩,共有XX棵生产树。果园面积共XX亩,共有XX棵生产树。果园面积共XX亩,共有XX棵生产树。果园面积共XX亩,共有XX棵生产树。</span
  98. >
  99. </common-box>
  100. </tab>
  101. <tab title="农事方案" class="tab-item plan-tab-item">
  102. <common-box title="农事方案">
  103. <template #right>
  104. <span @click="handleDetail('agricultural_plan')">查看更多</span>
  105. </template>
  106. <record-item v-if="detailList.length > 0" :record-item-data="detailList[0]" title-mode="default" class="recipe-item" />
  107. <empty
  108. v-else
  109. image="https://birdseye-img.sysuimars.com/birdseye-look-mini/custom-empty-image.png"
  110. image-size="80"
  111. description="暂无数据"
  112. class="empty-state"
  113. />
  114. </common-box>
  115. </tab>
  116. </tabs>
  117. </div>
  118. <div class="custom-bottom-fixed-btns">
  119. <div class="bottom-btn secondary-btn" @click="handleShareFarm">分享农场</div>
  120. <div class="bottom-btn primary-btn" @click="handleChatFarm">在线沟通</div>
  121. </div>
  122. </div>
  123. <fn-share-sheet v-model:show="showShare" @select="onSelect" :options="[{ name: '微信', icon: 'wechat' }]" />
  124. <!-- 农场信息 -->
  125. <farm-info-popup ref="farmInfoRef" :farmId="farmIdVal" :showBtn="true"></farm-info-popup>
  126. </template>
  127. <script setup>
  128. import { ref, onMounted} from "vue";
  129. import { useRoute, useRouter } from "vue-router";
  130. import { Tab, Tabs, Empty } from "vant";
  131. import wx from "weixin-js-sdk";
  132. import customHeader from "@/components/customHeader.vue";
  133. import FarmInfoCard from "@/components/pageComponents/FarmInfoCard.vue";
  134. import tabList from "@/components/pageComponents/TabList.vue";
  135. import commonBox from "@/components/pageComponents/CommonBox.vue";
  136. import StatsBox from "@/components/pageComponents/StatsBox.vue";
  137. import recordItem from "@/components/recordItem.vue";
  138. import farmInfoPopup from "../home/components/farmInfoPopup.vue";
  139. import FnShareSheet from "@/components/pageComponents/FnShareSheet.vue";
  140. import config from "@/api/config";
  141. import { ElMessage } from "element-plus";
  142. const router = useRouter();
  143. const route = useRoute();
  144. const activeTab = ref(0);
  145. const farmServiceTabs = ["过往服务", "未来服务"];
  146. const farmServiceActiveTab = ref(0);
  147. const farmInfoRef = ref(null);
  148. const handleFarmInfo = () => {
  149. farmInfoRef.value.handleShow();
  150. };
  151. const handleFarmServiceTabChange = (index) => {
  152. if (index === 0) {
  153. getFarmPastServiceCost();
  154. getDetailList();
  155. } else {
  156. getFutureFarmWorkList();
  157. serviceStatsData.value = [
  158. { value: "1258", unit: "元", desc: "预计收益" },
  159. { value: "1258", unit: "元", desc: "预计成本" },
  160. ];
  161. }
  162. };
  163. const serviceStatsData = ref([]);
  164. onMounted(() => {
  165. farmIdVal.value = route.query.farmId;
  166. paramsPage.value = {
  167. farmId: farmIdVal.value,
  168. limit: 1,
  169. page: 1,
  170. }
  171. getFarmDetail();
  172. getFarmWorkList();
  173. getDetailList();
  174. getFarmPastServiceCost();
  175. });
  176. const farmIdVal = ref(null);
  177. const farmDetail = ref({});
  178. const paramsPage = ref({});
  179. const getFarmDetail = () => {
  180. VE_API.user.getFarmDetail({ farmId: farmIdVal.value }).then(({ data }) => {
  181. farmDetail.value = data || {};
  182. });
  183. };
  184. const farmWorkData = ref({});
  185. const getFarmWorkList = () => {
  186. VE_API.user.getFarmWorkList(paramsPage.value).then(({ data }) => {
  187. if (data && data.length > 0) {
  188. farmWorkData.value = data[0] || {};
  189. }
  190. });
  191. };
  192. const detailList = ref([]);
  193. const getDetailList = () => {
  194. const params = {
  195. ...paramsPage.value,
  196. flowStatus: '4,5',
  197. };
  198. VE_API.user.getDetailList(params).then(({ data }) => {
  199. detailList.value = data || [];
  200. });
  201. };
  202. const getFutureFarmWorkList = () => {
  203. VE_API.user.getFutureFarmWorkList(paramsPage.value).then(({ data }) => {
  204. detailList.value = data || [];
  205. });
  206. };
  207. const getFarmPastServiceCost = () => {
  208. VE_API.user.getFarmPastServiceCost({ farmId: farmIdVal.value }).then(({ data }) => {
  209. serviceStatsData.value = [
  210. { value: data.totalCost, unit: "元", desc: "总收益" },
  211. { value: data.totalCost, unit: "元", desc: "投入成本" },
  212. { value: data.serviceCount, unit: "次", desc: "服务次数" },
  213. ];
  214. });
  215. };
  216. const handleDetail = (path) => {
  217. router.push(`/${path}?farmId=${farmIdVal.value}`);
  218. };
  219. const showShare = ref(false);
  220. const handleShareFarm = () => {
  221. showShare.value = true;
  222. };
  223. const handleChatFarm = () => {
  224. if(route.query.receiveUserId != 'null'){
  225. router.push(`/chat_frame?userId=${route.query.receiveUserId}&farmId=${farmIdVal.value}`);
  226. }else{
  227. ElMessage.warning('尚未绑定用户,暂时无法沟通');
  228. }
  229. };
  230. const onSelect = () => {
  231. const query = {
  232. agriculturalStoreId: route.query.agriculturalStoreId,
  233. farmId: route.query.farmId,
  234. speciesName: farmDetail.value.speciesName,
  235. containerId: farmDetail.value.containerId,
  236. receiveUserId: route.query.receiveUserId,
  237. };
  238. wx.miniProgram.navigateTo({
  239. url: `/pages/subPages/share_page/index?pageParams=${JSON.stringify(query)}&type=shareFarm`,
  240. });
  241. };
  242. </script>
  243. <style scoped lang="scss">
  244. .farm-details-page {
  245. width: 100%;
  246. height: 100vh;
  247. background: #f2f3f5;
  248. .farm-details-content {
  249. box-sizing: border-box;
  250. padding: 10px 12px 70px 12px;
  251. overflow: auto;
  252. height: calc(100% - 40px);
  253. box-sizing: border-box;
  254. .custom-tabs {
  255. ::v-deep {
  256. .van-tabs__wrap {
  257. height: auto;
  258. }
  259. .van-tabs__nav {
  260. .van-tab {
  261. color: #8b8b8b;
  262. background: #f7f8fa;
  263. height: 34px;
  264. font-weight: 400;
  265. border-radius: 25px;
  266. }
  267. .van-tab--active {
  268. color: #fff;
  269. background: #2199f8;
  270. font-weight: 400;
  271. }
  272. }
  273. .van-tabs__line {
  274. display: none;
  275. }
  276. .van-tabs__nav--line {
  277. padding: 12px 0;
  278. }
  279. }
  280. .tab-item + .tab-item {
  281. margin-top: 12px;
  282. }
  283. }
  284. .question-header {
  285. display: flex;
  286. align-items: center;
  287. margin-bottom: 6px;
  288. gap: 8px;
  289. font-weight: 500;
  290. .question-icon {
  291. width: 22px;
  292. height: 20px;
  293. }
  294. }
  295. .answer-content {
  296. color: #333333;
  297. margin: 6px 0 10px 0;
  298. }
  299. .answer-img {
  300. display: flex;
  301. gap: 5px;
  302. img {
  303. flex: 1;
  304. max-width: 105px;
  305. height: 105px;
  306. border-radius: 5px;
  307. object-fit: cover;
  308. }
  309. }
  310. .content-section {
  311. .recipe-item {
  312. border: 1px solid rgba(0, 0, 0, 0.1);
  313. margin: 12px 0 0 0;
  314. }
  315. }
  316. .plan-tab-item {
  317. .recipe-item {
  318. padding: 0;
  319. }
  320. }
  321. .plan-list-wrapper {
  322. height: 500px;
  323. margin-top: 12px;
  324. }
  325. .report-content {
  326. font-size: 13px;
  327. }
  328. .answer-btn {
  329. display: flex;
  330. align-items: center;
  331. justify-content: space-between;
  332. margin-top: 10px;
  333. > div {
  334. display: flex;
  335. gap: 10px;
  336. }
  337. }
  338. .answer-btn-item {
  339. padding: 7px 12px;
  340. border-radius: 25px;
  341. font-size: 12px;
  342. text-align: center;
  343. background: rgba(33, 153, 248, 0.1);
  344. color: #2199f8;
  345. min-width: 52px;
  346. box-sizing: border-box;
  347. &.primary {
  348. background: #2199f8;
  349. color: #ffffff;
  350. }
  351. }
  352. .empty-state {
  353. ::v-deep .van-empty {
  354. padding: 40px 0;
  355. }
  356. }
  357. }
  358. }
  359. </style>