大空间消毒机
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

815 lines
20 KiB

2 years ago
  1. <template>
  2. <div class="update_device_container">
  3. <div class="row_wrap">
  4. <p class="title">注射蠕动泵速率(g/min)</p>
  5. <p class="num">
  6. <van-field
  7. type="number"
  8. v-model="sprayLiquidConfigVal"
  9. :clickable="true"
  10. :formatter="formatter7"
  11. readonly
  12. @click.stop="hideClickKey(2)"
  13. />
  14. </p>
  15. </div>
  16. <div class="row_wrap">
  17. <p class="title">消毒停止过氧化氢浓度(ppm)</p>
  18. <p class="num">
  19. <van-field
  20. type="number"
  21. v-model="stoped_gs"
  22. :clickable="true"
  23. :formatter="formatter1"
  24. readonly
  25. @click.stop="hideClickKey(3)"
  26. />
  27. </p>
  28. </div>
  29. <div class="row_wrap">
  30. <p class="title">消毒继续过氧化氢浓度(ppm)</p>
  31. <p class="num">
  32. <van-field
  33. type="number"
  34. v-model="continued_gs"
  35. :clickable="true"
  36. :formatter="formatter2"
  37. readonly
  38. @click.stop="hideClickKey(4)"
  39. />
  40. </p>
  41. </div>
  42. <div class="row_wrap">
  43. <p class="title">消毒停止相对湿度(%RH)</p>
  44. <p class="num">
  45. <van-field
  46. type="number"
  47. v-model="stoped_humi"
  48. :clickable="true"
  49. :formatter="formatter9"
  50. readonly
  51. @click.stop="hideClickKey(9)"
  52. />
  53. </p>
  54. </div>
  55. <div class="row_wrap">
  56. <p class="title">消毒继续相对湿度(%RH)</p>
  57. <p class="num">
  58. <van-field
  59. type="number"
  60. v-model="continued_humi"
  61. :clickable="true"
  62. :formatter="formatter10"
  63. readonly
  64. @click.stop="hideClickKey(10)"
  65. />
  66. </p>
  67. </div>
  68. <div class="row_wrap">
  69. <p class="title">消毒停止过氧化氢相对饱和度(%RS)</p>
  70. <p class="num">
  71. <van-field
  72. type="number"
  73. :formatter="formatter3"
  74. v-model="stoped_satur"
  75. :clickable="true"
  76. readonly
  77. @click.stop="hideClickKey(5)"
  78. />
  79. </p>
  80. </div>
  81. <div class="row_wrap">
  82. <p class="title">消毒继续过氧化氢相对饱和度(%RS)</p>
  83. <p class="num">
  84. <van-field
  85. type="number"
  86. :formatter="formatter4"
  87. v-model="continued_satur"
  88. :clickable="true"
  89. readonly
  90. @click.stop="hideClickKey(6)"
  91. />
  92. </p>
  93. </div>
  94. <div class="row_wrap" @click="showLogPicker">
  95. <p class="title">Log等级</p>
  96. <div class="num">
  97. <p class="log">{{ logVal }}</p>
  98. </div>
  99. </div>
  100. <div class="row_wrap">
  101. <p class="title">配方名称</p>
  102. <div>
  103. <input
  104. id="id_formula"
  105. type="text"
  106. v-model="formula_id"
  107. class="formula_input"
  108. placeholder="请输入配方名称"
  109. @focus="handleShowKeyBoard"
  110. />
  111. </div>
  112. </div>
  113. <van-number-keyboard
  114. v-model="addLiquidConfigVal"
  115. :title="addLiquidConfigVal"
  116. :show="addLiquidConfigValShow"
  117. @input="val => handleInput(val, 1)"
  118. theme="custom"
  119. close-button-text="配置"
  120. @close="setAddliquidVal"
  121. @blur="addLiquidConfigValShow = false"
  122. />
  123. <van-number-keyboard
  124. v-model="sprayLiquidConfigVal"
  125. @input="val => handleInput(val, 2)"
  126. :title="sprayLiquidConfigVal"
  127. :show="sprayLiquidConfigValShow"
  128. theme="custom"
  129. @close="setSprayLiquidVal"
  130. close-button-text="配置"
  131. @blur="sprayLiquidConfigValShow = false"
  132. />
  133. <van-number-keyboard
  134. v-model="stoped_gs"
  135. @input="val => handleInput(val, 3)"
  136. :title="stoped_gs"
  137. :show="stoped_gsShow"
  138. theme="custom"
  139. @close="setStopedGsVal"
  140. close-button-text="配置"
  141. @blur="stoped_gsShow = false"
  142. />
  143. <van-number-keyboard
  144. v-model="continued_gs"
  145. @input="val => handleInput(val, 4)"
  146. :title="continued_gs"
  147. @close="setcontinuedGsVal"
  148. :show="continued_gsShow"
  149. theme="custom"
  150. close-button-text="配置"
  151. @blur="continued_gsShow = false"
  152. />
  153. <van-number-keyboard
  154. v-model="stoped_satur"
  155. @input="val => handleInput(val, 5)"
  156. :title="stoped_satur"
  157. @close="setstopedSaturVal"
  158. :show="stoped_saturShow"
  159. theme="custom"
  160. close-button-text="配置"
  161. @blur="stoped_saturShow = false"
  162. />
  163. <van-number-keyboard
  164. v-model="continued_satur"
  165. @input="val => handleInput(val, 6)"
  166. :title="continued_satur"
  167. @close="setContinuedSaturVal"
  168. :show="continued_saturShow"
  169. theme="custom"
  170. close-button-text="配置"
  171. @blur="continued_saturShow = false"
  172. />
  173. <van-number-keyboard
  174. v-model="max_humidity"
  175. @input="val => handleInput(val, 7)"
  176. :title="max_humidity"
  177. @close="setMaxHumidityVal"
  178. :show="max_humidityShow"
  179. theme="custom"
  180. close-button-text="配置"
  181. @blur="max_humidityShow = false"
  182. />
  183. <van-number-keyboard
  184. theme="custom"
  185. close-button-text="配置"
  186. @input="val => handleInput(val, 8)"
  187. @close="setHeat_timeVal"
  188. v-model="pre_heat_time_s"
  189. :title="pre_heat_time_s"
  190. :show="pre_heat_time_sShow"
  191. @blur="pre_heat_time_sShow = false"
  192. />
  193. <van-number-keyboard
  194. @input="val => handleInput(val, 9)"
  195. theme="custom"
  196. close-button-text="配置"
  197. @close="setstoped_humiVal"
  198. v-model="stoped_humi"
  199. :title="stoped_humi"
  200. :show="stoped_humiShow"
  201. @blur="stoped_humiShow = false"
  202. />
  203. <van-number-keyboard
  204. theme="custom"
  205. @input="val => handleInput(val, 10)"
  206. close-button-text="配置"
  207. @close="setcontinued_humiVal"
  208. v-model="continued_humi"
  209. :title="continued_humi"
  210. :show="continued_humiShow"
  211. @blur="continued_humiShow = false"
  212. />
  213. <LogPicker
  214. v-if="logVisible"
  215. :hiddenLogVisible="hiddenLogVisible"
  216. :changeLogVal="changeLogVal"
  217. :logVal="logVal"
  218. />
  219. <div class="btns">
  220. <div class="btn" @click="save">保存</div>
  221. <div class="btn ml" @click="hiddleSettingModal">返回</div>
  222. </div>
  223. <div class="key_wrap" v-if="showkeyboard" id="keyboard_formula">
  224. <SimpleKeyboard @onChange="onChange" :input="formula_id" />
  225. </div>
  226. </div>
  227. </template>
  228. <script setup>
  229. import { ref, onMounted, watch } from 'vue'
  230. import SimpleKeyboard from 'cpns/SimpleKeyboard'
  231. import { showSuccessToast, showFailToast } from 'vant'
  232. import {
  233. useSettingStore,
  234. useWebSocketStore,
  235. useOperatorStore,
  236. useFormulaStore,
  237. } from '@/store'
  238. import { storeToRefs } from 'pinia'
  239. import {
  240. setSettingValJSON,
  241. addFormulaJSON,
  242. getAllFormulaJSON,
  243. } from '@/mock/command'
  244. import LogPicker from 'cpns/dialogs/LogPicker'
  245. const settingStore = useSettingStore()
  246. const webSocketStore = useWebSocketStore()
  247. const operatorStore = useOperatorStore()
  248. const formulaStore = useFormulaStore()
  249. const { currentFormula } = storeToRefs(formulaStore)
  250. const max_humidity = ref('0')
  251. const continued_satur = ref('0')
  252. const stoped_satur = ref('0')
  253. const continued_gs = ref('0')
  254. const stoped_gs = ref('0')
  255. const addLiquidConfigVal = ref('0')
  256. const sprayLiquidConfigVal = ref('0')
  257. const stoped_humi = ref('0')
  258. const continued_humi = ref('0')
  259. const pre_heat_time_s = ref('0')
  260. const pre_heat_time_sShow = ref(false)
  261. const addLiquidConfigValShow = ref(false)
  262. const sprayLiquidConfigValShow = ref(false)
  263. const stoped_gsShow = ref(false)
  264. const continued_gsShow = ref(false)
  265. const stoped_saturShow = ref(false)
  266. const continued_saturShow = ref(false)
  267. const max_humidityShow = ref(false)
  268. const stoped_humiShow = ref(false)
  269. const continued_humiShow = ref(false)
  270. watch(currentFormula, (newValue, oldValue) => {
  271. stoped_gs.value = newValue?.stoped_gs
  272. continued_gs.value = newValue?.continued_gs
  273. stoped_satur.value = newValue?.stoped_satur
  274. continued_satur.value = newValue?.continued_satur
  275. stoped_humi.value = newValue?.stoped_humi
  276. continued_humi.value = newValue?.continued_humi
  277. injection_pump_speed.value = newValue?.injection_pump_speed
  278. })
  279. const logVisible = ref(false)
  280. const logVal = ref('6')
  281. const formula_id = ref('')
  282. const save = () => {
  283. if (formula_id.value == '') {
  284. showFailToast('配方名称不能为空')
  285. return
  286. }
  287. // const data = {
  288. // formula_id: formula_id.value,
  289. // loglevel: logVal.value,
  290. // injection_pump_speed: sprayLiquidConfigVal.value,
  291. // stoped_gs: stoped_gs.value,
  292. // continued_gs: continued_gs.value,
  293. // stoped_satur: stoped_satur.value,
  294. // continued_satur: continued_satur.value,
  295. // stoped_humi: stoped_humi.value,
  296. // continued_humi: continued_humi.value,
  297. // }
  298. // console.log(data)
  299. // webSocketStore.sendCommandMsg(addFormulaJSON(data))
  300. // webSocketStore.sendCommandMsg(getAllFormulaJSON)
  301. props.hideSettingModal()
  302. }
  303. const changeLogVal = val => {
  304. logVal.value = val
  305. logVisible.value = false
  306. }
  307. const hiddenLogVisible = () => {
  308. logVisible.value = false
  309. }
  310. const showLogPicker = () => {
  311. logVisible.value = true
  312. }
  313. const isFirstClick = ref(true)
  314. const props = defineProps({
  315. hideSettingModal: {
  316. type: Function,
  317. },
  318. })
  319. const hiddleSettingModal = () => {
  320. props.hideSettingModal()
  321. }
  322. const hideClickKey = flag => {
  323. isFirstClick.value = true
  324. stoped_humiShow.value = false
  325. continued_humiShow.value = false
  326. pre_heat_time_sShow.value = false
  327. addLiquidConfigValShow.value = false
  328. sprayLiquidConfigValShow.value = false
  329. stoped_gsShow.value = false
  330. continued_gsShow.value = false
  331. stoped_saturShow.value = false
  332. continued_saturShow.value = false
  333. max_humidityShow.value = false
  334. if (flag == 1) {
  335. addLiquidConfigValShow.value = true
  336. }
  337. if (flag == 2) {
  338. sprayLiquidConfigValShow.value = true
  339. }
  340. if (flag == 3) {
  341. stoped_gsShow.value = true
  342. }
  343. if (flag == 4) {
  344. continued_gsShow.value = true
  345. }
  346. if (flag == 5) {
  347. stoped_saturShow.value = true
  348. }
  349. if (flag == 6) {
  350. continued_saturShow.value = true
  351. }
  352. if (flag == 7) {
  353. max_humidityShow.value = true
  354. }
  355. if (flag == 8) {
  356. pre_heat_time_sShow.value = true
  357. }
  358. if (flag == 9) {
  359. stoped_humiShow.value = true
  360. }
  361. if (flag == 10) {
  362. continued_humiShow.value = true
  363. }
  364. }
  365. const handleInput = (value, index) => {
  366. if (isFirstClick.value) {
  367. if (index == 1) {
  368. setTimeout(() => {
  369. addLiquidConfigVal.value = value + ''
  370. })
  371. }
  372. if (index == 2) {
  373. setTimeout(() => {
  374. sprayLiquidConfigVal.value = value + ''
  375. })
  376. }
  377. if (index == 3) {
  378. setTimeout(() => {
  379. stoped_gs.value = value + ''
  380. })
  381. }
  382. if (index == 4) {
  383. setTimeout(() => {
  384. continued_gs.value = value + ''
  385. })
  386. }
  387. if (index == 5) {
  388. setTimeout(() => {
  389. stoped_satur.value = value + ''
  390. })
  391. }
  392. if (index == 6) {
  393. setTimeout(() => {
  394. continued_satur.value = value + ''
  395. })
  396. }
  397. if (index == 7) {
  398. setTimeout(() => {
  399. max_humidity.value = value + ''
  400. })
  401. }
  402. if (index == 8) {
  403. setTimeout(() => {
  404. pre_heat_time_s.value = value + ''
  405. })
  406. }
  407. if (index == 9) {
  408. setTimeout(() => {
  409. stoped_humi.value = value + ''
  410. })
  411. }
  412. if (index == 10) {
  413. setTimeout(() => {
  414. continued_humi.value = value + ''
  415. })
  416. }
  417. isFirstClick.value = false
  418. }
  419. }
  420. const formatter1 = value => {
  421. if (parseInt(value) == 0) {
  422. return '0'
  423. }
  424. let arr = settingStore.allSettingList.filter(item => item.name == 'stoped_gs')
  425. if (arr && arr.length > 0) {
  426. if (parseInt(value) > arr[0].val_upper_limit) {
  427. return arr[0].val_upper_limit + ''
  428. }
  429. if (parseInt(value) < arr[0].val_lower_limit) {
  430. return arr[0].val_lower_limit + ''
  431. }
  432. }
  433. return value.replace(/^0+/gi, '')
  434. }
  435. const formatter2 = value => {
  436. if (parseInt(value) == 0) {
  437. return '0'
  438. }
  439. let arr = settingStore.allSettingList.filter(
  440. item => item.name == 'continued_gs',
  441. )
  442. if (arr && arr.length > 0) {
  443. if (parseInt(value) > arr[0].val_upper_limit) {
  444. return arr[0].val_upper_limit + ''
  445. }
  446. if (parseInt(value) < arr[0].val_lower_limit) {
  447. return arr[0].val_lower_limit + ''
  448. }
  449. }
  450. return value.replace(/^0+/gi, '')
  451. }
  452. const formatter3 = value => {
  453. if (parseInt(value) == 0) {
  454. return '0'
  455. }
  456. let arr = settingStore.allSettingList.filter(
  457. item => item.name == 'stoped_satur',
  458. )
  459. if (arr && arr.length > 0) {
  460. if (parseInt(value) > arr[0].val_upper_limit) {
  461. return arr[0].val_upper_limit + ''
  462. }
  463. if (parseInt(value) < arr[0].val_lower_limit) {
  464. return arr[0].val_lower_limit + ''
  465. }
  466. }
  467. return value.replace(/^0+/gi, '')
  468. }
  469. const formatter4 = value => {
  470. if (parseInt(value) == 0) {
  471. return '0'
  472. }
  473. let arr = settingStore.allSettingList.filter(
  474. item => item.name == 'continued_satur',
  475. )
  476. if (arr && arr.length > 0) {
  477. if (parseInt(value) > arr[0].val_upper_limit) {
  478. return arr[0].val_upper_limit + ''
  479. }
  480. if (parseInt(value) < arr[0].val_lower_limit) {
  481. return arr[0].val_lower_limit + ''
  482. }
  483. }
  484. return value.replace(/^0+/gi, '')
  485. }
  486. const formatter5 = value => {
  487. if (parseInt(value) == 0) {
  488. return '0'
  489. }
  490. let arr = settingStore.allSettingList.filter(
  491. item => item.name == 'max_humidity',
  492. )
  493. if (arr && arr.length > 0) {
  494. if (parseInt(value) > arr[0].val_upper_limit) {
  495. return arr[0].val_upper_limit + ''
  496. }
  497. if (parseInt(value) < arr[0].val_lower_limit) {
  498. return arr[0].val_lower_limit + ''
  499. }
  500. }
  501. return value.replace(/^0+/gi, '')
  502. }
  503. const formatter6 = value => {
  504. if (parseInt(value) == 0) {
  505. return '0'
  506. }
  507. let arr = settingStore.allSettingList.filter(
  508. item => item.name == 'drainage_pump_speed',
  509. )
  510. if (arr && arr.length > 0) {
  511. if (parseInt(value) > arr[0].val_upper_limit) {
  512. return arr[0].val_upper_limit + ''
  513. }
  514. if (parseInt(value) < arr[0].val_lower_limit) {
  515. return arr[0].val_lower_limit + ''
  516. }
  517. }
  518. return value.replace(/^0+/gi, '')
  519. }
  520. const formatter7 = value => {
  521. if (parseInt(value) == 0) {
  522. return '0'
  523. }
  524. let arr = settingStore.allSettingList.filter(
  525. item => item.name == 'injection_pump_speed',
  526. )
  527. if (arr && arr.length > 0) {
  528. if (parseInt(value) > arr[0].val_upper_limit) {
  529. return arr[0].val_upper_limit + ''
  530. }
  531. if (parseInt(value) < arr[0].val_lower_limit) {
  532. return arr[0].val_lower_limit + ''
  533. }
  534. }
  535. return value.replace(/^0+/gi, '')
  536. }
  537. const formatter8 = value => {
  538. if (parseInt(value) == 0) {
  539. return '0'
  540. }
  541. let arr = settingStore.allSettingList.filter(
  542. item => item.name == 'pre_heat_time_s',
  543. )
  544. if (arr && arr.length > 0) {
  545. if (parseInt(value) > arr[0].val_upper_limit) {
  546. return arr[0].val_upper_limit + ''
  547. }
  548. if (parseInt(value) < arr[0].val_lower_limit) {
  549. return arr[0].val_lower_limit + ''
  550. }
  551. }
  552. return value.replace(/^0+/gi, '')
  553. }
  554. const formatter9 = value => {
  555. if (parseInt(value) == 0) {
  556. return '0'
  557. }
  558. let arr = settingStore.allSettingList.filter(
  559. item => item.name == 'stoped_humi',
  560. )
  561. if (arr && arr.length > 0) {
  562. if (parseInt(value) > arr[0].val_upper_limit) {
  563. return arr[0].val_upper_limit + ''
  564. }
  565. if (parseInt(value) < arr[0].val_lower_limit) {
  566. return arr[0].val_lower_limit + ''
  567. }
  568. }
  569. return value.replace(/^0+/gi, '')
  570. }
  571. const formatter10 = value => {
  572. if (parseInt(value) == 0) {
  573. return '0'
  574. }
  575. let arr = settingStore.allSettingList.filter(
  576. item => item.name == 'continued_humi',
  577. )
  578. if (arr && arr.length > 0) {
  579. if (parseInt(value) > arr[0].val_upper_limit) {
  580. return arr[0].val_upper_limit + ''
  581. }
  582. if (parseInt(value) < arr[0].val_lower_limit) {
  583. return arr[0].val_lower_limit + ''
  584. }
  585. }
  586. return value.replace(/^0+/gi, '')
  587. }
  588. const setAddliquidVal = () => {
  589. const val = parseInt(addLiquidConfigVal.value)
  590. if (isNaN(val)) {
  591. showFailToast('设置失败,请填写正确参数')
  592. return
  593. }
  594. }
  595. const setStopedGsVal = () => {
  596. const val = parseInt(stoped_gs.value)
  597. if (isNaN(val)) {
  598. showFailToast('设置失败,请填写正确参数')
  599. return
  600. }
  601. }
  602. const setcontinuedGsVal = () => {
  603. const val = parseInt(continued_gs.value)
  604. if (isNaN(val)) {
  605. showFailToast('设置失败,请填写正确参数')
  606. return
  607. }
  608. }
  609. const setstopedSaturVal = () => {
  610. const val = parseInt(stoped_satur.value)
  611. if (isNaN(val)) {
  612. showFailToast('设置失败,请填写正确参数')
  613. return
  614. }
  615. }
  616. const setContinuedSaturVal = () => {
  617. const val = parseInt(continued_satur.value)
  618. if (isNaN(val)) {
  619. showFailToast('设置失败,请填写正确参数')
  620. return
  621. }
  622. }
  623. const setMaxHumidityVal = () => {
  624. const val = parseInt(max_humidity.value)
  625. if (isNaN(val)) {
  626. showFailToast('设置失败,请填写正确参数')
  627. return
  628. }
  629. }
  630. const setHeat_timeVal = () => {
  631. const val = parseInt(pre_heat_time_s.value)
  632. if (isNaN(val)) {
  633. showFailToast('设置失败,请填写正确参数')
  634. return
  635. }
  636. }
  637. const setstoped_humiVal = () => {
  638. const val = parseInt(stoped_humi.value)
  639. if (isNaN(val)) {
  640. showFailToast('设置失败,请填写正确参数')
  641. return
  642. }
  643. }
  644. const setcontinued_humiVal = () => {
  645. const val = parseInt(continued_humi.value)
  646. if (isNaN(val)) {
  647. showFailToast('设置失败,请填写正确参数')
  648. return
  649. }
  650. }
  651. const setSprayLiquidVal = () => {
  652. const val = parseInt(sprayLiquidConfigVal.value)
  653. if (isNaN(val)) {
  654. showFailToast('设置失败,请填写正确参数')
  655. return
  656. }
  657. }
  658. const showkeyboard = ref(false)
  659. const onChange = a => {
  660. formula_id.value = a
  661. }
  662. const handleShowKeyBoard = () => {
  663. showkeyboard.value = true
  664. }
  665. onMounted(() => {
  666. document.addEventListener('click', e => {
  667. let box = document.getElementById('keyboard_formula')
  668. let room = document.getElementById('id_formula')
  669. if (!box?.contains(e.target) && e.target != room) {
  670. showkeyboard.value = false
  671. }
  672. })
  673. })
  674. </script>
  675. <style lang="scss" scoped>
  676. .update_device_container {
  677. box-sizing: border-box;
  678. width: 100%;
  679. height: 580px;
  680. display: grid;
  681. overflow: hidden;
  682. grid-template-columns: repeat(2, 1fr);
  683. row-gap: 20px;
  684. column-gap: 20px;
  685. padding: 20px;
  686. padding-bottom: 180px;
  687. position: relative;
  688. .btns {
  689. position: absolute;
  690. right: 20px;
  691. bottom: 20px;
  692. width: 300px;
  693. height: 68px;
  694. display: flex;
  695. align-items: center;
  696. justify-content: flex-end;
  697. .btn {
  698. width: 111px;
  699. height: 38px;
  700. border-radius: 19px;
  701. background: #06518b;
  702. display: flex;
  703. align-items: center;
  704. justify-content: center;
  705. font-family: Source Han Sans CN;
  706. font-size: 14px;
  707. font-weight: normal;
  708. line-height: normal;
  709. letter-spacing: 0.1em;
  710. color: #ffffff;
  711. }
  712. .ml {
  713. margin-left: 20px;
  714. }
  715. }
  716. .row_wrap {
  717. // width: 726px;
  718. height: 80px;
  719. border-radius: 14px;
  720. background: #f6f6f6;
  721. box-sizing: border-box;
  722. padding: 0 18px 0 40px;
  723. display: flex;
  724. align-items: center;
  725. justify-content: space-between;
  726. .title {
  727. font-family: Zona Pro;
  728. white-space: nowrap;
  729. font-size: 20px;
  730. font-weight: normal;
  731. letter-spacing: 0.06em;
  732. color: #000000;
  733. }
  734. .num {
  735. font-family: Source Han Sans CN;
  736. font-size: 14px;
  737. font-weight: 500;
  738. letter-spacing: 0.1em;
  739. color: #000000;
  740. display: flex;
  741. align-items: center;
  742. .log {
  743. width: 182px;
  744. display: flex;
  745. align-items: center;
  746. justify-content: center;
  747. }
  748. }
  749. .formula_input {
  750. border: none;
  751. height: 38px;
  752. padding: 0 12px;
  753. width: 220px;
  754. }
  755. .btn {
  756. width: 87px;
  757. height: 45px;
  758. border-radius: 23px;
  759. background: #06518b;
  760. font-family: Source Han Sans CN;
  761. font-size: 14px;
  762. font-weight: normal;
  763. letter-spacing: 0.1em;
  764. color: #ffffff;
  765. display: flex;
  766. align-items: center;
  767. justify-content: center;
  768. }
  769. }
  770. .key_wrap {
  771. position: absolute;
  772. left: 0;
  773. right: 0;
  774. bottom: 0;
  775. height: 230px;
  776. }
  777. }
  778. </style>