interact.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. <template>
  2. <div class="task-page" :style="{ height: `calc(100vh - ${tabBarHeight}px - 50px)` }">
  3. <div class="task-top">
  4. <div class="map-container" ref="mapContainer"></div>
  5. </div>
  6. <div class="task-list">
  7. <!-- <div class="list-filter">
  8. <div class="filter-item" :class="{ active: activeIndex === 0 }" @click="handleActiveFilter(0)">
  9. 待确认({{ taskCounts[0] || 0 }})
  10. </div>
  11. <div class="filter-item" :class="{ active: activeIndex === 2 }" @click="handleActiveFilter(2)">
  12. 已确认({{ taskCounts[2] || 0 }})
  13. </div>
  14. <div class="filter-item" :class="{ active: activeIndex === 3 }" @click="handleActiveFilter(3)">
  15. 待提醒({{ taskCounts[3] || 0 }})
  16. </div>
  17. </div> -->
  18. <div class="select-group">
  19. <el-select
  20. class="select-item"
  21. v-model="selectParma.farmWorkTypeId"
  22. placeholder="用户类型"
  23. @change="getSimpleList"
  24. >
  25. <el-option v-for="item in farmWorkTypeList" :key="item.id" :label="item.name" :value="item.id" />
  26. </el-select>
  27. <el-select
  28. class="select-item"
  29. v-model="selectParma.districtCode"
  30. placeholder="切换作物"
  31. @change="getSimpleList"
  32. >
  33. <el-option v-for="item in districtList" :key="item.code" :label="item.name" :value="item.code" />
  34. </el-select>
  35. </div>
  36. <!-- <div class="task-content-loading" v-if="loading && noData" v-loading="loading">
  37. </div> -->
  38. <div class="task-content" v-loading="loading">
  39. <div class="task-item" v-for="(item, index) in taskList" :key="index">
  40. <div class="img-text-wrap" @click.stop="toDetail(item)">
  41. <div class="left-wrap">
  42. <div class="left-img">
  43. <img src="@/assets/img/home/farm.png" alt="" />
  44. </div>
  45. <div class="right-text">
  46. <div class="farm-info">
  47. {{ item?.farmName }}
  48. <div class="info-tag-wrap">
  49. <div class="tag-item primary">
  50. {{ item?.typeName }}
  51. </div>
  52. <div class="tag-item second">托管客户</div>
  53. </div>
  54. </div>
  55. <div class="farm-addr">{{ item?.address }}</div>
  56. </div>
  57. </div>
  58. <div class="right-wrap" @click.stop="handleRemindCustomer(item)">提醒客户</div>
  59. </div>
  60. <div class="item-bottom">
  61. <div class="bottom-tag">
  62. <div class="tag-card active">
  63. <div class="card-content">
  64. <div class="card-main-text">花芽分化</div>
  65. <div class="card-sub-text">
  66. 当前物候期
  67. <span class="card-icon" @click="handleSelectCurrentPhenology(item)">
  68. <el-icon><Edit /></el-icon>
  69. </span>
  70. </div>
  71. </div>
  72. </div>
  73. <div class="tag-card">
  74. <div class="card-content">
  75. <div class="card-main-text">蒂蛀虫</div>
  76. <div class="card-sub-text">预计风险</div>
  77. </div>
  78. </div>
  79. <div class="tag-card">
  80. <div class="card-content">
  81. <div class="card-main-text">5天</div>
  82. <div class="card-sub-text">预计下次物候</div>
  83. </div>
  84. </div>
  85. </div>
  86. <div class="timeline">
  87. <div class="timeline-item" v-for="item in timelineList" :key="item.id">
  88. <div class="timeline-left">
  89. <div class="dot"></div>
  90. <div class="line"></div>
  91. </div>
  92. <div class="timeline-right">
  93. <div class="date">预计{{ item.date }}天后触发<span class="work-name">{{ item.workName }}</span></div>
  94. <div class="text">
  95. 预计报价<span class="price">{{ item.price }}元</span>
  96. <span class="action-detail">查看报价单</span>
  97. </div>
  98. </div>
  99. <div class="timeline-action" @click="handleTimelineAction(item)">转入农事任务</div>
  100. </div>
  101. </div>
  102. </div>
  103. </div>
  104. <div class="empty-data" v-if="noData">暂无数据</div>
  105. </div>
  106. </div>
  107. </div>
  108. <upload-execute ref="uploadExecuteRef" :onlyShare="onlyShare" @uploadSuccess="handleUploadSuccess" />
  109. <popup v-model:show="showTaskPopup" round class="task-tips-popup">
  110. <template v-if="taskPopupType === 'warning'">
  111. <img class="create-farm-icon" src="@/assets/img/home/create-farm-icon.png" alt="" />
  112. <div class="create-farm-text">
  113. <div>
  114. 您确认忽略 <span class="main-text">{{ currentTask?.farmName }}</span> 的
  115. <span class="main-text">{{ currentTask?.farmWorkName }}</span> 农事吗
  116. </div>
  117. </div>
  118. </template>
  119. <template v-else>
  120. <img class="farm-check-icon" src="@/assets/img/home/right.png" alt="" />
  121. <div class="create-farm-text success-text">农事已下发成功</div>
  122. </template>
  123. <div class="create-farm-btn" @click="handlePopupBtn">
  124. {{ taskPopupType === "warning" ? "确认忽略" : "我知道了" }}
  125. </div>
  126. </popup>
  127. <!-- 服务报价单 -->
  128. <price-sheet-popup :key="activeIndex" ref="priceSheetPopupRef"></price-sheet-popup>
  129. <!-- 新增:激活上传弹窗 -->
  130. <active-upload-popup ref="activeUploadPopupRef" @handleUploadSuccess="handleUploadSuccess"></active-upload-popup>
  131. </template>
  132. <script setup>
  133. import eventBus from "@/api/eventBus";
  134. import { computed, nextTick, onMounted, ref, watch } from "vue";
  135. import { useStore } from "vuex";
  136. import { Popup } from "vant";
  137. import IndexMap from "../../farm_manage/map/index";
  138. import { useRouter } from "vue-router";
  139. import uploadExecute from "./uploadExecute.vue";
  140. import priceSheetPopup from "@/components/popup/priceSheetPopup.vue";
  141. import { ElMessage } from "element-plus";
  142. import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
  143. const store = useStore();
  144. const router = useRouter();
  145. const indexMap = new IndexMap();
  146. const mapContainer = ref(null);
  147. const tabBarHeight = computed(() => store.state.home.tabBarHeight);
  148. const uploadExecuteRef = ref(null);
  149. const selectParma = ref({
  150. farmWorkTypeId: null,
  151. districtCode: null,
  152. });
  153. // 任务列表数据(用于显示,可能被筛选)
  154. const taskList = ref([]);
  155. // 各状态任务数量
  156. const taskCounts = ref([0, 0, 0]);
  157. // 当前选中的筛选索引
  158. const activeIndex = ref(2);
  159. const noData = ref(false);
  160. const loading = ref(false);
  161. const showTaskPopup = ref(false);
  162. const taskPopupType = ref("warning");
  163. // 根据 activeIndex 计算 startFlowStatus
  164. const getStartFlowStatus = (index) => {
  165. const statusMap = {
  166. 0: 0, // 待确认
  167. 1: "1,2,3", // 待完成
  168. 2: 4, // 待完成
  169. 3: 5, // 已完成
  170. };
  171. return statusMap[index] ?? 0;
  172. };
  173. const timelineList = ref([
  174. {
  175. date: "3",
  176. workName: "梢期杀虫",
  177. price: "1258"
  178. },
  179. {
  180. date: "5",
  181. workName: "梢期营养",
  182. price: "1758"
  183. },
  184. ])
  185. // 获取单个状态的任务数量
  186. function getTaskCount(flowStatus, index) {
  187. const location = store.state.home.miniUserLocationPoint;
  188. return VE_API.z_farm_work_record
  189. .getSimpleList({ role: 2, location, flowStatus })
  190. .then(({ data }) => {
  191. data = [
  192. ...data,
  193. {
  194. address: "深圳世界之窗",
  195. executeDate: "2025-12-29",
  196. executeEvidence: "",
  197. farmArea: "40.100412863459745",
  198. farmId: 93651,
  199. farmMiniUserId: 91344,
  200. farmMiniUserName: "舒浩农资",
  201. farmName: "世界之窗荔枝农场",
  202. farmWorkArrangeId: null,
  203. farmWorkLibId: "756894717878210560",
  204. farmWorkName: "二梢营养",
  205. id: "276563",
  206. isFollow: null,
  207. isIgnored: 0,
  208. isPublic: 0,
  209. orderId: "778920749103583232",
  210. point: "POINT(113.96804666992188 22.537601205078126)",
  211. quoteCount: "0",
  212. typeId: "2",
  213. typeName: "糯米糍",
  214. },
  215. {
  216. address: "汕尾市海丰县赤坑镇S241妙荔现代农业园",
  217. executeDate: "2025-12-27",
  218. executeEvidence: "",
  219. farmArea: "",
  220. farmId: 43318,
  221. farmMiniUserId: 81818,
  222. farmMiniUserName: "",
  223. farmName: "汕尾妙荔果园",
  224. farmWorkArrangeId: null,
  225. farmWorkLibId: "708734452137725956",
  226. farmWorkName: "杀梢",
  227. id: "277160",
  228. isFollow: null,
  229. isIgnored: 0,
  230. isPublic: 0,
  231. orderId: "781556915820826624",
  232. point: "POINT(115.455766 22.883073)",
  233. quoteCount: "0",
  234. typeId: "4",
  235. typeName: "仙进奉",
  236. },
  237. ];
  238. if (Array.isArray(data)) {
  239. taskCounts.value[index] = data.length;
  240. if (index === 2) {
  241. indexMap.initData(data);
  242. }
  243. } else if (data?.total !== undefined) {
  244. taskCounts.value[index] = data.total;
  245. } else {
  246. taskCounts.value[index] = 0;
  247. }
  248. })
  249. .catch((error) => {
  250. console.error(`获取状态${index}任务数量失败:`, error);
  251. taskCounts.value[index] = 0;
  252. });
  253. }
  254. const taskItemRefs = ref([]);
  255. const setTaskItemRef = (el, index) => {
  256. if (el) {
  257. taskItemRefs.value[index] = el;
  258. }
  259. };
  260. const handleUploadSuccess = async () => {
  261. // 先保存当前需要更新的 item id
  262. const currentItemIds = taskList.value.map((item) => item.id || item.workRecordId);
  263. // 刷新列表
  264. await getSimpleList();
  265. // 等待 DOM 更新完成,refs 被重新收集
  266. await nextTick();
  267. // 更新所有task-item的triggerImg
  268. taskItemRefs.value.forEach((ref) => {
  269. if (ref && ref.updateTriggerImg) {
  270. ref.updateTriggerImg();
  271. }
  272. });
  273. };
  274. const cityCode = ref("");
  275. //根据城市的坐标返回区县列表
  276. const districtList = ref([]);
  277. function getDistrictListByCity() {
  278. VE_API.z_farm_work_record.getDistrictListByCity({ point: mapPoint.value }).then(({ data }) => {
  279. districtList.value = data || [];
  280. // cityCode.value = data[0].code.slice(0, -2);
  281. cityCode.value = "";
  282. districtList.value.unshift({ code: cityCode.value, name: "全部" });
  283. selectParma.value.districtCode = cityCode.value;
  284. getSimpleList();
  285. });
  286. }
  287. //农事类型列表
  288. const farmWorkTypeList = ref([]);
  289. function getFarmWorkTypeList() {
  290. VE_API.z_farm_work_record.getFarmWorkTypeList().then(({ data }) => {
  291. farmWorkTypeList.value = data;
  292. farmWorkTypeList.value.unshift({ id: 0, name: "全部" });
  293. });
  294. }
  295. // 初始化时获取所有状态的任务数量
  296. function initTaskCounts() {
  297. const location = store.state.home.miniUserLocationPoint;
  298. // 并行请求三个状态的数量
  299. Promise.all([
  300. getTaskCount(0, 0), // 待确认
  301. getTaskCount("1,2,3", 1), // 待确认
  302. getTaskCount(4, 2), // 待完成
  303. getTaskCount(5, 3), // 已完成
  304. ]);
  305. }
  306. const mapPoint = ref(null);
  307. onMounted(() => {
  308. mapPoint.value = store.state.home.miniUserLocationPoint;
  309. // 初始化时获取所有状态的数量
  310. initTaskCounts();
  311. // 加载当前选中状态的数据列表
  312. getSimpleList();
  313. getDistrictListByCity();
  314. getFarmWorkTypeList();
  315. nextTick(() => {
  316. indexMap.initMap(mapPoint.value, mapContainer.value, true);
  317. });
  318. });
  319. // 监听 activeIndex 变化,重新加载数据
  320. watch(activeIndex, () => {
  321. getSimpleList();
  322. });
  323. function getSimpleList() {
  324. loading.value = true;
  325. noData.value = false;
  326. // 清空refs数组,避免索引错乱
  327. taskItemRefs.value = [];
  328. const startFlowStatus = getStartFlowStatus(activeIndex.value);
  329. const params = {
  330. ...selectParma.value,
  331. role: 2,
  332. location: mapPoint.value,
  333. flowStatus: startFlowStatus,
  334. farmWorkTypeId: selectParma.value.farmWorkTypeId || null,
  335. };
  336. return VE_API.z_farm_work_record
  337. .getSimpleList(params)
  338. .then(({ data }) => {
  339. loading.value = false;
  340. // 假设返回的数据结构是 { list: [], total: 0 } 或者直接是数组
  341. let filteredData = data;
  342. // 如果是"待确认"状态,过滤掉 isIgnored 为 1 的数据
  343. if (activeIndex.value === 0 && Array.isArray(data)) {
  344. filteredData = data.filter((item) => item.isIgnored !== 1);
  345. }
  346. if (Array.isArray(filteredData) && filteredData.length > 0) {
  347. taskList.value = filteredData;
  348. // 更新当前状态的数量
  349. taskCounts.value[activeIndex.value] = filteredData.length;
  350. if (activeIndex.value === 2) {
  351. // 地图使用筛选后的数据
  352. indexMap.initData(taskList.value);
  353. }
  354. } else {
  355. noData.value = true;
  356. taskList.value = [];
  357. taskCounts.value[activeIndex.value] = 0;
  358. }
  359. })
  360. .catch((error) => {
  361. console.error("获取任务列表失败:", error);
  362. loading.value = false;
  363. taskList.value = [];
  364. taskCounts.value[activeIndex.value] = 0;
  365. if (activeIndex.value === 2) {
  366. indexMap.initData(taskList.value);
  367. }
  368. noData.value = true;
  369. });
  370. }
  371. function handleActiveFilter(i) {
  372. activeIndex.value = i;
  373. selectParma.value.districtCode = cityCode.value;
  374. selectParma.value.farmWorkTypeId = null;
  375. }
  376. function toPage(item) {
  377. // router.push("/servicZes_agri")
  378. // if (activeIndex.value === 2) {
  379. // } else {
  380. // // 下发农事请求
  381. // const data = {
  382. // id: item.id,
  383. // };
  384. // VE_API.z_farm_work_record.issueFarmWorkRecord(data).then((res) => {
  385. // if (res.code === 0) {
  386. // taskPopupType.value = "success";
  387. // showTaskPopup.value = true;
  388. // getSimpleList();
  389. // }
  390. // });
  391. // }
  392. }
  393. const showUploadExecutePopup = (item) => {
  394. if (item?.executeEvidence.length) {
  395. onlyShare.value = true;
  396. } else {
  397. onlyShare.value = false;
  398. }
  399. setTimeout(() => {
  400. uploadExecuteRef.value.showPopup(item);
  401. }, 10);
  402. };
  403. function toDetail(item) {
  404. // if (activeIndex.value === 0) {
  405. // router.push({
  406. // path: "/modify_work",
  407. // query: { id: item.id },
  408. // });
  409. // } else {
  410. // }
  411. router.push({
  412. path: "/completed_work",
  413. query: { miniJson: JSON.stringify({ id: item.id }) },
  414. });
  415. }
  416. const priceSheetPopupRef = ref(null);
  417. const showPriceSheetPopup = (item) => {
  418. VE_API.z_farm_work_record.getDetail({ id: item.id }).then(({ data }) => {
  419. const res = data[0];
  420. priceSheetPopupRef.value.handleShowPopup(res);
  421. });
  422. };
  423. const onlyShare = ref(false);
  424. const currentTask = ref(null);
  425. function handleAction(item) {
  426. if (activeIndex.value === 0) {
  427. taskPopupType.value = "warning";
  428. showTaskPopup.value = true;
  429. currentTask.value = item;
  430. } else {
  431. onlyShare.value = true;
  432. setTimeout(() => {
  433. uploadExecuteRef.value.showPopup(item, "share-sheet");
  434. }, 10);
  435. }
  436. }
  437. function handlePopupBtn() {
  438. showTaskPopup.value = false;
  439. if (taskPopupType.value === "warning") {
  440. // 确认忽略
  441. VE_API.z_farm_work_record.ignoreFarmWorkRecord({ farmWorkRecordId: currentTask.value.id }).then((res) => {
  442. if (res.code === 0) {
  443. ElMessage.success("操作成功");
  444. getSimpleList();
  445. }
  446. });
  447. }
  448. }
  449. function handleForward(item) {
  450. if (item.quoteCount && item.quoteCount != 0) {
  451. onlyShare.value = true;
  452. setTimeout(() => {
  453. uploadExecuteRef.value.showPopup(
  454. { ...item, type: "quotation", farmWorkOrderId: item.orderId },
  455. "share-sheet"
  456. );
  457. }, 10);
  458. } else {
  459. ElMessage.warning("暂无报价数据,无法分享");
  460. return;
  461. }
  462. }
  463. const executorList = ref([{
  464. id: 1,
  465. name: "张三",
  466. phone: "13800138000",
  467. }, {
  468. id: 2,
  469. name: "李四",
  470. phone: "13800138001",
  471. }])
  472. function handleTimelineAction(item) {
  473. // activeUploadPopupRef.value.triggerFarmWork({
  474. // farmId: item.farmId,
  475. // workName: item.workName,
  476. // });
  477. eventBus.emit("activeUpload:show", {
  478. gardenIdVal: item.farmId,
  479. needExecutorVal: true,
  480. problemTitleVal: '请选择 ' + item.workName + ' 执行截止时间',
  481. imgDescVal: '请上传凭证(转入农事任务凭证)',
  482. arrangeIdVal: item.farmWorkArrangeId,
  483. executorListVal: executorList.value,
  484. });
  485. }
  486. const phenologyList = ref([{
  487. id: 1,
  488. name: "花芽分化",
  489. }, {
  490. id: 2,
  491. name: "开花",
  492. }, {
  493. id: 3,
  494. name: "成熟",
  495. }]);
  496. function handleSelectCurrentPhenology(item) {
  497. eventBus.emit("activeUpload:show", {
  498. gardenIdVal: item.farmId,
  499. problemTitleVal: '进入 物候期 的时间',
  500. imgDescVal: '请上传凭证(转入农事任务凭证)',
  501. arrangeIdVal: item.farmWorkArrangeId,
  502. selectCurrentPhenologyVal: true,
  503. phenologyListVal: phenologyList.value,
  504. });
  505. }
  506. function handleRemindCustomer(item) {
  507. router.push({
  508. path: "/remind_customer",
  509. query: { id: item.id },
  510. });
  511. }
  512. </script>
  513. <style lang="scss" scoped>
  514. .task-page {
  515. width: 100%;
  516. height: calc(100vh - 50px - 50px);
  517. overflow: auto;
  518. box-sizing: border-box;
  519. background: #f5f7fb;
  520. .map-container {
  521. width: 100%;
  522. height: 162px;
  523. clip-path: inset(0px round 8px);
  524. }
  525. .select-group {
  526. display: flex;
  527. padding: 0px 12px 0 12px;
  528. .select-item {
  529. width: 100%;
  530. ::v-deep {
  531. .el-select__wrapper {
  532. text-align: center;
  533. gap: 2px;
  534. box-shadow: none;
  535. justify-content: center;
  536. background: none;
  537. }
  538. .el-select__selection {
  539. flex: none;
  540. width: fit-content;
  541. }
  542. .el-select__placeholder {
  543. position: static;
  544. transform: none;
  545. width: fit-content;
  546. color: rgba(0, 0, 0, 0.2);
  547. }
  548. .el-select__caret {
  549. color: rgba(0, 0, 0, 0.2);
  550. }
  551. }
  552. }
  553. }
  554. .task-top {
  555. padding: 10px 12px 0 12px;
  556. }
  557. .task-content-loading {
  558. height: 80px;
  559. border-radius: 8px;
  560. position: absolute;
  561. top: 60px;
  562. left: 0;
  563. width: 100%;
  564. }
  565. .task-content {
  566. border-top: 1px solid rgba(0, 0, 0, 0.1);
  567. min-height: 80px;
  568. }
  569. .empty-data {
  570. text-align: center;
  571. font-size: 14px;
  572. color: #6f7274;
  573. padding: 20px 0;
  574. }
  575. .task-list {
  576. position: relative;
  577. background: #fff;
  578. padding: 12px 12px 8px 12px;
  579. }
  580. .list-filter {
  581. display: flex;
  582. align-items: center;
  583. justify-content: space-around;
  584. .filter-item {
  585. padding: 0 12px;
  586. height: 28px;
  587. color: rgba(0, 0, 0, 0.5);
  588. font-size: 14px;
  589. line-height: 28px;
  590. border-radius: 20px;
  591. &.active {
  592. color: #2199f8;
  593. background: rgba(33, 153, 248, 0.2);
  594. }
  595. }
  596. }
  597. .task-item {
  598. border-radius: 12px;
  599. border: 0.3px solid rgba(0, 0, 0, 0.2);
  600. padding: 12px;
  601. }
  602. .task-item + .task-item {
  603. margin-top: 10px;
  604. }
  605. .img-text-wrap {
  606. display: flex;
  607. align-items: flex-start;
  608. justify-content: space-between;
  609. padding-bottom: 10px;
  610. border-bottom: 0.5px solid rgba(0, 0, 0, 0.1);
  611. .left-wrap {
  612. display: flex;
  613. align-items: center;
  614. .left-img {
  615. width: 40px;
  616. height: 40px;
  617. border-radius: 6px;
  618. img {
  619. width: 100%;
  620. height: 100%;
  621. object-fit: contain;
  622. }
  623. }
  624. .right-text {
  625. padding-left: 8px;
  626. .farm-info {
  627. font-size: 14px;
  628. color: #1d2129;
  629. display: flex;
  630. align-items: center;
  631. .info-tag-wrap {
  632. margin-left: 10px;
  633. display: flex;
  634. align-items: center;
  635. gap: 4px;
  636. .tag-item {
  637. height: 20px;
  638. line-height: 20px;
  639. padding: 0 8px;
  640. border-radius: 2px;
  641. font-size: 12px;
  642. &.second {
  643. color: #ff953d;
  644. background: rgba(255, 149, 61, 0.1);
  645. }
  646. &.primary {
  647. color: #2199f8;
  648. background: #e8f3ff;
  649. }
  650. }
  651. }
  652. }
  653. .farm-addr {
  654. padding-top: 2px;
  655. font-size: 12px;
  656. color: #86909c;
  657. }
  658. }
  659. }
  660. .right-wrap {
  661. display: flex;
  662. align-items: center;
  663. justify-content: center;
  664. text-align: center;
  665. color: #fff;
  666. background: #2199f8;
  667. font-size: 12px;
  668. flex: none;
  669. width: 44px;
  670. height: 44px;
  671. padding: 8px;
  672. border-radius: 5px;
  673. box-sizing: border-box;
  674. .click-item {
  675. display: flex;
  676. align-items: center;
  677. gap: 2px;
  678. }
  679. .follow-text {
  680. color: #d0d0d0;
  681. }
  682. }
  683. }
  684. .item-bottom {
  685. padding-top: 10px;
  686. .bottom-tag {
  687. display: flex;
  688. gap: 10px;
  689. .tag-card {
  690. flex: 1;
  691. border-radius: 2px;
  692. padding: 4px;
  693. box-sizing: border-box;
  694. border: 0.4px solid rgba(215, 215, 215, 0.5);
  695. .card-content {
  696. display: flex;
  697. flex-direction: column;
  698. align-items: center;
  699. justify-content: center;
  700. text-align: center;
  701. .card-main-text {
  702. font-size: 16px;
  703. font-weight: 500;
  704. color: #202020;
  705. margin-bottom: 2px;
  706. }
  707. .card-sub-text {
  708. font-size: 10px;
  709. color: rgba(32, 32, 32, 0.4);
  710. display: flex;
  711. align-items: center;
  712. gap: 4px;
  713. .card-icon {
  714. display: inline-flex;
  715. align-items: center;
  716. justify-content: center;
  717. width: 12px;
  718. height: 12px;
  719. color: #2199f8;
  720. }
  721. }
  722. }
  723. &.active {
  724. background: rgba(33, 153, 248, 0.1);
  725. border: 0.5px solid #2199f8;
  726. .card-content {
  727. .card-main-text {
  728. color: #2199f8;
  729. }
  730. .card-sub-text {
  731. color: #2199f8;
  732. }
  733. }
  734. }
  735. }
  736. }
  737. .timeline {
  738. padding-top: 10px;
  739. .timeline-item {
  740. display: flex;
  741. align-items: flex-start;
  742. font-size: 14px;
  743. color: #ffffff;
  744. line-height: 22px;
  745. & + .timeline-item {
  746. margin-top: 10px;
  747. }
  748. .timeline-left {
  749. width: 22px;
  750. display: flex;
  751. flex-direction: column;
  752. align-items: center;
  753. .dot {
  754. width: 6px;
  755. height: 6px;
  756. border-radius: 50%;
  757. background: #A2D5FD;
  758. margin-top: 6px;
  759. }
  760. .line {
  761. border-left: 1px dashed #A2D5FD;
  762. margin-top: 4px;
  763. height: 28px;
  764. }
  765. }
  766. .timeline-right {
  767. padding-left: 5px;
  768. flex: 1;
  769. .date {
  770. color: #1D2129;
  771. font-weight: 500;
  772. font-size: 14px;
  773. line-height: 22px;
  774. }
  775. .text {
  776. font-size: 12px;
  777. color: #d7d7d7;
  778. .price {
  779. padding-left: 4px;
  780. }
  781. .action-detail {
  782. margin-left: 6px;
  783. color: #2199F8;
  784. border-bottom: 1px solid;
  785. }
  786. }
  787. .work-name {
  788. padding-left: 4px;
  789. }
  790. }
  791. .timeline-action {
  792. align-self: center;
  793. height: 28px;
  794. line-height: 28px;
  795. flex: none;
  796. background: rgba(33, 153, 248, 0.1);
  797. color: #2199F8;
  798. font-size: 12px;
  799. padding: 0px 11px;
  800. border-radius: 20px;
  801. }
  802. }
  803. }
  804. }
  805. .item-footer {
  806. margin-top: 10px;
  807. padding-top: 11px;
  808. border-top: 1px solid rgba(0, 0, 0, 0.1);
  809. display: flex;
  810. align-items: center;
  811. justify-content: space-between;
  812. font-size: 12px;
  813. .footer-l {
  814. color: #8b8b8b;
  815. font-size: 12px;
  816. &.primary-btn {
  817. display: inline-flex;
  818. align-items: center;
  819. border: 1px solid #2199f8;
  820. background: rgba(33, 153, 248, 0.1);
  821. padding: 0 12px;
  822. height: 32px;
  823. box-sizing: border-box;
  824. display: flex;
  825. align-items: center;
  826. border-radius: 20px;
  827. color: #2199f8;
  828. .share-icon {
  829. width: 12px;
  830. padding-right: 4px;
  831. }
  832. }
  833. &.farm-name-text {
  834. font-size: 14px;
  835. color: #6f7274;
  836. .name-text {
  837. padding-left: 4px;
  838. }
  839. }
  840. }
  841. .footer-r {
  842. display: flex;
  843. align-items: center;
  844. .btn {
  845. height: 32px;
  846. line-height: 32px;
  847. padding: 0 12px;
  848. border-radius: 20px;
  849. display: flex;
  850. align-items: center;
  851. box-sizing: border-box;
  852. &.second {
  853. // border: 1px solid #8B8B8B;
  854. // color: #8B8B8B;
  855. color: #2199f8;
  856. background: rgba(33, 153, 248, 0.1);
  857. }
  858. &.primary {
  859. background: #2199f8;
  860. color: #fff;
  861. }
  862. .btn-icon {
  863. padding-right: 4px;
  864. }
  865. &.warning {
  866. color: #ff953d;
  867. background: #fff;
  868. border: 1px solid #ff953d;
  869. }
  870. &.secondary-text {
  871. color: #2199f8;
  872. border: 1px solid #2199f8;
  873. }
  874. }
  875. .btn + .btn {
  876. margin-left: 8px;
  877. }
  878. }
  879. }
  880. }
  881. .task-tips-popup {
  882. width: 75%;
  883. padding: 28px 28px 20px;
  884. display: flex;
  885. flex-direction: column;
  886. align-items: center;
  887. justify-content: center;
  888. .create-farm-icon {
  889. width: 40px;
  890. height: 40px;
  891. margin-bottom: 12px;
  892. }
  893. .farm-check-icon {
  894. width: 68px;
  895. height: 68px;
  896. margin-bottom: 12px;
  897. }
  898. .create-farm-text {
  899. font-size: 20px;
  900. font-weight: 500;
  901. line-height: 40px;
  902. margin-bottom: 32px;
  903. text-align: center;
  904. &.success-text {
  905. font-size: 23px;
  906. font-weight: 400;
  907. }
  908. }
  909. .main-text {
  910. color: #2199f8;
  911. }
  912. .create-farm-btn {
  913. width: 100%;
  914. box-sizing: border-box;
  915. padding: 8px;
  916. border-radius: 25px;
  917. font-size: 16px;
  918. background: #2199f8;
  919. color: #fff;
  920. text-align: center;
  921. }
  922. }
  923. </style>