register.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. <template>
  2. <div class="register">
  3. <div class="box-card">
  4. <el-tabs v-model="activeName" @tab-click="handleClick">
  5. <el-tab-pane label="用户注册" name="first" v-if="registerConfig.register.indexOf('username') != -1">
  6. <el-form v-if="activeName == 'first'" :model="registerForm" :rules="registerRules" ref="registerRef" label-width="80px" label-position="right" show-message>
  7. <el-form-item label="用户名" prop="username"><el-input v-model="registerForm.username" placeholder="请输入用户名"></el-input></el-form-item>
  8. <el-form-item label="密码" prop="password"><el-input v-model="registerForm.password" placeholder="请输入密码" type="password"></el-input></el-form-item>
  9. <el-form-item label="确认密码" prop="checkPass"><el-input v-model="registerForm.checkPass" placeholder="请输入确认密码" type="password"></el-input></el-form-item>
  10. <el-form-item label="验证码" prop="code">
  11. <el-input v-model="registerForm.code" placeholder="请输入验证码" maxlength="4">
  12. <template slot="append">
  13. <img :src="captcha.img" mode class="captcha" @click="getCode" />
  14. </template>
  15. </el-input>
  16. </el-form-item>
  17. </el-form>
  18. <div class="xy" @click="check">
  19. <div class="xy-wrap">
  20. <div class="iconfont" :class="ischecked ? 'icon-xuanze-duoxuan' : 'icon-xuanze'"></div>
  21. <div class="content">
  22. 阅读并同意
  23. <b @click.stop="getAggrement">《服务协议》</b>
  24. </div>
  25. </div>
  26. <div class="toLogin" @click="toLogin">已有账号,立即登录</div>
  27. </div>
  28. <el-button @click="register">立即注册</el-button>
  29. </el-tab-pane>
  30. <el-tab-pane label="手机动态码注册" name="second" v-if="registerConfig.register.indexOf('mobile') != -1">
  31. <el-form v-if="activeName == 'second'" :model="registerForm" :rules="mobileRules" ref="mobileRuleForm">
  32. <el-form-item prop="mobile">
  33. <el-input v-model="registerForm.mobile" placeholder="请输入手机号">
  34. <template slot="prepend">
  35. <i class="iconfont icon-shouji-copy"></i>
  36. </template>
  37. </el-input>
  38. </el-form-item>
  39. <el-form-item prop="vercode">
  40. <el-input v-model="registerForm.vercode" autocomplete="off" placeholder="请输入验证码" maxlength="4">
  41. <template slot="prepend">
  42. <i class="iconfont icon-yanzhengma"></i>
  43. </template>
  44. <template slot="append">
  45. <img :src="captcha.img" mode class="captcha" @click="getCode" />
  46. </template>
  47. </el-input>
  48. </el-form-item>
  49. <el-form-item prop="dynacode">
  50. <el-input v-model="registerForm.dynacode" maxlength="4" placeholder="请输入短信动态码">
  51. <template slot="prepend">
  52. <i class="iconfont icon-dongtaima"></i>
  53. </template>
  54. <template slot="append">
  55. <div class="dynacode" :class="dynacodeData.seconds == 120 ? 'ns-text-color' : 'ns-text-color-gray'" @click="sendMobileCode('mobileRuleForm')">
  56. {{ dynacodeData.codeText }}
  57. </div>
  58. </template>
  59. </el-input>
  60. </el-form-item>
  61. </el-form>
  62. <div class="xy" @click="check">
  63. <div class="xy-wrap">
  64. <div class="iconfont" :class="ischecked ? 'icon-xuanze-duoxuan' : 'icon-xuanze'"></div>
  65. <div class="content">
  66. 阅读并同意
  67. <b @click.stop="getAggrement">《服务协议》</b>
  68. </div>
  69. </div>
  70. <div class="toLogin" @click="toLogin">已有账号,立即登录</div>
  71. </div>
  72. <el-button @click="registerMobile">立即注册</el-button>
  73. </el-tab-pane>
  74. </el-tabs>
  75. <el-dialog :title="agreement.title" :visible.sync="aggrementVisible" width="60%" :before-close="aggrementClose" :lock-scroll="false" center>
  76. <div v-html="agreement.content" class="xyContent"></div>
  77. </el-dialog>
  78. </div>
  79. <!-- 浮层区 -->
  80. <div class="floatLayer-wrap" v-show="is_show && reward" :style="{ width: bgWidth, height: bgHeight }">
  81. <div class="reward-wrap">
  82. <img :src="$util.img('public/uniapp/register_reward/register_reward_img.png')" mode="widthFix" class="bg-img-head" />
  83. <img :src="$util.img('public/uniapp/register_reward/register_reward_money.png')" mode="widthFix" class="bg-img-money" />
  84. <img :src="$util.img('public/uniapp/register_reward/register_reward_head.png')" mode="widthFix" class="bg-img" />
  85. <div class="wrap">
  86. <div>
  87. <div class="reward-content">
  88. <div class="reward-item" v-if="reward && reward.point > 0">
  89. <div class="head">积分奖励</div>
  90. <div class="content">
  91. <div class="info">
  92. <div>
  93. <span class="num">{{ reward.point }}</span>
  94. <span class="type">积分</span>
  95. </div>
  96. <div class="desc">用于下单时抵现或兑换商品等</div>
  97. </div>
  98. <div class="tip" @click="closeRewardPopup('point')">立即查看</div>
  99. </div>
  100. </div>
  101. <div class="reward-item" v-if="reward && reward.growth > 0">
  102. <div class="head">成长值</div>
  103. <div class="content">
  104. <div class="info">
  105. <div>
  106. <span class="num">{{ reward.growth }}</span>
  107. <span class="type">成长值</span>
  108. </div>
  109. <div class="desc">用于提升会员等级</div>
  110. </div>
  111. <div class="tip" @click="closeRewardPopup('growth')">立即查看</div>
  112. </div>
  113. </div>
  114. <div class="reward-item" v-if="reward && reward.balance > 0">
  115. <div class="head">红包奖励</div>
  116. <div class="content">
  117. <div class="info">
  118. <div>
  119. <span class="num">{{ reward.balance }}</span>
  120. <span class="type">元</span>
  121. </div>
  122. <div class="desc">不可提现下单时可用</div>
  123. </div>
  124. <div class="tip" @click="closeRewardPopup('balance')">立即查看</div>
  125. </div>
  126. </div>
  127. <div class="reward-item" v-if="reward && reward.coupon_list.length > 0">
  128. <div class="head">优惠券奖励</div>
  129. <div class="content" v-for="(item, index) in reward.coupon_list" :key="index">
  130. <div class="info">
  131. <div>
  132. <span class="num coupon-name">{{ item.coupon_name }}</span>
  133. </div>
  134. <div class="desc" v-if="item.at_least > 0">满{{ item.at_least }}{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}</div>
  135. <div class="desc" v-else>无门槛,{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}</div>
  136. </div>
  137. <div class="tip" @click="closeRewardPopup('coupon')">立即查看</div>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. <div class="close-btn" @click="closeRewardPopup()"><i class="iconfont icon-guanbi"></i></div>
  144. </div>
  145. </div>
  146. </div>
  147. </template>
  148. <script>
  149. import { getRegisiterAggrement, registerConfig, registerMobileCode, getRegisterReward } from '@/api/auth/register';
  150. import { captcha } from '@/api/website';
  151. export default {
  152. name: 'register',
  153. layout: 'login',
  154. components: {},
  155. data() {
  156. var checkPassValidata = (rule, value, callback) => {
  157. if (value === '') {
  158. callback(new Error('请再次输入密码'));
  159. } else if (value !== this.registerForm.password) {
  160. callback(new Error('两次输入密码不一致!'));
  161. } else {
  162. callback();
  163. }
  164. };
  165. let self = this;
  166. var passwordValidata = function(rule, value, callback) {
  167. let regConfig = self.registerConfig;
  168. if (!value) {
  169. return callback(new Error('请输入密码'));
  170. } else {
  171. if (regConfig.pwd_len > 0) {
  172. if (value.length < regConfig.pwd_len) {
  173. return callback(new Error('密码长度不能小于' + regConfig.pwd_len + '位'));
  174. } else {
  175. callback();
  176. }
  177. }
  178. if (regConfig.pwd_complexity != '') {
  179. let passwordErrorMsg = '密码需包含',
  180. reg = '';
  181. if (regConfig.pwd_complexity.indexOf('number') != -1) {
  182. reg += '(?=.*?[0-9])';
  183. passwordErrorMsg += '数字';
  184. } else if (regConfig.pwd_complexity.indexOf('letter') != -1) {
  185. reg += '(?=.*?[a-z])';
  186. passwordErrorMsg += '、小写字母';
  187. } else if (regConfig.pwd_complexity.indexOf('upper_case') != -1) {
  188. reg += '(?=.*?[A-Z])';
  189. passwordErrorMsg += '、大写字母';
  190. } else if (regConfig.pwd_complexity.indexOf('symbol') != -1) {
  191. reg += '(?=.*?[#?!@$%^&*-])';
  192. passwordErrorMsg += '、特殊字符';
  193. } else {
  194. reg += '';
  195. passwordErrorMsg += '';
  196. }
  197. reg = new RegExp(reg);
  198. if (reg.test(value)) {
  199. return callback(new Error(passwordErrorMsg));
  200. } else {
  201. callback();
  202. }
  203. }
  204. }
  205. };
  206. var isMobile = (rule, value, callback) => {
  207. if (!value) {
  208. return callback(new Error('手机号不能为空'));
  209. } else {
  210. if (/^\d{11}$/.test(value)) {
  211. callback();
  212. } else {
  213. callback(new Error('请输入正确的手机号'));
  214. }
  215. }
  216. };
  217. return {
  218. registerForm: {
  219. username: '',
  220. password: '',
  221. checkPass: '',
  222. code: '',
  223. mobile: '',
  224. vercode: '',
  225. dynacode: '',
  226. key: ''
  227. },
  228. registerRules: {
  229. username: [
  230. {
  231. required: true,
  232. message: '请输入用户名',
  233. trigger: 'blur'
  234. }
  235. ],
  236. password: [
  237. {
  238. required: true,
  239. validator: passwordValidata,
  240. trigger: 'blur'
  241. }
  242. ],
  243. checkPass: [
  244. {
  245. required: true,
  246. validator: checkPassValidata,
  247. trigger: 'blur'
  248. }
  249. ],
  250. code: [
  251. {
  252. required: true,
  253. message: '请输入验证码',
  254. trigger: 'blur'
  255. }
  256. ]
  257. },
  258. mobileRules: {
  259. mobile: [
  260. {
  261. required: true,
  262. validator: isMobile,
  263. trigger: 'blur'
  264. }
  265. ],
  266. vercode: [
  267. {
  268. required: true,
  269. message: '请输入验证码',
  270. trigger: 'blur'
  271. }
  272. ],
  273. dynacode: [
  274. {
  275. required: true,
  276. message: '请输入短信动态码',
  277. trigger: 'blur'
  278. }
  279. ]
  280. },
  281. dynacodeData: {
  282. seconds: 120,
  283. timer: null,
  284. codeText: '获取动态码',
  285. isSend: false
  286. }, // 动态码
  287. ischecked: false,
  288. agreement: '',
  289. aggrementVisible: false,
  290. captcha: {
  291. // 验证码
  292. id: '',
  293. img: ''
  294. },
  295. registerConfig: {
  296. register: ''
  297. },
  298. activeName: 'first', // tab切换
  299. reward: null,
  300. is_show: false,
  301. bgWidth: '',
  302. bgHeight: ''
  303. };
  304. },
  305. created() {
  306. this.getCode();
  307. this.regisiterAggrement();
  308. this.getRegisterConfig();
  309. this.getRegisterReward();
  310. if (process.client) {
  311. this.bgWidth = document.documentElement.clientWidth + 'px';
  312. this.bgHeight = document.documentElement.clientHeight + 'px';
  313. }
  314. },
  315. head() {
  316. return {
  317. title: '注册-' + this.$store.state.site.siteInfo.site_name
  318. };
  319. },
  320. methods: {
  321. closeRewardPopup(type) {
  322. this.is_show = false;
  323. switch (type) {
  324. case 'point':
  325. this.$router.push('/member/my_point');
  326. break;
  327. case 'balance':
  328. this.$router.push('/member/account');
  329. break;
  330. case 'growth':
  331. this.$router.push('/member');
  332. break;
  333. case 'coupon':
  334. this.$router.push('/member/coupon');
  335. break;
  336. default:
  337. this.$router.push('/member');
  338. this.is_show = false;
  339. }
  340. },
  341. getRegisterReward() {
  342. getRegisterReward()
  343. .then(res => {
  344. if (res.code >= 0) {
  345. let data = res.data;
  346. if (data.is_use == 1 && (data.value.point > 0 || data.value.balance > 0 || data.value.growth > 0 || data.value.coupon_list.length > 0)) {
  347. this.reward = data.value;
  348. }
  349. }
  350. })
  351. .catch(err => {
  352. console.log(err, 'getRegisterReward');
  353. });
  354. },
  355. sendMobileCode(formName) {
  356. if (this.dynacodeData.seconds != 120) return;
  357. this.$refs[formName].clearValidate('dynacode');
  358. this.$refs[formName].validateField('mobile', valid => {
  359. if (valid) {
  360. return false;
  361. }
  362. });
  363. this.$refs[formName].validateField('vercode', valid => {
  364. if (!valid) {
  365. registerMobileCode({
  366. mobile: this.registerForm.mobile,
  367. captcha_id: this.captcha.id,
  368. captcha_code: this.registerForm.vercode
  369. })
  370. .then(res => {
  371. if (res.code >= 0) {
  372. this.registerForm.key = res.data.key;
  373. if (this.dynacodeData.seconds == 120 && this.dynacodeData.timer == null) {
  374. this.dynacodeData.timer = setInterval(() => {
  375. this.dynacodeData.seconds--;
  376. this.dynacodeData.codeText = this.dynacodeData.seconds + 's后可重新获取';
  377. }, 1000);
  378. }
  379. }
  380. })
  381. .catch(err => {
  382. this.$message.error(err.message);
  383. });
  384. } else {
  385. return false;
  386. }
  387. });
  388. },
  389. handleClick(tab, event) {},
  390. check() {
  391. this.ischecked = !this.ischecked;
  392. },
  393. toLogin() {
  394. this.$router.push('/auth/login');
  395. },
  396. // 获取注册配置
  397. getRegisterConfig() {
  398. registerConfig().then(res => {
  399. if (res.code >= 0) {
  400. this.registerConfig = res.data.value;
  401. if (this.registerConfig.register == '') {
  402. this.$message({
  403. message: '平台未启用注册',
  404. type: 'warning',
  405. duration: 2000,
  406. onClose: () => {
  407. this.$router.push({ name: 'login', params: { third_party: true } });
  408. }
  409. });
  410. } else if (this.registerConfig.register.indexOf('username') != -1) {
  411. this.activeName = 'first';
  412. } else {
  413. this.activeName = 'second';
  414. }
  415. }
  416. });
  417. },
  418. // 账号密码注册
  419. register() {
  420. this.$refs.registerRef.validate(valid => {
  421. if (valid) {
  422. if (!this.ischecked) {
  423. return this.$message({
  424. message: '请先阅读协议并勾选',
  425. type: 'warning'
  426. });
  427. }
  428. var data = {
  429. username: this.registerForm.username.trim(),
  430. password: this.registerForm.password
  431. };
  432. var user_test = /^[A-Za-z0-9]+$/;
  433. if (!user_test.test(data.username)) {
  434. return this.$message({
  435. message: '用户名只能输入数字跟英文',
  436. type: 'warning'
  437. });
  438. }
  439. if (this.captcha.id != '') {
  440. data.captcha_id = this.captcha.id;
  441. data.captcha_code = this.registerForm.code;
  442. }
  443. this.$store
  444. .dispatch('member/register_token', data)
  445. .then(res => {
  446. if (res.code >= 0) {
  447. if (this.reward) {
  448. this.is_show = true;
  449. } else {
  450. this.$router.push('/member');
  451. }
  452. }
  453. })
  454. .catch(err => {
  455. this.$message.error(err.message);
  456. this.getCode();
  457. });
  458. } else {
  459. return false;
  460. }
  461. });
  462. },
  463. // 手机号注册
  464. registerMobile() {
  465. this.$refs.mobileRuleForm.validate(valid => {
  466. if (valid) {
  467. if (!this.ischecked) {
  468. return this.$message({
  469. message: '请先阅读协议并勾选',
  470. type: 'warning'
  471. });
  472. }
  473. var data = {
  474. mobile: this.registerForm.mobile,
  475. key: this.registerForm.key,
  476. code: this.registerForm.dynacode
  477. };
  478. if (this.captcha.id != '') {
  479. data.captcha_id = this.captcha.id;
  480. data.captcha_code = this.registerForm.code;
  481. }
  482. this.$store
  483. .dispatch('member/registerMobile_token', data)
  484. .then(res => {
  485. if (res.code >= 0) {
  486. if (this.reward) {
  487. this.is_show = true;
  488. } else {
  489. this.$router.push('/member');
  490. }
  491. }
  492. })
  493. .catch(err => {
  494. this.$message.error(err.message);
  495. this.getCode();
  496. });
  497. } else {
  498. return false;
  499. }
  500. });
  501. },
  502. aggrementClose() {
  503. this.aggrementVisible = false;
  504. },
  505. // 获取协议
  506. regisiterAggrement() {
  507. getRegisiterAggrement().then(res => {
  508. if (res.code >= 0) {
  509. this.agreement = res.data;
  510. }
  511. });
  512. },
  513. getAggrement() {
  514. this.aggrementVisible = true;
  515. },
  516. // 获取验证码
  517. getCode() {
  518. captcha({
  519. captcha_id: 'this.captcha.id'
  520. })
  521. .then(res => {
  522. if (res.code >= 0) {
  523. this.captcha = res.data;
  524. this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
  525. }
  526. })
  527. .catch(err => {
  528. this.$message.error(err.message);
  529. });
  530. }
  531. }
  532. };
  533. </script>
  534. <style lang="scss" scoped>
  535. .register {
  536. width: 100%;
  537. height: 100%;
  538. display: flex;
  539. justify-content: center;
  540. align-items: center;
  541. margin: 20px 0;
  542. }
  543. .box-card {
  544. width: 500px;
  545. margin: 0 auto;
  546. display: flex;
  547. background-color: #ffffff;
  548. padding: 0 30px 30px 30px;
  549. flex-direction: column;
  550. padding-bottom: 256px;
  551. .register-title {
  552. border-bottom: 1px solid #f1f1f1;
  553. text-align: left;
  554. margin-bottom: 20px;
  555. font-size: 16px;
  556. color: $base-color;
  557. padding: 10px 0;
  558. }
  559. .register-account {
  560. width: 100%;
  561. text-align: center;
  562. }
  563. .code {
  564. width: 80%;
  565. text-align: left;
  566. }
  567. .el-form {
  568. margin: 0 30px;
  569. .captcha {
  570. vertical-align: top;
  571. max-width: inherit;
  572. max-height: 38px;
  573. line-height: 38px;
  574. cursor: pointer;
  575. }
  576. }
  577. .xyContent {
  578. height: 600px;
  579. overflow-y: scroll;
  580. }
  581. .xy {
  582. margin-left: 110px;
  583. display: flex;
  584. justify-content: space-between;
  585. align-items: center;
  586. text-align: left;
  587. margin-right: 30px;
  588. .toLogin {
  589. cursor: pointer;
  590. }
  591. .xy-wrap {
  592. display: flex;
  593. align-items: center;
  594. font-size: $ns-font-size-base;
  595. cursor: pointer;
  596. .iconfont {
  597. display: flex;
  598. align-content: center;
  599. }
  600. .content {
  601. margin-left: 3px;
  602. b {
  603. color: $base-color;
  604. }
  605. }
  606. }
  607. .icon-xuanze-duoxuan {
  608. color: $base-color;
  609. }
  610. }
  611. .el-button {
  612. margin: 20px 0 0 25px;
  613. background-color: $base-color;
  614. color: #ffffff;
  615. width: calc(100% - 60px);
  616. }
  617. }
  618. .floatLayer-wrap {
  619. height: 100%;
  620. width: 100%;
  621. background-color: rgba(0, 0, 0, 0.5);
  622. z-index: 999;
  623. position: absolute;
  624. .reward-wrap {
  625. width: 400px;
  626. height: auto;
  627. position: absolute;
  628. top: 50%;
  629. left: 50%;
  630. transform: translate(-50%, -50%);
  631. .bg-img {
  632. width: 100%;
  633. will-change: transform;
  634. }
  635. .bg-img-head {
  636. position: absolute;
  637. top: -90px;
  638. width: 100%;
  639. }
  640. .bg-img-money {
  641. position: absolute;
  642. width: 100%;
  643. left: -20px;
  644. top: 80px;
  645. z-index: 10;
  646. }
  647. .wrap {
  648. width: calc(100% - 1px);
  649. height: 100%;
  650. background-color: #ef3030;
  651. margin-top: -40px;
  652. padding-bottom: 30px;
  653. border-bottom-left-radius: 5px;
  654. border-bottom-right-radius: 5px;
  655. & > div {
  656. position: relative;
  657. }
  658. }
  659. .reward-content {
  660. margin: 0 25px 0 25px;
  661. }
  662. .reward-item {
  663. .head {
  664. color: #fff;
  665. text-align: center;
  666. line-height: 1;
  667. margin: 10px 0;
  668. }
  669. .content {
  670. display: flex;
  671. padding: 8px 13px;
  672. background: #fff;
  673. border-radius: 5px;
  674. margin-bottom: 5px;
  675. width: auto;
  676. .info {
  677. flex: 1;
  678. }
  679. .tip {
  680. color: #ff222d;
  681. padding: 5px 0 5px 15px;
  682. width: 70px;
  683. line-height: 1.5;
  684. letter-spacing: 1px;
  685. border-left: 1px dashed #e5e5e5;
  686. height: 40px;
  687. line-height: 40px;
  688. }
  689. .num {
  690. font-size: 26px;
  691. color: #ff222d;
  692. font-weight: bolder;
  693. line-height: 1;
  694. }
  695. .coupon-name {
  696. font-size: 19px;
  697. }
  698. .type {
  699. font-size: $ns-font-size-base;
  700. margin-left: 5px;
  701. line-height: 1;
  702. }
  703. .desc {
  704. margin-top: 4px;
  705. color: $base-color;
  706. font-size: $ns-font-size-base;
  707. line-height: 1;
  708. }
  709. }
  710. }
  711. .btn {
  712. position: absolute;
  713. width: calc(100% - 50px);
  714. bottom: 20px;
  715. left: 25px;
  716. .btn-img {
  717. width: 100%;
  718. }
  719. }
  720. }
  721. }
  722. .close-btn {
  723. text-align: center;
  724. margin-top: 20px;
  725. .iconfont {
  726. color: #fff;
  727. font-size: 20px;
  728. }
  729. }
  730. .clear {
  731. content: '';
  732. display: block;
  733. clear: both;
  734. }
  735. </style>