reviewWork.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. <template>
  2. <div class="work-wrap">
  3. <custom-header name="农事详情" :isClose="paramsPage.goBack ? false : true"></custom-header>
  4. <div
  5. class="work-content recheck-title"
  6. :class="{ 'no-bottom': curRole == '0' && (!workItem.reviewImage || !workItem.reviewImage.length) }"
  7. v-loading="loading"
  8. >
  9. <div class="tabs-content-item">
  10. <div class="common-card-title">
  11. <img class="icon" src="@/assets/img/home/label-icon.png" alt="" />
  12. <span>农事信息</span>
  13. </div>
  14. <div class="info-box">
  15. <div class="info-l">
  16. <img class="farm-img" src="@/assets/img/home/farm.png" alt="" />
  17. </div>
  18. <div class="info-r">
  19. <div class="farm-name">{{ workItem.farmName }}</div>
  20. <div class="info-item">
  21. <div class="info-name">农事名称:</div>
  22. <div class="info-value">{{ workItem.farmWorkName }} ({{ workItem.executeDate }})</div>
  23. </div>
  24. <div class="info-item">
  25. <div class="info-name">农事目的:</div>
  26. <div class="info-value">{{ workItem.purpose || "--" }}</div>
  27. </div>
  28. <div class="info-item">
  29. <div class="info-name">肥药处方:</div>
  30. <div class="info-value">
  31. <div class="rescription" v-if="workItem?.prescriptionList">
  32. <span
  33. v-for="(fertilizer, fertilizerI) in workItem.prescriptionList"
  34. :key="fertilizerI"
  35. >
  36. <span
  37. v-for="(pest, pestI) in fertilizer.pesticideFertilizerList"
  38. :key="'sub' + pestI"
  39. >
  40. {{ pest.defaultName || pest.pesticideFertilizerName }}
  41. <span
  42. v-if="
  43. pestI !== fertilizer.pesticideFertilizerList.length - 1 ||
  44. fertilizerI !== workItem.prescriptionList.length - 1
  45. "
  46. >
  47. +
  48. </span>
  49. </span>
  50. </span>
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. </div>
  56. <div class="info-box subject-content">
  57. <div class="subject-box">
  58. <div class="subject-item cost-l">
  59. <img class="subject-img" src="@/assets/img/home/nz.png" alt="" />
  60. <div class="subject-tag">
  61. {{ workItem.serviceMain }}
  62. <el-icon class="right-icon" size="10"><ArrowRight /></el-icon>
  63. </div>
  64. </div>
  65. <div class="subject-item">
  66. <img class="subject-img" :src="workItem.expertIcon" alt="" />
  67. <div class="subject-tag">
  68. {{ workItem.expertName }}
  69. <el-icon class="right-icon" size="10"><ArrowRight /></el-icon>
  70. </div>
  71. </div>
  72. </div>
  73. </div>
  74. </div>
  75. <div class="tabs-content-item">
  76. <div class="common-card-title">
  77. <img class="icon" src="@/assets/img/home/label-icon.png" alt="" />
  78. <span>复核成效</span>
  79. </div>
  80. <div class="info-box bottom-box">
  81. <div class="recheck-box">
  82. <div class="recheck-ablum">
  83. <div class="img-list over-img-box">
  84. <album-carousel :key="1" labelText="农事前" :images="triggerImg"></album-carousel>
  85. </div>
  86. <div class="img-list over-img-box">
  87. <album-carousel
  88. class="execute-img"
  89. :key="1"
  90. labelText="执行照片"
  91. :images="workItem.executeEvidence"
  92. ></album-carousel>
  93. </div>
  94. <div
  95. class="img-list over-img-box"
  96. v-if="workItem.reviewImage && workItem.reviewImage.length"
  97. >
  98. <album-carousel
  99. :key="2"
  100. labelText="农事后"
  101. :images="workItem.reviewImage"
  102. ></album-carousel>
  103. </div>
  104. <div class="img-list over-img-box" v-if="combinedReviewImages.length">
  105. <album-carousel :key="3" :images="combinedReviewImages"></album-carousel>
  106. </div>
  107. <div class="img-list" v-else>
  108. <div
  109. class="recheck-text-wrap active"
  110. :class="{
  111. 'center-wrap': !imageArr.length,
  112. }"
  113. >
  114. <div class="date" v-show="workItem.reviewDate">{{ workItem.reviewDate }}</div>
  115. <upload
  116. exampleImg
  117. @handleUpload="handleUpload"
  118. class="upload-wrap"
  119. :style="{
  120. height:
  121. imageArr.length && !diffInDays(workItem.reviewDate) > 0
  122. ? 'auto'
  123. : '254px',
  124. }"
  125. >
  126. <template
  127. v-if="
  128. diffInDays(workItem.reviewDate) == 0 ||
  129. diffInDays(workItem.reviewDate) == null
  130. "
  131. >
  132. <img
  133. class="img-icon"
  134. :src="require(`@/assets/img/gallery/img-icon-act.png`)"
  135. alt=""
  136. />
  137. <div class="recheck-text">点击上传照片</div>
  138. </template>
  139. <!-- <template v-else>
  140. <img class="img-icon" src="@/assets/img/gallery/img-icon.png" alt="" />
  141. <div class="recheck-text">等待复核</div>
  142. <div class="recheck-desc" v-show="diffInDays(workItem.reviewDate) >= 0">
  143. (剩余{{ diffInDays(workItem.reviewDate) }}天)
  144. </div>
  145. </template> -->
  146. </upload>
  147. <div
  148. class="submit"
  149. v-show="imageArr.length && !diffInDays(workItem.reviewDate) > 0"
  150. @click="handleSubmit('reviewImage2')"
  151. >
  152. 确认上传
  153. </div>
  154. </div>
  155. </div>
  156. <!-- <div class="img-list" v-else>
  157. <div
  158. class="recheck-text-wrap no-events"
  159. :class="{
  160. active: !diffInDays(workItem.reviewDate) > 0 && curRole === '0',
  161. 'yse-events': curRole === '0' && !diffInDays(workItem.reviewDate) > 0,
  162. 'center-wrap': !imageArr2.length,
  163. }"
  164. >
  165. <div class="date" v-show="workItem.reviewDate">{{ workItem.reviewDate }}</div>
  166. <upload
  167. exampleImg
  168. @handleUpload="handleUpload2"
  169. class="upload-wrap"
  170. :style="{
  171. height:
  172. imageArr2.length && !diffInDays(workItem.reviewDate) > 0
  173. ? 'auto'
  174. : '254px',
  175. }"
  176. >
  177. <template
  178. v-if="
  179. diffInDays(workItem.reviewDate) == 0 ||
  180. diffInDays(workItem.reviewDate) == null
  181. "
  182. >
  183. <img
  184. class="img-icon"
  185. :src="
  186. require(`@/assets/img/gallery/img-icon${
  187. curRole === '0' ? '-act' : ''
  188. }.png`)
  189. "
  190. alt=""
  191. />
  192. <div class="recheck-text">
  193. {{ curRole === "2" ? "等待农户上传" : "点击上传照片" }}
  194. </div>
  195. <div
  196. class="recheck-desc"
  197. v-show="curRole === '2' && diffInDays(workItem.reviewDate) != 0"
  198. >
  199. </div>
  200. </template>
  201. <template v-else>
  202. <img class="img-icon" src="@/assets/img/gallery/img-icon.png" alt="" />
  203. <div class="recheck-text">等待复核</div>
  204. <div class="recheck-desc" v-show="diffInDays(workItem.reviewDate) >= 0">
  205. (剩余{{ diffInDays(workItem.reviewDate) }}天)
  206. </div>
  207. </template>
  208. </upload>
  209. <div
  210. class="submit"
  211. v-show="imageArr2.length && !diffInDays(workItem.reviewDate) > 0"
  212. @click="handleSubmit('reviewImage2')"
  213. >
  214. 确认上传
  215. </div>
  216. </div>
  217. </div> -->
  218. </div>
  219. </div>
  220. </div>
  221. </div>
  222. <!-- 按钮 -->
  223. <div class="up-btn-group" v-show="isPlan">
  224. <template v-if="curRole === '2'">
  225. <div
  226. class="up-btn"
  227. :class="{ btn: workItem.executeEvidence && workItem.executeEvidence.length }"
  228. v-show="workItem.reviewImage && !workItem.reviewImage.length"
  229. >
  230. 提醒农户拍照
  231. </div>
  232. </template>
  233. <template v-else>
  234. <div
  235. class="up-btn btn"
  236. @click="handleContact"
  237. v-show="workItem.reviewImage && workItem.reviewImage.length && !imageArr.length"
  238. >
  239. 联系专家
  240. </div>
  241. </template>
  242. </div>
  243. <div class="fixed-btn-wrap" v-if="curRole == '2'">
  244. <template v-if="workItem.reviewImage && workItem.reviewImage.length">
  245. <div class="fixed-btn more" @click="handleMore">查看更多农事</div>
  246. <div class="fixed-btn excute" @click="handleShare">生成成果报告</div>
  247. </template>
  248. <template v-else>
  249. <div class="fixed-btn second" @click="handleRemindUser">提醒农户拍照</div>
  250. </template>
  251. </div>
  252. <div
  253. class="fixed-btn-wrap center"
  254. v-if="curRole == '0' && workItem.reviewImage && workItem.reviewImage.length"
  255. >
  256. <div class="fixed-btn excute" @click="handleShare">转发</div>
  257. </div>
  258. <!-- 组合照片(用于生成合成图片) -->
  259. <div class="review-hide-box">
  260. <div class="review-image" ref="reviewComboRef">
  261. <div class="review-mask">
  262. <div class="review-text">复核成效</div>
  263. <div class="review-content">
  264. 促进分蘖芽萌发、加快分蘖生长,同时补充氮素等关键养分,增强植株长势,为形成足够穗数、提高群体产量打基础。
  265. </div>
  266. </div>
  267. <div class="vs-wrap" v-if="workItem?.reviewImage && workItem?.reviewImage?.length">
  268. <img src="@/assets/img/home/vs.png" alt="" />
  269. </div>
  270. <div class="review-image-item" v-if="triggerImg?.length">
  271. <div class="review-image-item-title">农事前</div>
  272. <img
  273. class="review-image-item-img left-img"
  274. :src="base_img_url2 + triggerImg[triggerImg.length - 1].cloudFilename"
  275. alt=""
  276. />
  277. </div>
  278. <div class="review-image-item" v-if="workItem?.reviewImage?.length">
  279. <div class="review-image-item-title">农事后</div>
  280. <img
  281. class="review-image-item-img right-img"
  282. :src="base_img_url2 + workItem.reviewImage[workItem.reviewImage.length - 1]"
  283. alt=""
  284. />
  285. </div>
  286. </div>
  287. </div>
  288. </div>
  289. <!-- 上传图片弹窗 -->
  290. <upload-popup :executionData="workItem"></upload-popup>
  291. <!-- 分享农事成效弹窗 -->
  292. <review-popup ref="reviewPopupRef" />
  293. <!-- 上传农事成效弹窗 -->
  294. <upload-execute ref="uploadExecuteRef" :onlyShare="true" />
  295. </div>
  296. </template>
  297. <script setup>
  298. import { Tab, Tabs } from "vant";
  299. import customHeader from "@/components/customHeader.vue";
  300. import { onMounted, ref, onDeactivated, onActivated, onUnmounted, nextTick, watch } from "vue";
  301. import { useRoute, useRouter } from "vue-router";
  302. import upload from "@/components/upload";
  303. import AlbumCarousel from "@/components/album_compoents/albumCarousel";
  304. import { ElMessage } from "element-plus";
  305. import uploadPopup from "@/components/popup/uploadPopup.vue";
  306. import { base_img_url2 } from "@/api/config";
  307. import reviewPopup from "@/views/old_mini/task_condition/components/reviewPopup.vue";
  308. import uploadExecute from "@/views/old_mini/task_condition/components/uploadExecute.vue";
  309. import html2canvas from "html2canvas";
  310. const route = useRoute();
  311. const router = useRouter();
  312. const uploadExecuteRef = ref(null);
  313. const workItem = ref({});
  314. const curRole = ref("");
  315. // 农事规划页面-显示上传农事凭证按钮
  316. const isPlan = ref(false);
  317. const loading = ref(false);
  318. const reviewComboRef = ref(null);
  319. const combinedReviewImages = ref([]);
  320. const diffInDays = (date, type = "minus") => {
  321. const targetDate = new Date(date);
  322. const currentDate = new Date(); // 获取当前系统时间
  323. let diffInMs;
  324. if (type === "minus") {
  325. diffInMs = targetDate - currentDate;
  326. } else {
  327. diffInMs = currentDate - targetDate;
  328. }
  329. const day = Math.floor(diffInMs / (1000 * 60 * 60 * 24));
  330. return day + 1 >= 0 ? day + 1 : null;
  331. };
  332. const paramsPage = ref({});
  333. onActivated(() => {
  334. window.scrollTo(0, 0);
  335. curRole.value = localStorage.getItem("SET_USER_CUR_ROLE");
  336. paramsPage.value = route.query.miniJson ? JSON.parse(route.query.miniJson) : {};
  337. getDetail();
  338. getTriggerImg(paramsPage.value.id);
  339. });
  340. const getDetail = () => {
  341. if (!paramsPage.value.id) return;
  342. loading.value = true;
  343. VE_API.z_farm_work_record
  344. .getDetail({ id: paramsPage.value.id })
  345. .then(({ data }) => {
  346. workItem.value = data[0];
  347. })
  348. .finally(() => {
  349. loading.value = false;
  350. });
  351. };
  352. const triggerImg = ref([]);
  353. const getTriggerImg = (farmWorkRecordId) => {
  354. VE_API.z_farm_work_record.getTriggerImg({ farmWorkRecordId }).then(({ data }) => {
  355. triggerImg.value = data || [];
  356. });
  357. };
  358. // 生成组合照片,传给相册组件
  359. const generateCombinedReviewImage = async () => {
  360. if (!reviewComboRef.value) return;
  361. try {
  362. await nextTick();
  363. const el = reviewComboRef.value;
  364. const canvas = await html2canvas(el, {
  365. backgroundColor: "#ffffff00",
  366. allowTaint: true, // 允许跨域图片
  367. useCORS: true, // 使用CORS
  368. scale: 2, // 提高分辨率(2倍)
  369. logging: true, // 开启日志(调试用)
  370. });
  371. const dataUrl = canvas.toDataURL("image/png");
  372. combinedReviewImages.value = [dataUrl];
  373. } catch (e) {
  374. console.error("生成组合照片失败", e);
  375. }
  376. };
  377. watch(
  378. () => [triggerImg.value, workItem.value.reviewImage],
  379. ([preImgs, reviewImgs]) => {
  380. if (preImgs && preImgs.length && reviewImgs && reviewImgs.length) {
  381. generateCombinedReviewImage();
  382. }
  383. },
  384. { deep: true }
  385. );
  386. //确认上传
  387. const handleSubmit = () => {
  388. const params = {
  389. executeEvidence: imageArr.value,
  390. recordId: workItem.value.id,
  391. };
  392. VE_API.monitor.addReviewImg(params).then(({ code }) => {
  393. if (code === 0) {
  394. getDetail();
  395. ElMessage.success("您已上传成功");
  396. imageArr.value = [];
  397. }
  398. });
  399. };
  400. const reviewPopupRef = ref(null);
  401. const handleShare = () => {
  402. const preImg = triggerImg.value.length
  403. ? base_img_url2 + triggerImg.value[triggerImg.value.length - 1].cloudFilename
  404. : "";
  405. const resImg = workItem.value?.reviewImage?.length
  406. ? base_img_url2 + workItem.value.reviewImage[workItem.value.reviewImage.length - 1]
  407. : "";
  408. reviewPopupRef.value.handleShowPopup(workItem.value.id, preImg, resImg);
  409. };
  410. const handleRemindUser = () => {
  411. uploadExecuteRef.value.showPopup({ ...workItem.value, type: "remindUser" });
  412. };
  413. const handleMore = () => {
  414. router.push(`/service_detail?farmId=${workItem.value.farmId}`);
  415. };
  416. // 清理数据的函数
  417. const clearData = () => {
  418. workItem.value = {};
  419. triggerImg.value = [];
  420. imageArr.value = [];
  421. paramsPage.value = {};
  422. isPlan.value = false;
  423. curRole.value = "";
  424. loading.value = false;
  425. };
  426. onDeactivated(() => {
  427. clearData();
  428. });
  429. onUnmounted(() => {
  430. clearData();
  431. });
  432. // //联系专家
  433. // const handleContact = () => {
  434. // router.push(`/dialogue?userId=${workItem.value.expert}&name=${workItem.value.expertUserName}`);
  435. // };
  436. const imageArr = ref([]);
  437. const handleUpload = ({ imgArr }) => {
  438. imageArr.value = imgArr;
  439. };
  440. </script>
  441. <style lang="scss" scoped>
  442. .work-wrap {
  443. .center-wrap {
  444. ::v-deep {
  445. .van-uploader__wrapper {
  446. justify-content: center;
  447. }
  448. }
  449. }
  450. .work-content {
  451. padding-top: 1px;
  452. background: #f5f5f5;
  453. padding-bottom: 12px;
  454. font-size: 14px;
  455. height: calc(100vh - 40px);
  456. box-sizing: border-box;
  457. overflow: auto;
  458. &.recheck-title {
  459. padding-bottom: 86px;
  460. .common-card-title {
  461. font-size: 16px;
  462. display: flex;
  463. align-items: center;
  464. border-bottom: 1px solid #f5f5f5;
  465. padding-bottom: 10px;
  466. .icon {
  467. width: 14px;
  468. height: 8px;
  469. padding-right: 6px;
  470. }
  471. }
  472. &.no-bottom {
  473. padding-bottom: 26px;
  474. }
  475. }
  476. .up-btn-group {
  477. position: fixed;
  478. bottom: 80px;
  479. left: 12px;
  480. display: flex;
  481. justify-content: center;
  482. width: calc(100% - 24px);
  483. .up-btn {
  484. background: linear-gradient(45deg, #9fd5ff, #2199f8);
  485. flex: 1;
  486. height: 40px;
  487. border: 2px solid rgba(255, 255, 255, 0.66);
  488. color: #fff;
  489. font-size: 14px;
  490. border-radius: 40px;
  491. line-height: 38px;
  492. text-align: center;
  493. box-sizing: border-box;
  494. }
  495. .orange {
  496. margin-left: 12px;
  497. background: linear-gradient(45deg, #ffd887, #ed9e1e);
  498. }
  499. .btn {
  500. width: 200px;
  501. flex: none;
  502. }
  503. }
  504. .fixed-btn-wrap {
  505. position: fixed;
  506. z-index: 10;
  507. bottom: 0;
  508. left: 0;
  509. width: 100%;
  510. padding: 10px 12px 25px;
  511. box-sizing: border-box;
  512. display: flex;
  513. align-items: center;
  514. justify-content: space-between;
  515. background: #fff;
  516. box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
  517. &.center {
  518. justify-content: center;
  519. }
  520. .fixed-btn {
  521. width: 120px;
  522. text-align: center;
  523. height: 40px;
  524. line-height: 40px;
  525. background: linear-gradient(180deg, #70bffe, #2199f8);
  526. border-radius: 25px;
  527. color: #fff;
  528. font-size: 14px;
  529. box-sizing: border-box;
  530. &.expert {
  531. width: 180px;
  532. }
  533. &.orange {
  534. color: #ff953d;
  535. border: 1px solid #ff953d;
  536. background: #fff;
  537. }
  538. &.excute {
  539. background: linear-gradient(180deg, #ffd887, #ed9e1e);
  540. }
  541. &.more {
  542. background: #ffffff;
  543. border: 1px solid rgba(153, 153, 153, 0.5);
  544. color: #666666;
  545. }
  546. &.second {
  547. background: #ffffff;
  548. border: 1px solid #2199f8;
  549. color: #2199f8;
  550. }
  551. }
  552. }
  553. .tabs-content-item {
  554. padding: 12px 12px 16px 12px;
  555. margin: 0 12px;
  556. border-radius: 8px;
  557. background: #fff;
  558. margin-top: 12px;
  559. position: relative;
  560. .execute-img {
  561. margin-top: 12px;
  562. }
  563. .card-title {
  564. display: flex;
  565. justify-content: space-between;
  566. align-items: center;
  567. padding-bottom: 10px;
  568. .card-title-l {
  569. display: flex;
  570. align-items: center;
  571. font-size: 16px;
  572. .icon {
  573. width: 14px;
  574. height: 8px;
  575. padding-right: 6px;
  576. }
  577. }
  578. .card-title-r {
  579. font-size: 14px;
  580. color: #2199f8;
  581. }
  582. }
  583. .info-box {
  584. &.subject-content {
  585. border: none;
  586. }
  587. &.cost-wrap {
  588. padding-top: 8px;
  589. }
  590. &.bottom-box {
  591. flex-direction: column;
  592. }
  593. padding-top: 12px;
  594. display: flex;
  595. align-items: center;
  596. .info-l {
  597. .farm-img {
  598. width: 78px;
  599. width: 78px;
  600. border-radius: 8px;
  601. object-fit: scale-down;
  602. }
  603. }
  604. .info-r {
  605. padding-left: 12px;
  606. }
  607. .farm-name {
  608. font-weight: bold;
  609. font-size: 14px;
  610. color: #000;
  611. padding-bottom: 4px;
  612. }
  613. .info-item {
  614. display: flex;
  615. font-size: 12px;
  616. .info-name {
  617. color: #bbbbbb;
  618. flex: none;
  619. }
  620. .info-value {
  621. color: #666666;
  622. }
  623. }
  624. .info-item + .info-item {
  625. margin-top: 4px;
  626. }
  627. }
  628. .subject-box {
  629. width: 100%;
  630. display: flex;
  631. align-items: center;
  632. justify-content: space-around;
  633. background: #fafafa;
  634. .subject-item {
  635. border-radius: 8px;
  636. padding: 4px 4px;
  637. display: flex;
  638. flex-direction: column;
  639. align-items: center;
  640. justify-content: center;
  641. width: 33%;
  642. .subject-img {
  643. width: 30px;
  644. height: 30px;
  645. object-fit: cover;
  646. border-radius: 50%;
  647. padding-bottom: 4px;
  648. }
  649. .subject-tag {
  650. font-size: 12px;
  651. padding: 2px 3px 3px 8px;
  652. background: #e0efff;
  653. color: #2199f8;
  654. border-radius: 4px;
  655. &.cost-text {
  656. margin-left: 8px;
  657. font-size: 16px;
  658. color: #2199f8;
  659. padding: 1px 8px;
  660. }
  661. }
  662. }
  663. .subject-item + .subject-item {
  664. margin-left: 6px;
  665. }
  666. .cost-l {
  667. position: relative;
  668. &::after {
  669. content: "";
  670. position: absolute;
  671. right: 0;
  672. top: 16px;
  673. height: calc(100% - 32px);
  674. width: 1px;
  675. background: rgba(0, 0, 0, 0.05);
  676. }
  677. }
  678. }
  679. .cost-box {
  680. border-radius: 5px;
  681. background: none;
  682. .cost-item {
  683. display: flex;
  684. align-items: center;
  685. flex-direction: row;
  686. }
  687. .subject-item {
  688. background: none;
  689. width: 50%;
  690. }
  691. .cost-l {
  692. position: relative;
  693. &::after {
  694. content: "";
  695. position: absolute;
  696. right: 0;
  697. top: 0;
  698. height: 100%;
  699. width: 1px;
  700. background: rgba(0, 0, 0, 0.05);
  701. }
  702. }
  703. .cost-text {
  704. font-size: 16px;
  705. color: #2199f8;
  706. padding-bottom: 5px;
  707. }
  708. }
  709. .recheck-box,
  710. .recheck-ablum {
  711. width: 100%;
  712. }
  713. .evaluate {
  714. background: #fff;
  715. border-radius: 5px;
  716. padding: 4px 8px 10px 8px;
  717. margin-right: 8px;
  718. .evaluate-title {
  719. font-size: 16px;
  720. font-weight: 500;
  721. display: flex;
  722. align-items: center;
  723. justify-content: space-between;
  724. margin-bottom: 8px;
  725. .more {
  726. font-size: 14px;
  727. color: #999999;
  728. font-weight: 400;
  729. display: flex;
  730. align-items: center;
  731. }
  732. }
  733. .rate {
  734. display: flex;
  735. justify-content: space-between;
  736. ::v-deep {
  737. .el-rate {
  738. --el-rate-icon-margin: 0;
  739. }
  740. .el-rate--small .el-rate__icon {
  741. font-size: 12px;
  742. }
  743. }
  744. .rate-item {
  745. display: flex;
  746. align-items: center;
  747. border-radius: 4px;
  748. padding: 4px 0px;
  749. font-size: 11px;
  750. .name {
  751. margin-right: 2px;
  752. color: #666666;
  753. position: relative;
  754. top: 2px;
  755. }
  756. .num {
  757. color: #f3c11d;
  758. margin-left: 2px;
  759. }
  760. }
  761. .line {
  762. width: 1px;
  763. height: 12px;
  764. background: #cdd7e1;
  765. position: relative;
  766. top: 13px;
  767. margin: 0 3px;
  768. }
  769. }
  770. .comment {
  771. .user-info {
  772. display: flex;
  773. align-items: center;
  774. margin-bottom: 2px;
  775. .user-name {
  776. font-weight: 500;
  777. margin-left: 8px;
  778. span {
  779. font-weight: 400;
  780. font-size: 12px;
  781. color: #999999;
  782. }
  783. }
  784. }
  785. }
  786. }
  787. .img-list + .img-list,
  788. .upload-wrap {
  789. margin-top: 12px;
  790. }
  791. .over-img-box {
  792. ::v-deep {
  793. img {
  794. border-radius: 8px;
  795. }
  796. }
  797. }
  798. .img-list {
  799. width: 100%;
  800. }
  801. .upload-wrap {
  802. display: flex;
  803. flex-direction: column;
  804. justify-content: center;
  805. height: 254px;
  806. width: 100%;
  807. padding: 25px 0 12px 10px;
  808. box-sizing: border-box;
  809. }
  810. .recheck-text-wrap {
  811. width: 100%;
  812. border-radius: 8px;
  813. background: #f2f3f5;
  814. color: #666666;
  815. font-size: 14px;
  816. position: relative;
  817. &.active {
  818. background: rgba(33, 153, 248, 0.1);
  819. border: 1px solid #2199f8;
  820. color: #2199f8;
  821. .date {
  822. background: linear-gradient(170deg, #9fd5ff, #2199f8);
  823. }
  824. .recheck-desc {
  825. color: #2199f8;
  826. }
  827. }
  828. .submit {
  829. background: #2199f8;
  830. border-radius: 4px;
  831. padding: 8px;
  832. font-size: 16px;
  833. color: #fff;
  834. margin: 0 10px 16px;
  835. text-align: center;
  836. }
  837. .date {
  838. position: absolute;
  839. top: 0;
  840. left: 0;
  841. background: #bebebe;
  842. border-radius: 8px 0 8px 0;
  843. color: #fff;
  844. font-size: 12px;
  845. padding: 3px 6px;
  846. font-family: "PangMenZhengDao";
  847. }
  848. .recheck-text {
  849. padding: 8px 0 2px 0;
  850. }
  851. .recheck-desc {
  852. font-size: 12px;
  853. color: #999999;
  854. }
  855. .img-icon {
  856. width: 40px;
  857. height: 40px;
  858. }
  859. }
  860. .sub-title {
  861. display: flex;
  862. align-items: center;
  863. justify-content: center;
  864. .sub-line {
  865. width: 12px;
  866. height: 2px;
  867. border-radius: 1px;
  868. background: #d9d9d9;
  869. }
  870. .sub-name {
  871. padding: 0 5px;
  872. font-size: 14px;
  873. color: #666666;
  874. }
  875. }
  876. }
  877. }
  878. .review-hide-box {
  879. position: absolute;
  880. left: 0;
  881. width: 100%;
  882. height: 100%;
  883. z-index: -1;
  884. bottom: 0;
  885. }
  886. .review-image {
  887. position: relative;
  888. display: flex;
  889. align-items: center;
  890. justify-content: center;
  891. gap: 8px;
  892. margin: 12px;
  893. background: #fff;
  894. border-radius: 8px;
  895. .review-mask {
  896. z-index: 1;
  897. pointer-events: none;
  898. position: absolute;
  899. left: 0;
  900. top: 0;
  901. width: 100%;
  902. height: 100%;
  903. border-radius: 8px;
  904. background: linear-gradient(
  905. 360deg,
  906. rgba(0, 0, 0, 0.78) 0%,
  907. rgba(0, 0, 0, 0.437208) 19.87%,
  908. rgba(0, 0, 0, 0) 33.99%
  909. );
  910. display: flex;
  911. flex-direction: column;
  912. align-items: baseline;
  913. justify-content: end;
  914. padding: 12px;
  915. box-sizing: border-box;
  916. color: #fff;
  917. .review-text {
  918. font-family: "PangMenZhengDao";
  919. font-size: 16px;
  920. margin-bottom: 1px;
  921. }
  922. .review-content {
  923. font-size: 10px;
  924. line-height: 15px;
  925. }
  926. }
  927. .vs-wrap {
  928. position: absolute;
  929. left: 50%;
  930. top: 50%;
  931. transform: translate(-50%, -50%);
  932. width: 40px;
  933. height: 40px;
  934. z-index: 10;
  935. img {
  936. width: 100%;
  937. height: 100%;
  938. object-fit: cover;
  939. }
  940. }
  941. .review-image-item {
  942. position: relative;
  943. flex: 1;
  944. .review-image-item-title {
  945. position: absolute;
  946. top: 0;
  947. left: 0;
  948. background: rgba(54, 52, 52, 0.6);
  949. padding: 4px 10px;
  950. border-radius: 8px 0 8px 0;
  951. backdrop-filter: 4px;
  952. font-size: 12px;
  953. color: #fff;
  954. }
  955. .review-image-item-img {
  956. width: 100%;
  957. height: 250px;
  958. object-fit: cover;
  959. }
  960. .left-img {
  961. border-radius: 8px 0 0 8px;
  962. }
  963. .right-img {
  964. border-radius: 0 8px 8px 0;
  965. }
  966. }
  967. }
  968. }
  969. </style>