index.vue 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507
  1. <template>
  2. <div class="achievement-report-page" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
  3. <!-- 天气遮罩 -->
  4. <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
  5. <!-- 组件:天气 -->
  6. <div class="weather-info-wrap">
  7. <weather-info ref="weatherInfoRef" from="growth_report" class="weather-info" :showTabMask="showTabMask"
  8. @weatherExpanded="weatherExpanded" @changeGarden="changeGarden" @changeGardenTab="changeGardenTab"
  9. @closeTabMask="closeTabMask">
  10. </weather-info>
  11. <!-- 邀请关注 -->
  12. <!-- <div class="invite-follow" v-if="currentFarmName && activeGardenTab === 'current'">
  13. <div class="invite-content">
  14. <icon name="share" />
  15. <span>邀请关注</span>
  16. </div>
  17. </div> -->
  18. </div>
  19. <!-- 农场列表 -->
  20. <div v-show="activeGardenTab === 'list'">
  21. <garden-list ref="gardenListRef" :garden-id="selectedGardenId" @loaded="handleGardenLoaded"
  22. @selectGarden="handleGardenSelected" />
  23. </div>
  24. <div class="report-content-wrap" v-if="hasReport && activeGardenTab === 'current'" v-loading="loading"
  25. element-loading-background="rgba(0, 0, 0, 0.1)">
  26. <!-- <div class="history-risk-report-btn" @click="handleHistoryRiskReportClick">
  27. <span class="risk-report-icon">
  28. <i></i>
  29. </span>
  30. <span class="risk-report-text">历史风险报告</span>
  31. </div> -->
  32. <div class="report-content has-report" :style="{ minHeight: `calc(100vh - ${tabBarHeight}px)` }">
  33. <!-- <img src="@/assets/img/home/qrcode.png" alt="" class="code-icon" /> -->
  34. <img class="header-img" src="@/assets/img/home/report.png" alt="" />
  35. <div class="report-header">
  36. <!-- <div class="type-tabs report-tabs">
  37. <div class="type-item" :class="{ 'type-item-active': activeReportIndex === 0 }">作物长势</div>
  38. <div class="type-item" :class="{ 'type-item-active': activeReportIndex === 1 }">历史风险</div>
  39. <div class="type-item" :class="{ 'type-item-active': activeReportIndex === 2 }">土壤改良</div>
  40. <div class="type-item" :class="{ 'type-item-active': activeReportIndex === 3 }">种植建议</div>
  41. </div> -->
  42. <div class="type-tabs" v-if="subjectData.length > 1">
  43. <div
  44. @click="handleTypeTabClick(item, index)"
  45. class="type-item"
  46. v-for="(item, index) in visibleSubjectData"
  47. :class="{ 'type-item-active': activeSubjectIndex === index }"
  48. :key="index">{{ item.speciesName }}</div>
  49. <div
  50. v-if="showSubjectToggle"
  51. class="subject-toggle"
  52. @click="typeTabsExpanded = !typeTabsExpanded"
  53. >
  54. {{ typeTabsExpanded ? "点击收起" : "点击展开更多" }}
  55. </div>
  56. </div>
  57. <div class="time-tag">{{ workItems?.[0]?.reportDate || new Date().toISOString().split('T')[0] }}</div>
  58. <div class="report-title">荔枝长势报告</div>
  59. <div class="report-info">
  60. <div class="info-item">
  61. <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
  62. <span class="info-text">{{ currentFarmName }}</span>
  63. </div>
  64. </div>
  65. </div>
  66. <div class="report-box">
  67. <div class="box-title">气象风险</div>
  68. <div class="box-text">
  69. <div class="box-bg">
  70. <!-- <div class="types-info">
  71. 当前 <span class="text-bold">水稻</span> 处于为 分蘖初期<span class="text-link" @click="handleAdjustPopup">(校准物候期)</span>
  72. </div> -->
  73. <div class="types-info">
  74. 当前 <span class="text-bold">荔枝</span> 处于膨果期
  75. </div>
  76. <div class="tp-img">
  77. <img src="@/assets/img/common/tp-1.png" alt="">
  78. <img src="@/assets/img/common/tp-2.png" alt="">
  79. <img src="@/assets/img/common/tp-3.png" alt="">
  80. <img src="@/assets/img/common/tp-4.png" alt="">
  81. <img src="@/assets/img/common/tp-5.png" alt="">
  82. <img src="@/assets/img/common/tp-6.png" alt="">
  83. </div>
  84. </div>
  85. <div class="warning-part">
  86. <div class="warning-title">
  87. <div class="title-l">
  88. <div class="title-line"></div>
  89. <div class="title-block"></div>
  90. </div>
  91. <div>未来7-15天气象风险</div>
  92. <div class="title-l">
  93. <div class="title-block"></div>
  94. <div class="title-line title-line-right"></div>
  95. </div>
  96. </div>
  97. <div class="report-part" v-for="(part, partI) in riskList" :key="partI">
  98. <div class="part-title">{{ part.title }}</div>
  99. <div class="part-text">{{ part.description }}</div>
  100. </div>
  101. </div>
  102. </div>
  103. </div>
  104. <div class="report-box">
  105. <div class="box-title">农事建议</div>
  106. <div class="box-text">
  107. <div class="warning-part" v-for="(part, partI) in adviceList" :key="partI">
  108. <div class="report-part">
  109. <div class="part-top">
  110. <div class="part-title">{{ part.title }}</div>
  111. <!-- <div class="part-link">
  112. <el-icon class="part-link-icon"><Link /></el-icon>
  113. <div class="text-link">查看农事</div>
  114. </div> -->
  115. </div>
  116. <div class="part-text">{{ part.description }}</div>
  117. </div>
  118. </div>
  119. </div>
  120. </div>
  121. <div class="report-box">
  122. <div class="box-title">巡园重点</div>
  123. <div class="box-text">
  124. <div class="warning-part" v-for="(part, partI) in patrolList" :key="partI">
  125. <div class="report-part">
  126. <div class="part-top">
  127. <div class="part-title">{{ part.title }}</div>
  128. <!-- <div class="part-link">
  129. <el-icon class="part-link-icon"><Link /></el-icon>
  130. <div class="text-link">查看互动</div>
  131. </div> -->
  132. </div>
  133. <div class="part-text">{{ part.description }}</div>
  134. </div>
  135. </div>
  136. </div>
  137. </div>
  138. <div class="report-box" v-for="(work, workI) in workItems" :key="workI">
  139. <div class="box-title">{{ work?.title }}</div>
  140. <div class="box-text">
  141. <div class="box-bg" v-show="work?.backgroundDesc">
  142. <span class="box-subtitle">背景描述:</span>
  143. <div class="pre-text">{{ work?.backgroundDesc }}</div>
  144. </div>
  145. <div class="box-advice" v-show="work?.suggestion">
  146. <span class="box-subtitle">对策建议:</span>
  147. <div class="pre-text">{{ work?.suggestion }}</div>
  148. </div>
  149. <div class="box-sum pre-text" v-show="work?.summary">{{ work?.summary }}</div>
  150. </div>
  151. </div>
  152. </div>
  153. <!-- <swipe ref="swipeRef" class="my-swipe" :loop="false" indicator-color="white" @change="handleSwipeChange">
  154. <swipe-item v-for="(item, index) in regionsData" :key="index">
  155. </swipe-item>
  156. </swipe> -->
  157. </div>
  158. <div v-else-if="activeGardenTab === 'current'" class="fake-report-wrap report-content-wrap">
  159. <div class="report-content">
  160. <img class="header-img" src="@/assets/img/home/report.png" alt="" />
  161. <div class="report-header" :class="{ 'no-farm': !currentFarmName }">
  162. <!-- <img class="header-book" src="@/assets/img/home/book.png" alt="" /> -->
  163. <div class="time-tag">{{ new Date().toISOString().split('T')[0] }}</div>
  164. <div class="report-title" @click="handleAddFarm">作物长势报告</div>
  165. <div class="report-info pb-4">
  166. <div class="info-item">
  167. <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
  168. <span class="info-text">示范农场</span>
  169. </div>
  170. </div>
  171. </div>
  172. <div class="fake-img">
  173. <img src="@/assets/img/home/fake.png" alt="" class="fake-img-item" />
  174. </div>
  175. <div class="lock-img">
  176. <img @click="handleLockClick" src="@/assets/img/home/lock-blue.png" alt=""
  177. class="has-click lock-img-item" />
  178. <div class="lock-text">
  179. 专属数字农场,种好卖好
  180. <div>点击解锁一键溯源增产</div>
  181. </div>
  182. <div @click="handleLockClick" class="lock-btn has-click">点击解锁</div>
  183. </div>
  184. <div class="lock-bg"></div>
  185. </div>
  186. </div>
  187. <!-- 农场列表引导 -->
  188. <div class="mask-wrap" @click="closeTabMask" v-if="showTabMask"></div>
  189. <tip-popup v-model:show="showBindSuccess" type="success" text="您的农场已绑定成功" hideBtn />
  190. <start-interact-popup ref="startInteractPopupRef" />
  191. <agri-execute-popup ref="agriExecutePopupRef" />
  192. <!-- 校准物候期 -->
  193. <adjust-popup ref="adjustPopupRef" />
  194. </div>
  195. </template>
  196. <script setup>
  197. import wx from "weixin-js-sdk";
  198. import weatherInfo from "@/components/weatherInfo.vue";
  199. import { ref, onActivated, onDeactivated, onUnmounted, computed, nextTick } from "vue";
  200. import { useRoute, useRouter } from "vue-router";
  201. import { useStore } from "vuex";
  202. import { Swipe, SwipeItem, Badge, Icon } from 'vant';
  203. import tipPopup from "@/components/popup/tipPopup.vue";
  204. import startInteractPopup from "@/components/popup/startInteractPopup.vue";
  205. import agriExecutePopup from "@/components/popup/agriExecutePopup.vue";
  206. import gardenList from "@/components/gardenList.vue";
  207. import adjustPopup from "./adjustPopup.vue";
  208. const store = useStore();
  209. const tabBarHeight = computed(() => store.state.home.tabBarHeight);
  210. const route = useRoute();
  211. const router = useRouter();
  212. const loading = ref(false);
  213. const hasReport = ref(true);
  214. const workItems = ref([]);
  215. const swipeRef = ref(null);
  216. //
  217. const riskList = ref([
  218. {
  219. title: '病虫风险',
  220. description: '当前膨果期对病虫害高度敏感,易受害。经过飞鸟智慧大脑计算病虫风险:病虫胁迫指数处于中等水平,存在一定的病虫害发生风险,局部区域可能出现病害流行或虫害爆发,需加强监测预警,及时巡园'
  221. },
  222. {
  223. title: '阴雨寡照风险',
  224. description: '经过飞鸟智慧大脑计气象风险:阴雨寡照胁迫指数处于中等水平,存在一定的植株缺素风险,局部区域可能会出现长势异常现象,需加强监测预警,及时巡园'
  225. },
  226. ]);
  227. const adviceList = ref([
  228. {
  229. title: '根外追肥',
  230. description: '荔枝膨果期遇持续阴雨寡照,需及时排水防渍,重点根外喷施磷酸二氢钾并配合补充钙硼肥,以快速恢复树势、促进膨果壮果。'
  231. },
  232. {
  233. title: '虫害防治',
  234. description: '通过叶面喷施针对性杀虫剂,快速压低蒂蛀虫种群数量,保护果实免受蛀害。'
  235. },
  236. ]);
  237. const patrolList = ref([
  238. {
  239. title: '进程互动',
  240. description: '是否有60%的荔枝进入果实转色期?'
  241. },
  242. {
  243. title: '长势互动',
  244. description: '是是否有10%的荔枝出现生理落果或裂果症状'
  245. },
  246. {
  247. title: '病虫互动',
  248. description: '是否有10%的荔枝发现蒂蛀虫为害特征?'
  249. },
  250. ]);
  251. //
  252. const paramsPage = ref({});
  253. const showBindSuccess = ref(false);
  254. const startInteractPopupRef = ref(null);
  255. const agriExecutePopupRef = ref(null);
  256. const adjustPopupRef = ref(null);
  257. const handleAdjustPopup = () => {
  258. adjustPopupRef.value.open();
  259. }
  260. // 天气组件相关
  261. const isExpanded = ref(false);
  262. const weatherInfoRef = ref(null);
  263. const showTabMask = ref(false);
  264. const TAB_GUIDE_SHOWN_KEY = "GROWTH_REPORT_TAB_GUIDE_SHOWN";
  265. const weatherExpanded = (isExpandedValue) => {
  266. isExpanded.value = isExpandedValue;
  267. };
  268. // 点击遮罩时收起天气
  269. const handleMaskClick = () => {
  270. if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
  271. weatherInfoRef.value.toggleExpand();
  272. }
  273. };
  274. const currentFarmName = ref('');
  275. const selectedGardenId = ref(null);
  276. const gardenListRef = ref(null);
  277. const activeGardenTab = ref('current');
  278. const changeGardenTab = (tab) => {
  279. activeGardenTab.value = tab;
  280. }
  281. const handleGardenLoaded = ({ hasFarm }) => {
  282. weatherInfoRef.value?.setGardenLoaded?.(hasFarm);
  283. };
  284. const handleGardenSelected = (garden) => {
  285. selectedGardenId.value = garden?.id ?? null;
  286. weatherInfoRef.value?.setSelectedGarden?.(garden);
  287. };
  288. // 切换农场时,更新报告数据
  289. const changeGarden = async ({ id, name }) => {
  290. if (!id) return;
  291. currentFarmName.value = name;
  292. if (sessionStorage.getItem('activeSwipeIndex')) {
  293. currentIndex.value = Number(sessionStorage.getItem('activeSwipeIndex'));
  294. } else {
  295. currentIndex.value = 0;
  296. swipeRef.value && swipeRef.value.swipeTo(0, { immediate: true });
  297. }
  298. paramsPage.value = {
  299. ...(paramsPage.value || {}),
  300. subjectId: id,
  301. };
  302. // 初始化品种/大物候期转换
  303. startInteractPopupRef.value.getPhenologyInitOrConfirmStatus();
  304. await getSubjectData(id);
  305. hasReport.value = true;
  306. // await getRegions();
  307. };
  308. onActivated(() => {
  309. window.scrollTo(0, 0);
  310. // 从新增农场页返回时,优先用缓存中的最新选中农场
  311. const savedFarmId = localStorage.getItem("selectedFarmId");
  312. selectedGardenId.value = savedFarmId ? Number(savedFarmId) : null;
  313. gardenListRef.value?.refreshFarmList?.();
  314. // 如果路由中带有 miniJson,并且其中有 showBind,则展示绑定成功弹窗
  315. const { miniJson } = route.query || {};
  316. if (miniJson) {
  317. try {
  318. const parsed = typeof miniJson === "string" ? JSON.parse(miniJson) : miniJson;
  319. if (parsed && parsed.showBind) {
  320. showBindSuccess.value = true;
  321. // 处理完后清空路由中的 miniJson 参数,避免重复弹出
  322. const newQuery = { ...(route.query || {}) };
  323. delete newQuery.miniJson;
  324. router.replace({ path: route.path, query: newQuery });
  325. }
  326. } catch (e) {
  327. // miniJson 解析失败时忽略,不影响正常流程
  328. }
  329. }
  330. // getResultReport();
  331. });
  332. const closeTabMask = () => {
  333. showTabMask.value = false;
  334. };
  335. const userInfo = localStorage.getItem("localUserInfo");
  336. const userInfoObj = userInfo ? JSON.parse(userInfo) : {};
  337. const handleLockClick = () => {
  338. if (currentFarmName.value) {
  339. // router.push("/interaction?subjectId=" + localStorage.getItem("selectedFarmId"));
  340. router.push(`/create_farm?from=growth_report&isReload=true`);
  341. return;
  342. }
  343. if (userInfoObj?.tel) {
  344. router.push(`/create_farm?from=growth_report&isReload=true`);
  345. return;
  346. }
  347. wx.miniProgram.navigateTo({
  348. url: '/pages/subPages/phone_auth/index',
  349. });
  350. }
  351. const handleAddFarm = () => {
  352. router.push(`/create_farm?from=growth_report&isReload=true`);
  353. }
  354. const handleHistoryRiskReportClick = () => {
  355. router.push("/history_risk_report");
  356. }
  357. const todayPatrolFocus = ref([]);
  358. const pendingFarmWork = ref([]);
  359. const handlePendingFarmWorkClick = (card) => {
  360. router.push({
  361. path: "/work_detail",
  362. query: {
  363. miniJson: JSON.stringify({
  364. paramsPage: JSON.stringify({
  365. farmId: paramsPage.value.farmId,
  366. farmWorkLibId: card?.farmWorkLibId,
  367. recordId: card?.recordId,
  368. typeId: regionsData.value[currentIndex.value].typeId
  369. }),
  370. }),
  371. },
  372. });
  373. }
  374. // 点击今日巡园重点
  375. const handleTodayPatrolFocusClick = (card) => {
  376. if (!card.interactionTypeId) return;
  377. router.push(`/interaction_list?farmId=${paramsPage.value.farmId}&regionId=${paramsPage.value.regionId}&interactionTypeId=${card.interactionTypeId}`);
  378. }
  379. const getTodayPatrolFocus = () => {
  380. VE_API.report.todayPatrolFocus({ farmId: paramsPage.value.farmId }).then(({ data }) => {
  381. todayPatrolFocus.value = data || [];
  382. });
  383. }
  384. const getPendingFarmWork = () => {
  385. VE_API.report.pendingFarmWork({ farmId: paramsPage.value.farmId, regionId: paramsPage.value.regionId }).then(({ data }) => {
  386. pendingFarmWork.value = data || [];
  387. });
  388. }
  389. const currentIndex = ref(0);
  390. const handleSwipeChange = (index) => {
  391. currentIndex.value = index;
  392. if (paramsPage.value.regionId !== regionsData.value[index].regionId) {
  393. paramsPage.value = {
  394. ...(paramsPage.value || {}),
  395. farmId: regionsData.value[index].farmId,
  396. regionId: regionsData.value[index].regionId,
  397. };
  398. getTodayPatrolFocus();
  399. getPendingFarmWork();
  400. getDetail();
  401. }
  402. }
  403. const getDetail = () => {
  404. if (!paramsPage.value.farmId) return;
  405. loading.value = true;
  406. VE_API.report
  407. .reproductiveReport({ farmId: paramsPage.value.farmId, regionId: paramsPage.value.regionId })
  408. .then(({ data }) => {
  409. workItems.value = data || [];
  410. })
  411. .finally(() => {
  412. loading.value = false;
  413. });
  414. };
  415. const subjectData = ref([])
  416. const typeTabsExpanded = ref(false);
  417. const visibleSubjectData = computed(() => {
  418. if (typeTabsExpanded.value) {
  419. return subjectData.value;
  420. }
  421. return subjectData.value.slice(0, 4);
  422. });
  423. const showSubjectToggle = computed(() => subjectData.value.length > 4);
  424. const getSubjectData = async (id) => {
  425. const res = await VE_API.monitor.listFarmsBySubjectId({ subjectId: id });
  426. // subjectData.value = res.data || [];
  427. subjectData.value = [...res.data, ...res.data, ...res.data, ...res.data];
  428. typeTabsExpanded.value = false;
  429. }
  430. const activeReportIndex = ref(0);
  431. const activeSubjectIndex = ref(0);
  432. const handleTypeTabClick = (item, index) => {
  433. activeSubjectIndex.value = index;
  434. paramsPage.value = {
  435. ...(paramsPage.value || {}),
  436. farmId: item.farmId,
  437. };
  438. getTodayPatrolFocus();
  439. }
  440. const regionsData = ref([]);
  441. const getRegions = async () => {
  442. VE_API.monitor.listRegionsBySubjectId({
  443. subjectId: paramsPage.value.subjectId,
  444. }).then(({ data }) => {
  445. console.log(data);
  446. regionsData.value = data || [];
  447. if (regionsData.value.length > 0) {
  448. hasReport.value = true;
  449. const hasShownTabGuide = localStorage.getItem(TAB_GUIDE_SHOWN_KEY) === "1";
  450. // 首次进入且有分区数据:显示农场列表引导
  451. if (!hasShownTabGuide) {
  452. showTabMask.value = true;
  453. localStorage.setItem(TAB_GUIDE_SHOWN_KEY, "1");
  454. } else {
  455. showTabMask.value = false;
  456. }
  457. // 切换农场tab回到当前农场tab
  458. weatherInfoRef.value && weatherInfoRef.value.handleGardenClick('current');
  459. // 如果不是点击农情报告已生成弹窗过来的,则显示农情互动弹窗
  460. if (!route.query.hideInteraction) {
  461. agriExecutePopupRef.value.showPopup(regionsData.value[currentIndex.value].farmId);
  462. }
  463. paramsPage.value = {
  464. ...(paramsPage.value || {}),
  465. farmId: regionsData.value[currentIndex.value].farmId,
  466. regionId: regionsData.value[currentIndex.value].regionId,
  467. };
  468. getTodayPatrolFocus();
  469. getPendingFarmWork();
  470. getDetail();
  471. // 如果是新增品种后跳转过来的,等待 Swipe 实例挂载后再定位
  472. if (route.query.addVarietyCount) {
  473. const targetIndex = Number(route.query.addVarietyCount);
  474. if (!Number.isNaN(targetIndex) && targetIndex >= 0) {
  475. const safeIndex = Math.min(targetIndex, regionsData.value.length - 1);
  476. const reverseIndex = Math.min(
  477. regionsData.value.length - 1,
  478. Math.max(0, regionsData.value.length - safeIndex)
  479. );
  480. nextTick(() => {
  481. swipeRef.value?.swipeTo?.(reverseIndex, { immediate: true });
  482. });
  483. }
  484. }
  485. if (sessionStorage.getItem('activeSwipeIndex')) {
  486. nextTick(() => {
  487. swipeRef.value?.swipeTo?.(currentIndex.value, { immediate: true });
  488. });
  489. sessionStorage.removeItem('activeSwipeIndex');
  490. }
  491. } else {
  492. // 切换农场tab回到当前农场tab
  493. // weatherInfoRef.value && weatherInfoRef.value.handleGardenClick('current');
  494. showTabMask.value = false;
  495. hasReport.value = false;
  496. }
  497. });
  498. }
  499. // 清理数据的函数
  500. const clearData = () => {
  501. workItems.value = [];
  502. paramsPage.value = {};
  503. loading.value = false;
  504. };
  505. onDeactivated(() => {
  506. sessionStorage.setItem('activeSwipeIndex', currentIndex.value);
  507. clearData();
  508. });
  509. onUnmounted(() => {
  510. clearData();
  511. });
  512. </script>
  513. <style lang="scss" scoped>
  514. .mask-wrap {
  515. position: fixed;
  516. bottom: 0;
  517. left: 0;
  518. width: 100%;
  519. height: 300px;
  520. background-color: rgba(0, 0, 0, 0.52);
  521. z-index: 99999;
  522. }
  523. .achievement-report-page {
  524. width: 100%;
  525. height: 100vh;
  526. background: linear-gradient(195.35deg, #d4e4ff 16.34%, rgba(93, 189, 255, 0) 50.3%),
  527. linear-gradient(156.64deg, rgba(255, 255, 255, 0.16) 27.7%, rgba(255, 255, 255, 0) 72.82%);
  528. .weather-mask {
  529. position: fixed;
  530. top: 0;
  531. left: 0;
  532. width: 100%;
  533. height: 100%;
  534. background-color: rgba(0, 0, 0, 0.52);
  535. z-index: 11;
  536. }
  537. .weather-info-wrap {
  538. width: calc(100% - 20px);
  539. position: absolute;
  540. z-index: 12;
  541. left: 10px;
  542. top: 10px;
  543. .weather-info {
  544. width: 100%;
  545. }
  546. .invite-follow {
  547. position: absolute;
  548. right: -6px;
  549. top: 50px;
  550. .invite-content {
  551. display: flex;
  552. align-items: center;
  553. gap: 4px;
  554. font-size: 14px;
  555. font-family: "PangMenZhengDao";
  556. color: #fff;
  557. line-height: 30px;
  558. padding: 0 12px;
  559. border-radius: 20px 0 0 20px;
  560. height: 30px;
  561. cursor: pointer;
  562. background: #2199F8;
  563. position: relative;
  564. &::after {
  565. content: '';
  566. position: absolute;
  567. bottom: -6px;
  568. right: 0;
  569. width: 0px;
  570. height: 0px;
  571. border-right: 3px solid transparent;
  572. border-top: 3px solid #75a8cd;
  573. border-left: 3px solid #75a8cd;
  574. border-bottom: 3px solid transparent;
  575. }
  576. }
  577. }
  578. }
  579. .fake-report-wrap {
  580. width: 100%;
  581. .no-report-img {
  582. width: 100%;
  583. }
  584. .fake-img {
  585. position: relative;
  586. .fake-img-item {
  587. width: 100%;
  588. }
  589. }
  590. }
  591. .report-content-wrap {
  592. height: 100%;
  593. // padding-bottom: 60px;
  594. overflow: auto;
  595. box-sizing: border-box;
  596. position: relative;
  597. .history-risk-report-btn {
  598. position: absolute;
  599. right: 0px;
  600. top: 110px;
  601. z-index: 13;
  602. height: 26px;
  603. padding: 0 10px 0 8px;
  604. display: inline-flex;
  605. align-items: center;
  606. gap: 4px;
  607. color: #ffffff;
  608. font-size: 14px;
  609. border-radius: 13px 0 0 13px;
  610. background: linear-gradient(180deg, #60c2ff 0%, #2199f8 100%);
  611. box-shadow: 0 2px 6px rgba(33, 153, 248, 0.3);
  612. cursor: pointer;
  613. .risk-report-icon {
  614. width: 14px;
  615. height: 14px;
  616. border-radius: 2px;
  617. background: #ffffff;
  618. position: relative;
  619. display: inline-flex;
  620. align-items: center;
  621. justify-content: center;
  622. transform: rotate(-12deg);
  623. i {
  624. width: 8px;
  625. height: 2px;
  626. border-radius: 2px;
  627. background: #42a7ff;
  628. box-shadow: 0 3px 0 #42a7ff;
  629. }
  630. }
  631. .risk-report-text {
  632. line-height: 1;
  633. white-space: nowrap;
  634. }
  635. }
  636. .bottom-btn {
  637. z-index: 2;
  638. position: fixed;
  639. bottom: 0;
  640. left: 0;
  641. width: 100%;
  642. background: #fff;
  643. height: 60px;
  644. display: flex;
  645. align-items: center;
  646. justify-content: space-between;
  647. padding: 0 12px;
  648. box-sizing: border-box;
  649. box-shadow: 2px 2px 4.5px 0px rgba(0, 0, 0, 0.4);
  650. .btn-item {
  651. height: 40px;
  652. line-height: 40px;
  653. padding: 0 24px;
  654. border-radius: 20px;
  655. font-size: 14px;
  656. &.second {
  657. color: #666666;
  658. border: 1px solid rgba(153, 153, 153, 0.5);
  659. }
  660. &.primay {
  661. padding: 0 34px;
  662. background: linear-gradient(180deg, #76c3ff, #2199f8);
  663. color: #fff;
  664. }
  665. }
  666. }
  667. }
  668. .code-icon {
  669. position: absolute;
  670. right: 10px;
  671. top: 12px;
  672. width: 48px;
  673. }
  674. .report-content {
  675. // background: url("@/assets/img/home/report_bg.png") no-repeat center center;
  676. // background: linear-gradient(0deg, #9BCCFF, #9BCCFF),
  677. // linear-gradient(160deg, rgba(255, 255, 255, 0.16) 30%, rgba(255, 255, 255, 0) 72%);
  678. background: #abd4ff;
  679. background-size: 100% auto;
  680. background-position: top center;
  681. padding: 0 10px 26px 10px;
  682. box-sizing: border-box;
  683. position: relative;
  684. &.has-report {
  685. min-height: 100%;
  686. background: linear-gradient(0deg, #9BCCFF, #9BCCFF),
  687. linear-gradient(156.64deg, rgba(255, 255, 255, 0.16) 27.7%, rgba(255, 255, 255, 0) 72.82%);
  688. }
  689. .lock-bg {
  690. position: absolute;
  691. top: 230px;
  692. left: 0;
  693. width: 100%;
  694. height: calc(100% - 230px);
  695. background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.38) 50%, rgba(255, 255, 255, 0) 100%),
  696. linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2));
  697. }
  698. .lock-img {
  699. pointer-events: none;
  700. position: fixed;
  701. z-index: 10;
  702. top: 50%;
  703. left: 50%;
  704. transform: translate(-50%, -20%);
  705. width: 100%;
  706. display: flex;
  707. align-items: center;
  708. justify-content: center;
  709. flex-direction: column;
  710. gap: 16px;
  711. .lock-img-item {
  712. width: 57px;
  713. }
  714. .has-click {
  715. pointer-events: auto;
  716. }
  717. .lock-text {
  718. font-size: 14px;
  719. color: #000;
  720. padding: 5px 64px;
  721. line-height: 21px;
  722. background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #FFFFFF 50%, rgba(255, 255, 255, 0) 100%);
  723. }
  724. .lock-btn {
  725. width: 140px;
  726. height: 40px;
  727. line-height: 40px;
  728. text-align: center;
  729. background: linear-gradient(180deg, #76C3FF 0%, #2199F8 100%);
  730. border-radius: 25px;
  731. color: #fff;
  732. font-size: 16px;
  733. }
  734. }
  735. .header-img {
  736. position: absolute;
  737. top: 0;
  738. left: 0;
  739. width: 100%;
  740. }
  741. .type-tabs {
  742. background: rgba(255, 255, 255, 0.8);
  743. display: flex;
  744. align-items: center;
  745. flex-wrap: wrap;
  746. gap: 8px;
  747. width: fit-content;
  748. border-radius: 5px;
  749. padding: 5px;
  750. margin-bottom: 22px;
  751. &.report-tabs {
  752. padding: 0 5px;
  753. height: 38px;
  754. background: none;
  755. margin-bottom: 6px;
  756. .type-item {
  757. height: 34px;
  758. line-height: 34px;
  759. font-size: 14px;
  760. color: #858585;
  761. }
  762. }
  763. .type-item {
  764. height: 28px;
  765. line-height: 28px;
  766. text-align: center;
  767. padding: 0 6px;
  768. min-width: 80px;
  769. color: #9A9A9A;
  770. background: #FFFFFF;
  771. box-sizing: border-box;
  772. border-radius: 2px;
  773. &.type-item-active {
  774. background: #2199F8;
  775. color: #fff;
  776. }
  777. }
  778. }
  779. .subject-toggle {
  780. margin-top: 4px;
  781. margin-bottom: 5px;
  782. font-size: 14px;
  783. color: rgba(0, 0, 0, 0.6);
  784. width: 100%;
  785. cursor: pointer;
  786. text-align: center;
  787. }
  788. .report-header {
  789. position: relative;
  790. padding-top: 148px;
  791. &.no-farm {
  792. padding-top: 102px;
  793. }
  794. .header-book {
  795. position: absolute;
  796. right: 0;
  797. bottom: -6px;
  798. height: 88px;
  799. z-index: 10;
  800. }
  801. .time-tag {
  802. background: #2199F8;
  803. border-radius: 5px 0 5px 0;
  804. height: 23px;
  805. line-height: 23px;
  806. font-size: 13px;
  807. font-weight: 500;
  808. color: #fff;
  809. padding: 0 9px;
  810. width: fit-content;
  811. margin-bottom: 4px;
  812. }
  813. .report-title {
  814. font-family: "PangMenZhengDao";
  815. font-size: 34px;
  816. line-height: 38px;
  817. color: #000000;
  818. }
  819. .report-info {
  820. padding: 12px 0 28px 0;
  821. &.pb-4 {
  822. padding-bottom: 4px;
  823. }
  824. .info-item {
  825. width: fit-content;
  826. display: flex;
  827. height: 33px;
  828. align-items: center;
  829. padding: 0 18px 0 6px;
  830. background: rgba(255, 255, 255, 0.58);
  831. backdrop-filter: blur(5px);
  832. border-radius: 20px;
  833. gap: 6px;
  834. .info-icon {
  835. width: 26px;
  836. height: 26px;
  837. object-fit: cover;
  838. border-radius: 50%;
  839. }
  840. .info-text {
  841. font-size: 14px;
  842. color: #000;
  843. }
  844. }
  845. .info-item+.info-item {
  846. margin-top: 5px;
  847. }
  848. }
  849. // 左滑查看更多标签
  850. .swipe-more-tag {
  851. position: absolute;
  852. bottom: 10px;
  853. right: -16px;
  854. box-sizing: border-box;
  855. width: 36px;
  856. height: 86px;
  857. // padding: 0px 10px 2px 0;
  858. background: rgba(0, 0, 0, 0.7);
  859. border-radius: 10px 0 0 10px;
  860. letter-spacing: 2px;
  861. color: #ffffff;
  862. font-size: 12px;
  863. text-align: center;
  864. line-height: 14px;
  865. writing-mode: vertical-rl;
  866. text-orientation: mixed;
  867. padding-right: 5px;
  868. }
  869. }
  870. .report-box {
  871. display: flex;
  872. align-items: center;
  873. padding: 8px 12px;
  874. // background: linear-gradient(0deg, #ffffff 86%, #2199f8 136%);
  875. background: #fff;
  876. border: 1px solid #ffffff;
  877. border-radius: 8px;
  878. gap: 5px;
  879. position: relative;
  880. &.warning-bg {
  881. background: linear-gradient(0deg, #FFFFFF 86%, #FF9B48 136%);
  882. }
  883. .report-box-item {
  884. flex: 1;
  885. background: rgba(33, 153, 248, 0.1);
  886. border-radius: 8px;
  887. min-height: 62px;
  888. box-sizing: border-box;
  889. padding: 2px 4px;
  890. display: flex;
  891. flex-direction: column;
  892. justify-content: center;
  893. .item-content {
  894. color: #2199f8;
  895. font-size: 14px;
  896. text-align: center;
  897. }
  898. .item-title {
  899. color: #000000;
  900. font-size: 10px;
  901. text-align: center;
  902. padding-top: 5px;
  903. }
  904. }
  905. .box-title {
  906. position: absolute;
  907. top: -8px;
  908. left: -1px;
  909. height: 32px;
  910. line-height: 26px;
  911. font-family: "PangMenZhengDao";
  912. font-size: 14px;
  913. padding: 0 10px;
  914. color: #ffffff;
  915. background: url("@/assets/img/home/title-bg.png") no-repeat center center / 100% 100%;
  916. &.warning {
  917. background: url("@/assets/img/home/title-bg-warning.png") no-repeat center center / 100% 100%;
  918. }
  919. }
  920. .w-100 {
  921. width: 100%;
  922. }
  923. .box-text {
  924. padding: 22px 0 8px 0;
  925. font-weight: 350;
  926. line-height: 21px;
  927. width: 100%;
  928. box-sizing: border-box;
  929. .pre-text {
  930. white-space: pre-line;
  931. word-break: break-word;
  932. }
  933. .box-subtitle {
  934. color: #000;
  935. }
  936. .box-bg {
  937. font-weight: 400;
  938. color: rgba(0, 0, 0, 0.5);
  939. margin-bottom: 8px;
  940. }
  941. .types-info {
  942. background: rgba(33, 153, 248, 0.1);
  943. color: #000000;
  944. padding: 6px;
  945. border-radius: 5px;
  946. .text-bold {
  947. font-weight: bold;
  948. }
  949. }
  950. .tp-img {
  951. display: grid;
  952. grid-template-columns: repeat(3, 1fr);
  953. gap: 6px;
  954. width: 100%;
  955. margin-top: 8px;
  956. box-sizing: border-box;
  957. img {
  958. width: 100%;
  959. height: 78px;
  960. object-fit: contain;
  961. }
  962. }
  963. .text-link {
  964. color: #2199F8;
  965. text-decoration: underline;
  966. }
  967. .report-part {
  968. color: rgba(0, 0, 0, 0.5);
  969. .part-title {
  970. background: #2199F8;
  971. height: 24px;
  972. line-height: 24px;
  973. padding: 0 8px;
  974. color: #fff;
  975. border-radius: 2px;
  976. width: fit-content;
  977. }
  978. .part-text {
  979. padding-top: 6px;
  980. }
  981. .part-top {
  982. display: flex;
  983. align-items: center;
  984. justify-content: space-between;
  985. .part-link {
  986. display: inline-flex;
  987. align-items: center;
  988. gap: 4px;
  989. color: #2199F8;
  990. .part-link-icon {
  991. transform: rotate(270deg);
  992. }
  993. }
  994. }
  995. }
  996. .warning-part + .warning-part {
  997. margin-top: 8px;
  998. }
  999. .report-part + .report-part {
  1000. margin-top: 8px;
  1001. }
  1002. .warning-part {
  1003. background: rgba(178, 178, 178, 0.08);
  1004. border-radius: 5px;
  1005. padding: 11px 6px 6px;
  1006. color: rgba(0, 0, 0, 0.5);
  1007. width: 100%;
  1008. box-sizing: border-box;
  1009. .warning-title {
  1010. display: flex;
  1011. align-items: center;
  1012. justify-content: center;
  1013. gap: 10px;
  1014. padding-bottom: 13px;
  1015. .title-l {
  1016. display: flex;
  1017. align-items: center;
  1018. .title-line {
  1019. width: 76px;
  1020. height: 1px;
  1021. background: linear-gradient(90deg, rgba(118, 118, 118, 0) 0%, rgba(118, 118, 118, 0.4) 100%);
  1022. &.title-line-right {
  1023. background: linear-gradient(270deg, rgba(118, 118, 118, 0) 0%, rgba(118, 118, 118, 0.4) 100%);
  1024. }
  1025. }
  1026. .title-block {
  1027. width: 6px;
  1028. height: 6px;
  1029. background: rgba(61, 61, 61, 0.2);
  1030. transform: rotate(45deg);
  1031. }
  1032. }
  1033. }
  1034. }
  1035. .box-advice {
  1036. color: rgba(0, 0, 0, 0.5);
  1037. padding-top: 10px;
  1038. }
  1039. .box-sum {
  1040. margin-top: 10px;
  1041. background: rgba(33, 153, 248, 0.1);
  1042. border-radius: 5px;
  1043. padding: 10px;
  1044. line-height: 20px;
  1045. color: #2199F8;
  1046. }
  1047. &.next-info {
  1048. padding: 8px 0 8px 0;
  1049. }
  1050. }
  1051. .row {
  1052. display: grid;
  1053. grid-template-columns: repeat(3, 1fr);
  1054. gap: 6px;
  1055. .status-card {
  1056. border-radius: 2px;
  1057. padding: 7px 0;
  1058. background: #ffffff;
  1059. border: 0.5px solid #e5e6eb;
  1060. color: #000;
  1061. display: flex;
  1062. flex-direction: column;
  1063. align-items: center;
  1064. justify-content: center;
  1065. &.today-red {
  1066. background: #FF6A6A;
  1067. color: #fff;
  1068. .status-sub {
  1069. color: #fff;
  1070. }
  1071. }
  1072. &.pending-card {
  1073. color: #fff;
  1074. position: relative;
  1075. padding: 9px 0 7px 0;
  1076. .tag-name {
  1077. position: absolute;
  1078. top: -8px;
  1079. right: 0;
  1080. background: #fff;
  1081. color: #FF6A6A;
  1082. font-size: 10px;
  1083. height: 17px;
  1084. line-height: 17px;
  1085. padding: 0 3px;
  1086. border-radius: 2px;
  1087. box-sizing: border-box;
  1088. border: 0.5px solid #FF6A6A;
  1089. }
  1090. }
  1091. .status-badge {
  1092. // position: absolute;
  1093. // top: 0;
  1094. // right: 0;
  1095. }
  1096. .status-title {
  1097. font-size: 16px;
  1098. line-height: 24px;
  1099. &.status-title-small {
  1100. font-size: 13px;
  1101. line-height: 18px;
  1102. }
  1103. }
  1104. .status-sub {
  1105. font-size: 10px;
  1106. color: rgba(32, 32, 32, 0.4);
  1107. line-height: 15px;
  1108. &.pending-sub {
  1109. color: #fff;
  1110. line-height: 13px;
  1111. }
  1112. }
  1113. &.risk-strong {
  1114. background: #FF6A6A;
  1115. border-color: #FF6A6A;
  1116. .status-title,
  1117. .status-sub {
  1118. color: #ffffff;
  1119. }
  1120. }
  1121. &.danger {
  1122. background: #FFE9E9;
  1123. border-color: #ff8e8e;
  1124. .status-sub {
  1125. color: #FF6A6A;
  1126. }
  1127. }
  1128. }
  1129. }
  1130. }
  1131. .report-box+.report-box {
  1132. margin-top: 20px;
  1133. }
  1134. .report-excute {
  1135. position: relative;
  1136. margin-top: 12px;
  1137. .tag-label {
  1138. position: absolute;
  1139. top: 0;
  1140. left: 0;
  1141. padding: 4px 10px;
  1142. background: rgba(54, 52, 52, 0.8);
  1143. color: #fff;
  1144. font-size: 12px;
  1145. border-radius: 8px 0 8px 0;
  1146. z-index: 1;
  1147. }
  1148. ::v-deep {
  1149. .carousel-container .carousel-wrapper .carousel-img {
  1150. min-width: calc(100vw - 32px);
  1151. width: calc(100vw - 32px);
  1152. }
  1153. }
  1154. }
  1155. }
  1156. .download-btn {
  1157. position: fixed;
  1158. bottom: 20px;
  1159. left: 50%;
  1160. // background: #fff;
  1161. // box-shadow: 2px 2px 4.5px 0px #00000066;
  1162. // width: 100%;
  1163. transform: translateX(-50%);
  1164. }
  1165. .review-hide-box {
  1166. position: absolute;
  1167. left: 0;
  1168. width: 100%;
  1169. height: 100%;
  1170. z-index: -1;
  1171. bottom: 0;
  1172. }
  1173. .review-image {
  1174. position: relative;
  1175. display: flex;
  1176. align-items: center;
  1177. justify-content: center;
  1178. gap: 8px;
  1179. margin: 12px;
  1180. background: #fff;
  1181. border-radius: 8px;
  1182. .review-mask {
  1183. z-index: 1;
  1184. pointer-events: none;
  1185. position: absolute;
  1186. left: 0;
  1187. top: 0;
  1188. width: 100%;
  1189. height: 100%;
  1190. border-radius: 8px;
  1191. background: linear-gradient(360deg,
  1192. rgba(0, 0, 0, 0.78) 0%,
  1193. rgba(0, 0, 0, 0.437208) 19.87%,
  1194. rgba(0, 0, 0, 0) 33.99%);
  1195. display: flex;
  1196. flex-direction: column;
  1197. align-items: baseline;
  1198. justify-content: end;
  1199. padding: 12px;
  1200. box-sizing: border-box;
  1201. color: #fff;
  1202. .review-text {
  1203. font-family: "PangMenZhengDao";
  1204. font-size: 16px;
  1205. margin-bottom: 1px;
  1206. }
  1207. .review-content {
  1208. font-size: 10px;
  1209. line-height: 15px;
  1210. }
  1211. }
  1212. .vs-wrap {
  1213. position: absolute;
  1214. left: 50%;
  1215. top: 50%;
  1216. transform: translate(-50%, -50%);
  1217. width: 40px;
  1218. height: 40px;
  1219. z-index: 10;
  1220. img {
  1221. width: 100%;
  1222. height: 100%;
  1223. object-fit: cover;
  1224. }
  1225. }
  1226. .review-image-item {
  1227. position: relative;
  1228. flex: 1;
  1229. .review-image-item-title {
  1230. position: absolute;
  1231. top: 0;
  1232. left: 0;
  1233. background: rgba(54, 52, 52, 0.6);
  1234. padding: 4px 10px;
  1235. border-radius: 8px 0 8px 0;
  1236. backdrop-filter: 4px;
  1237. font-size: 12px;
  1238. color: #fff;
  1239. }
  1240. // .review-image-item-img {
  1241. // width: 100%;
  1242. // height: 250px;
  1243. // object-fit: cover;
  1244. // }
  1245. .review-image-item-img {
  1246. width: 100%;
  1247. height: 100%;
  1248. object-fit: cover;
  1249. object-position: center;
  1250. }
  1251. .left-img {
  1252. border-radius: 8px 0 0 8px;
  1253. }
  1254. .right-img {
  1255. border-radius: 0 8px 8px 0;
  1256. }
  1257. }
  1258. }
  1259. }
  1260. .cavans-popup {
  1261. width: 100%;
  1262. max-width: 100%;
  1263. max-height: 92vh;
  1264. background: none;
  1265. border-radius: 12px;
  1266. overflow: auto;
  1267. display: flex;
  1268. flex-direction: column;
  1269. backdrop-filter: 4px;
  1270. .cavans-content {
  1271. text-align: center;
  1272. padding: 0 12px;
  1273. height: fit-content;
  1274. overflow: auto;
  1275. .current-img {
  1276. width: 100%;
  1277. }
  1278. }
  1279. // 底部操作按钮
  1280. .bottom-actions {
  1281. flex-shrink: 0;
  1282. .action-buttons {
  1283. padding: 12px 0 4px 0;
  1284. display: flex;
  1285. justify-content: space-around;
  1286. .action-btn {
  1287. display: flex;
  1288. flex-direction: column;
  1289. align-items: center;
  1290. cursor: pointer;
  1291. &.text-btn {
  1292. font-size: 12px;
  1293. color: rgba(255, 255, 255, 0.7);
  1294. }
  1295. .icon-circle {
  1296. width: 48px;
  1297. height: 48px;
  1298. border-radius: 50%;
  1299. display: flex;
  1300. align-items: center;
  1301. justify-content: center;
  1302. color: #fff;
  1303. margin-bottom: 4px;
  1304. .el-icon {
  1305. color: #fff;
  1306. }
  1307. img {
  1308. width: 50px;
  1309. }
  1310. }
  1311. &.blue-btn .icon-circle {
  1312. background: #2199f8;
  1313. }
  1314. &.green-btn .icon-circle {
  1315. background: #07c160;
  1316. }
  1317. &.orange-btn .icon-circle {
  1318. background: #ff790b;
  1319. }
  1320. .btn-label {
  1321. font-size: 12px;
  1322. color: #fff;
  1323. }
  1324. }
  1325. }
  1326. .cancel-btn {
  1327. text-align: center;
  1328. font-size: 18px;
  1329. color: #fff;
  1330. cursor: pointer;
  1331. }
  1332. }
  1333. }
  1334. </style>