login.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. <template>
  2. <view class="login-container">
  3. <!-- 顶部渐变背景区域 -->
  4. <view class="header-bg"></view>
  5. <!-- Logo 区域(长按显示设置按钮) -->
  6. <view class="logo-section" @longpress="logoTime">
  7. <view class="logo-circle">
  8. <image
  9. src="./assets/logo.png"
  10. class="logo-img"
  11. mode="aspectFit"
  12. ></image>
  13. </view>
  14. <text class="app-title">{{
  15. $isneutral ? '云飞智控' : '智控'
  16. }}</text>
  17. </view>
  18. <!-- 设置按钮(长按 Logo 显示) -->
  19. <view class="set-btn" @click="set" v-if="setTF">
  20. <u-icon name="setting-fill" size="44" color="#24b35d"></u-icon>
  21. </view>
  22. <!-- 登录表单卡片 -->
  23. <view class="form-card">
  24. <form @submit="formSubmit">
  25. <!-- 账号输入 -->
  26. <view class="form-item">
  27. <u-icon name="account" size="36" color="#999"></u-icon>
  28. <u-input
  29. v-model="formdata.username"
  30. class="form-input"
  31. placeholder="请输入账号/手机号"
  32. placeholderStyle="color:#BBBBBB;"
  33. color="#333"
  34. :border="false"
  35. @blur="blur"
  36. />
  37. </view>
  38. <!-- 密码输入 -->
  39. <view class="form-item">
  40. <u-icon name="lock" size="36" color="#999"></u-icon>
  41. <u-input
  42. v-model="formdata.passwold"
  43. type="password"
  44. :password-icon="true"
  45. :clearable="false"
  46. placeholder="请输入密码"
  47. placeholderStyle="color:#BBBBBB;"
  48. suffixIconStyle="color:#999;"
  49. color="#333"
  50. :border="false"
  51. class="form-input"
  52. @confirm="formSubmit"
  53. @input="passwoldddata"
  54. />
  55. </view>
  56. <!-- 记住密码 -->
  57. <view class="form-extra">
  58. <u-checkbox-group>
  59. <u-checkbox
  60. v-model="checked"
  61. shape="square"
  62. size="28"
  63. active-color="#24b35d"
  64. :label-disabled="false"
  65. @change="rempass"
  66. >记住密码</u-checkbox
  67. >
  68. </u-checkbox-group>
  69. </view>
  70. <!-- 登录按钮 -->
  71. <view class="login-btn-wrap">
  72. <button form-type="submit" class="login-btn" @click="denglu">
  73. 登 录
  74. </button>
  75. </view>
  76. <!-- 用户隐私协议 -->
  77. <view class="agreement">
  78. <u-checkbox-group>
  79. <u-checkbox
  80. v-model="agree"
  81. shape="circle"
  82. size="26"
  83. active-color="#24b35d"
  84. :label-disabled="false"
  85. >
  86. 我已阅读并同意
  87. </u-checkbox>
  88. </u-checkbox-group>
  89. <text class="agree-link" @click="goAgreement">《用户隐私协议》</text>
  90. </view>
  91. </form>
  92. </view>
  93. <!-- 底部版本号 -->
  94. <view class="version-footer">
  95. <text class="version-text">V{{ appVersion || '1.0.0' }}</text>
  96. </view>
  97. <!-- 设置服务器地址弹窗 -->
  98. <view class="setbg" v-if="setbgtf">
  99. <view class="mengban" @click.stop="setbgtf = !setbgtf"></view>
  100. <view class="set_http">
  101. <view class="set_http_top">
  102. <u-icon name="close" size="40" @click="setbgtf = !setbgtf"></u-icon>
  103. <text class="set_title">设置服务器地址</text>
  104. <u-icon name="checkbox-mark" size="40" @click="sethttp"></u-icon>
  105. </view>
  106. <view class="set_http_bot">
  107. <text class="set_label">服务器访问地址</text>
  108. <view class="set_http_bot_input">
  109. <input
  110. type="text"
  111. v-model="value"
  112. placeholder="请在此处输入服务器地址(http://...)"
  113. />
  114. <u-icon
  115. :name="arrowtf ? 'arrow-up' : 'arrow-down'"
  116. @click="arrow"
  117. ></u-icon>
  118. </view>
  119. <scroll-view scroll-y="true" class="scroll-Y" v-if="arrowtf">
  120. <view
  121. :id="'demo' + index"
  122. class="scroll-view-item"
  123. v-for="(item, index) in httparr"
  124. :key="index"
  125. @click="value = item"
  126. >{{ item }}</view
  127. >
  128. </scroll-view>
  129. </view>
  130. </view>
  131. </view>
  132. <!-- 升级弹窗 -->
  133. <u-modal
  134. title="升级中请勿随意操作"
  135. :show-confirm-button="false"
  136. v-model="showA"
  137. :content="contentA"
  138. >
  139. <view class="upgradeBox">
  140. <u-line-progress
  141. v-show="isShow"
  142. active-color="#24b35d"
  143. :striped="true"
  144. :percent="percentNum"
  145. :striped-active="true"
  146. ></u-line-progress>
  147. </view>
  148. </u-modal>
  149. </view>
  150. </template>
  151. <script>
  152. import { needPrivacyPopup } from '@/util/privacyConfig.js';
  153. export default {
  154. data() {
  155. return {
  156. checked: false,
  157. formdata: {
  158. username: '',
  159. passwold: '',
  160. },
  161. setbgtf: false,
  162. setTF: false,
  163. value: 'https://web.hnyfwlw.com',
  164. httparr: ['https://web.hnyfwlw.com'],
  165. arrowtf: false,
  166. showA: false,
  167. contentA: '',
  168. isShow: false,
  169. percentNum: 0,
  170. apkPath: '',
  171. passvalue: false,
  172. turnover: true,
  173. agree: false,
  174. appVersion: '',
  175. };
  176. },
  177. onShow() {
  178. // 已同意当前版本的隐私协议,自动勾选表单协议复选框
  179. if (!needPrivacyPopup()) {
  180. this.agree = true;
  181. }
  182. // 获取当前 app 版本号
  183. // #ifdef APP-PLUS
  184. this.appVersion = plus.runtime.version;
  185. // #endif
  186. // #ifndef APP-PLUS
  187. this.appVersion = '1.0.0';
  188. // #endif
  189. // 恢复记住的密码
  190. uni.getStorage({
  191. key: 'user_pass',
  192. success: (res) => {
  193. if (res.data) {
  194. this.formdata.passwold = res.data;
  195. this.checked = true;
  196. } else {
  197. this.checked = false;
  198. }
  199. },
  200. });
  201. // 恢复记住的用户名
  202. uni.getStorage({
  203. key: 'user_name',
  204. success: (res) => {
  205. this.formdata.username = res.data;
  206. },
  207. });
  208. // 恢复服务器地址
  209. uni.getStorage({
  210. key: 'http',
  211. success: (res) => {
  212. this.value = res.data;
  213. },
  214. });
  215. console.log(this.value);
  216. uni.getStorage({
  217. key: 'turnover',
  218. success: (res) => {
  219. console.log(res.data);
  220. this.turnover = res.data;
  221. },
  222. });
  223. // 从“安装未知应用”设置页返回后,继续安装已下载的更新包
  224. // #ifdef APP-PLUS
  225. if (this.apkPath) {
  226. this.installApk(this.apkPath, true);
  227. }
  228. // #endif
  229. this.getEquipList();
  230. },
  231. methods: {
  232. // 版本检测
  233. async getEquipList() {
  234. const res = await this.$myRequest({
  235. url: '/api/api_gateway?method=home.homes.app_version_record',
  236. data: {
  237. ret: 'first',
  238. },
  239. });
  240. console.log(res);
  241. this.appName = res[0].app_name;
  242. this.versions = Number(res[0].app_num.match(/\d+/g).join(''));
  243. var id = Number(plus.runtime.version.match(/\d+/g).join(''));
  244. console.log(this.versions, plus.runtime.version);
  245. if (this.percentNum > 0) {
  246. console.log('更新中');
  247. } else {
  248. console.log(this.turnover);
  249. if (this.turnover) {
  250. if (this.versions > id) {
  251. uni.showModal({
  252. title: '检测到有新版本,是否更新?',
  253. content: '建议更新,不更新可能会出现部分数据无法获取!',
  254. confirmText: '更新',
  255. cancelText: '不更新',
  256. success: (res) => {
  257. if (res.confirm) {
  258. console.log('用户点击确定');
  259. this.showA = true;
  260. this.isShow = true;
  261. this.upgrade();
  262. } else if (res.cancel) {
  263. console.log('用户点击取消');
  264. uni.showModal({
  265. title: '是否每次进入提示更新?',
  266. content: '不再提示后可在<我的>-<关于我们>-<版本更新>中更新',
  267. confirmText: '提示',
  268. cancelText: '不再提示',
  269. success: (res) => {
  270. if (res.confirm) {
  271. console.log('用户点击确定');
  272. uni.setStorage({
  273. key: 'turnover',
  274. data: true,
  275. });
  276. } else if (res.cancel) {
  277. uni.setStorage({
  278. key: 'turnover',
  279. data: false,
  280. });
  281. }
  282. },
  283. });
  284. }
  285. },
  286. });
  287. } else {
  288. uni.getStorage({
  289. key: 'session_key',
  290. success: (res) => {
  291. console.log(res);
  292. if (res.data != '') {
  293. uni.switchTab({
  294. url: '../index/index',
  295. });
  296. }
  297. },
  298. });
  299. }
  300. } else {
  301. uni.getStorage({
  302. key: 'session_key',
  303. success: (res) => {
  304. console.log(res);
  305. if (res.data != '') {
  306. uni.switchTab({
  307. url: '../index/index',
  308. });
  309. }
  310. },
  311. });
  312. }
  313. }
  314. },
  315. // 应用升级下载
  316. upgrade() {
  317. console.log(this.appName);
  318. var appName = '';
  319. if (this.$isneutral) {
  320. appName = 'big_data'; // 云飞
  321. } else {
  322. appName = 'big_data2'; // 中性
  323. }
  324. var url = 'https://hnyfwlw.com/app/' + appName + '.apk';
  325. const downloadTask = uni.downloadFile({
  326. url: url,
  327. success: (res) => {
  328. console.log(res);
  329. if (res.statusCode === 200) {
  330. console.log('安装包下载成功,即将安装:' + res.tempFilePath);
  331. this.installApk(res.tempFilePath);
  332. this.showA = false;
  333. this.isShow = false;
  334. }
  335. },
  336. fail: (err) => {
  337. console.log(err);
  338. },
  339. complete: (com) => {
  340. console.log(com);
  341. },
  342. });
  343. downloadTask.onProgressUpdate((res) => {
  344. this.percentNum = res.progress;
  345. if (res.progress == 100) {
  346. console.log('下载完成了');
  347. }
  348. });
  349. },
  350. // 调起系统安装器安装更新包,失败时引导开启“安装未知应用”后自动重试一次
  351. // fromGuide:从系统设置页返回后的重试,不再引导,直接提示失败原因
  352. installApk(path, fromGuide) {
  353. this.apkPath = '';
  354. plus.runtime.install(
  355. path,
  356. { force: false },
  357. () => {
  358. console.log('已调起安装');
  359. },
  360. (e) => {
  361. console.log('安装失败:', e);
  362. // Android 8.0 及以上需用户在系统设置中开启“允许安装未知应用”,
  363. // 该权限属于特殊权限,系统不会弹窗申请,只能引导用户到设置页手动开启。
  364. // 注意:不做安装前预检查,部分机型(如小米)已授权时检查接口仍返回未授权
  365. if (
  366. !fromGuide &&
  367. plus.os.name === 'Android' &&
  368. parseFloat(plus.os.version) >= 8
  369. ) {
  370. this.apkPath = path;
  371. uni.showModal({
  372. title: '需要安装权限',
  373. content: '请在接下来打开的页面中,允许本应用“安装未知应用”',
  374. showCancel: false,
  375. success: () => {
  376. var main = plus.android.runtimeMainActivity();
  377. var Intent = plus.android.importClass(
  378. 'android.content.Intent',
  379. );
  380. var Uri = plus.android.importClass('android.net.Uri');
  381. var intent = new Intent(
  382. 'android.settings.MANAGE_UNKNOWN_APP_SOURCES',
  383. );
  384. intent.setData(Uri.parse('package:' + main.getPackageName()));
  385. main.startActivity(intent);
  386. },
  387. });
  388. } else {
  389. uni.showModal({
  390. title: '安装失败',
  391. content:
  392. '若已开启“安装未知应用”仍失败,小米手机请检查系统“纯净模式”等安装限制后重新更新',
  393. showCancel: false,
  394. });
  395. }
  396. },
  397. );
  398. },
  399. // 登录表单提交
  400. async formSubmit() {
  401. // 1. 必填校验:用户名
  402. if (!this.formdata.username || !this.formdata.username.trim()) {
  403. uni.showToast({
  404. title: '请输入账号/手机号',
  405. icon: 'none',
  406. });
  407. return;
  408. }
  409. // 2. 必填校验:密码
  410. if (!this.formdata.passwold) {
  411. uni.showToast({
  412. title: '请输入密码',
  413. icon: 'none',
  414. });
  415. return;
  416. }
  417. // 3. 隐私协议校验
  418. if (!this.agree) {
  419. uni.showToast({
  420. title: '请先阅读并同意用户隐私协议',
  421. icon: 'none',
  422. });
  423. return;
  424. }
  425. // 4. 发起登录请求(仅成功时才继续后续流程)
  426. try {
  427. const res = await this.$myRequest({
  428. url: '/api/api_gateway?method=user.login.login_user',
  429. data: {
  430. username: this.formdata.username,
  431. password: this.formdata.passwold,
  432. },
  433. });
  434. // 兼容:登录接口可能直接返回 session_key,也可能在 data 里
  435. let session_key = res.session_key || (res.data && res.data.session_key);
  436. if (!session_key) {
  437. uni.showToast({
  438. title: res.msg || res.message || '登录失败,请检查账号密码',
  439. icon: 'none',
  440. });
  441. return;
  442. }
  443. // 5. 登录成功,存储 session_key 并跳转
  444. uni.setStorage({
  445. key: 'session_key',
  446. data: session_key,
  447. success: () => {
  448. // 登录前清除可能残留的权限缓存,再用新账号拉取
  449. this.$resetPermissionList();
  450. this.$fetchPermissionList();
  451. uni.switchTab({
  452. url: '../index/index',
  453. });
  454. },
  455. });
  456. } catch (err) {
  457. // 网络错误或接口抛错,提示后不再往下走
  458. console.log('登录请求失败:', err);
  459. uni.showToast({
  460. title: (err && err.message) || '网络异常,请稍后重试',
  461. icon: 'none',
  462. });
  463. }
  464. },
  465. // 密码输入过滤中文
  466. passwoldddata() {
  467. this.formdata.passwold = this.formdata.passwold.replace(
  468. /[\u4E00-\u9FA5]/g,
  469. '',
  470. );
  471. },
  472. // 记住密码
  473. rempass(val) {
  474. this.passvalue = val.value;
  475. if (val.value) {
  476. uni.setStorage({
  477. key: 'user_pass',
  478. data: this.formdata.passwold,
  479. success: function () {
  480. console.log('success');
  481. },
  482. });
  483. }
  484. },
  485. // 用户名失焦保存
  486. blur(val) {
  487. uni.setStorage({
  488. key: 'user_name',
  489. data: val,
  490. success: function () {
  491. console.log('success');
  492. },
  493. });
  494. },
  495. // 长按标题触发设置按钮显示
  496. logoTime() {
  497. this.setTF = true;
  498. },
  499. // 打开设置弹窗
  500. set() {
  501. this.setbgtf = true;
  502. },
  503. // 保存服务器地址设置
  504. sethttp() {
  505. uni.setStorage({
  506. key: 'http',
  507. data: this.value,
  508. success: () => {
  509. this.setbgtf = false;
  510. uni.showToast({
  511. title: '修改成功',
  512. icon: 'none',
  513. });
  514. this.getEquipList();
  515. uni.removeStorage({
  516. key: 'session_key',
  517. });
  518. },
  519. });
  520. },
  521. // 服务器地址下拉展开/收起
  522. arrow() {
  523. this.arrowtf = !this.arrowtf;
  524. },
  525. // 登录时处理记住密码
  526. denglu() {
  527. if (this.passvalue) {
  528. uni.setStorage({
  529. key: 'user_pass',
  530. data: this.formdata.passwold,
  531. success: function () {
  532. console.log('success');
  533. },
  534. });
  535. } else {
  536. uni.removeStorage({
  537. key: 'user_pass',
  538. success: function () {
  539. console.log('success');
  540. },
  541. });
  542. }
  543. },
  544. // 跳转用户隐私协议
  545. goAgreement() {
  546. uni.navigateTo({
  547. url: './agreement',
  548. });
  549. },
  550. },
  551. };
  552. </script>
  553. <style lang="scss" scoped>
  554. /* 页面整体容器 */
  555. .login-container {
  556. height: 100vh;
  557. width: 100%;
  558. background: linear-gradient(180deg, #d1f2e8 6.77%, #fff 28.02%);
  559. position: relative;
  560. overflow: hidden;
  561. box-sizing: border-box;
  562. }
  563. /* 顶部淡绿色渐变背景层 */
  564. .header-bg {
  565. position: absolute;
  566. top: 0;
  567. left: 0;
  568. width: 100%;
  569. height: 420rpx;
  570. z-index: 0;
  571. }
  572. /* Logo 区域 */
  573. .logo-section {
  574. position: relative;
  575. z-index: 1;
  576. display: flex;
  577. flex-direction: column;
  578. align-items: center;
  579. padding-top: 160rpx;
  580. }
  581. /* 绿色圆形 Logo */
  582. .logo-circle {
  583. width: 160rpx;
  584. height: 160rpx;
  585. display: flex;
  586. align-items: center;
  587. justify-content: center;
  588. margin-bottom: 32rpx;
  589. }
  590. /* Logo 内的真实图片 */
  591. .logo-img {
  592. width: 80%;
  593. height: 80%;
  594. }
  595. /* 应用标题 */
  596. .app-title {
  597. font-size: 40rpx;
  598. color: #333333;
  599. font-weight: 500;
  600. letter-spacing: 2rpx;
  601. }
  602. /* 设置按钮 */
  603. .set-btn {
  604. position: absolute;
  605. right: 40rpx;
  606. top: 80rpx;
  607. z-index: 10;
  608. }
  609. /* 登录表单(无卡片,直接平铺) */
  610. .form-card {
  611. position: relative;
  612. z-index: 1;
  613. width: 640rpx;
  614. margin: 72rpx auto 0;
  615. padding: 0 16rpx;
  616. }
  617. /* 表单输入项 */
  618. .form-item {
  619. display: flex;
  620. align-items: center;
  621. border-bottom: 1rpx solid #e5e5e5;
  622. padding: 28rpx 0;
  623. .form-input {
  624. flex: 1;
  625. margin-left: 20rpx;
  626. font-size: 28rpx;
  627. }
  628. ::v-deep .uni-input-input {
  629. color: #333333 !important;
  630. font-size: 28rpx !important;
  631. }
  632. ::v-deep .uicon-eye,
  633. ::v-deep .uicon-eye-off {
  634. color: #bbbbbb !important;
  635. }
  636. }
  637. /* 表单附加项:记住密码 */
  638. .form-extra {
  639. margin-top: 24rpx;
  640. display: flex;
  641. align-items: center;
  642. ::v-deep .u-checkbox__label {
  643. font-size: 26rpx;
  644. color: #666666;
  645. margin-left: 8rpx;
  646. }
  647. ::v-deep .u-checkbox__icon-wrap {
  648. border-color: #cccccc;
  649. }
  650. }
  651. /* 登录按钮 */
  652. .login-btn-wrap {
  653. margin-top: 48rpx;
  654. .login-btn {
  655. width: 100%;
  656. height: 96rpx;
  657. line-height: 96rpx;
  658. background: linear-gradient(135deg, #24b35d 0%, #1a9e4e 100%);
  659. border-radius: 48rpx;
  660. color: #ffffff;
  661. font-size: 32rpx;
  662. font-weight: 500;
  663. border: none;
  664. box-shadow: 0 8rpx 24rpx rgba(36, 179, 93, 0.3);
  665. &::after {
  666. border: none;
  667. }
  668. }
  669. }
  670. /* 用户隐私协议 */
  671. .agreement {
  672. margin-top: 28rpx;
  673. display: flex;
  674. align-items: center;
  675. justify-content: center;
  676. ::v-deep .u-checkbox__label {
  677. font-size: 22rpx;
  678. color: #999999;
  679. margin-left: 4rpx;
  680. }
  681. ::v-deep .u-checkbox__icon-wrap {
  682. border-color: #cccccc;
  683. }
  684. .agree-link {
  685. font-size: 22rpx;
  686. color: #24b35d;
  687. margin-left: 4rpx;
  688. }
  689. }
  690. /* 底部版本号 */
  691. .version-footer {
  692. position: absolute;
  693. bottom: 60rpx;
  694. left: 0;
  695. width: 100%;
  696. text-align: center;
  697. z-index: 1;
  698. .version-text {
  699. font-size: 24rpx;
  700. color: #bbbbbb;
  701. letter-spacing: 4rpx;
  702. }
  703. }
  704. /* 服务器设置弹窗 */
  705. .setbg {
  706. width: 100%;
  707. height: 100vh;
  708. position: absolute;
  709. top: 0;
  710. z-index: 99999;
  711. .mengban {
  712. width: 100%;
  713. height: 100vh;
  714. position: absolute;
  715. top: 0;
  716. background-color: rgba($color: #000000, $alpha: 0.5);
  717. }
  718. .set_http {
  719. position: absolute;
  720. width: 90%;
  721. left: 5%;
  722. top: 30%;
  723. .set_http_top {
  724. display: flex;
  725. justify-content: space-around;
  726. align-items: center;
  727. background-color: #24b35d;
  728. height: 100rpx;
  729. line-height: 100rpx;
  730. color: #ffffff;
  731. border-top-right-radius: 20rpx;
  732. border-top-left-radius: 20rpx;
  733. .set_title {
  734. font-size: 30rpx;
  735. }
  736. }
  737. .set_http_bot {
  738. background-color: #ffffff;
  739. border-bottom-right-radius: 20rpx;
  740. border-bottom-left-radius: 20rpx;
  741. padding: 30rpx;
  742. .set_label {
  743. font-size: 26rpx;
  744. color: #666666;
  745. }
  746. .set_http_bot_input {
  747. margin-top: 20rpx;
  748. border: 2rpx solid #eeeeee;
  749. border-radius: 12rpx;
  750. padding: 16rpx 24rpx;
  751. font-size: 28rpx;
  752. display: flex;
  753. justify-content: space-between;
  754. align-items: center;
  755. input {
  756. width: 90%;
  757. font-size: 28rpx;
  758. }
  759. }
  760. }
  761. .scroll-Y {
  762. border: 2rpx solid #eeeeee;
  763. border-radius: 12rpx;
  764. margin-top: 16rpx;
  765. .scroll-view-item {
  766. padding: 0 20rpx;
  767. height: 70rpx;
  768. font-size: 26rpx;
  769. line-height: 70rpx;
  770. border-bottom: 2rpx solid #f5f5f5;
  771. color: #333333;
  772. }
  773. }
  774. }
  775. }
  776. /* 升级进度框 */
  777. .upgradeBox {
  778. padding: 15rpx;
  779. }
  780. ::v-deep .u-flex {
  781. display: flex;
  782. align-items: center;
  783. }
  784. </style>