add.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. <template>
  2. <div class="center">
  3. <div class="title">Create NFTs</div>
  4. <div class="content">
  5. <div class="l">
  6. <div class="name">Preview</div>
  7. <template v-if="configList.length">
  8. <div class="show">
  9. <div class="card" :class="selectItem.modelName">
  10. <div class="logo">
  11. <img v-if="uploadItem && uploadItem.imagePath" :src="uploadItem.imagePath" alt="">
  12. </div>
  13. <div class="member">{{ projectName === '' ? 'xxxx' : projectName }}</div>
  14. <div class="number">{{ projectNo === '' ? '0000' : projectNo }}</div>
  15. </div>
  16. <img class="bg" :src="selectItem.mainImagePath" />
  17. </div>
  18. <div class="list">
  19. <div
  20. class="item"
  21. :class="{ on: item.modelName === selectItem.modelName }"
  22. @click="select(item, index)"
  23. v-for="(item, index) in configList"
  24. :key="index">
  25. <img :src="item.previewImagePath" alt="" />
  26. </div>
  27. </div>
  28. </template>
  29. <div class="wait" v-else>
  30. <img width="30" src="../../static/img/icon-loading-gray.png" alt="" />
  31. </div>
  32. </div>
  33. <div class="r">
  34. <div class="name">Card face</div>
  35. <div class="face">
  36. <input type="file" class="file" @change="uploadImg" accept="image/png,image/jpg,image/jpeg" />
  37. <div class="on" v-if="uploadItem && uploadItem.imagePath">
  38. <img src="../../static/img/icon-add-cover-on.svg" alt="" />
  39. <img class="img" :src="uploadItem.imagePath" alt="" />
  40. </div>
  41. <div class="off" v-else>
  42. <img src="../../static/img/icon-add-cover-off.svg" alt="" />
  43. </div>
  44. </div>
  45. <div class="desc">Recommended size 500*500 or more</div>
  46. <div class="name">Project Name</div>
  47. <div class="input"><input type="text" maxlength="30" v-model="projectName" placeholder="Your NFT Project Name" /></div>
  48. <div class="name">Project Description</div>
  49. <div class="textarea"><textarea placeholder="Your NFT Project Description" maxlength="250" v-model="projectDesc"></textarea></div>
  50. <div class="name">Collection Size</div>
  51. <div class="input"><input type="text" v-model="projectSize" placeholder="0" /></div>
  52. <div class="showNo" v-if="showNoStr">No.{{ projectNo === '' ? '0000' : projectNo }}~{{projectSize}}</div>
  53. <div class="name">NFTs Price</div>
  54. <div class="price">
  55. <div class="currency" @click="showCurrencyDialog" v-if="currencyItem">
  56. <img class="head" :src="currencyItem.iconPath" alt="" />
  57. <div class="font">{{currencyItem.tokenSymbol}}</div>
  58. <img class="arrow" src="../../static/img/icon-add-arrow.svg" alt="" />
  59. </div>
  60. <div class="no-select" @click="showCurrencyDialog" v-else>
  61. <div class="font">Select a reward</div>
  62. <img class="arrow" src="../../static/img/icon-add-arrow-white.svg" alt="" />
  63. </div>
  64. <div class="input"><input type="number" v-model="projectPrice" @input="changePrice" placeholder="0" /></div>
  65. <!-- 货币列表 -->
  66. <div class="currency-pop" v-if="currencyDialog">
  67. <currency-list @selectCurrencyItem="selectCurrencyItem"></currency-list>
  68. </div>
  69. </div>
  70. <div class="explain">
  71. <ul>
  72. <li class="special">The NFT colection is minted on BNB Smart Chain (BEP20)</li>
  73. <li>NFT will be released in blind box mode</li>
  74. <li>Users need to pay service fees when transferring NFTs</li>
  75. </ul>
  76. </div>
  77. <div class="footer"></div>
  78. </div>
  79. </div>
  80. <div class="create">
  81. <button class="on" v-if="isNext" @click="next">Create</button>
  82. <button class="off" v-else>Create</button>
  83. </div>
  84. </div>
  85. <div class="feedBack" @click="feedback">
  86. <a href="mailto:service@cybertogether.net">
  87. <div class="mail">
  88. <img src="../../static/img/icon-feedback.svg" alt="" />
  89. </div>
  90. <div class="font">Feedback</div>
  91. </a>
  92. </div>
  93. <div class="loading" v-if="showLoading">
  94. <img src="../../static/img/icon-add-loading.svg" alt="" />
  95. </div>
  96. <div class="succ" v-if="showSuccess">
  97. <img class="icon" src="../../static/img/icon-notice-succ.svg" alt="" />
  98. <div class="notic">We have created your NFT collection</div>
  99. <button class="btn" @click="jumpList">Done</button>
  100. </div>
  101. <div class="succ-bg" v-if="showSuccess"></div>
  102. <div class="mask-bg" v-if="currencyDialog" @click="hideCurrencyDialog"></div>
  103. </template>
  104. <script lang="ts" setup>
  105. import { ref, onMounted, watchEffect } from 'vue';
  106. import Api from '../../static/http/api';
  107. import { postRequest } from '../../static/http';
  108. import { uploadFile } from '../../static/utils/upload'
  109. import { Report } from '../../static/report'
  110. import { businessType, pageSource, objectType } from '../../static/report/enum'
  111. import currencyList from '../../components/currency-list.vue';
  112. const isNext = ref(false);
  113. const showLoading = ref(false);
  114. const showSuccess = ref(false);
  115. const maxSize = ref(1000);
  116. const configList = ref([]);
  117. const selectItem = ref(null);
  118. const uploadItem = ref({});
  119. const currencyDialog = ref(false);
  120. const currencyItem = ref(null);
  121. const projectName = ref('');
  122. const projectDesc = ref('');
  123. const projectSize = ref('');
  124. const projectNo = ref('');
  125. const projectPrice = ref('');
  126. const showNoStr = ref(false);
  127. const buttonType = {
  128. feedback: 'feedback-button',
  129. create: 'create-button',
  130. }
  131. const getConfig = () => {
  132. postRequest(Api.createConfig).then(res => {
  133. let { code, data } = res;
  134. if ( code === 0 ) {
  135. configList.value = data.itemModels;
  136. maxSize.value = data.maxCollectionSize;
  137. selectItem.value = data.itemModels[0];
  138. }
  139. })
  140. }
  141. const next = () => {
  142. // show loading
  143. showLoading.value = true;
  144. // post
  145. postRequest(Api.userNftAdd, {
  146. params: {
  147. // 项目图标
  148. cardFaceImagePath: uploadItem.value && uploadItem.value.objectKey || '',
  149. // 发行数量
  150. nftCollectionSize: projectSize.value || '',
  151. // 选中的模版id
  152. nftItemImageModel: selectItem.value && selectItem.value.modelName || '',
  153. // 项目描述
  154. nftProjectDescription: projectDesc.value || '',
  155. // 项目名称
  156. nftProjectName: projectName.value || '',
  157. // 销售价格
  158. saleCurrencyAmount: projectPrice.value || '',
  159. // 销售的货币code
  160. saleCurrencyCode: currencyItem.value && currencyItem.value.currencyCode || '',
  161. }
  162. }).then(res => {
  163. if (res.code === 0) {
  164. showSuccess.value = true;
  165. }
  166. }).finally(() => {
  167. showLoading.value = false;
  168. })
  169. // Report
  170. Report({
  171. baseInfo: {
  172. pageSource: pageSource.creatorPage,
  173. },
  174. params: {
  175. eventData: {
  176. businessType: businessType.buttonClick,
  177. objectType: buttonType.create,
  178. }
  179. }
  180. })
  181. }
  182. const select = (item: any, index: number) => {
  183. selectItem.value = item;
  184. let objectType;
  185. switch(index) {
  186. case 0:
  187. objectType = `first-NFT-selection-button`;
  188. break;
  189. case 1:
  190. objectType = `second-NFT-selection-button`;
  191. break;
  192. case 2:
  193. objectType = `third-NFT-selection-button`;
  194. break;
  195. case 3:
  196. objectType = `forth-NFT-selection-button`;
  197. break;
  198. }
  199. // Report
  200. Report({
  201. baseInfo: {
  202. pageSource: pageSource.creatorPage,
  203. },
  204. params: {
  205. eventData: {
  206. businessType: businessType.buttonClick,
  207. objectType: objectType,
  208. }
  209. }
  210. })
  211. }
  212. const showCurrencyDialog = () => {
  213. currencyDialog.value = true;
  214. }
  215. const hideCurrencyDialog = () => {
  216. currencyDialog.value = false;
  217. }
  218. const selectCurrencyItem = (data: any) => {
  219. currencyItem.value = data;
  220. hideCurrencyDialog();
  221. }
  222. const uploadImg = (e: any) => {
  223. let file = e.target.files[0];
  224. // 清空file
  225. e.target.value = '';
  226. // upload
  227. uploadFile(file).then(res => {
  228. // @ts-ignore
  229. uploadItem.value = res;
  230. })
  231. }
  232. const hideSuccess = () => {
  233. showSuccess.value = false;
  234. }
  235. const jumpList = () => {
  236. location.href = `/nft/list`
  237. }
  238. const changePrice = (e: any) => {
  239. projectPrice.value = String(Math.abs(e.target.value))
  240. }
  241. const feedback = () => {
  242. // Report
  243. Report({
  244. baseInfo: {
  245. pageSource: pageSource.creatorPage,
  246. },
  247. params: {
  248. eventData: {
  249. businessType: businessType.buttonClick,
  250. objectType: buttonType.feedback,
  251. }
  252. }
  253. })
  254. }
  255. let timer = ref(0);
  256. watchEffect(() => {
  257. let emojiReg = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi;
  258. let nameValue = projectName.value.trim();
  259. projectName.value = nameValue.replace(emojiReg, '');
  260. // setTimeout
  261. clearTimeout(timer.value);
  262. timer.value = setTimeout(() => {
  263. projectDesc.value = projectDesc.value.trim()
  264. }, 400)
  265. // 数量
  266. let num = projectSize.value;
  267. num = num.replace(/\D/g, '');
  268. if (Number(num) > maxSize.value) {
  269. num = String(maxSize.value);
  270. }
  271. if (num) {
  272. projectSize.value = String(Number(num));
  273. } else {
  274. projectSize.value = '';
  275. }
  276. // 编号
  277. if (projectSize.value !== '') {
  278. projectNo.value = String(1).padStart(String(projectSize.value).length, '0')
  279. } else {
  280. projectNo.value = ''
  281. }
  282. showNoStr.value = projectNo.value != '';
  283. // 是否可以创建
  284. let ifUpload = uploadItem.value && uploadItem.value.objectKey || false;
  285. let ifName = projectName.value !== '';
  286. let ifDesc = projectDesc.value !== '';
  287. let ifSize = projectSize.value !== '' && Number(projectSize.value) > 0;
  288. let ifCurrency = currencyItem.value && currencyItem.value.currencyCode;
  289. let ifPrice = projectPrice.value && projectPrice.value !== '' && Number(projectPrice.value) > 0;
  290. isNext.value = ifUpload && ifName && ifDesc && ifSize && ifCurrency && ifPrice;
  291. })
  292. onMounted(() => {
  293. // config
  294. getConfig()
  295. // Report
  296. Report({
  297. baseInfo: {
  298. pageSource: pageSource.creatorPage,
  299. },
  300. params: {
  301. eventData: {
  302. businessType: businessType.pageView,
  303. }
  304. }
  305. })
  306. })
  307. </script>
  308. <style lang="less" scoped>
  309. .center {
  310. overflow-y: auto;
  311. padding: 0 50px;
  312. width: 1100px;
  313. margin: 10px auto 0;
  314. box-sizing: border-box;
  315. height: calc(100% - 10px);
  316. background-color: #fff;
  317. border-radius: 20px 20px 0 0;
  318. .title {
  319. padding: 22px 0;
  320. font-size: 20px;
  321. font-weight: 600;
  322. line-height: 24px;
  323. }
  324. .content {
  325. width: 100%;
  326. clear: both;
  327. display: flex;
  328. justify-content: space-between;
  329. .name {
  330. height: 24px;
  331. font-size: 12px;
  332. color: #939393;
  333. }
  334. .showNo {
  335. color: #939393;
  336. font-size: 12px;
  337. margin-top: -10px;
  338. margin-bottom: 24px;
  339. }
  340. .l {
  341. width: 400px;
  342. .wait {
  343. padding: 200px 0;
  344. text-align: center;
  345. img {
  346. opacity: .6;
  347. animation: rotate 1s infinite linear;
  348. }
  349. }
  350. .show {
  351. position: relative;
  352. overflow: hidden;
  353. width: 400px;
  354. height: 400px;
  355. border-radius: 10px;
  356. .card {
  357. position: absolute;
  358. left: 53px;
  359. top: 103px;
  360. width: 294px;
  361. height: 186px;
  362. .logo {
  363. position: absolute;
  364. top: 50%;
  365. left: 50%;
  366. transform: translate(-50%, -50%);
  367. width: 100px;
  368. height: 100px;
  369. border-radius: 50%;
  370. background-color: #fff;
  371. img {
  372. width: 100%;
  373. height: 100%;
  374. border-radius: 50%;
  375. object-fit: cover;
  376. }
  377. }
  378. .member {
  379. position: absolute;
  380. top: 11px;
  381. left: 11px;
  382. width: 228px;
  383. font-size: 12px;
  384. text-align: left;
  385. font-weight: 800;
  386. line-height: 13px;
  387. }
  388. .number {
  389. position: absolute;
  390. top: 11px;
  391. right: 10px;
  392. font-size: 12px;
  393. font-weight: 800;
  394. line-height: 13px;
  395. letter-spacing: 1px;
  396. }
  397. &.s1 {
  398. .member, .number {
  399. color: #ffffff;
  400. }
  401. }
  402. &.s2 {
  403. .member, .number {
  404. color: #4AC3E1;
  405. }
  406. }
  407. &.s3 {
  408. .member, .number {
  409. color: #606C94;
  410. }
  411. }
  412. &.s4 {
  413. .member, .number {
  414. color: #504215;
  415. }
  416. }
  417. }
  418. .bg {
  419. width: 100%;
  420. height: 100%;
  421. }
  422. }
  423. .list {
  424. margin-top: 20px;
  425. display: flex;
  426. .item {
  427. width: calc(100% / 4);
  428. cursor: pointer;
  429. overflow: hidden;
  430. margin-right: 13px;
  431. border-radius: 5px;
  432. img {
  433. width: 100%;
  434. border-radius: 5px;
  435. }
  436. &:last-child {
  437. margin: 0;
  438. }
  439. &.on {
  440. position: relative;
  441. &::before {
  442. position: absolute;
  443. display: block;
  444. top: 0;
  445. right: 0;
  446. content: '';
  447. width: 44px;
  448. height: 44px;
  449. background-size: 100%;
  450. background-image: url('../../static/img/icon-add-select.svg');
  451. }
  452. }
  453. }
  454. }
  455. }
  456. .r {
  457. width: 520px;
  458. .face {
  459. position: relative;
  460. width: 80px;
  461. margin-bottom: 10px;
  462. .file {
  463. position: absolute;
  464. z-index: 2;
  465. width: 100%;
  466. height: 100%;
  467. opacity: 0;
  468. cursor: pointer;
  469. }
  470. .off {
  471. display: flex;
  472. align-items: center;
  473. justify-content: center;
  474. cursor: pointer;
  475. width: 80px;
  476. height: 80px;
  477. border-radius: 100px;
  478. border: 1px dashed #D0D0D0;
  479. background: rgba(0, 0, 0, 0.02);
  480. }
  481. .on {
  482. position: relative;
  483. display: flex;
  484. align-items: center;
  485. justify-content: center;
  486. cursor: pointer;
  487. width: 80px;
  488. height: 80px;
  489. overflow: hidden;
  490. border-radius: 100px;
  491. background: #353535;
  492. .img {
  493. position: absolute;
  494. opacity: .4;
  495. width: 100%;
  496. height: 100%;
  497. border-radius: 100px;
  498. }
  499. }
  500. }
  501. .desc {
  502. color: #B4B4B4;
  503. font-size: 12px;
  504. font-weight: 400;
  505. line-height: 16px;
  506. margin-bottom: 22px;
  507. }
  508. .input {
  509. display: flex;
  510. align-items: center;
  511. justify-content: center;
  512. height: 41px;
  513. margin-bottom: 22px;
  514. border-radius: 5px;
  515. background: #FFFFFF;
  516. border: 1px solid #E0E0E0;
  517. input {
  518. border: 0;
  519. outline: none;
  520. padding: 3px 0;
  521. color: #777;
  522. font-size: 16px;
  523. font-weight: 500;
  524. letter-spacing: 0.3px;
  525. width: calc(100% - 24px);
  526. &::placeholder {
  527. color: rgba(0, 0, 0, .3);
  528. }
  529. }
  530. }
  531. .textarea {
  532. display: flex;
  533. align-items: center;
  534. justify-content: center;
  535. height: 88px;
  536. margin-bottom: 22px;
  537. border-radius: 5px;
  538. background: #FFFFFF;
  539. border: 1px solid #E0E0E0;
  540. textarea {
  541. resize: none;
  542. border: 0;
  543. height: 70px;
  544. outline: none;
  545. color: #777;
  546. font-size: 16px;
  547. font-weight: 500;
  548. letter-spacing: 0.3px;
  549. width: calc(100% - 24px);
  550. font-family: "Segoe UI", Helvetica, Arial, sans-serif;
  551. &::placeholder {
  552. color: rgba(0, 0, 0, .3);
  553. }
  554. }
  555. }
  556. .price {
  557. position: relative;
  558. display: flex;
  559. justify-content: space-between;
  560. .currency {
  561. display: flex;
  562. align-items: center;
  563. justify-content: center;
  564. flex-direction: row;
  565. cursor: pointer;
  566. height: 43px;
  567. padding: 0 14px;
  568. margin-right: 13px;
  569. border-radius: 25px;
  570. background: #F4F4F4;
  571. .head {
  572. overflow: hidden;
  573. width: 20px;
  574. height: 20px;
  575. margin-right: 8px;
  576. border-radius: 50%;
  577. background-color: #999;
  578. }
  579. .font {
  580. max-width: 250px;
  581. font-size: 15px;
  582. font-weight: 500;
  583. white-space: nowrap;
  584. overflow: hidden;
  585. text-overflow: ellipsis;
  586. }
  587. .arrow {
  588. margin-left: 8px
  589. }
  590. }
  591. .no-select {
  592. display: flex;
  593. align-items: center;
  594. justify-content: center;
  595. flex-direction: row;
  596. cursor: pointer;
  597. height: 43px;
  598. padding: 0 14px;
  599. margin-right: 13px;
  600. border-radius: 25px;
  601. background: #1d9bf0;
  602. .font {
  603. max-width: 250px;
  604. color: #fff;
  605. font-size: 15px;
  606. font-weight: 500;
  607. white-space: nowrap;
  608. overflow: hidden;
  609. text-overflow: ellipsis;
  610. }
  611. .arrow {
  612. margin-left: 8px
  613. }
  614. }
  615. .input {
  616. flex: 1;
  617. margin-bottom: 0;
  618. }
  619. .currency-pop {
  620. position: absolute;
  621. overflow: hidden;
  622. z-index: 3;
  623. left: 0;
  624. bottom: 50px;
  625. width: 375px;
  626. max-height: 420px;
  627. border-radius: 20px;
  628. background-color: #fff;
  629. box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.25);
  630. }
  631. }
  632. .explain {
  633. color: #B4B4B4;
  634. font-size: 12px;
  635. font-weight: 400;
  636. line-height: 18px;
  637. ul {
  638. padding: 0;
  639. margin-left: 14px;
  640. }
  641. .special {
  642. color: #E29015;
  643. }
  644. }
  645. .footer {
  646. height: 80px;
  647. }
  648. }
  649. }
  650. .create {
  651. position: fixed;
  652. left: 50%;
  653. bottom: 0;
  654. width: 1100px;
  655. text-align: right;
  656. padding: 15px 30px;
  657. transform: translateX(-50%);
  658. box-sizing: border-box;
  659. background-color: #fff;
  660. border-top: solid 1px #ECECEC;
  661. .on {
  662. border: 0;
  663. height: 50px;
  664. color: #FFFFFF;
  665. cursor: pointer;
  666. padding: 0 50px;
  667. font-size: 18px;
  668. font-weight: 700;
  669. letter-spacing: 0.3px;
  670. border-radius: 25px;
  671. background: #1D9BF0;
  672. }
  673. .off {
  674. border: 0;
  675. height: 50px;
  676. color: #FFFFFF;
  677. cursor: pointer;
  678. padding: 0 50px;
  679. font-size: 18px;
  680. font-weight: 700;
  681. letter-spacing: 0.3px;
  682. border-radius: 25px;
  683. background: #E4E4E4;
  684. }
  685. }
  686. }
  687. .feedBack {
  688. position: absolute;
  689. right: 44px;
  690. bottom: 88px;
  691. cursor: pointer;
  692. font-size: 12px;
  693. text-align: center;
  694. a:link, a:visited {
  695. color: #A8A8A8;
  696. text-decoration: none;
  697. }
  698. .mail {
  699. display: flex;
  700. align-items: center;
  701. justify-content: center;
  702. margin: auto;
  703. width: 50px;
  704. height: 50px;
  705. margin-bottom: 10px;
  706. border-radius: 50%;
  707. background-color: #fff;
  708. }
  709. .font {
  710. opacity: 0.7;
  711. color: #A8A8A8;
  712. letter-spacing: 0.3px;
  713. }
  714. }
  715. .loading {
  716. display: flex;
  717. align-items: center;
  718. justify-content: center;
  719. position: absolute;
  720. top: 0;
  721. left: 0;
  722. z-index: 2;
  723. width: 100%;
  724. height: 100%;
  725. background: rgba(255, 255, 255, .8);
  726. img {
  727. width: 100px;
  728. animation: rotate 1s linear infinite;
  729. }
  730. }
  731. @keyframes rotate {
  732. 0% {
  733. transform: rotate(0);
  734. }
  735. 100% {
  736. transform: rotate(360deg);
  737. }
  738. }
  739. .succ {
  740. position: absolute;
  741. z-index: 2;
  742. top: 50%;
  743. left: 50%;
  744. width: 500px;
  745. height: 400px;
  746. border-radius: 20px;
  747. background-color: #fff;
  748. transform: translate(-50%, -50%);
  749. .icon {
  750. display: block;
  751. width: 120px;
  752. height: 120px;
  753. margin: 78px auto 27px auto;
  754. }
  755. .notic {
  756. font-size: 20px;
  757. font-weight: 700;
  758. text-align: center;
  759. line-height: 24px;
  760. }
  761. .btn {
  762. display: block;
  763. border: 0;
  764. cursor: pointer;
  765. width: 440px;
  766. height: 50px;
  767. color: #fff;
  768. font-size: 18px;
  769. font-weight: 700;
  770. margin: 70px auto 0;
  771. border-radius: 50px;
  772. background: #1D9BF0;
  773. }
  774. }
  775. .succ-bg {
  776. position: absolute;
  777. top: 0;
  778. left: 0;
  779. width: 100%;
  780. height: 100%;
  781. background: rgba(0, 0, 0, .8);
  782. }
  783. .mask-bg {
  784. position: absolute;
  785. top: 0;
  786. left: 0;
  787. z-index: 2;
  788. width: 100%;
  789. height: 100%;
  790. }
  791. </style>