index.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. <template>
  2. <div class="container">
  3. <svg-icon name="wallet-bg" class="bg-img" />
  4. <van-pull-refresh v-model="loading" @refresh="onRefresh" style="height:100%">
  5. <div class="user-info-body">
  6. <div class="user-info-lf">
  7. <van-image width="28px" height="28px" round :src="walletStore.avatar" />
  8. <div class="user-info">
  9. <div class="user-info-name" @click="showWallet = true">
  10. <div>{{ walletStore.username }}</div>
  11. <svg-icon
  12. style="width: 16px; height: 16px; margin-left: 3px"
  13. name="down"
  14. />
  15. </div>
  16. <div class="user-info-key-body">
  17. <span class="user-info-key-body-text">{{
  18. formatAddress(walletStore.account)
  19. }}</span>
  20. <svg-icon
  21. class="im-copy-btn"
  22. style="width: 16px; height: 16px"
  23. name="copy"
  24. :data-clipboard-text="walletStore.account"
  25. />
  26. </div>
  27. </div>
  28. </div>
  29. <div class="network">
  30. <van-image
  31. width="20px"
  32. height="20px"
  33. round
  34. :src="walletStore.accountIcon"
  35. />
  36. <div class="network-name">{{ walletStore.accountName }}</div>
  37. </div>
  38. </div>
  39. <div class="amount">
  40. <div class="amount-item-box">
  41. <div>Total assets</div>
  42. <div class="amount-item">
  43. <div class="item-text">
  44. <svg-icon class="my" style="width: 28px; height: 28px" name="my" />
  45. <div>{{ isShow ? totalMoney : "****" }}</div>
  46. </div>
  47. <svg-icon
  48. style="width: 16px; height: 16px"
  49. :name="isShow ? 'eyes' : 'seyes'"
  50. @click="isShow = !isShow"
  51. />
  52. </div>
  53. </div>
  54. <svg-icon
  55. style="width: 24px; height: 24px; margin-right: 27px"
  56. name="right"
  57. @click="goToPageDetail"
  58. />
  59. </div>
  60. <div class="card-box">
  61. <div class="box-cont" @click="goToPage('exchange')">
  62. <svg-icon
  63. class="box-cont-icon"
  64. style="width: 30px; height: 30px"
  65. name="1"
  66. />
  67. <div>{{ $t("wallet.GoldCoinExchange") }}</div>
  68. </div>
  69. <div class="box-cont" @click="goToPage('proceeds')">
  70. <svg-icon
  71. class="box-cont-icon"
  72. style="width: 30px; height: 30px"
  73. name="2"
  74. />
  75. <div>{{ $t("wallet.Collection") }}</div>
  76. </div>
  77. <div class="box-cont" @click="goToPage('transferDetail')">
  78. <svg-icon
  79. class="box-cont-icon"
  80. style="width: 30px; height: 30px"
  81. name="3"
  82. />
  83. <div>{{ $t("wallet.Transfer") }}</div>
  84. </div>
  85. <div class="box-cont" @click="goToDapp(1)">
  86. <svg-icon
  87. class="box-cont-icon"
  88. style="width: 30px; height: 30px"
  89. name="4"
  90. />
  91. <div>{{ $t("wallet.Competition") }}</div>
  92. </div>
  93. <div class="box-cont" @click="goToDapp(2)">
  94. <svg-icon
  95. class="box-cont-icon"
  96. style="width: 30px; height: 30px"
  97. name="5"
  98. />
  99. <div>{{ $t("wallet.BlockBrowser") }}</div>
  100. </div>
  101. </div>
  102. <div class="list-box">
  103. <div class="list-title">
  104. <div>{{ $t("wallet.Token") }}</div>
  105. <svg-icon
  106. style="width: 24px; height: 24px"
  107. name="add"
  108. @click="changePop(1)"
  109. />
  110. </div>
  111. <div class="list-ul">
  112. <template v-for="(item, i) in walletStore.tokenList" :key="i">
  113. <div
  114. class="list-li"
  115. v-if="item.name == 'ACC' || !item.show"
  116. @click="changePop(2, item)"
  117. >
  118. <div class="list-li-lf">
  119. <van-image width="30px" height="30px" round :src="item.logo" />
  120. <div style="margin-left: 8px">{{ item.name }}</div>
  121. </div>
  122. <div class="list-li-ri">
  123. <div>{{ item.balance }}</div>
  124. <div class="list-li-ri-num">${{ item.money }}</div>
  125. </div>
  126. </div>
  127. </template>
  128. </div>
  129. </div>
  130. </van-pull-refresh>
  131. <van-popup v-model:show="showWallet" position="bottom" round>
  132. <div class="pop-content">
  133. <div class="pop-title">
  134. <svg-icon
  135. style="width: 24px; height: 24px"
  136. name="left-arrow"
  137. @click="showWallet = false"
  138. />
  139. <div class="title">{{ $t("wallet.SelectWallet") }}</div>
  140. </div>
  141. <div class="tree">
  142. <div class="tree-lf">
  143. <div
  144. class="tree-lf-icon"
  145. v-for="(item, i) in networkList"
  146. :class="netWorkIndex == i ? 'active-bg' : ''"
  147. @click="changeNetwork(i)"
  148. >
  149. <van-image lazy-load class="network-item-icon" :src="item.icon" />
  150. </div>
  151. </div>
  152. <div class="tree-ri">
  153. <div class="tree-ri-title">
  154. {{ networkList[netWorkIndex]?.name }}
  155. </div>
  156. <div class="tree-ul">
  157. <div
  158. class="tree-li"
  159. v-for="(item, i) in currentWallets"
  160. :class="item.id == walletStore.id ? 'tree-active' : ''"
  161. @click="changeWallet(item)"
  162. >
  163. <van-image
  164. width="37px"
  165. height="37px"
  166. round
  167. :src="item.avatar"
  168. />
  169. <div class="tree-li-cont">
  170. <div class="tree-li-text">{{ item.username }}</div>
  171. <div class="tree-li-address">
  172. <span>{{ formatAddress(item.account) }}</span>
  173. <svg-icon
  174. class="im-copy-btn"
  175. style="width: 16px; height: 16px; margin-left: 2px"
  176. name="copy"
  177. :data-clipboard-text="item.account"
  178. />
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. </div>
  184. </div>
  185. <div class="pop-btn" @click="addWallet">
  186. <van-button class="btn" type="primary" size="large" color="#4765DD">
  187. <svg-icon
  188. style="width: 24px; height: 24px; margin-right: 4px"
  189. name="add1"
  190. />{{ $t("wallet.AddWallet") }}
  191. </van-button>
  192. </div>
  193. </div>
  194. </van-popup>
  195. <van-popup
  196. v-model:show="showHistory"
  197. position="bottom"
  198. round
  199. style="height: 500px"
  200. >
  201. <div class="pop-content" style="height: 500px">
  202. <div class="pop-title">
  203. <svg-icon
  204. style="width: 24px; height: 24px"
  205. name="left-arrow"
  206. @click="showHistory = false"
  207. />
  208. <div class="title">
  209. {{
  210. type == 1
  211. ? $t("wallet.AddTokens")
  212. : $t("wallet.HistoricalRecords")
  213. }}
  214. </div>
  215. </div>
  216. <!-- 1 -->
  217. <div class="pop-ul" v-if="type == 1">
  218. <div class="pop-li" v-for="(item, i) in walletStore.tokenList">
  219. <div class="pop-li-lf" v-if="item.name != 'ACC'">
  220. <van-image width="32px" height="32px" round :src="item.logo" />
  221. <div style="margin-left: 6px">
  222. <div>{{ item.name }}</div>
  223. <div class="pop-address">{{ formatAddress(item.address) }}</div>
  224. </div>
  225. </div>
  226. <svg-icon
  227. v-if="item.name != 'ACC'"
  228. style="width: 20px; height: 20px"
  229. :name="item.show ? 'add-icon' : 'del-icon'"
  230. @click="tokensHandle(item)"
  231. />
  232. </div>
  233. </div>
  234. <!-- 2 -->
  235. <div class="pop-list" v-if="type == 2">
  236. <div class="pop-list-box" v-for="(item, i) in historyList">
  237. <svg-icon
  238. style="width: 24px; height: 24px; color: #fff"
  239. :name="item.from?.hash == walletStore.account ? 'fs' : 'js'"
  240. />
  241. <div class="pop-list-ul">
  242. <div class="pop-list-li">
  243. <div class="pop-list-li-title">
  244. {{
  245. item.from?.hash == walletStore.account
  246. ? $t("wallet.Send")
  247. : $t("wallet.Receive")
  248. }}
  249. </div>
  250. <div class="pop-list-li-status">{{ $t("wallet.Success") }}</div>
  251. </div>
  252. <div class="pop-list-li">
  253. <div>{{ $t("wallet.TransferAmount") }}</div>
  254. <div>{{ item.value }}{{ selectUrl.name }}</div>
  255. </div>
  256. <div class="pop-list-li">
  257. <div>
  258. {{
  259. item.from?.hash == walletStore.account
  260. ? $t("wallet.Send")
  261. : $t("wallet.Receive")
  262. }}{{ $t("wallet.Time") }}
  263. </div>
  264. <div>{{ item.timestamp }}</div>
  265. </div>
  266. <div class="pop-list-li">
  267. <div>{{ $t("wallet.ReceivingAddress") }}</div>
  268. <div>
  269. {{ formatAddress(item.to?.hash) }}
  270. <svg-icon
  271. class="im-copy-btn"
  272. style="width: 16px; height: 16px"
  273. name="copy"
  274. :data-clipboard-text="item.to?.hash"
  275. />
  276. </div>
  277. </div>
  278. <div class="pop-list-li">
  279. <div>hash</div>
  280. <div>
  281. {{ formatAddress(item.hash) }}
  282. <svg-icon
  283. class="im-copy-btn"
  284. style="width: 16px; height: 16px"
  285. name="copy"
  286. :data-clipboard-text="item.hash"
  287. />
  288. </div>
  289. </div>
  290. <div class="pop-list-li" v-if="selectUrl.name == 'ACC'">
  291. <div>{{ $t("wallet.MinerIsFee") }}</div>
  292. <div>{{ item.gas_price }}ACC</div>
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. </div>
  298. </van-popup>
  299. </div>
  300. </template>
  301. <script setup>
  302. import { getNetwork } from "@/api/path/login.api";
  303. import { useWalletStore } from "@/stores/modules/walletStore";
  304. import { useSystemStore } from "@/stores/modules/systemStore";
  305. import { transactions, tokenTransfers } from "@/api/path/backend.api";
  306. import { openDapp } from "@/composables/dAppView";
  307. import { cryptoEncode } from "@/utils/crypto";
  308. import { useCopy } from "@/hooks/use-copy.js";
  309. import { Device } from "@capacitor/device";
  310. useCopy();
  311. const router = useRouter();
  312. const walletStore = useWalletStore();
  313. const systemStore = useSystemStore();
  314. const loading = ref(false);
  315. const isShow = ref(true);
  316. const showWallet = ref(false);
  317. const showHistory = ref(false);
  318. const networkList = ref([]);
  319. const netWorkIndex = ref(0);
  320. const type = ref("");
  321. const historyList = ref([]);
  322. const selectUrl = ref({});
  323. const goToPage = (url) => {
  324. router.push(url);
  325. };
  326. const onRefresh = () => {
  327. setTimeout(() => {
  328. gethotTokens();
  329. loading.value = false;
  330. }, 1000);
  331. };
  332. // 跳转详情
  333. const goToPageDetail = () => {
  334. router.push({
  335. path: "walletDetail",
  336. query: {
  337. id: walletStore.id,
  338. },
  339. });
  340. };
  341. const changePop = (val, item) => {
  342. type.value = val;
  343. if (val == 2) {
  344. getDetail(item);
  345. selectUrl.value = item;
  346. return;
  347. }
  348. showHistory.value = true;
  349. };
  350. // 查看历史记录
  351. const getDetail = (item) => {
  352. historyList.value = [];
  353. if (item.name == "ACC") {
  354. getList();
  355. } else {
  356. getDBList(item.address);
  357. }
  358. showHistory.value = true;
  359. };
  360. const getList = async () => {
  361. const res = await transactions(walletStore.account);
  362. const items = res.items || [];
  363. if (items.length > 0) {
  364. items.forEach((val) => {
  365. val.timestamp = getDateTime(val.timestamp);
  366. val.gas_price = getPrice(val.fee.value).toFixed(9);
  367. if (val.value !== "0") {
  368. val.value = getPrice(val.value).toFixed(6);
  369. }
  370. });
  371. historyList.value = items;
  372. }
  373. };
  374. const getDBList = async (DBaddress) => {
  375. const res = await tokenTransfers(walletStore.account,DBaddress);
  376. const items = res.items || [];
  377. if (items.length > 0) {
  378. items.forEach((val) => {
  379. val.timestamp = getDateTime(val.timestamp);
  380. val.value = getPrice(val.total.value).toFixed(6);
  381. val.hash = val.transaction_hash;
  382. });
  383. historyList.value = items;
  384. }
  385. };
  386. // 计算总和
  387. const totalMoney = computed(() => {
  388. const list = walletStore.tokenList;
  389. if (!Array.isArray(list) || list.length === 0) return 0;
  390. let total = Number(list[0].money || 0);
  391. for (let i = 1; i < list.length; i++) {
  392. if (!list[i].show) {
  393. total += Number(list[i].money || 0);
  394. }
  395. }
  396. return Number(total.toFixed(4));
  397. });
  398. // 添加钱包
  399. const addWallet = () => {
  400. walletStore.accountName = networkList.value[netWorkIndex.value].name;
  401. walletStore.accountIcon = networkList.value[netWorkIndex.value].icon;
  402. walletStore.rpcUrl = networkList.value[netWorkIndex.value].url;
  403. router.push({
  404. path: "/login",
  405. query: {
  406. isFirst: false,
  407. },
  408. });
  409. };
  410. // 网络数据
  411. const initNetwork = async () => {
  412. const { data } = await getNetwork({});
  413. networkList.value = data;
  414. };
  415. const currentChainName = computed(
  416. () => networkList.value[netWorkIndex.value]?.name
  417. );
  418. // 当前链对应的钱包数组
  419. const currentWallets = computed(() => {
  420. return walletStore.walletList.filter(
  421. (w) => w.accountName === currentChainName.value
  422. );
  423. });
  424. // 切换网络
  425. const changeNetwork = (i) => {
  426. netWorkIndex.value = i;
  427. };
  428. // 切换钱包
  429. const changeWallet = (item) => {
  430. walletStore.switchWallet(item.id, item.account);
  431. showWallet.value = false;
  432. };
  433. // 代币显示隐藏
  434. const tokensHandle = (item) => {
  435. walletStore.changeToten(item.name);
  436. };
  437. // 更新代币信息
  438. const gethotTokens = async () => {
  439. await walletStore.updateTokenVal();
  440. };
  441. // 跳转竞赛
  442. const goToDapp = (val) => {
  443. const dapp = cryptoEncode(
  444. JSON.stringify({
  445. address: walletStore.account,
  446. privateKey: walletStore.privateKey,
  447. })
  448. );
  449. if(val == 1){
  450. openDapp("https://accgame.angeltokens.io/", { dapp });
  451. }else{
  452. openDapp("https://backend.angeltoken.net/",{}, true);
  453. }
  454. };
  455. const formatAddress = (address) => {
  456. if (!address) return "";
  457. return address.slice(0, 8) + "..." + address.slice(-6);
  458. };
  459. const getPrice = (price) => {
  460. const num = parseFloat(price) / Math.pow(10, 18);
  461. return num;
  462. };
  463. const getDateTime = (isoString) => {
  464. const date = new Date(isoString);
  465. const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}:${String(date.getSeconds()).padStart(2, "0")}`;
  466. return formattedDate;
  467. };
  468. onMounted(async () => {
  469. initNetwork();
  470. gethotTokens();
  471. const deviceId = await Device.getId();
  472. systemStore.DeviceId = deviceId.identifier;
  473. });
  474. </script>
  475. <style lang="less" scoped>
  476. .container {
  477. position: relative;
  478. display: flex;
  479. flex-direction: column;
  480. height: calc(100vh - 50px);
  481. .bg-img {
  482. height: 18.8rem;
  483. min-width: 100%;
  484. width: 100vw;
  485. position: absolute;
  486. top: -0.8rem;
  487. left: 0;
  488. z-index: -1;
  489. }
  490. :deep(.van-pull-refresh__text){
  491. color: #fff !important;
  492. }
  493. :deep(.van-loading__text){
  494. color: #fff !important;
  495. }
  496. .user-info-body {
  497. padding: 60px 17px 25px;
  498. display: flex;
  499. align-items: center;
  500. justify-content: space-between;
  501. .user-info-lf {
  502. display: flex;
  503. align-items: center;
  504. .user-info {
  505. margin-left: 11px;
  506. font-family:
  507. PingFang SC,
  508. PingFang SC;
  509. font-size: 10px;
  510. .user-info-name {
  511. font-weight: 500;
  512. color: #ffffff;
  513. display: flex;
  514. align-items: center;
  515. margin-bottom: 2px;
  516. }
  517. .user-info-key-body {
  518. font-weight: 400;
  519. color: rgba(255, 255, 255, 0.6);
  520. display: flex;
  521. align-items: center;
  522. .user-info-key-body-text {
  523. margin-right: 4px;
  524. }
  525. }
  526. }
  527. }
  528. .network {
  529. display: flex;
  530. align-items: center;
  531. border-radius: 27px;
  532. border: 1px solid rgba(255, 255, 255, 0.6);
  533. padding: 0 5px;
  534. font-family:
  535. PingFang SC,
  536. PingFang SC;
  537. font-weight: 400;
  538. font-size: 15px;
  539. color: #ffffff;
  540. height: 25px;
  541. line-height: 25px;
  542. box-sizing: border-box;
  543. .network-name {
  544. margin-left: 5px;
  545. }
  546. }
  547. }
  548. .amount {
  549. height: 102px;
  550. background-color: rgba(242, 242, 242, 0.2);
  551. backdrop-filter: blur(3px);
  552. -webkit-backdrop-filter: blur(3px);
  553. border-radius: 15px;
  554. margin: 0 17px 20px 17px;
  555. box-shadow: 0 7px 10px #15277031;
  556. box-sizing: border-box;
  557. display: flex;
  558. align-items: center;
  559. justify-content: space-between;
  560. font-family:
  561. PingFang SC,
  562. PingFang SC;
  563. font-weight: 400;
  564. font-size: 15px;
  565. color: #ffffff;
  566. &:before {
  567. height: calc(100% - 4px);
  568. width: calc(100% - 4px);
  569. content: "";
  570. position: absolute;
  571. inset: 0;
  572. z-index: -1;
  573. padding: 2px; /* 边框宽度 */
  574. background: linear-gradient(
  575. 135deg,
  576. rgba(255, 255, 255, 0.6) 0%,
  577. rgba(255, 255, 255, 0.2) 25%,
  578. rgba(255, 255, 255, 0.1) 50%,
  579. rgba(255, 255, 255, 0.2) 75%,
  580. rgba(255, 255, 255, 0.6) 100%
  581. ); //linear-gradient(135deg, #ffffff64, #ffffff2e); /* 渐变方向可调 */
  582. -webkit-mask:
  583. linear-gradient(#fff 0 0) content-box,
  584. linear-gradient(#fff 0 0);
  585. -webkit-mask-composite: xor;
  586. mask-composite: exclude;
  587. border-radius: 15px; /* 必须和父元素一致 */
  588. pointer-events: none; /* 避免遮挡点击 */
  589. }
  590. .amount-item-box {
  591. margin: 21px 21px 27px 27px;
  592. }
  593. .amount-item {
  594. margin-top: 7px;
  595. font-weight: 600;
  596. font-size: 25px;
  597. display: flex;
  598. position: relative;
  599. .item-text {
  600. display: flex;
  601. align-items: center;
  602. margin-right: 2px;
  603. .my {
  604. position: relative;
  605. top: 1px;
  606. }
  607. }
  608. }
  609. }
  610. .card-box {
  611. background: #ffffff;
  612. box-shadow: 0px 4px 8px -2px rgba(25, 75, 137, 0.25);
  613. border-radius: 17px;
  614. height: 78px;
  615. margin: 0 17px;
  616. padding: 15px 10px;
  617. box-sizing: border-box;
  618. display: flex;
  619. align-items: center;
  620. font-family:
  621. PingFang SC,
  622. PingFang SC;
  623. font-weight: 400;
  624. font-size: 12px;
  625. color: #000000;
  626. .box-cont {
  627. width: calc(100% / 5);
  628. display: flex;
  629. flex-direction: column;
  630. align-items: center;
  631. .box-cont-icon {
  632. margin-bottom: 4px;
  633. color: #fff;
  634. }
  635. }
  636. }
  637. .list-box {
  638. background: #ffffff;
  639. border-radius: 12px;
  640. margin: 25px 17px;
  641. padding: 16px;
  642. box-sizing: border-box;
  643. display: flex;
  644. flex-direction: column;
  645. flex: 1;
  646. overflow: hidden;
  647. .list-title {
  648. display: flex;
  649. justify-content: space-between;
  650. align-items: center;
  651. font-family:
  652. PingFang SC,
  653. PingFang SC;
  654. font-weight: 500;
  655. font-size: 17px;
  656. color: #000000;
  657. margin-bottom: 23px;
  658. }
  659. .list-ul {
  660. flex: 1;
  661. display: flex;
  662. flex-direction: column;
  663. overflow: auto;
  664. .list-li {
  665. display: flex;
  666. align-items: center;
  667. justify-content: space-between;
  668. font-family:
  669. PingFang SC,
  670. PingFang SC;
  671. font-weight: 500;
  672. margin-bottom: 12px;
  673. .list-li-lf {
  674. display: flex;
  675. align-items: center;
  676. font-size: 15px;
  677. color: #000000;
  678. }
  679. .list-li-ri {
  680. font-size: 12px;
  681. color: @font-color2;
  682. text-align: right;
  683. .list-li-ri-num {
  684. font-weight: 400;
  685. font-size: 10px;
  686. color: #8d8d8d;
  687. }
  688. }
  689. }
  690. .list-li:last-child {
  691. margin-bottom: 0;
  692. }
  693. }
  694. .list-ul::-webkit-scrollbar {
  695. width: 0;
  696. }
  697. }
  698. .pop-content {
  699. display: flex;
  700. flex-direction: column;
  701. .pop-title {
  702. padding: 17px;
  703. border-bottom: 1px solid #f2f2f2;
  704. display: flex;
  705. align-items: center;
  706. font-family:
  707. PingFang SC,
  708. PingFang SC;
  709. font-weight: 500;
  710. font-size: 17px;
  711. color: #000000;
  712. .title {
  713. flex: 1;
  714. display: flex;
  715. justify-content: center;
  716. }
  717. }
  718. .tree {
  719. display: flex;
  720. height: 300px;
  721. overflow: hidden;
  722. .tree-lf {
  723. display: flex;
  724. flex-direction: column;
  725. width: 67px;
  726. overflow: auto;
  727. .tree-lf-icon {
  728. height: 67px;
  729. padding: 16px;
  730. box-sizing: border-box;
  731. display: flex;
  732. align-items: center;
  733. justify-content: center;
  734. }
  735. .active-bg {
  736. background: #eceffc;
  737. }
  738. }
  739. .tree-lf::-webkit-scrollbar {
  740. width: 0;
  741. }
  742. .tree-ri {
  743. margin-left: 10px;
  744. margin-right: 17px;
  745. flex: 1;
  746. overflow: auto;
  747. .tree-ri-title {
  748. margin: 10px 0 4px;
  749. font-family:
  750. PingFang SC,
  751. PingFang SC;
  752. font-weight: 500;
  753. font-size: 15px;
  754. color: #000000;
  755. }
  756. .tree-ul {
  757. .tree-li {
  758. background: #f2f2f2;
  759. border-radius: 8px;
  760. border: 1px solid #f2f2f2;
  761. padding: 14px 16px;
  762. display: flex;
  763. align-items: center;
  764. margin-bottom: 12px;
  765. .tree-li-cont {
  766. margin-left: 12px;
  767. font-family:
  768. PingFang SC,
  769. PingFang SC;
  770. font-weight: 400;
  771. font-size: 12px;
  772. color: #8d8d8d;
  773. .tree-li-text {
  774. font-weight: 500;
  775. font-size: 15px;
  776. color: @theme-color1;
  777. }
  778. .tree-li-address {
  779. display: flex;
  780. align-items: center;
  781. }
  782. }
  783. }
  784. .tree-active {
  785. background: #fafbff;
  786. border: 1px solid @theme-color1;
  787. }
  788. }
  789. }
  790. .tree-ri::-webkit-scrollbar {
  791. width: 0;
  792. }
  793. }
  794. .pop-btn {
  795. margin: 17px;
  796. .btn {
  797. height: 40px;
  798. border-radius: 50px;
  799. font-family:
  800. PingFang SC,
  801. PingFang SC;
  802. font-weight: 500;
  803. font-size: 15px;
  804. color: #ffffff;
  805. }
  806. :deep(.van-button__text) {
  807. display: flex;
  808. align-items: center;
  809. }
  810. }
  811. .pop-list {
  812. flex: 1;
  813. display: flex;
  814. flex-direction: column;
  815. overflow: auto;
  816. .pop-list-box {
  817. display: flex;
  818. padding: 17px 17px 0;
  819. .pop-list-ul {
  820. padding-bottom: 12px;
  821. flex: 1;
  822. margin-left: 8px;
  823. border-bottom: 1px solid #f2f2f2;
  824. box-sizing: border-box;
  825. .pop-list-li {
  826. display: flex;
  827. align-items: center;
  828. justify-content: space-between;
  829. font-family:
  830. PingFang SC,
  831. PingFang SC;
  832. margin-bottom: 4px;
  833. font-weight: 400;
  834. font-size: 12px;
  835. color: @font-color2;
  836. .pop-list-li-title {
  837. font-weight: 500;
  838. font-size: 15px;
  839. color: #000000;
  840. }
  841. .pop-list-li-status {
  842. font-weight: 500;
  843. font-size: 15px;
  844. color: @theme-color1 !important;
  845. }
  846. }
  847. .pop-list-li div:last-child {
  848. color: #8d8d8d;
  849. }
  850. }
  851. }
  852. }
  853. .pop-list::-webkit-scrollbar {
  854. width: 0;
  855. }
  856. .pop-ul {
  857. flex: 1;
  858. display: flex;
  859. flex-direction: column;
  860. overflow: auto;
  861. margin: 16px 16px 0;
  862. .pop-li {
  863. display: flex;
  864. align-items: center;
  865. justify-content: space-between;
  866. margin-bottom: 16px;
  867. .pop-li-lf {
  868. display: flex;
  869. align-items: center;
  870. font-family:
  871. PingFang SC,
  872. PingFang SC;
  873. font-weight: 400;
  874. font-size: 15px;
  875. color: #4f4f4f;
  876. .pop-address {
  877. font-size: 12px;
  878. color: #8d8d8d;
  879. }
  880. }
  881. }
  882. }
  883. }
  884. }
  885. </style>