wifi.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. <template>
  2. <view style="height: 100vh">
  3. <view v-if="!connected">
  4. <scroll-view class="main-container" scroll-y="true"
  5. :refresher-enabled="false">
  6. <view v-for="(item, index) in deviceListDataShow" :key="item.id" class="list-item" hover-class="list-item-hover"
  7. hover-start-time="0" hover-stay-time="100" @click="listViewTap(item.id)">
  8. <image v-if="item.manufacturer==='eciot'" src="/static/img/ecble.png" class="list-item-img"></image>
  9. <image v-else src="/static/img/ble.png" class="list-item-img"></image>
  10. <text class="list-item-name">{{item.name}}</text>
  11. <image v-if="item.rssi >= -41" src="/static/img/s5.png" mode="aspectFit" class="list-item-rssi-img"></image>
  12. <image v-else-if="item.rssi >= -55" src="/static/img/s4.png" mode="aspectFit" class="list-item-rssi-img"></image>
  13. <image v-else-if="item.rssi >= -65" src="/static/img/s3.png" mode="aspectFit" class="list-item-rssi-img"></image>
  14. <image v-else-if="item.rssi >= -75" src="/static/img/s2.png" mode="aspectFit" class="list-item-rssi-img"></image>
  15. <image v-else="item.rssi < -75" src="/static/img/s1.png" mode="aspectFit" class="list-item-rssi-img"></image>
  16. <text class="list-item-rssi">{{item.rssi}}</text>
  17. <view class="list-item-line"></view>
  18. </view>
  19. <u-popup :show="showSendData" >
  20. <view class="slot-content">
  21. <view>
  22. <u--input
  23. :placeholder="i18('请输入值')"
  24. border="surround"
  25. v-model="sendData"
  26. ></u--input>
  27. </view>
  28. <view style="margin:10px;text-decoration: underline;margin-bottom: 0px" @click="sendLanyaData">
  29. <u-button>发送</u-button>
  30. </view>
  31. </view>
  32. </u-popup>
  33. <view v-if="deviceListDataShow.length==0" class="notice"> - {{ $t('buletooth.nodevice') }} -</view>
  34. <view class="gap"></view>
  35. </scroll-view>
  36. </view>
  37. <view v-if="connected">
  38. <view class="text-area">
  39. <u--form v-if="isCompanyUser()" style="width: 100%;"
  40. labelPosition="left"
  41. ref="uForm"
  42. >
  43. <u-form-item
  44. label="WIFI Name:"
  45. borderBottom
  46. labelWidth="auto"
  47. @click="openChooseWifi"
  48. ref="item1"
  49. >
  50. <u--input
  51. v-model="SSID"
  52. disabled
  53. disabledColor="#ffffff"
  54. placeholder="Choose wifi:"
  55. border="none"
  56. labelWidth="auto"
  57. ></u--input>
  58. <u-icon
  59. slot="right"
  60. name="arrow-right"
  61. ></u-icon>
  62. </u-form-item>
  63. <u-form-item
  64. label="Password:"
  65. borderBottom
  66. ref="item1"
  67. labelWidth="auto"
  68. >
  69. <u--input
  70. v-model="password"
  71. border="none"
  72. labelWidth="auto"
  73. ></u--input>
  74. </u-form-item>
  75. </u--form>
  76. <u--form v-else style="width: 100%;"
  77. labelPosition="left"
  78. ref="uForm"
  79. >
  80. <u-form-item
  81. label="WIFI名称:"
  82. borderBottom
  83. labelWidth="auto"
  84. @click="openChooseWifi"
  85. ref="item1"
  86. >
  87. <u--input
  88. v-model="SSID"
  89. disabled
  90. disabledColor="#ffffff"
  91. placeholder="请选择wifi:"
  92. border="none"
  93. ></u--input>
  94. <u-icon
  95. slot="right"
  96. name="arrow-right"
  97. ></u-icon>
  98. </u-form-item>
  99. <u-form-item
  100. label="密码:"
  101. borderBottom
  102. ref="item1"
  103. >
  104. <u--input
  105. v-model="password"
  106. border="none"
  107. ></u--input>
  108. </u-form-item>
  109. <u-form-item
  110. label="二维码ID:"
  111. borderBottom
  112. ref="item1"
  113. labelWidth="auto"
  114. >
  115. <u--input
  116. v-model="qrcodeid"
  117. border="none"
  118. ></u--input>
  119. </u-form-item>
  120. <u-form-item
  121. @click="showProductList = true"
  122. label="产品类型:"
  123. borderBottom
  124. ref="item1"
  125. labelWidth="auto"
  126. >
  127. <u--input disabled
  128. v-model="productName"
  129. border="none"
  130. ></u--input>
  131. </u-form-item>
  132. </u--form>
  133. </view>
  134. <view style="margin:10px">
  135. <u-button text="Confirm" v-if="isCompanyUser()" @click="doConnectUser(1)" size="small" type="primary"></u-button>
  136. <u-button text="开始配网" v-else @click="doConnect(2)" size="small" type="primary"></u-button>
  137. </view>
  138. <u-picker @cancel="showWiftList=false" @confirm="chooseWifi" :show="showWiftList" :columns="wifiList"></u-picker>
  139. <u-picker @cancel="showProductList=false" keyName="text" @confirm="chooseProduct" :show="showProductList" :columns="chooseProductList"></u-picker>
  140. </view>
  141. </view>
  142. </template>
  143. <script>
  144. // #ifdef APP
  145. import ecUI from '@/utils/ecUI.js'
  146. import ecBLE from '@/utils/ecBLE/ecBLE.js'
  147. // #endif
  148. // #ifdef MP
  149. const ecUI = require('@/utils/ecUI.js')
  150. const ecBLE = require('@/utils/ecBLE/ecBLE.js')
  151. // #endif
  152. import i18 from '@/utils/i18.js'
  153. import {getDevcieByQrcodeID} from "@/api/device/device";
  154. import {sendWifi,sendPwd,sendEnd} from "@/utils/weitiandi/device/device.js";
  155. let ctx
  156. let deviceListData = []
  157. export default {
  158. data() {
  159. return {
  160. showProductList:false,
  161. showPwd:false,
  162. rightPwd:"",
  163. pwd:"",
  164. timer:"",
  165. buleid:"",
  166. deviceListDataShow: [],
  167. showTimer:null,
  168. connected:false,
  169. uuid:"",
  170. showDeviceNo:false,
  171. inputDeviceNo:"",
  172. commonCode:"",
  173. showSendData:false,
  174. sendData:"",
  175. qrcodeid:"",
  176. productName:"",
  177. deviceno:"",
  178. SSID:"",
  179. password:"",
  180. showWiftList:false,
  181. productId:56,
  182. chooseProductList:[[ {
  183. id:56,text:"3"
  184. },
  185. {
  186. id:56,text:"4"
  187. },
  188. {
  189. id:57,text:"5"
  190. }
  191. ]],
  192. wifiList: [
  193. []
  194. ],
  195. peiwangTimer:null,
  196. }
  197. },
  198. onLoad() {
  199. uni.setNavigationBarTitle({
  200. title: i18('WIFI配网')
  201. })
  202. this.deviceno = this.generateTimestamp();
  203. ecUI.showLoading("Bluetooth initing")
  204. ctx = this
  205. clearInterval(this.timer);
  206. this.timer = setInterval(() => {
  207. ctx.deviceListDataShow = JSON.parse(JSON.stringify(deviceListData))
  208. }, 800)
  209. console.log(this.commonCode)
  210. this.productName = this.chooseProductList[0][0].text;
  211. },
  212. onUnload(){
  213. ecBLE.stopBluetoothDevicesDiscovery();
  214. ecBLE.closeBLEConnection()
  215. },
  216. onShow() {
  217. if(this.showTimer!= null){
  218. clearTimeout(this.showTimer);
  219. }
  220. this.showTimer = setTimeout(() => {
  221. ctx.openBluetoothAdapter()
  222. }, 100)
  223. },
  224. methods: {
  225. isCompanyUser(){
  226. return true;
  227. },
  228. chooseProduct(e){
  229. this.productId = e.value[0].id;
  230. this.productName = e.value[0].text;
  231. this.showProductList= false;
  232. },
  233. generateTimestamp() {
  234. const date = new Date();
  235. const year = date.getFullYear().toString().substr(2);
  236. const month = date.getMonth() + 1;
  237. const day = date.getDate();
  238. const hours = date.getHours();
  239. const minutes = date.getMinutes();
  240. // 生成6位随机数字
  241. const randomNum = Math.floor(Math.random() * 900000) + 100000;
  242. // 将数字拼接成字符串
  243. const timestamp = `${year}${month < 10 ? '0' + month : month}${day < 10 ? '0' + day : day}${hours}${minutes < 10 ? '0' + minutes : minutes}${randomNum}`;
  244. return timestamp;
  245. },
  246. getAuth(){
  247. wx.getSetting({
  248. success(res) {
  249. if (!res.authSetting['scope.userLocation']) {
  250. wx.authorize({
  251. scope: 'scope.userLocation',
  252. success () {
  253. // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
  254. }
  255. })
  256. }
  257. }
  258. })
  259. },
  260. chooseWifi(e){
  261. this.SSID = e.value[0];
  262. this.showWiftList= false;
  263. },
  264. openChooseWifi(){
  265. if(this.wifiList[0].length == 0){
  266. this.getWifiList();
  267. }else{
  268. this.showWiftList = true;
  269. }
  270. },
  271. openWifi(){
  272. let self = this;
  273. uni.startWifi({
  274. success(res) {
  275. console.log(res);
  276. // self.getWifiList();
  277. },
  278. fail(res) {
  279. console.log(res)
  280. uni.showToast({
  281. title: i18('请打开WIFI'),
  282. icon: 'none',
  283. duration: 3000
  284. });
  285. }
  286. })
  287. },
  288. getWifi(){
  289. // #ifdef MP-WEIXIN
  290. var that = this
  291. wx.getConnectedWifi({
  292. success(res) {
  293. console.log(res)
  294. that.BSSID = res.wifi.BSSID
  295. that.WIFIName = res.wifi.SSID
  296. },
  297. fail(res) {
  298. console.log(res)
  299. //报错的相关处理
  300. },
  301. })
  302. // #endif
  303. },
  304. getWifiList() {
  305. var that = this
  306. uni.getWifiList({
  307. success: res => {
  308. console.log('res', res);
  309. uni.onGetWifiList((res) => {
  310. that.showWiftList = true;
  311. uni.hideLoading();
  312. console.log("获取wifi列表");
  313. that.wifiList = [[]];
  314. console.log(res.wifiList); //在这里提取列表数据
  315. //通过遍历将WIFI名字存入集合,以便下卡框等组件使用
  316. for (var i = 0; i < res.wifiList.length; i++) {
  317. that.wifiList[0].push(res.wifiList[i].SSID)
  318. }
  319. });
  320. },
  321. fail(res) {
  322. console.log(res)
  323. uni.showToast({
  324. title: i18('获取wifi失败,请检查wifi'),
  325. icon: 'none',
  326. duration: 2000
  327. });
  328. },
  329. });
  330. },
  331. doConnectUser(){
  332. if(this.SSID == ""){
  333. uni.showToast({
  334. title: i18('请选择WIFI'),
  335. icon: 'none',
  336. duration: 3000
  337. });
  338. return;
  339. }
  340. if(this.password == ""){
  341. uni.showToast({
  342. title: i18('请输入wifi密码'),
  343. icon: 'none',
  344. duration: 3000
  345. });
  346. return;
  347. }
  348. /**
  349. * ID:XXX+回车换行(设备编号)
  350. * QR:XXXX+回车换行(二维码ID)
  351. * ssid:WiFi名字+回车换行
  352. * psd:wifi密码+回车换行
  353. * 最后+OK
  354. */
  355. let self = this;
  356. let endStr = "$$";
  357. ecUI.showLoading("正在配置网络信息")
  358. setTimeout(function(){
  359. sendWifi(self.SSID+endStr);
  360. },400);
  361. setTimeout(function(){
  362. sendPwd(self.password+endStr);
  363. },600);
  364. setTimeout(function(){
  365. sendEnd("OK"+endStr);
  366. },800);
  367. this.peiwangTimer = setTimeout(function(){
  368. ecUI.hideLoading();
  369. self.$modal.showToast("配网失败,请检查状态");
  370. },30000);
  371. },
  372. doConnect(){
  373. if(this.SSID == ""){
  374. uni.showToast({
  375. title: '请选择WIFI',
  376. icon: 'none',
  377. duration: 3000
  378. });
  379. return;
  380. }
  381. if(this.password == ""){
  382. uni.showToast({
  383. title: '请输入wifi密码',
  384. icon: 'none',
  385. duration: 3000
  386. });
  387. return;
  388. }
  389. if(this.qrcodeid == ""){
  390. uni.showToast({
  391. title: '请输入二维码ID',
  392. icon: 'none',
  393. duration: 3000
  394. });
  395. return;
  396. }
  397. if(this.deviceno == ""){
  398. uni.showToast({
  399. title: '请输入设备编号',
  400. icon: 'none',
  401. duration: 3000
  402. });
  403. return;
  404. }
  405. /**
  406. * ID:XXX+回车换行(设备编号)
  407. * QR:XXXX+回车换行(二维码ID)
  408. * ssid:WiFi名字+回车换行
  409. * psd:wifi密码+回车换行
  410. * 最后+OK
  411. */
  412. let self = this;
  413. getDevcieByQrcodeID(this.qrcodeid).then(res=>{
  414. if(res.data != null){
  415. self.$modal.showToast("当前二维码已经配置设备");
  416. }else{
  417. let endStr = "$$";
  418. ecUI.showLoading("正在配置网络信息")
  419. setTimeout(function(){
  420. self.sendBlueData("ID:"+self.deviceno+endStr);
  421. },200);
  422. setTimeout(function(){
  423. self.sendBlueData("QR:"+self.qrcodeid+endStr);
  424. },400);
  425. setTimeout(function(){
  426. self.sendBlueData("ssid:"+self.SSID+endStr);
  427. },600);
  428. setTimeout(function(){
  429. self.sendBlueData("psd:"+self.password+endStr);
  430. },800);
  431. setTimeout(function(){
  432. self.sendBlueData("pid:"+self.productId+endStr);
  433. },1000);
  434. setTimeout(function(){
  435. self.sendBlueData("OK");
  436. },1200);
  437. }
  438. })
  439. },
  440. stringToHex(str) {
  441. let hex = '';
  442. for (let i = 0; i < str.length; i++) {
  443. const char = str.charCodeAt(i);
  444. const hexChar = char.toString(16).padStart(2, '0');
  445. hex += hexChar;
  446. }
  447. return hex;
  448. },
  449. doByTime(func,time){
  450. setTimeout(function (){
  451. func();
  452. },time);
  453. },
  454. sendLanyaData(){
  455. this.$modal.showToast("正在发送");
  456. this.sendBlueData(this.sendData);
  457. },
  458. i18(text){
  459. return text;
  460. },
  461. cancel(){
  462. this.showPwd = false;
  463. uni.navigateBack({
  464. });
  465. },
  466. resetPwd(){
  467. let self = this;
  468. if(!this.inputDeviceNo){
  469. self.$modal.showToast("请输入序列号");
  470. return;
  471. }
  472. let uuidRight = false;
  473. if(this.inputDeviceNo == this.commonCode || this.uuid == this.inputDeviceNo){
  474. uuidRight = true;
  475. }
  476. if(!uuidRight){
  477. self.$modal.showToast("序列号有误");
  478. return;
  479. }
  480. if(uuidRight){
  481. this.$modal.confirm("密码将被重置为123456").then(res=>{
  482. setPwd("123456")
  483. self.$modal.showToast("密码修改成功");
  484. this.rightPwd = "123456";
  485. self.loginSuccess();
  486. });
  487. }
  488. },
  489. getBeijingTime() {
  490. const date = new Date();
  491. const utcTime = date.getTime() + (date.getTimezoneOffset() * 60 * 1000);
  492. const beijingTime = new Date(utcTime + (8 * 60 * 60 * 1000));
  493. return beijingTime;
  494. },
  495. generateUniqueNumber(date) {
  496. let dateString = date.toISOString().slice(0, 10).replace(/-/g, '');
  497. console.log(dateString)
  498. let hash = w_md5.hex_md5_32(dateString);
  499. console.log(hash);//32位小写
  500. let str = "";
  501. for (let i = 0; i < 6; i++) {
  502. const c = hash.charCodeAt(i);
  503. str = str+""+c+""
  504. }
  505. return str.substr(0,6);
  506. },
  507. goBack(){
  508. uni.navigateBack({
  509. });
  510. },
  511. $t(title){
  512. return title;
  513. },
  514. inputPwd(){
  515. if(!this.pwd ){
  516. this.$modal.showToast(this.$t('buletooth.errpwd'));
  517. }else{
  518. if(this.rightPwd && this.rightPwd === this.pwd){
  519. this.loginSuccess();
  520. }else{
  521. this.$modal.showToast(this.$t('buletooth.errpwd'));
  522. }
  523. }
  524. },
  525. loginSuccess(){
  526. this.showPwd = false;
  527. this.showDeviceNo = false;
  528. uni.setStorageSync("pwd",this.rightPwd);
  529. uni.setStorageSync('blueid', this.buleid);
  530. this.pwd = "";
  531. ecBLE.stopBluetoothDevicesDiscovery();
  532. uni.navigateTo({
  533. url: '/pages/weitiandi/bluetooth/status'
  534. });
  535. },
  536. getLocalPwd(){
  537. let pwd = uni.getStorageSync("pwd");
  538. return pwd;
  539. },
  540. sendBlueData(tempSendData){
  541. tempSendData = this.stringToHex(tempSendData);
  542. let data = tempSendData
  543. .replace(/\s*/g, '')
  544. .replace(/\n/g, '')
  545. .replace(/\r/g, '')
  546. data = "55a0"+data;
  547. console.log("写入数据:"+data);
  548. ecBLE.writeBLECharacteristicValue(data, true)
  549. },
  550. listViewTap(id){
  551. let self = this;
  552. ecUI.showLoading("Bluetooth connectting")
  553. ecBLE.onBLEConnectionStateChange(res => {
  554. console.log(res);
  555. if (res.ok) {
  556. self.connected = true;
  557. self.openWifi();
  558. ecUI.hideLoading()
  559. self.showSendData = true;
  560. ecBLE.stopBluetoothDevicesDiscovery();
  561. //
  562. } else {
  563. ecUI.hideLoading()
  564. this.$modal.showToast("蓝牙断开");
  565. self.goBack();
  566. }
  567. });
  568. //receive data
  569. ecBLE.onBLECharacteristicValueChange((str, strHex) => {
  570. let isCheckRevHex = true;
  571. let data =
  572. (isCheckRevHex ? strHex.replace(/[0-9a-fA-F]{2}/g, ' $&') : str)
  573. console.log(data);
  574. data = data.trim();
  575. data = data.split(" ")
  576. if(data[1] == 'A3' && data[3] == '01' ){
  577. self.$modal.closeLoading();
  578. clearTimeout(self.peiwangTimer);
  579. self.peiwangTimer = null;
  580. uni.showModal({
  581. title: i18('提示'),
  582. content: i18('配网成功,请扫码绑定设备'),
  583. showCancel: false,
  584. confirmText: i18('确认'),
  585. success: function(res) {
  586. if (res.confirm) {
  587. self.goBack();
  588. }
  589. }
  590. })
  591. }
  592. })
  593. self.connected = false;
  594. ecBLE.createBLEConnection(id);
  595. setTimeout(function (){
  596. if(!self.connected){
  597. self.$modal.showToast(i18('连接失败'));
  598. self.startBluetoothDevicesDiscovery()
  599. }
  600. },10000);
  601. },
  602. showInputPwd(){
  603. this.showPwd = true;
  604. },
  605. messageCallback(data){
  606. let self = this;
  607. console.log(data);
  608. let type = data.type;
  609. let real_data = data.real_data;
  610. if(type == 253){
  611. self.$modal.closeLoading();
  612. self.uuid = real_data.substr(0,6);
  613. }
  614. self.$forceUpdate();
  615. console.log('收到服务器内容:' + JSON.stringify(data));
  616. },
  617. forgetPwd(){
  618. this.$modal.loading("正在读取设备ID");
  619. getUUID()
  620. this.showDeviceNo = true;
  621. },
  622. openBluetoothAdapter() {
  623. let self = this;
  624. ecBLE.onBluetoothAdapterStateChange(res => {
  625. ecUI.hideLoading()
  626. if (res.ok) {
  627. ctx.startBluetoothDevicesDiscovery()
  628. } else {
  629. ecUI.showModal(
  630. this.$t('buletooth.tip'),
  631. `Bluetooth adapter error | ${res.errCode} | ${res.errMsg}`,
  632. () => {
  633. }
  634. )
  635. }
  636. })
  637. ecBLE.openBluetoothAdapter()
  638. },
  639. startBluetoothDevicesDiscovery() {
  640. ecBLE.stopBluetoothDevicesDiscovery();
  641. console.log('start search')
  642. ecBLE.onBluetoothDeviceFound(res => {
  643. let isRight = true;
  644. if(res.name.startsWith('BT_') || res.name.startsWith('WGD')){
  645. isRight = true;
  646. }
  647. if(!isRight){
  648. return;
  649. }
  650. for (const item of deviceListData) {
  651. if (item.id === res.id) {
  652. item.name = res.name
  653. item.rssi = res.rssi
  654. return
  655. }
  656. }
  657. let manufacturer = ''
  658. if (res.name.length === 11 && res.name.startsWith('@')) {
  659. manufacturer = 'eciot'
  660. }
  661. if (res.name.length === 15 && res.name.startsWith('BT_')) {
  662. manufacturer = 'eciot'
  663. }
  664. manufacturer = 'eciot'
  665. deviceListData.push({
  666. id: res.id,
  667. name: res.name,
  668. rssi: res.rssi,
  669. manufacturer,
  670. })
  671. })
  672. ecBLE.startBluetoothDevicesDiscovery()
  673. },
  674. }
  675. }
  676. </script>
  677. <style>
  678. .main-container {
  679. height: 100vh;
  680. }
  681. .list-item {
  682. height: 57px;
  683. position: relative;
  684. }
  685. .list-item-hover {
  686. background-color: #e5e4e9;
  687. }
  688. .list-item-img {
  689. position: absolute;
  690. width: 36px;
  691. height: 36px;
  692. left: 20px;
  693. top: 10px;
  694. }
  695. .list-item-name {
  696. position: absolute;
  697. font-size: 22px;
  698. left: 76px;
  699. top: 0px;
  700. line-height: 56px;
  701. }
  702. .list-item-rssi-img {
  703. position: absolute;
  704. width: 20px;
  705. height: 20px;
  706. right: 20px;
  707. top: 13px;
  708. }
  709. .list-item-rssi {
  710. position: absolute;
  711. width: 40px;
  712. height: 20px;
  713. right: 10px;
  714. top: 33px;
  715. font-size: 12px;
  716. font-weight: bold;
  717. display: flex;
  718. justify-content: center;
  719. }
  720. .list-item-line {
  721. position: absolute;
  722. height: 1px;
  723. width: 100vw;
  724. left: 20px;
  725. top: 56px;
  726. background-color: #c6c6c8;
  727. }
  728. .notice {
  729. display: flex;
  730. justify-content: center;
  731. align-items: center;
  732. margin-top: 10px;
  733. font-size: 13px;
  734. color: #909399;
  735. }
  736. .gap {
  737. height: 57px;
  738. }
  739. .text-area {
  740. display: flex;
  741. justify-content: center;
  742. background: white;
  743. width: 100%;
  744. height: 100%;
  745. }
  746. </style>