plan.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. <template>
  2. <div class="plan-page">
  3. <custom-header
  4. :name="headerTitle"
  5. isGoBack
  6. @goback="goback"
  7. :isClose="route.query.headerTitle ? true : false"
  8. ></custom-header>
  9. <div class="plan-content">
  10. <div class="plan-content-header" v-if="pageType === 'plant'">
  11. <el-select
  12. class="select-item"
  13. v-model="specieValue"
  14. placeholder="选择品类"
  15. @change="() => getListMySchemes('left')"
  16. >
  17. <el-option
  18. v-for="item in options"
  19. :key="item.id"
  20. :label="item.name"
  21. :value="item.defaultContainerId"
  22. />
  23. </el-select>
  24. <tab-list
  25. class="tabs-list"
  26. type="light"
  27. v-model="active"
  28. :tabs="tabs"
  29. :scrollType="scrollType"
  30. @change="handleTabChange"
  31. />
  32. </div>
  33. <div class="tip-box">
  34. <Highlight
  35. :keywords="['关注农事/托管农事', '取消关注']"
  36. source-string="提示:关注农事/托管农事 会触发农情互动,并且为您推送农事,取消关注 则不会为您推送任何与该农事相关的内容"
  37. />
  38. </div>
  39. <div
  40. class="timeline-wrap"
  41. :class="{
  42. 'timeline-container-plant-wrap': pageType == 'plant',
  43. 'timeline-container-no-permission-wrap': !hasPlanPermission,
  44. 'no-default-plan-wrap':
  45. active !== tabs[0]?.id && pageType == 'plant' && tabs[currentTabIndex]?.enabled == 0,
  46. }"
  47. >
  48. <farm-work-plan-timeline
  49. :pageType="pageType"
  50. :farmId="route.query.farmId"
  51. :containerId="containerIdData"
  52. @row-click="handleRowClick"
  53. :disableClick="!hasPlanPermission || active === tabs[0]?.id"
  54. :isStandard="active === tabs[0]?.id"
  55. :schemeId="active"
  56. />
  57. </div>
  58. </div>
  59. <div
  60. class="custom-bottom-fixed-btns"
  61. :class="{ center: active === tabs[0]?.id && pageType == 'plant' }"
  62. v-has-permission="'农事规划'"
  63. >
  64. <div class="bottom-btn-group-wrap">
  65. <div
  66. class="bottom-btn-group"
  67. :class="{ 'justify-center': active === tabs[0]?.id && pageType == 'plant' }"
  68. >
  69. <div
  70. class="bottom-btn secondary-btn"
  71. @click="handlePhenologySetting"
  72. v-show="active !== tabs[0]?.id"
  73. >
  74. 物候期设置
  75. </div>
  76. <div class="bottom-btn secondary-btn" v-if="pageType === 'plant'" @click="openCopyPlanPopup">
  77. {{ active === tabs[0]?.id ? "复制方案" : "方案设置" }}
  78. </div>
  79. </div>
  80. <div class="bottom-btn primary-btn" @click="addNewTask" v-show="active !== tabs[0]?.id">新增农事</div>
  81. </div>
  82. <template v-if="active !== tabs[0]?.id && pageType == 'plant' && tabs[currentTabIndex]?.enabled == 0">
  83. <div class="bottom-btn-divider"></div>
  84. <div class="bottom-btn primary-btn submit-btn" @click="handleSubmitPlan">提交方案</div>
  85. </template>
  86. </div>
  87. </div>
  88. <!-- 农事信息弹窗 -->
  89. <detail-dialog ref="detailDialogRef" @triggerFarmWork="triggerFarmWork"></detail-dialog>
  90. <!-- 复制方案弹窗 -->
  91. <Popup v-model:show="showCopyPlan" class="copy-plan-popup" round closeable :close-on-click-overlay="false">
  92. <div class="copy-plan-content">
  93. <div class="label">{{ active === tabs[0]?.id ? "复制为" : "方案名称" }}</div>
  94. <el-input v-model="copyPlanName" size="large" placeholder="请输入方案名称" class="copy-plan-input" />
  95. </div>
  96. <div class="copy-plan-footer">
  97. <div class="btn btn-cancel" @click="handleCancelCopyPlan">
  98. {{ active === tabs[0]?.id ? "取消复制" : "删除方案" }}
  99. </div>
  100. <div class="btn btn-confirm" @click="handleConfirmCopyPlan">
  101. {{ active === tabs[0]?.id ? "确定复制" : "确定设置" }}
  102. </div>
  103. </div>
  104. </Popup>
  105. <!-- 物候期设置弹窗 -->
  106. <Popup
  107. v-model:show="showPhenologySetting"
  108. class="copy-plan-popup phenology-popup"
  109. round
  110. closeable
  111. :close-on-click-overlay="false"
  112. >
  113. <div class="phenology-header">物候期时间设置</div>
  114. <div class="phenology-list">
  115. <div class="phenology-item" v-for="(item, index) in mergedReproductiveList" :key="item.id || index">
  116. <div class="item-label">
  117. <span class="label-text">{{ item.name }}</span>
  118. <span>起始时间</span>
  119. </div>
  120. <div class="item-value">
  121. <el-date-picker
  122. style="width: 100%"
  123. size="large"
  124. value-format="YYYY-MM-DD"
  125. v-model="item.startDate"
  126. type="date"
  127. placeholder="选择日期"
  128. />
  129. </div>
  130. </div>
  131. </div>
  132. <div class="phenology-footer" @click="handleConfirmPhenologySetting">确认设置</div>
  133. </Popup>
  134. <tip-popup
  135. v-model:show="showTipPopup"
  136. type="warning"
  137. text2="还未完善此方案不可用"
  138. :highlightText="highlightText"
  139. buttonText="我知道了"
  140. @confirm="handleBtn"
  141. />
  142. </template>
  143. <script setup>
  144. import { ref, onMounted, computed } from "vue";
  145. import { Popup, Highlight } from "vant";
  146. import customHeader from "@/components/customHeader.vue";
  147. import tabList from "@/components/pageComponents/TabList.vue";
  148. import FarmWorkPlanTimeline from "@/components/pageComponents/FarmWorkPlanTimeline.vue";
  149. import { useRouter, useRoute } from "vue-router";
  150. import detailDialog from "@/components/detailDialog.vue";
  151. import eventBus from "@/api/eventBus";
  152. import tipPopup from "@/components/popup/tipPopup.vue";
  153. import { ElMessage, ElMessageBox } from "element-plus";
  154. const router = useRouter();
  155. const route = useRoute();
  156. const showTipPopup = ref(false);
  157. const highlightText = ref("");
  158. const handleBtn = () => {
  159. showTipPopup.value = false;
  160. setTimeout(() => {
  161. router.go(-1);
  162. }, 10);
  163. };
  164. const goback = () => {
  165. if (
  166. tabs.value[currentTabIndex.value]?.enabled == 0 &&
  167. pageType.value === "plant" &&
  168. active.value !== tabs.value[0]?.id
  169. ) {
  170. highlightText.value = tabs.value[currentTabIndex.value]?.name;
  171. showTipPopup.value = true;
  172. } else {
  173. router.go(-1);
  174. }
  175. };
  176. const userInfoStr = localStorage.getItem("localUserInfo");
  177. const userInfo = userInfoStr ? JSON.parse(userInfoStr) : {};
  178. // 检查是否有"农事规划"权限
  179. const hasPlanPermission = computed(() => {
  180. try {
  181. const permissions = userInfo?.agriculturalPermissions || [];
  182. return permissions.includes("农事规划");
  183. } catch (error) {
  184. console.error("解析用户信息失败:", error);
  185. return false;
  186. }
  187. });
  188. const pageType = ref("");
  189. const headerTitle = ref("");
  190. onMounted(() => {
  191. pageType.value = route.query.pageType || "";
  192. headerTitle.value = route.query.headerTitle || (pageType.value === "plant" ? "种植方案" : "农事规划");
  193. if (!pageType.value) {
  194. getFarmWorkPlanForPhenology();
  195. } else {
  196. getSpecieList();
  197. }
  198. });
  199. // 获取品类列表
  200. const specieValue = ref(null);
  201. const options = ref([]);
  202. const getSpecieList = () => {
  203. VE_API.farm.fetchSpecieList({ agriculturalId: userInfo?.agriculturalId }).then(({ data }) => {
  204. if (data && data.length) {
  205. options.value = data || [];
  206. if (sessionStorage.getItem("specieValue")) {
  207. specieValue.value = sessionStorage.getItem("specieValue");
  208. currentTabIndex.value = sessionStorage.getItem("currentTabIndex");
  209. sessionStorage.removeItem("specieValue");
  210. sessionStorage.removeItem("currentTabIndex");
  211. } else {
  212. specieValue.value = data[0]?.defaultContainerId;
  213. }
  214. getListMySchemes("left");
  215. }
  216. });
  217. };
  218. // 获取方案列表
  219. const active = ref(null);
  220. const tabs = ref([]);
  221. // 控制标签滚动方向:'left' | 'right' | 'auto' | ''
  222. const scrollType = ref("auto");
  223. const containerIdData = ref(null);
  224. const getListMySchemes = (type = "auto") => {
  225. VE_API.home.listMySchemes({ containerId: specieValue.value }).then(({ data }) => {
  226. tabs.value = data || [];
  227. containerIdData.value = tabs.value[0]?.containerId;
  228. if (sessionStorage.getItem("active")) {
  229. active.value = sessionStorage.getItem("active");
  230. sessionStorage.removeItem("active");
  231. } else {
  232. if (type === "right") {
  233. active.value = data[data.length - 1].id;
  234. } else if (type === "left") {
  235. active.value = data[0].id;
  236. } else {
  237. currentTab.value = data.filter((item) => item.id === currentTab.value.id)[0];
  238. copyPlanName.value = currentTab.value.name;
  239. }
  240. }
  241. scrollType.value = type;
  242. getFarmWorkPlanForPhenology();
  243. });
  244. };
  245. const currentTab = ref(null);
  246. const currentTabIndex = ref(0);
  247. const handleTabChange = (id, item, index) => {
  248. active.value = id;
  249. currentTab.value = item;
  250. currentTabIndex.value = index;
  251. getFarmWorkPlanForPhenology();
  252. };
  253. const mergedReproductiveList = ref([]);
  254. const containerSpaceTimeId = ref(null);
  255. const schemeId = ref(null);
  256. const getPhenologyList = async () => {
  257. const params = {
  258. containerSpaceTimeId: containerSpaceTimeId.value,
  259. agriculturalId: userInfo?.agriculturalId,
  260. farmId: route.query.farmId,
  261. };
  262. const res = await VE_API.monitor.listPhenology(params);
  263. if (res.code === 0) {
  264. mergedReproductiveList.value = res.data || [];
  265. }
  266. };
  267. const farmWorkIds = ref([]);
  268. const arrangeIds = ref([]);
  269. // 获取农事规划数据以获取 containerSpaceTimeId
  270. const getFarmWorkPlanForPhenology = async () => {
  271. try {
  272. const { data, code } = await VE_API.monitor.farmWorkPlan({
  273. containerId: specieValue.value,
  274. farmId: route.query.farmId,
  275. schemeId: active.value,
  276. });
  277. if (code === 0 && data?.phenologyList?.[0]?.containerSpaceTimeId) {
  278. containerSpaceTimeId.value = data.phenologyList[0].containerSpaceTimeId;
  279. schemeId.value = data.phenologyList[0].reproductiveList[0].farmWorkArrangeList[0].schemeId;
  280. // 收集所有farmWorkId
  281. farmWorkIds.value = [];
  282. arrangeIds.value = [];
  283. data.phenologyList.forEach((phenology) => {
  284. if (Array.isArray(phenology.reproductiveList)) {
  285. phenology.reproductiveList.forEach((reproductive) => {
  286. if (Array.isArray(reproductive.farmWorkArrangeList)) {
  287. reproductive.farmWorkArrangeList.forEach((farmWork) => {
  288. if (farmWork.farmWorkId && farmWork.isFollow !== 0) {
  289. farmWorkIds.value.push(farmWork.farmWorkId);
  290. arrangeIds.value.push(farmWork.id);
  291. }
  292. });
  293. }
  294. });
  295. }
  296. });
  297. await getPhenologyList(containerSpaceTimeId.value);
  298. }
  299. } catch (error) {
  300. console.error("获取农事规划数据失败:", error);
  301. }
  302. };
  303. // 复制方案弹窗相关
  304. const showCopyPlan = ref(false);
  305. const showPhenologySetting = ref(false);
  306. const copyPlanName = ref("");
  307. const openCopyPlanPopup = () => {
  308. copyPlanName.value = "";
  309. showCopyPlan.value = true;
  310. if (active.value !== tabs.value[0]?.id) {
  311. copyPlanName.value = currentTab.value.name;
  312. }
  313. };
  314. // 物候期设置弹窗
  315. const handlePhenologySetting = () => {
  316. showPhenologySetting.value = true;
  317. };
  318. /**
  319. * 确认物候期设置
  320. */
  321. const handleConfirmPhenologySetting = async () => {
  322. const params = {
  323. farmId: route.query.farmId,
  324. agriculturalId: userInfo?.agriculturalId,
  325. items: mergedReproductiveList.value.map((item) => ({
  326. phenologyId: item.id,
  327. startDate: item.startDate,
  328. })),
  329. };
  330. const res = await VE_API.monitor.batchSaveFarmPhenologyTime(params);
  331. if (res.code === 0) {
  332. ElMessage.success("设置成功");
  333. showPhenologySetting.value = false;
  334. getFarmWorkPlanForPhenology();
  335. }
  336. };
  337. // 取消复制方案
  338. const handleCancelCopyPlan = () => {
  339. if (active.value === tabs.value[0]?.id) {
  340. showCopyPlan.value = false;
  341. } else {
  342. ElMessageBox.confirm("确定要删除该方案吗?", "提示", {
  343. confirmButtonText: "确定",
  344. cancelButtonText: "取消",
  345. type: "warning",
  346. }).then(() => {
  347. VE_API.monitor
  348. .deleteScheme({
  349. schemeId: active.value,
  350. })
  351. .then(({ code }) => {
  352. if (code === 0) {
  353. showCopyPlan.value = false;
  354. ElMessage.success("删除成功");
  355. getListMySchemes("left");
  356. }
  357. });
  358. });
  359. }
  360. };
  361. // 确定复制方案
  362. const handleConfirmCopyPlan = () => {
  363. if (!copyPlanName.value.trim()) {
  364. ElMessage.warning("请输入方案名称");
  365. return;
  366. }
  367. if (active.value === tabs.value[0]?.id) {
  368. VE_API.monitor
  369. .copyScheme({
  370. containerId: specieValue.value,
  371. sourceSchemeId: active.value,
  372. schemeName: copyPlanName.value,
  373. })
  374. .then(({ code, data }) => {
  375. if (code === 0) {
  376. showCopyPlan.value = false;
  377. ElMessage.success("复制成功");
  378. getListMySchemes("right");
  379. currentTab.value = data;
  380. }
  381. });
  382. } else {
  383. VE_API.monitor
  384. .renameScheme({
  385. schemeId: active.value,
  386. name: copyPlanName.value,
  387. })
  388. .then(({ code }) => {
  389. if (code === 0) {
  390. showCopyPlan.value = false;
  391. ElMessage.success("修改成功");
  392. getListMySchemes("auto");
  393. }
  394. });
  395. }
  396. };
  397. // 验证药肥报价信息并返回结果
  398. // 返回: { allTrue: boolean, invalidIds: string[] }
  399. const validatePesticideFertilizerQuotes = async () => {
  400. const { data, code } = await VE_API.monitor.batchValidatePesticideFertilizerQuotes({
  401. ids: farmWorkIds.value,
  402. schemeId: active.value,
  403. });
  404. if (code !== 0 || !data) {
  405. return { allTrue: false, invalidIds: [] };
  406. }
  407. // 判断所有值是否都为true
  408. const allTrue = Object.values(data).every((value) => value === true);
  409. // 收集所有不为true的ID
  410. const invalidIds = Object.keys(data).filter((key) => data[key] !== true);
  411. return { allTrue, invalidIds };
  412. };
  413. // 提交方案
  414. const handleSubmitPlan = async () => {
  415. // 调用验证方法,传入所有ids
  416. if (farmWorkIds.value.length > 0) {
  417. const { allTrue } = await validatePesticideFertilizerQuotes();
  418. if (allTrue) {
  419. VE_API.monitor
  420. .enableScheme({
  421. schemeId: active.value,
  422. })
  423. .then(({ code }) => {
  424. if (code === 0) {
  425. ElMessage.success("提交成功");
  426. getListMySchemes("auto");
  427. }
  428. });
  429. } else {
  430. ElMessage.warning("当前方案有未完善报价信息的农事,请先完善报价信息");
  431. }
  432. }
  433. };
  434. const savePlanPageInfo = () => {
  435. sessionStorage.setItem("specieValue", specieValue.value);
  436. sessionStorage.setItem("active", active.value);
  437. sessionStorage.setItem("arrangeIds", JSON.stringify(arrangeIds.value));
  438. sessionStorage.setItem("currentTabIndex", currentTabIndex.value);
  439. };
  440. // 新增农事
  441. const addNewTask = () => {
  442. savePlanPageInfo();
  443. router.push({
  444. path: "/add_work",
  445. query: {
  446. containerSpaceTimeId: containerSpaceTimeId.value,
  447. schemeId: schemeId.value,
  448. },
  449. });
  450. };
  451. const triggerFarmWork = () => {
  452. eventBus.emit("activeUpload:show", {
  453. gardenIdVal: route.query.farmId,
  454. problemTitleVal: "请选择您出现" + curFarmObj.value.farmWorkName + "的时间",
  455. arrangeIdVal: curFarmObj.value.id,
  456. needExecutorVal: true,
  457. });
  458. };
  459. const curFarmObj = ref({});
  460. const handleRowClick = (item) => {
  461. curFarmObj.value = item;
  462. savePlanPageInfo();
  463. sessionStorage.setItem("farmWorkIds", JSON.stringify(item.invalidIds));
  464. const enabled = tabs.value[currentTabIndex.value]?.enabled;
  465. router.push({
  466. path: "/modify",
  467. query: {
  468. id: item.id,
  469. noPrice: pageType.value === "plant" ? true : false,
  470. farmId: route.query.farmId,
  471. farmWorkId: item.farmWorkId,
  472. containerSpaceTimeId: item.containerSpaceTimeId,
  473. isDefault: active.value === tabs.value[0]?.id,
  474. enabled: enabled,
  475. isEdit: item.isEdit,
  476. },
  477. });
  478. };
  479. </script>
  480. <style scoped lang="scss">
  481. .plan-page {
  482. width: 100%;
  483. height: 100vh;
  484. background: #f5f7fb;
  485. .plan-content {
  486. .plan-content-header {
  487. display: flex;
  488. align-items: center;
  489. gap: 12px;
  490. margin: 10px 0 10px 12px;
  491. .select-item {
  492. width: 82px;
  493. ::v-deep {
  494. .el-select__wrapper {
  495. box-shadow: none;
  496. border-radius: 25px;
  497. border: 0.5px solid rgba(153, 153, 153, 0.5);
  498. }
  499. }
  500. }
  501. .tabs-list {
  502. width: calc(100% - 94px);
  503. margin-right: 8px;
  504. }
  505. }
  506. .tip-box {
  507. padding: 5px 10px;
  508. background: rgba(33, 153, 248, 0.1);
  509. border-radius: 5px;
  510. font-size: 12px;
  511. margin: 8px 10px;
  512. color: #444;
  513. }
  514. .timeline-wrap {
  515. height: calc(100vh - 90px - 80px);
  516. padding: 0 12px;
  517. &.timeline-container-plant-wrap {
  518. height: calc(100vh - 90px - 85px - 38px);
  519. }
  520. &.no-default-plan-wrap {
  521. height: calc(100vh - 90px - 85px - 100px);
  522. }
  523. // 没有权限时,底部按钮不显示,高度增加 73px
  524. &.timeline-container-no-permission-wrap {
  525. height: calc(100vh - 90px - 18px);
  526. }
  527. }
  528. }
  529. // 控制区域样式
  530. .custom-bottom-fixed-btns {
  531. flex-direction: column;
  532. .bottom-btn-group-wrap {
  533. display: flex;
  534. gap: 12px;
  535. width: 100%;
  536. justify-content: space-between;
  537. .bottom-btn-group {
  538. display: flex;
  539. gap: 12px;
  540. &.justify-center {
  541. justify-content: center;
  542. width: 100%;
  543. }
  544. }
  545. }
  546. &.center {
  547. justify-content: center;
  548. .bottom-btn {
  549. padding: 10px 45px;
  550. }
  551. }
  552. .bottom-btn-divider {
  553. width: calc(100% + 24px);
  554. height: 1px;
  555. background: #f0f0f0;
  556. margin: 10px -12px;
  557. }
  558. .submit-btn {
  559. padding: 10px 83px;
  560. }
  561. }
  562. }
  563. .copy-plan-popup {
  564. width: 100%;
  565. padding: 50px 12px 20px 12px;
  566. &::before {
  567. content: "";
  568. position: absolute;
  569. top: 0;
  570. left: 0;
  571. width: 100%;
  572. height: 136px;
  573. pointer-events: none;
  574. background: url("@/assets/img/monitor/popup-header-bg.png") no-repeat center center / 100% 100%;
  575. }
  576. .copy-plan-content {
  577. display: flex;
  578. align-items: center;
  579. gap: 12px;
  580. .label {
  581. font-size: 16px;
  582. font-weight: 500;
  583. }
  584. .copy-plan-input {
  585. width: calc(100% - 80px);
  586. }
  587. }
  588. .copy-plan-footer {
  589. display: flex;
  590. gap: 12px;
  591. margin-top: 20px;
  592. .btn {
  593. flex: 1;
  594. color: #666666;
  595. border: 1px solid #999999;
  596. border-radius: 25px;
  597. padding: 10px 0;
  598. font-size: 16px;
  599. text-align: center;
  600. &.btn-confirm {
  601. color: #fff;
  602. border: 1px solid #2199f8;
  603. background: #2199f8;
  604. }
  605. }
  606. }
  607. }
  608. .phenology-popup {
  609. padding: 28px 20px 20px;
  610. .phenology-header {
  611. font-size: 24px;
  612. text-align: center;
  613. margin-bottom: 20px;
  614. font-family: "PangMenZhengDao";
  615. }
  616. .phenology-list {
  617. width: 100%;
  618. .phenology-item {
  619. width: 100%;
  620. display: flex;
  621. align-items: center;
  622. justify-content: space-between;
  623. .item-label {
  624. display: flex;
  625. align-items: center;
  626. gap: 4px;
  627. font-size: 15px;
  628. color: rgba(0, 0, 0, 0.4);
  629. .label-text {
  630. color: #000;
  631. font-size: 16px;
  632. font-weight: 500;
  633. }
  634. }
  635. .item-value {
  636. width: calc(100% - 156px);
  637. }
  638. }
  639. .phenology-item + .phenology-item {
  640. margin-top: 10px;
  641. }
  642. }
  643. .phenology-footer {
  644. width: 100%;
  645. text-align: center;
  646. font-size: 16px;
  647. margin-top: 20px;
  648. color: #fff;
  649. background: #2199f8;
  650. border-radius: 25px;
  651. padding: 10px 0;
  652. }
  653. }
  654. </style>