index.vue 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  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. <weather-info ref="weatherInfoRef" from="growth_report" class="weather-info" @weatherExpanded="weatherExpanded"
  7. @changeGarden="changeGarden" :isGarden="true"></weather-info>
  8. <div class="report-content-wrap" v-if="hasReport" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.1)">
  9. <swipe class="my-swipe" :loop="false" indicator-color="white" @change="handleSwipeChange">
  10. <swipe-item v-for="(item, index) in regionsData" :key="index">
  11. <div class="report-content has-report" :style="{ minHeight: `calc(100vh - ${tabBarHeight}px)` }">
  12. <!-- <img src="@/assets/img/home/qrcode.png" alt="" class="code-icon" /> -->
  13. <img class="header-img" src="@/assets/img/home/report.png" alt="" />
  14. <div class="report-header">
  15. <!-- <img class="header-book" src="@/assets/img/home/book.png" alt="" /> -->
  16. <div class="time-tag">{{ workItems?.[0]?.reportDate }}</div>
  17. <div class="report-title">{{regionsData[currentIndex]?.regionName}}长势报告</div>
  18. <div class="report-info">
  19. <div class="info-item">
  20. <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
  21. <span class="info-text">{{ currentFarmName }}</span>
  22. </div>
  23. </div>
  24. <!-- 左滑查看更多 -->
  25. <div class="swipe-more-tag" v-show="currentIndex < regionsData.length - 1">
  26. 左滑查看更多分区
  27. </div>
  28. </div>
  29. <div class="report-box">
  30. <div class="box-title warning">今日巡园重点</div>
  31. <div class="box-text w-100">
  32. <div class="row">
  33. <div v-for="(card, cardI) in todayPatrolFocus" :key="cardI" class="status-card" :class="card.type"
  34. >
  35. <!-- <badge class="status-badge" dot
  36. :offset="[80, -10]">
  37. </badge> -->
  38. <div class="status-title">
  39. {{ card.title }}
  40. </div>
  41. <div class="status-sub" v-if="card.source === 'NEXT_PHENOLOGY'">
  42. 预计{{card.daysUntilNext}}天后进入
  43. </div>
  44. <div class="status-sub" v-else>
  45. {{ card.description }}
  46. </div>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. <div class="report-box">
  52. <div class="box-title warning">待执行农事</div>
  53. <div class="box-text w-100">
  54. <div class="row">
  55. <div v-for="(card, cardI) in pendingFarmWork" :key="cardI" class="status-card pending-card" :style="{ background: card.purposeColor }" :class="card.type"
  56. >
  57. <!-- <badge class="status-badge" dot
  58. :offset="[80, -10]">
  59. </badge> -->
  60. <!-- <div class="tag-name" :style="{ borderColor: card.purposeColor, color: card.purposeColor }">限时 3 天</div> -->
  61. <div class="status-title">
  62. {{ card.name }}
  63. </div>
  64. <div class="status-sub pending-sub">
  65. {{ card.status }}
  66. </div>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. <div class="report-box" v-for="(work, workI) in workItems" :key="workI">
  72. <div class="box-title">{{ work?.title }}</div>
  73. <div class="box-text">
  74. <div class="box-bg" v-show="work?.backgroundDesc">
  75. <span class="box-subtitle">背景描述:</span>
  76. <div v-html="work?.backgroundDesc"></div>
  77. </div>
  78. <div class="box-advice" v-show="work?.suggestion">
  79. <span class="box-subtitle">对策建议:</span>
  80. <div v-html="work?.suggestion"></div>
  81. </div>
  82. <div class="box-sum" v-show="work?.summary" v-html="work?.summary"></div>
  83. </div>
  84. </div>
  85. <!-- <div class="report-box">
  86. <div class="box-text next-info">
  87. <div class="box-bg">
  88. <span class="box-subtitle">下一次农情互动预告:</span>
  89. <div v-html="workItem?.nextInteractionPreview"></div>
  90. </div>
  91. </div>
  92. </div> -->
  93. </div>
  94. </swipe-item>
  95. </swipe>
  96. </div>
  97. <div v-else class="fake-report-wrap report-content-wrap">
  98. <div class="report-content">
  99. <img class="header-img" src="@/assets/img/home/report.png" alt="" />
  100. <div class="report-header">
  101. <!-- <img class="header-book" src="@/assets/img/home/book.png" alt="" /> -->
  102. <div class="time-tag">{{ new Date().toISOString().split('T')[0] }}</div>
  103. <div class="report-title" @click="handleAddFarm">作物长势报告</div>
  104. <div class="report-info pb-4">
  105. <div class="info-item">
  106. <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
  107. <span class="info-text">示范农场</span>
  108. </div>
  109. </div>
  110. </div>
  111. <div class="fake-img">
  112. <img src="@/assets/img/home/fake.png" alt="" class="fake-img-item" />
  113. </div>
  114. <div class="lock-img">
  115. <img @click="handleLockClick" src="@/assets/img/home/lock-blue.png" alt="" class="has-click lock-img-item" />
  116. <div class="lock-text">
  117. 专属数字农场,种好卖好
  118. <div>点击解锁一键溯源增产</div>
  119. </div>
  120. <div @click="handleLockClick" class="lock-btn has-click">点击解锁</div>
  121. </div>
  122. <div class="lock-bg"></div>
  123. </div>
  124. </div>
  125. <!-- 首次进入页面的左滑查看提示遮罩 -->
  126. <div class="swipe-guide-mask" v-if="showSwipeGuide" @click="closeSwipeGuide">
  127. <div class="swipe-guide-content">
  128. <img class="swipe-guide-icon" src="@/assets/img/home/point.png" alt="swipe" />
  129. <div class="swipe-guide-text">左滑查看其它分区报告</div>
  130. </div>
  131. </div>
  132. <tip-popup v-model:show="showBindSuccess" type="success" text="您的农场已绑定成功" hideBtn />
  133. <start-interact-popup ref="startInteractPopupRef" />
  134. <agri-execute-popup ref="agriExecutePopupRef" />
  135. </div>
  136. </template>
  137. <script setup>
  138. import wx from "weixin-js-sdk";
  139. import weatherInfo from "@/components/weatherInfo.vue";
  140. import { ref, onActivated, onDeactivated, onUnmounted, computed } from "vue";
  141. import { useRoute, useRouter } from "vue-router";
  142. import { useStore } from "vuex";
  143. import { Swipe, SwipeItem, Badge } from 'vant';
  144. import tipPopup from "@/components/popup/tipPopup.vue";
  145. import startInteractPopup from "@/components/popup/startInteractPopup.vue";
  146. import agriExecutePopup from "@/components/popup/agriExecutePopup.vue";
  147. const store = useStore();
  148. const tabBarHeight = computed(() => store.state.home.tabBarHeight);
  149. const route = useRoute();
  150. const router = useRouter();
  151. const loading = ref(false);
  152. const hasReport = ref(false);
  153. const workItems = ref([]);
  154. const paramsPage = ref({});
  155. const showBindSuccess = ref(false);
  156. const startInteractPopupRef = ref(null);
  157. const agriExecutePopupRef = ref(null);
  158. // 天气组件相关
  159. const isExpanded = ref(false);
  160. const weatherInfoRef = ref(null);
  161. // 首次进入页面的左滑提示遮罩
  162. const showSwipeGuide = ref(false);
  163. const weatherExpanded = (isExpandedValue) => {
  164. isExpanded.value = isExpandedValue;
  165. };
  166. // 点击遮罩时收起天气
  167. const handleMaskClick = () => {
  168. if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
  169. weatherInfoRef.value.toggleExpand();
  170. }
  171. };
  172. const currentFarmName = ref('');
  173. // 切换农场时,更新报告数据
  174. const changeGarden = ({ id, name }) => {
  175. if (!id) return;
  176. currentFarmName.value = name;
  177. paramsPage.value = {
  178. ...(paramsPage.value || {}),
  179. subjectId: id,
  180. };
  181. // 初始化品种/大物候期转换
  182. startInteractPopupRef.value.getPhenologyInitOrConfirmStatus();
  183. getRegions();
  184. if(regionsData.value.length && !route.query.hideInteraction) {
  185. agriExecutePopupRef.value.showPopup(regionsData.value[currentIndex.value].farmId);
  186. }
  187. };
  188. onActivated(() => {
  189. window.scrollTo(0, 0);
  190. // 如果路由中带有 miniJson,并且其中有 showBind,则展示绑定成功弹窗
  191. const { miniJson } = route.query || {};
  192. if (miniJson) {
  193. try {
  194. const parsed = typeof miniJson === "string" ? JSON.parse(miniJson) : miniJson;
  195. if (parsed && parsed.showBind) {
  196. showBindSuccess.value = true;
  197. // 处理完后清空路由中的 miniJson 参数,避免重复弹出
  198. const newQuery = { ...(route.query || {}) };
  199. delete newQuery.miniJson;
  200. router.replace({ path: route.path, query: newQuery });
  201. }
  202. } catch (e) {
  203. // miniJson 解析失败时忽略,不影响正常流程
  204. }
  205. }
  206. // getResultReport();
  207. });
  208. // 关闭左滑提示遮罩
  209. const closeSwipeGuide = () => {
  210. showSwipeGuide.value = false;
  211. };
  212. const userInfo = localStorage.getItem("localUserInfo");
  213. const userInfoObj = userInfo ? JSON.parse(userInfo) : {};
  214. const handleLockClick = () => {
  215. if (currentFarmName.value) {
  216. router.push("/interaction?subjectId=" + localStorage.getItem("selectedFarmId"));
  217. return;
  218. }
  219. if (userInfoObj?.tel) {
  220. router.push(`/create_farm?from=growth_report&isReload=true`);
  221. return;
  222. }
  223. wx.miniProgram.navigateTo({
  224. url: '/pages/subPages/phone_auth/index',
  225. });
  226. }
  227. const handleAddFarm = () => {
  228. router.push(`/create_farm?from=growth_report&isReload=true`);
  229. }
  230. const todayPatrolFocus = ref([]);
  231. const pendingFarmWork = ref([]);
  232. const getTodayPatrolFocus = () => {
  233. VE_API.report.todayPatrolFocus({ farmId: paramsPage.value.farmId, regionId:paramsPage.value.regionId }).then(({ data }) => {
  234. todayPatrolFocus.value = data || [];
  235. });
  236. }
  237. const getPendingFarmWork = () => {
  238. VE_API.report.pendingFarmWork({ farmId: paramsPage.value.farmId, regionId: paramsPage.value.regionId }).then(({ data }) => {
  239. pendingFarmWork.value = data || [];
  240. });
  241. }
  242. const currentIndex = ref(0);
  243. const handleSwipeChange = (index) => {
  244. currentIndex.value = index;
  245. if (paramsPage.value.regionId !== regionsData.value[index].regionId) {
  246. paramsPage.value = {
  247. ...(paramsPage.value || {}),
  248. farmId: regionsData.value[index].farmId,
  249. regionId: regionsData.value[index].regionId,
  250. };
  251. getTodayPatrolFocus();
  252. getPendingFarmWork();
  253. getDetail();
  254. }
  255. }
  256. const getDetail = () => {
  257. if (!paramsPage.value.farmId) return;
  258. loading.value = true;
  259. VE_API.report
  260. .reproductiveReport({ farmId: paramsPage.value.farmId, regionId: paramsPage.value.regionId })
  261. .then(({ data }) => {
  262. workItems.value = data || [];
  263. })
  264. .finally(() => {
  265. loading.value = false;
  266. });
  267. };
  268. const regionsData = ref([]);
  269. const getRegions = async () => {
  270. VE_API.monitor.listRegionsBySubjectId({
  271. subjectId: paramsPage.value.subjectId,
  272. }).then(({ data }) => {
  273. regionsData.value = data || [];
  274. if(regionsData.value.length > 0) {
  275. const guideKey = "GROWTH_REPORT_SWIPE_GUIDE_SHOWN";
  276. if (!localStorage.getItem(guideKey) && regionsData.value.length > 1) {
  277. showSwipeGuide.value = true;
  278. localStorage.setItem(guideKey, "1");
  279. }
  280. hasReport.value = true;
  281. paramsPage.value = {
  282. ...(paramsPage.value || {}),
  283. farmId: regionsData.value[currentIndex.value].farmId,
  284. regionId: regionsData.value[currentIndex.value].regionId,
  285. };
  286. getTodayPatrolFocus();
  287. getPendingFarmWork();
  288. getDetail();
  289. } else {
  290. hasReport.value = false;
  291. }
  292. });
  293. }
  294. // 清理数据的函数
  295. const clearData = () => {
  296. workItems.value = [];
  297. paramsPage.value = {};
  298. loading.value = false;
  299. };
  300. onDeactivated(() => {
  301. clearData();
  302. });
  303. onUnmounted(() => {
  304. clearData();
  305. });
  306. </script>
  307. <style lang="scss" scoped>
  308. .achievement-report-page {
  309. width: 100%;
  310. height: 100vh;
  311. background: linear-gradient(195.35deg, #d4e4ff 16.34%, rgba(93, 189, 255, 0) 50.3%),
  312. linear-gradient(156.64deg, rgba(255, 255, 255, 0.16) 27.7%, rgba(255, 255, 255, 0) 72.82%);
  313. .weather-mask {
  314. position: fixed;
  315. top: 0;
  316. left: 0;
  317. width: 100%;
  318. height: 100%;
  319. background-color: rgba(0, 0, 0, 0.52);
  320. z-index: 11;
  321. }
  322. .weather-info {
  323. width: calc(100% - 20px);
  324. position: absolute;
  325. z-index: 12;
  326. left: 10px;
  327. top: 12px;
  328. }
  329. .fake-report-wrap {
  330. width: 100%;
  331. .no-report-img {
  332. width: 100%;
  333. }
  334. .fake-img {
  335. position: relative;
  336. .fake-img-item {
  337. width: 100%;
  338. }
  339. }
  340. }
  341. .report-content-wrap {
  342. height: 100%;
  343. // padding-bottom: 60px;
  344. overflow: auto;
  345. box-sizing: border-box;
  346. position: relative;
  347. .bottom-btn {
  348. z-index: 2;
  349. position: fixed;
  350. bottom: 0;
  351. left: 0;
  352. width: 100%;
  353. background: #fff;
  354. height: 60px;
  355. display: flex;
  356. align-items: center;
  357. justify-content: space-between;
  358. padding: 0 12px;
  359. box-sizing: border-box;
  360. box-shadow: 2px 2px 4.5px 0px rgba(0, 0, 0, 0.4);
  361. .btn-item {
  362. height: 40px;
  363. line-height: 40px;
  364. padding: 0 24px;
  365. border-radius: 20px;
  366. font-size: 14px;
  367. &.second {
  368. color: #666666;
  369. border: 1px solid rgba(153, 153, 153, 0.5);
  370. }
  371. &.primay {
  372. padding: 0 34px;
  373. background: linear-gradient(180deg, #76c3ff, #2199f8);
  374. color: #fff;
  375. }
  376. }
  377. }
  378. }
  379. // 首次进入页面左滑提示遮罩
  380. .swipe-guide-mask {
  381. position: fixed;
  382. left: 0;
  383. top: 0;
  384. width: 100%;
  385. height: 100%;
  386. background: rgba(0, 0, 0, 0.6);
  387. z-index: 99999;
  388. display: flex;
  389. align-items: center;
  390. justify-content: center;
  391. .swipe-guide-content {
  392. display: flex;
  393. flex-direction: column;
  394. align-items: center;
  395. justify-content: center;
  396. color: #ffffff;
  397. text-align: center;
  398. }
  399. .swipe-guide-icon {
  400. width: 71px;
  401. height: 79px;
  402. object-fit: contain;
  403. margin-bottom: 23px;
  404. }
  405. .swipe-guide-text {
  406. font-size: 20px;
  407. }
  408. }
  409. .code-icon {
  410. position: absolute;
  411. right: 10px;
  412. top: 12px;
  413. width: 48px;
  414. }
  415. .report-content {
  416. // background: url("@/assets/img/home/report_bg.png") no-repeat center center;
  417. // background: linear-gradient(0deg, #9BCCFF, #9BCCFF),
  418. // linear-gradient(160deg, rgba(255, 255, 255, 0.16) 30%, rgba(255, 255, 255, 0) 72%);
  419. background: #abd4ff;
  420. background-size: 100% auto;
  421. background-position: top center;
  422. padding: 0 16px 26px 16px;
  423. box-sizing: border-box;
  424. position: relative;
  425. &.has-report {
  426. min-height: 100%;
  427. background: linear-gradient(0deg, #9BCCFF, #9BCCFF),
  428. linear-gradient(156.64deg, rgba(255, 255, 255, 0.16) 27.7%, rgba(255, 255, 255, 0) 72.82%);
  429. }
  430. .lock-bg {
  431. position: absolute;
  432. top: 230px;
  433. left: 0;
  434. width: 100%;
  435. height: calc(100% - 230px);
  436. background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.38) 50%, rgba(255, 255, 255, 0) 100%),
  437. linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2));
  438. }
  439. .lock-img {
  440. pointer-events: none;
  441. position: fixed;
  442. z-index: 10;
  443. top: 50%;
  444. left: 50%;
  445. transform: translate(-50%, -20%);
  446. width: 100%;
  447. display: flex;
  448. align-items: center;
  449. justify-content: center;
  450. flex-direction: column;
  451. gap: 16px;
  452. .lock-img-item {
  453. width: 57px;
  454. }
  455. .has-click {
  456. pointer-events: auto;
  457. }
  458. .lock-text {
  459. font-size: 14px;
  460. color: #000;
  461. padding: 5px 64px;
  462. line-height: 21px;
  463. background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #FFFFFF 50%, rgba(255, 255, 255, 0) 100%);
  464. }
  465. .lock-btn {
  466. width: 140px;
  467. height: 40px;
  468. line-height: 40px;
  469. text-align: center;
  470. background: linear-gradient(180deg, #76C3FF 0%, #2199F8 100%);
  471. border-radius: 25px;
  472. color: #fff;
  473. font-size: 16px;
  474. }
  475. }
  476. .header-img {
  477. position: absolute;
  478. top: 0;
  479. left: 0;
  480. width: 100%;
  481. }
  482. .report-header {
  483. position: relative;
  484. padding-top: 112px;
  485. .header-book {
  486. position: absolute;
  487. right: 0;
  488. bottom: -6px;
  489. height: 88px;
  490. z-index: 10;
  491. }
  492. .time-tag {
  493. background: #2199F8;
  494. border-radius: 5px 0 5px 0;
  495. height: 23px;
  496. line-height: 23px;
  497. font-size: 13px;
  498. font-weight: 500;
  499. color: #fff;
  500. padding: 0 9px;
  501. width: fit-content;
  502. margin-bottom: 2px;
  503. }
  504. .report-title {
  505. font-family: "PangMenZhengDao";
  506. font-size: 34px;
  507. line-height: 38px;
  508. color: #000000;
  509. }
  510. .report-info {
  511. padding: 12px 0 28px 0;
  512. &.pb-4 {
  513. padding-bottom: 4px;
  514. }
  515. .info-item {
  516. width: fit-content;
  517. display: flex;
  518. height: 33px;
  519. align-items: center;
  520. padding: 0 18px 0 6px;
  521. background: linear-gradient(90deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 255, 255, 0.0696) 100%);
  522. border-radius: 20px;
  523. border: 0.5px solid rgba(33, 153, 248, 0.35);
  524. gap: 6px;
  525. .info-icon {
  526. width: 26px;
  527. height: 26px;
  528. object-fit: cover;
  529. border-radius: 50%;
  530. }
  531. .info-text {
  532. font-size: 14px;
  533. color: #000;
  534. }
  535. }
  536. .info-item+.info-item {
  537. margin-top: 5px;
  538. }
  539. }
  540. // 左滑查看更多标签
  541. .swipe-more-tag {
  542. position: absolute;
  543. bottom: 10px;
  544. right: -16px;
  545. box-sizing: border-box;
  546. width: 36px;
  547. height: 134px;
  548. padding: 0px 10px 2px 0;
  549. background: rgba(0, 0, 0, 0.7);
  550. border-radius: 10px 0 0 10px;
  551. letter-spacing: 2px;
  552. color: #ffffff;
  553. font-size: 12px;
  554. text-align: center;
  555. line-height: 20px;
  556. writing-mode: vertical-rl;
  557. text-orientation: mixed;
  558. }
  559. }
  560. .report-box {
  561. display: flex;
  562. align-items: center;
  563. padding: 8px;
  564. background: linear-gradient(0deg, #ffffff 86.32%, #2199f8 136.87%);
  565. border: 1px solid #ffffff;
  566. border-radius: 8px;
  567. gap: 5px;
  568. position: relative;
  569. .report-box-item {
  570. flex: 1;
  571. background: rgba(33, 153, 248, 0.1);
  572. border-radius: 8px;
  573. min-height: 62px;
  574. box-sizing: border-box;
  575. padding: 2px 4px;
  576. display: flex;
  577. flex-direction: column;
  578. justify-content: center;
  579. .item-content {
  580. color: #2199f8;
  581. font-size: 14px;
  582. text-align: center;
  583. }
  584. .item-title {
  585. color: #000000;
  586. font-size: 10px;
  587. text-align: center;
  588. padding-top: 5px;
  589. }
  590. }
  591. .box-title {
  592. position: absolute;
  593. top: -8px;
  594. left: -1px;
  595. height: 32px;
  596. line-height: 26px;
  597. font-family: "PangMenZhengDao";
  598. font-size: 14px;
  599. padding: 0 10px;
  600. color: #ffffff;
  601. background: url("@/assets/img/home/title-bg.png") no-repeat center center / 100% 100%;
  602. &.warning {
  603. background: url("@/assets/img/home/title-bg-warning.png") no-repeat center center / 100% 100%;
  604. }
  605. }
  606. .w-100 {
  607. width: 100%;
  608. }
  609. .box-text {
  610. padding: 22px 0 8px 0;
  611. font-weight: 350;
  612. line-height: 21px;
  613. .box-subtitle {
  614. color: #000;
  615. }
  616. .box-bg {
  617. font-weight: 400;
  618. color: rgba(0, 0, 0, 0.5);
  619. }
  620. .box-advice {
  621. color: rgba(0, 0, 0, 0.5);
  622. padding-top: 10px;
  623. }
  624. .box-sum {
  625. margin-top: 10px;
  626. background: rgba(33, 153, 248, 0.1);
  627. border-radius: 5px;
  628. padding: 10px;
  629. line-height: 20px;
  630. color: #2199F8;
  631. }
  632. &.next-info {
  633. padding: 8px 0 8px 0;
  634. }
  635. }
  636. .row {
  637. display: grid;
  638. grid-template-columns: repeat(3, 1fr);
  639. gap: 6px;
  640. .status-card {
  641. border-radius: 2px;
  642. padding: 7px 0;
  643. background: #ffffff;
  644. border: 0.5px solid #e5e6eb;
  645. color: #000;
  646. display: flex;
  647. flex-direction: column;
  648. align-items: center;
  649. justify-content: center;
  650. &.pending-card {
  651. color: #fff;
  652. position: relative;
  653. padding: 9px 0 7px 0;
  654. .tag-name {
  655. position: absolute;
  656. top: -8px;
  657. right: 0;
  658. background: #fff;
  659. color: #FF6A6A;
  660. font-size: 10px;
  661. height: 17px;
  662. line-height: 17px;
  663. padding: 0 3px;
  664. border-radius: 2px;
  665. box-sizing: border-box;
  666. border: 0.5px solid #FF6A6A;
  667. }
  668. }
  669. .status-badge {
  670. // position: absolute;
  671. // top: 0;
  672. // right: 0;
  673. }
  674. .status-title {
  675. font-size: 16px;
  676. line-height: 24px;
  677. }
  678. .status-sub {
  679. font-size: 10px;
  680. color: rgba(32, 32, 32, 0.4);
  681. &.pending-sub {
  682. color: #fff;
  683. line-height: 13px;
  684. }
  685. }
  686. &.risk-strong {
  687. background: #FF6A6A;
  688. border-color: #FF6A6A;
  689. .status-title,
  690. .status-sub {
  691. color: #ffffff;
  692. }
  693. }
  694. &.danger {
  695. background: #FFE9E9;
  696. border-color: #ff8e8e;
  697. .status-sub {
  698. color: #FF6A6A;
  699. }
  700. }
  701. }
  702. }
  703. }
  704. .report-box+.report-box {
  705. margin-top: 20px;
  706. }
  707. .report-excute {
  708. position: relative;
  709. margin-top: 12px;
  710. .tag-label {
  711. position: absolute;
  712. top: 0;
  713. left: 0;
  714. padding: 4px 10px;
  715. background: rgba(54, 52, 52, 0.8);
  716. color: #fff;
  717. font-size: 12px;
  718. border-radius: 8px 0 8px 0;
  719. z-index: 1;
  720. }
  721. ::v-deep {
  722. .carousel-container .carousel-wrapper .carousel-img {
  723. min-width: calc(100vw - 32px);
  724. width: calc(100vw - 32px);
  725. }
  726. }
  727. }
  728. }
  729. .download-btn {
  730. position: fixed;
  731. bottom: 20px;
  732. left: 50%;
  733. // background: #fff;
  734. // box-shadow: 2px 2px 4.5px 0px #00000066;
  735. // width: 100%;
  736. transform: translateX(-50%);
  737. }
  738. .review-hide-box {
  739. position: absolute;
  740. left: 0;
  741. width: 100%;
  742. height: 100%;
  743. z-index: -1;
  744. bottom: 0;
  745. }
  746. .review-image {
  747. position: relative;
  748. display: flex;
  749. align-items: center;
  750. justify-content: center;
  751. gap: 8px;
  752. margin: 12px;
  753. background: #fff;
  754. border-radius: 8px;
  755. .review-mask {
  756. z-index: 1;
  757. pointer-events: none;
  758. position: absolute;
  759. left: 0;
  760. top: 0;
  761. width: 100%;
  762. height: 100%;
  763. border-radius: 8px;
  764. background: linear-gradient(360deg,
  765. rgba(0, 0, 0, 0.78) 0%,
  766. rgba(0, 0, 0, 0.437208) 19.87%,
  767. rgba(0, 0, 0, 0) 33.99%);
  768. display: flex;
  769. flex-direction: column;
  770. align-items: baseline;
  771. justify-content: end;
  772. padding: 12px;
  773. box-sizing: border-box;
  774. color: #fff;
  775. .review-text {
  776. font-family: "PangMenZhengDao";
  777. font-size: 16px;
  778. margin-bottom: 1px;
  779. }
  780. .review-content {
  781. font-size: 10px;
  782. line-height: 15px;
  783. }
  784. }
  785. .vs-wrap {
  786. position: absolute;
  787. left: 50%;
  788. top: 50%;
  789. transform: translate(-50%, -50%);
  790. width: 40px;
  791. height: 40px;
  792. z-index: 10;
  793. img {
  794. width: 100%;
  795. height: 100%;
  796. object-fit: cover;
  797. }
  798. }
  799. .review-image-item {
  800. position: relative;
  801. flex: 1;
  802. .review-image-item-title {
  803. position: absolute;
  804. top: 0;
  805. left: 0;
  806. background: rgba(54, 52, 52, 0.6);
  807. padding: 4px 10px;
  808. border-radius: 8px 0 8px 0;
  809. backdrop-filter: 4px;
  810. font-size: 12px;
  811. color: #fff;
  812. }
  813. // .review-image-item-img {
  814. // width: 100%;
  815. // height: 250px;
  816. // object-fit: cover;
  817. // }
  818. .review-image-item-img {
  819. width: 100%;
  820. height: 100%;
  821. object-fit: cover;
  822. object-position: center;
  823. }
  824. .left-img {
  825. border-radius: 8px 0 0 8px;
  826. }
  827. .right-img {
  828. border-radius: 0 8px 8px 0;
  829. }
  830. }
  831. }
  832. }
  833. .cavans-popup {
  834. width: 100%;
  835. max-width: 100%;
  836. max-height: 92vh;
  837. background: none;
  838. border-radius: 12px;
  839. overflow: auto;
  840. display: flex;
  841. flex-direction: column;
  842. backdrop-filter: 4px;
  843. .cavans-content {
  844. text-align: center;
  845. padding: 0 12px;
  846. height: fit-content;
  847. overflow: auto;
  848. .current-img {
  849. width: 100%;
  850. }
  851. }
  852. // 底部操作按钮
  853. .bottom-actions {
  854. flex-shrink: 0;
  855. .action-buttons {
  856. padding: 12px 0 4px 0;
  857. display: flex;
  858. justify-content: space-around;
  859. .action-btn {
  860. display: flex;
  861. flex-direction: column;
  862. align-items: center;
  863. cursor: pointer;
  864. &.text-btn {
  865. font-size: 12px;
  866. color: rgba(255, 255, 255, 0.7);
  867. }
  868. .icon-circle {
  869. width: 48px;
  870. height: 48px;
  871. border-radius: 50%;
  872. display: flex;
  873. align-items: center;
  874. justify-content: center;
  875. color: #fff;
  876. margin-bottom: 4px;
  877. .el-icon {
  878. color: #fff;
  879. }
  880. img {
  881. width: 50px;
  882. }
  883. }
  884. &.blue-btn .icon-circle {
  885. background: #2199f8;
  886. }
  887. &.green-btn .icon-circle {
  888. background: #07c160;
  889. }
  890. &.orange-btn .icon-circle {
  891. background: #ff790b;
  892. }
  893. .btn-label {
  894. font-size: 12px;
  895. color: #fff;
  896. }
  897. }
  898. }
  899. .cancel-btn {
  900. text-align: center;
  901. font-size: 18px;
  902. color: #fff;
  903. cursor: pointer;
  904. }
  905. }
  906. }
  907. </style>