Bläddra i källkod

完成检查更新模块/代码优化

fanghuisheng 1 år sedan
förälder
incheckning
abcb958ef0

+ 21 - 0
src/api/system/setting.js

@@ -0,0 +1,21 @@
+import { request, uploads } from '@/utils/request';
+
+// 检测App是否有更新
+export function checkUpdates(data) {
+    return request({
+        baseUrl: "https://www.pgyer.com",
+        url: '/apiv2/app/check',
+        method: 'POST',
+        params: data
+    })
+}
+
+// 安装 App
+export function install(data) {
+    return request({
+        baseUrl: "https://www.pgyer.com",
+        url: '/apiv2/app/install',
+        method: 'GET',
+        params: data
+    })
+}

+ 114 - 0
src/components/oa-transForm/index.vue

@@ -0,0 +1,114 @@
+<template>
+  <view
+    class="content-section"
+    :style="[
+      {
+        transform: coverTransform,
+        transition: coverTransition,
+      },
+    ]"
+    @touchstart="coverTouchstart"
+    @touchmove="coverTouchmove"
+    @touchend="coverTouchend"
+  >
+    <image class="mine-image" src="@/static/images/mine/arc.png"></image>
+    <slot name="content"></slot>
+  </view>
+</template>
+<script setup>
+import { onReady, onLoad, onShow, onNavigationBarButtonTap, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
+import { ref, onMounted, inject, shallowRef, reactive, getCurrentInstance, watchEffect, toRefs } from "vue";
+
+const { proxy } = getCurrentInstance();
+
+const data = reactive({
+  coverTransform: "translateY(0px)",
+  coverTransition: "0s",
+  moving: false,
+});
+
+const { coverTransform, coverTransition, moving } = toRefs(data);
+
+let startY = 0,
+  moveY = 0,
+  pageAtTop = true;
+
+/**
+ * @触摸开始
+ */
+function coverTouchstart(e) {
+  if (pageAtTop === false) {
+    return;
+  }
+  coverTransition.value = "transform .1s linear";
+  startY = e.touches[0].clientY;
+}
+
+/**
+ * @触摸移动
+ */
+function coverTouchmove(e) {
+  moveY = e.touches[0].clientY;
+  let moveDistance = moveY - startY;
+  if (moveDistance < 0) {
+    moving.value = false;
+    return;
+  }
+  moving.value = true;
+  if (moveDistance >= 80 && moveDistance < 100) {
+    moveDistance = 80;
+  }
+  if (moveDistance > 0 && moveDistance <= 80) {
+    coverTransform.value = `translateY(${moveDistance}px)`;
+  }
+}
+
+/**
+ * @触摸结束
+ */
+function coverTouchend() {
+  if (moving.value === false) {
+    return;
+  }
+  moving.value = false;
+  coverTransition.value = "transform 0.3s cubic-bezier(.21,1.93,.53,.64)";
+  coverTransform.value = "translateY(0px)";
+}
+
+onLoad((option) => {});
+</script>
+<style lang="scss" scoped>
+.content-section {
+  position: relative;
+  margin-top: -85px;
+  padding-bottom: 50.67px;
+  background-color: #f5f6f7;
+
+  .mine-image {
+    position: absolute;
+    left: 0;
+    top: -16px;
+    width: 100%;
+    height: 36upx;
+  }
+
+  .mine-actions {
+    margin: 0.625rem 0.625rem;
+    padding: 20px 0px;
+    border-radius: 8px;
+    background-color: white;
+
+    .action-item {
+      .icon {
+        font-size: 28px;
+      }
+
+      .text {
+        display: block;
+        font-size: 13px;
+        margin: 8px 0px;
+      }
+    }
+  }
+}
+</style>

+ 294 - 0
src/components/oa-upgrade/index.vue

@@ -0,0 +1,294 @@
+<template>
+  <view class="upgrade-popup">
+    <image class="header-bg" src="@/static/images/common/oa-upgrade.png" mode="widthFix"></image>
+    <view
+      class="iconfont ucicon-oa-upgrade header-bg"
+      style="font-size: 110px; margin-top: -110px"
+      :style="{
+        color: themesColor,
+        fill: themesColor,
+      }"
+    ></view>
+
+    <view class="main">
+      <view
+        class="version"
+        :style="{
+          color: themesColor,
+        }"
+      >
+        发现新版本v{{ versionName }}
+      </view>
+      <view class="content">
+        <text class="desc">{{ versionDesc }}</text>
+      </view>
+      <!--下载状态-进度条显示 -->
+      <view class="footer" v-if="isStartDownload">
+        <view class="progress-view" :class="{ active: !hasProgress }" @click="handleInstallApp">
+          <!-- 进度条 -->
+          <view v-if="hasProgress" style="height: 100%">
+            <view class="txt">{{ percentText }}</view>
+            <view class="progress" :style="setProStyle"></view>
+          </view>
+          <view v-else>
+            <view class="btn upgrade force">{{ isDownloadFinish ? "立即安装" : "下载中..." }}</view>
+          </view>
+        </view>
+      </view>
+      <!-- 强制更新 -->
+      <view class="footer" v-else-if="isForceUpdate">
+        <view class="btn upgrade force" @click="handleUpgrade">立即更新</view>
+      </view>
+      <!-- 可选择更新 -->
+      <view class="footer" v-else>
+        <view class="btn close" @click="handleCancel">以后再说</view>
+        <view
+          class="btn upgrade"
+          :style="{
+            backgroundColor: themesColor,
+          }"
+          @click="handleUpgrade"
+        >
+          立即更新
+        </view>
+      </view>
+    </view>
+  </view>
+  <view class="upgrade-show"></view>
+</template>
+<script setup>
+import { onReady, onLoad, onShow, onNavigationBarButtonTap, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
+import { ref, onMounted, inject, shallowRef, reactive, getCurrentInstance, watchEffect, toRefs, computed } from "vue";
+
+import { downloadApp, installApp } from "@/utils/upgrade.js";
+
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  //弹窗数据
+  modalArray: {
+    type: Object,
+    default: {},
+  },
+  //主题颜色
+  themesColor: {
+    type: String,
+    default: "#3f99ff",
+  },
+});
+const emits = defineEmits(["closeModal"]);
+const { modalArra, themesColor } = toRefs(props);
+
+const checkInfo = reactive({
+  isForceUpdate: false, //是否强制更新
+  versionName: props.modalArray.buildVersion, //版本名称
+  versionDesc: props.modalArray.buildUpdateDescription.replace(/\\n/, "\n"), //更新说明
+  downloadUrl: props.modalArray.downloadURL, //APP下载链接
+  isDownloadFinish: false, //是否下载完成
+  hasProgress: false, //是否能显示进度条
+  currentPercent: 0, //当前下载百分比
+  isStartDownload: false, //是否开始下载
+  newFileName: "", //下载后app本地路径名称
+});
+
+const { modalTitle, modalContent, isForceUpdate, versionName, versionDesc, downloadUrl, isDownloadFinish, hasProgress, currentPercent, isStartDownload, newFileName } = toRefs(checkInfo);
+
+//设置进度条样式,实时更新进度位置
+const setProStyle = computed(() => {
+  return {
+    width: (510 * currentPercent.value) / 100 + "rpx", //510:按钮进度条宽度
+  };
+});
+
+//百分比文字
+const percentText = computed(() => {
+  let percent = currentPercent.value;
+  if (typeof percent !== "number" || isNaN(percent)) return "下载中...";
+  if (percent < 100) return `下载中${percent}%`;
+  return "立即安装";
+});
+
+//更新
+function handleUpgrade() {
+  if (downloadUrl.value) {
+    isStartDownload.value = true;
+    //开始下载App
+    downloadApp(downloadUrl.value, (current) => {
+      //下载进度监听
+      hasProgress.value = true;
+      currentPercent.value = current;
+    })
+      .then((fileName) => {
+        //下载完成
+        isDownloadFinish.value = true;
+        newFileName.value = fileName;
+        if (fileName) {
+          //自动安装App
+          handleInstallApp();
+        }
+      })
+      .catch((e) => {
+        console.log(e, "e");
+      });
+  } else {
+    uni.showToast({
+      title: "下载链接不存在",
+      icon: "none",
+    });
+  }
+}
+
+//安装app
+function handleInstallApp() {
+  //下载完成才能安装,防止下载过程中点击
+  if (isDownloadFinish.value && newFileName.value) {
+    installApp(newFileName.value, () => {
+      //安装成功,关闭升级弹窗
+      emits("closeModal", false);
+    });
+  }
+}
+
+/** 取消按钮 */
+function handleCancel() {
+  emits("closeModal", false);
+}
+
+onLoad((option) => {});
+</script>
+
+<style lang="scss" scoped>
+.upgrade-popup {
+  width: 580rpx;
+  height: auto;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  background: #fff;
+  border-radius: 20rpx;
+  box-sizing: border-box;
+  border: 1px solid #eee;
+  z-index: 1200;
+}
+
+.header-bg {
+  display: flex;
+  width: 230rpx;
+  margin: -112rpx auto 0 auto;
+}
+
+.main {
+  padding: 10rpx 30rpx 30rpx;
+  box-sizing: border-box;
+  .version {
+    font-size: 36rpx;
+    font-weight: 700;
+    width: 100%;
+    text-align: center;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    letter-spacing: 1px;
+  }
+
+  .content {
+    margin-top: 60rpx;
+    .desc {
+      display: block;
+      box-sizing: border-box;
+      margin-top: 20rpx;
+      font-size: 28rpx;
+      color: #6a6a6a;
+      max-height: 80vh;
+      overflow-y: auto;
+    }
+  }
+
+  .footer {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: relative;
+    flex-shrink: 0;
+    margin-top: 100rpx;
+
+    .btn {
+      width: 246rpx;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      position: relative;
+      z-index: 999;
+      height: 90rpx;
+      box-sizing: border-box;
+      font-size: 30rpx;
+      border-radius: 10rpx;
+      letter-spacing: 2rpx;
+
+      &.force {
+        width: 500rpx;
+      }
+
+      &.close {
+        border: 1px solid #e0e0e0;
+        margin-right: 25rpx;
+        color: #000;
+      }
+
+      &.upgrade {
+        color: white;
+      }
+    }
+
+    .progress-view {
+      width: 510rpx;
+      height: 90rpx;
+      display: flex;
+      position: relative;
+      align-items: center;
+      border-radius: 6rpx;
+      background-color: #dcdcdc;
+      display: flex;
+      justify-content: flex-start;
+      padding: 0px;
+      box-sizing: border-box;
+      border: none;
+      overflow: hidden;
+
+      &.active {
+        background-color: #026df7;
+      }
+
+      .progress {
+        height: 100%;
+        background-color: #026df7;
+        padding: 0px;
+        box-sizing: border-box;
+        border: none;
+        border-top-left-radius: 10rpx;
+        border-bottom-left-radius: 10rpx;
+      }
+
+      .txt {
+        font-size: 28rpx;
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        color: #fff;
+      }
+    }
+  }
+}
+
+.upgrade-show {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1110;
+  background: rgba(0, 0, 0, 0.6);
+}
+</style>

+ 1 - 1
src/config.js

@@ -5,7 +5,7 @@ export default {
   //#endif
 
   //#ifdef H5
-  baseUrl: import.meta.env.MODE === "production" ? "http://" + window.location.host + "/prod-api" : "http://172.16.120.165:13200/prod-api",
+  baseUrl: import.meta.env.MODE === "production" ? `http://${window.location.host}/prod-api` : `http://172.16.120.165:13200/dev-api`,
   //#endif
 
   websiteUrl: "https://qhome.usky.cn",

+ 4 - 1
src/main.js

@@ -21,6 +21,8 @@ import oaUpload from "@/components/oa-upload/index"
 import oaScroll from "@/components/oa-scroll/index"
 import oaTouch from "@/components/oa-touch/index"
 import oaDropdown from "@/components/oa-dropdown/index"
+import oaUpgrade from "@/components/oa-upgrade/index"
+import oaTransForm from "@/components/oa-transForm/index"
 
 export function createApp() {
   const app = createSSRApp(App);
@@ -34,7 +36,8 @@ export function createApp() {
   app.component('oa-scroll', oaScroll)
   app.component('oa-touch', oaTouch)
   app.component('oa-dropdown', oaDropdown)
-  
+  app.component('oa-upgrade', oaUpgrade)
+  app.component('oa-transForm', oaTransForm)
 
   // 挂载全局json导出
   app.component("downloadExcel", JsonExcel);

+ 9 - 6
src/manifest.json

@@ -2,8 +2,8 @@
     "name" : "综合智慧云",
     "appid" : "__UNI__36DE3A0",
     "description" : "综合智慧云app,助力企业数字化转型升级",
-    "versionName" : "2.1.0",
-    "versionCode" : 10,
+    "versionName" : "2.1.2",
+    "versionCode" : 11,
     "transformPx" : false,
     /* 5+App特有相关 */
     "app-plus" : {
@@ -55,25 +55,28 @@
                     "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                     "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>",
                     "<uses-permission android:name=\"android.permission.INTERNET\"/>",
                     "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
                     "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                     "<uses-permission android:name=\"android.permission.NFC\"/>",
                     "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
                     "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                     "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",
                     "<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
                     "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                     "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                     "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
                     "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
                     "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
-                    "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
-                    "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>"
+                    "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>"
                 ],
-                "minSdkVersion" : ""
+                "minSdkVersion" : "",
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
+                "targetSdkVersion" : 30
             },
             /* ios打包配置 */
             "ios" : {

+ 151 - 207
src/pages/mine.vue

@@ -20,128 +20,118 @@
       <view class="vip-card-box"> </view>
     </view>
 
-    <view
-      class="content-section"
-      :style="[
-        {
-          transform: coverTransform,
-          transition: coverTransition,
-        },
-      ]"
-      @touchstart="coverTouchstart"
-      @touchmove="coverTouchmove"
-      @touchend="coverTouchend"
-    >
-      <image class="mine-image" src="@/static/images/mine/arc.png"></image>
-
-      <view class="menu-list">
-        <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleToEditInfo()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-user menu-item-icon"></view>
-            <view>我的信息</view>
-          </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleToSecure()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-yanzheng menu-item-icon"></view>
-            <view>账号与安全</view>
-          </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleAbout()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-aixin menu-item-icon"></view>
-            <view>关于我们</view>
+    <oa-transForm>
+      <template #content>
+        <view class="menu-list">
+          <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleToEditInfo()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-user menu-item-icon"></view>
+              <view>我的信息</view>
+            </view>
           </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleHelp()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-Help menu-item-icon"></view>
-            <view>常见问题</view>
+          <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleToSecure()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-yanzheng menu-item-icon"></view>
+              <view>账号与安全</view>
+            </view>
           </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleCleanTmp()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-qinglihuancun menu-item-icon"></view>
-            <view>清理缓存</view>
-            <view style="margin: 0 15px 0 auto; font-size: 14px; color: #909399">{{ proxy.$settingStore.currentSize }}</view>
+          <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleAbout()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-aixin menu-item-icon"></view>
+              <view>关于我们</view>
+            </view>
           </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleToUpgrade()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-jianchagengxin menu-item-icon"></view>
-            <view>检查更新</view>
+          <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleHelp()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-Help menu-item-icon"></view>
+              <view>常见问题</view>
+            </view>
           </view>
-        </view>
-        <!-- <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleSetting()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-shezhi menu-item-icon"></view>
-            <view>设置</view>
+          <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleCleanTmp()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-qinglihuancun menu-item-icon"></view>
+              <view>清理缓存</view>
+              <view style="margin: 0 15px 0 auto; font-size: 14px; color: #909399">{{ proxy.$settingStore.currentSize }}</view>
+            </view>
           </view>
-        </view> -->
-      </view>
 
-      <!-- <view class="menu-list">
-        <view class="list-cell list-cell-arrow" @click="goMessagePush()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-aixin menu-item-icon"></view>
-            <view>推送设置</view>
+          <view class="list-cell list-cell-arrow" @click="handleToUpgrade">
+            <view class="menu-item">
+              <view class="iconfont ucicon-jianchagengxin menu-item-icon"></view>
+              <view>检查更新</view>
+            </view>
           </view>
+          <!-- <view class="list-cell list-cell-arrow" @click="proxy.$settingStore.handleSetting()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-shezhi menu-item-icon"></view>
+              <view>设置</view>
+            </view>
+          </view> -->
         </view>
-        <view class="list-cell list-cell-arrow" @click="goBuilding()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-aixin menu-item-icon"></view>
-            <view>建筑管理</view>
+
+        <!-- <view class="menu-list">
+          <view class="list-cell list-cell-arrow" @click="goMessagePush()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-aixin menu-item-icon"></view>
+              <view>推送设置</view>
+            </view>
           </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @click="goFunReport()">
-          <view class="menu-item">
-            <view class="iconfont ucicon-aixin menu-item-icon"></view>
-            <view>功能报备</view>
+          <view class="list-cell list-cell-arrow" @click="goBuilding()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-aixin menu-item-icon"></view>
+              <view>建筑管理</view>
+            </view>
           </view>
-        </view>
-      </view> -->
-
-      <view class="cu-list menu">
-        <view class="cu-item mt0">
-          <view class="content flex align-center">
-            <text class="iconfont ucicon-colorlens" :class="'text-' + themeColor.name"></text>
-            <view class="padding solid radius shadow-blur ml10" :class="'bg-' + themeColor.name"></view>
-            <view class="title ml10">
-              主题色:<text :class="'text-' + themeColor.name">{{ themeColor.title }}</text>
+          <view class="list-cell list-cell-arrow" @click="goFunReport()">
+            <view class="menu-item">
+              <view class="iconfont ucicon-aixin menu-item-icon"></view>
+              <view>功能报备</view>
             </view>
           </view>
-          <view class="action">
-            <button class="cu-btn round shadow" @click="colorModal = true" :class="'bg-' + themeColor.name">
-              <text class="iconfont ucicon-colorlens"></text>
-              选择主题
-            </button>
+        </view> -->
+
+        <view class="cu-list menu">
+          <view class="cu-item mt0">
+            <view class="content flex align-center">
+              <text class="iconfont ucicon-colorlens" :class="'text-' + themeColor.name"></text>
+              <view class="padding solid radius shadow-blur ml10" :class="'bg-' + themeColor.name"></view>
+              <view class="title ml10">
+                主题色:<text :class="'text-' + themeColor.name">{{ themeColor.title }}</text>
+              </view>
+            </view>
+            <view class="action">
+              <button class="cu-btn round shadow" @click="colorModal = true" :class="'bg-' + themeColor.name">
+                <text class="iconfont ucicon-colorlens"></text>
+                选择主题
+              </button>
+            </view>
           </view>
         </view>
-      </view>
 
-      <view class="menu-list" @click="proxy.$settingStore.handleLogout">
-        <view class="list-cell">
-          <view class="menu-item">
-            <view class="button">退 出 登 录</view>
+        <view class="menu-list" @click="proxy.$settingStore.handleLogout">
+          <view class="list-cell">
+            <view class="menu-item">
+              <view class="button">退 出 登 录</view>
+            </view>
           </view>
         </view>
-      </view>
 
-      <!-- <view class="menu-list">
-        <view class="list-cell list-cell-arrow" @tap="goSiteManage" v-if="permissionLabel == 1">
-          <view class="menu-item">
-            <image class="menu-item-image" src="@/static/images/setting/setting-icon2.png" style="width: 15px; height: 15px"></image>
-            <view>站点管理</view>
+        <!-- <view class="menu-list">
+          <view class="list-cell list-cell-arrow" @tap="goSiteManage" v-if="permissionLabel == 1">
+            <view class="menu-item">
+              <image class="menu-item-image" src="@/static/images/setting/setting-icon2.png" style="width: 15px; height: 15px"></image>
+              <view>站点管理</view>
+            </view>
           </view>
-        </view>
-        <view class="list-cell list-cell-arrow" @tap="goAuthManage" v-if="permissionLabel == 1">
-          <view class="menu-item">
-            <image class="menu-item-image" src="@/static/images/setting/setting-icon4.png" style="width: 15px; height: 15px"></image>
-            <view>权限管理</view>
+          <view class="list-cell list-cell-arrow" @tap="goAuthManage" v-if="permissionLabel == 1">
+            <view class="menu-item">
+              <image class="menu-item-image" src="@/static/images/setting/setting-icon4.png" style="width: 15px; height: 15px"></image>
+              <view>权限管理</view>
+            </view>
           </view>
-        </view>
-      </view> -->
-    </view>
+        </view> -->
+      </template>
+    </oa-transForm>
 
     <!-- 选择颜色模态框 -->
     <view class="cu-modal" :class="{ show: colorModal }">
@@ -162,6 +152,8 @@
         </view>
       </view>
     </view>
+
+    <oa-upgrade v-if="modalShow" :modalArray="modalArray" :themesColor="proxy.$settingStore.themeColor.color" @closeModal="closeModal" />
   </view>
 
   <oa-tabbar :tabbarValue="2"></oa-tabbar>
@@ -174,48 +166,80 @@ import { onLoad, onShow, onReady, onHide, onLaunch, onNavigationBarButtonTap, on
 import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
 import { useStores, commonStores } from "@/store/modules/index";
 
+import { checkUpdates } from "@/api/system/setting";
 import { uploadAvatar, updateUserProfile } from "@/api/system/user";
 import { getAuthorization } from "@/api/business/zhxf/messagePush/index.js";
 
 const useStore = useStores();
-
 const { proxy } = getCurrentInstance();
 
 const avatar = computed(() => {
   return useStore.$state.avatar;
 });
-
 const themeColor = computed(() => {
   return proxy.$settingStore.themeColor;
 });
 
-const windowHeight = computed(() => {
-  return uni.getSystemInfoSync().windowHeight - 50;
-});
-
 const data = reactive({
   nickName: useStore.$state.nickName,
   phone: useStore.$state.phonenumber,
   version: config.appInfo.version,
 
-  coverTransform: "translateY(0px)",
-  coverTransition: "0s",
-  moving: false,
-
   colorModal: false,
   themeList: proxy.$constData.themeList,
+
+  modalShow: false,
+  modalArray: {},
 });
 
-const { coverTransform, coverTransition, moving, colorModal, themeList } = toRefs(data);
+const { colorModal, themeList, modalShow, modalArray } = toRefs(data);
 
-const permissionLabel = ref(1);
+/**
+ * @检查更新
+ */
+function handleToUpgrade() {
+  proxy.$modal.loading("加载中");
+
+  let data = {
+    _api_key: "fba7440cd37400b6ff46e303896af4df",
+    appKey: "705a19c80c291a47067103824330eb66",
+    buildVersion: config.appInfo.version,
+    // buildVersion: "2.1.0",
+  };
+  checkUpdates(data).then((res) => {
+    if (res.code == 0) {
+      let platform = uni.getSystemInfoSync().platform; //手机平台
+
+      if (res.data.buildHaveNewVersion == true) {
+        //安卓手机弹窗升级
+        if (platform === "android") {
+          modalShow.value = true;
+          modalArray.value = res.data;
+        }
+        //IOS无法在线升级提示到商店下载
+        else {
+          uni.showModal({
+            title: "发现新版本 " + res.data.buildVersion,
+            content: "请到App store进行升级",
+            showCancel: false,
+          });
+        }
+      } else {
+        proxy.$modal.msg("您的软件版本已是最新");
+      }
 
-function getAuthorizationApi(params) {
-  getAuthorization(params).then((res) => {
-    permissionLabel.value = res.data.permissionLabel;
+      proxy.$modal.closeLoading();
+    }
   });
 }
 
+/**
+ * @关闭弹窗
+ */
+function closeModal(flag) {
+  modalShow.value = flag;
+}
+
 /**
  * @推送设置
  */
@@ -253,20 +277,6 @@ function handleToLogin() {
   proxy.$tab.reLaunch("/pages/login");
 }
 
-/**
- * @upload上传头像
- * @api接口请求
- */
-function uploadApi(res) {
-  let data = { name: "file", filePath: res.tempFilePaths[0] };
-  uploadAvatar(data).then((response) => {
-    useStore.$state.avatar = response.data.url;
-    updateUserProfile({
-      avatar: response.data.url,
-    }).then(() => {});
-  });
-}
-
 /**
  * @点击头像
  */
@@ -285,50 +295,18 @@ function handleToAvatar(type) {
   }
 }
 
-let startY = 0,
-  moveY = 0,
-  pageAtTop = true;
-
-/**
- * @触摸开始
- */
-function coverTouchstart(e) {
-  if (pageAtTop === false) {
-    return;
-  }
-  coverTransition.value = "transform .1s linear";
-  startY = e.touches[0].clientY;
-}
-
-/**
- * @触摸移动
- */
-function coverTouchmove(e) {
-  moveY = e.touches[0].clientY;
-  let moveDistance = moveY - startY;
-  if (moveDistance < 0) {
-    moving.value = false;
-    return;
-  }
-  moving.value = true;
-  if (moveDistance >= 80 && moveDistance < 100) {
-    moveDistance = 80;
-  }
-  if (moveDistance > 0 && moveDistance <= 80) {
-    coverTransform.value = `translateY(${moveDistance}px)`;
-  }
-}
-
 /**
- * @触摸结束
+ * @upload上传头像
+ * @api接口请求
  */
-function coverTouchend() {
-  if (moving.value === false) {
-    return;
-  }
-  moving.value = false;
-  coverTransition.value = "transform 0.3s cubic-bezier(.21,1.93,.53,.64)";
-  coverTransform.value = "translateY(0px)";
+function uploadApi(res) {
+  let data = { name: "file", filePath: res.tempFilePaths[0] };
+  uploadAvatar(data).then((response) => {
+    useStore.$state.avatar = response.data.url;
+    updateUserProfile({
+      avatar: response.data.url,
+    }).then(() => {});
+  });
 }
 
 onShow(() => {});
@@ -392,40 +370,6 @@ onNavigationBarButtonTap((e) => {
     }
   }
 
-  .content-section {
-    position: relative;
-    margin-top: -85px;
-    padding-bottom: 50.67px;
-    background-color: #f5f6f7;
-
-    .mine-image {
-      position: absolute;
-      left: 0;
-      top: -16px;
-      width: 100%;
-      height: 36upx;
-    }
-
-    .mine-actions {
-      margin: 0.625rem 0.625rem;
-      padding: 20px 0px;
-      border-radius: 8px;
-      background-color: white;
-
-      .action-item {
-        .icon {
-          font-size: 28px;
-        }
-
-        .text {
-          display: block;
-          font-size: 13px;
-          margin: 8px 0px;
-        }
-      }
-    }
-  }
-
   .cu-list.menu-avatar .cu-item {
     border-radius: 5px;
     padding: 30rpx 0;

+ 61 - 60
src/pages/mine/info/index.vue

@@ -21,7 +21,7 @@
         <view class="list-cell list-cell-arrow" @click="handleUserModal('修改手机号')">
           <view class="menu-item">
             <view class="title">手机号</view>
-            <view style="margin: 0 15px 0 auto; font-size: 14px; color: #909399">{{ user.phonenumber }}</view>
+            <view style="margin: 0 15px 0 auto; font-size: 14px; color: #909399">{{ user.phonenumber.substr(0, 3) + "******" + user.phonenumber.substr(9) }}</view>
           </view>
         </view>
         <view class="list-cell list-cell-arrow" @click="handleUserModal('修改邮箱')">
@@ -95,14 +95,19 @@
 
   <u-modal :show="modalShow" :showConfirmButton="true" :showCancelButton="true" @cancel="modalShow = false" @confirm="handleConfirm">
     <view class="slot-content" style="width: 100%">
-      <view class="mb15" style="color: #909399">{{ modalTitle }}</view>
+      <view class="mb15" style="text-align: center; color: #000; font-weight: 600">{{ modalTitle }}</view>
 
       <view v-if="modalTitle === '修改昵称'">
         <u--input v-model="userArr.nickName" :maxlength="5" :placeholder="modalTitle" border="bottom" clearable></u--input>
       </view>
 
       <view v-if="modalTitle === '修改手机号'">
-        <u--input type="number" v-model="userArr.phonenumber" :maxlength="11" :placeholder="modalTitle" border="bottom" clearable></u--input>
+        <u-input v-model="phone" placeholder="请输入手机号" :maxlength="11" border="bottom" />
+        <u-input v-model="verify" placeholder="请输入验证码" :maxlength="6" border="bottom">
+          <template #suffix>
+            <button class="verify" @click="getVerifyCode">{{ !useStore.codeTime ? "获取验证码" : useStore.codeTime + "s" }}</button>
+          </template>
+        </u-input>
       </view>
 
       <view v-if="modalTitle === '修改邮箱'">
@@ -128,61 +133,26 @@ import { useStores, commonStores } from "@/store/modules/index";
 import { updateUserProfile, getUserProfile } from "@/api/system/user";
 
 const useStore = useStores();
-
 const { proxy } = getCurrentInstance();
 
-const avatar = computed(() => {
-  return useStore.$state.avatar;
-});
-
-const user = computed(() => {
-  return useStore.$state.user;
-});
-
-const userArr = computed(() => {
-  return useStore.$state.userArr;
-});
-
-const postGroup = computed(() => {
-  return useStore.$state.postGroup;
-});
-
-const roleGroup = computed(() => {
-  return useStore.$state.roleGroup;
-});
-
 const data = reactive({
-  tabsList: [
-    {
-      name: "个人信息",
-    },
-    // {
-    //   name: "其它信息",
-    // },
-    {
-      name: "企业/团队",
-    },
-  ],
+  tabsList: [{ name: "个人信息" }, { name: "企业/团队" }],
   tabsCurrent: 0,
 
   sexs: [
-    {
-      text: "男",
-      value: "0",
-    },
-    {
-      text: "女",
-      value: "1",
-    },
+    { text: "男", value: "0" },
+    { text: "女", value: "1" },
   ],
 
   modalShow: false,
   modalTitle: "",
-});
 
-const { name, phone, tabsList, tabsCurrent, sexs, modalShow, modalTitle } = toRefs(data);
+  phone: undefined,
+  verify: undefined,
+});
 
-const form = ref(null);
+const { tabsList, tabsCurrent, sexs, modalShow, modalTitle, phone, verify } = toRefs(data);
+const { avatar, user, userArr, postGroup, roleGroup } = toRefs(useStore.$state);
 
 function handleUserModal(title) {
   modalShow.value = true;
@@ -195,18 +165,32 @@ function handleConfirm() {
       proxy.$modal.showToast("昵称不能为空");
       return;
     }
+
+    updateUserProfile(userArr.value).then((response) => {
+      proxy.$tab.reLaunch("/pages/mine");
+      useStore.getUser();
+    });
   }
 
   if (modalTitle.value == "修改手机号") {
-    if (!userArr.value.phonenumber) {
-      proxy.$modal.showToast("手机号不能为空");
-      return;
-    }
-
-    if (!/^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(userArr.value.phonenumber)) {
-      proxy.$modal.showToast("请输入正确的手机号");
-      return;
-    }
+    useStore.PhoneVerify({
+      data: {
+        phone: phone.value,
+        verify: verify.value,
+      },
+      success: (res) => {
+        userArr.value.phonenumber = phone.value;
+
+        updateUserProfile(userArr.value).then((response) => {
+          proxy.$modal.msgSuccess("修改成功");
+          proxy.$tab.reLaunch("/pages/mine");
+          useStore.getUser();
+        });
+      },
+      error: (res) => {
+        return false;
+      },
+    });
   }
 
   if (modalTitle.value == "修改邮箱") {
@@ -219,6 +203,11 @@ function handleConfirm() {
       proxy.$modal.showToast("请输入正确的邮箱地址");
       return;
     }
+
+    updateUserProfile(userArr.value).then((response) => {
+      proxy.$tab.reLaunch("/pages/mine");
+      useStore.getUser();
+    });
   }
 
   if (modalTitle.value == "修改性别") {
@@ -226,16 +215,27 @@ function handleConfirm() {
       proxy.$modal.showToast("请选择性别");
       return;
     }
+
+    updateUserProfile(userArr.value).then((response) => {
+      proxy.$tab.reLaunch("/pages/mine");
+      useStore.getUser();
+    });
   }
+}
 
-  updateUserProfile(userArr.value).then((response) => {
-    proxy.$tab.reLaunch("/pages/mine");
-    useStore.getUser();
+/**
+ * @点击发送验证码
+ */
+function getVerifyCode() {
+  verify.value = undefined;
+  useStore.GetCodeImg({
+    phone: phone.value,
+    success: (res) => {
+      proxy.$modal.msgSuccess("发送成功");
+    },
   });
 }
 
-function submit(ref) {}
-
 /**
  * @tabs点击事件
  */
@@ -248,6 +248,7 @@ onLoad((options) => {
 });
 
 onReady(() => {
+  // const form = ref(null);
   //   form.value.setRules(rules.value);
 });
 

+ 29 - 41
src/pages/mine/secure/index.vue

@@ -122,25 +122,8 @@ import { useStores, commonStores } from "@/store/modules/index";
 import { updateUserProfile, updateUserPwd } from "@/api/system/user";
 
 const useStore = useStores();
-
 const { proxy } = getCurrentInstance();
 
-const avatar = computed(() => {
-  return useStore.$state.avatar;
-});
-
-const user = computed(() => {
-  return useStore.$state.user;
-});
-
-const userArr = computed(() => {
-  return useStore.$state.userArr;
-});
-
-const phonenumber = computed(() => {
-  return user.value.phonenumber.substr(0, 3) + "******" + user.value.phonenumber.substr(9);
-});
-
 const data = reactive({
   modalShow: false,
   modalTitle: "",
@@ -157,6 +140,11 @@ const data = reactive({
 });
 
 const { modalShow, modalTitle, oldPassword, oldPasswordBool, newPassword, newPasswordBool, confirmPassword, confirmPasswordBool, phone, verify } = toRefs(data);
+const { avatar, user, userArr } = toRefs(useStore.$state);
+
+const phonenumber = computed(() => {
+  return user.value.phonenumber.substr(0, 3) + "******" + user.value.phonenumber.substr(9);
+});
 
 function handleUserModal(title) {
   modalShow.value = true;
@@ -165,6 +153,27 @@ function handleUserModal(title) {
 
 /** 确定按钮 */
 function handleConfirm() {
+  if (modalTitle.value == "修改手机号") {
+    useStore.PhoneVerify({
+      data: {
+        phone: phone.value,
+        verify: verify.value,
+      },
+      success: (res) => {
+        userArr.value.phonenumber = phone.value;
+
+        updateUserProfile(userArr.value).then((response) => {
+          proxy.$modal.msgSuccess("修改成功");
+          handleCancel(); //调用取消按钮
+          useStore.getUser();
+        });
+      },
+      error: (res) => {
+        return false;
+      },
+    });
+  }
+
   if (modalTitle.value == "修改密码") {
     if (!oldPassword.value) {
       proxy.$modal.showToast("旧密码不能为空");
@@ -190,34 +199,15 @@ function handleConfirm() {
       proxy.$modal.showToast("两次输入的密码不一致");
       return;
     }
-  }
-
-  if (modalTitle.value == "修改手机号") {
-    useStore.PhoneVerify({
-      data: {
-        phone: phone.value,
-        verify: verify.value,
-      },
-      success: (res) => {
-        userArr.value.phonenumber = phone.value;
 
-        updateUserProfile(userArr.value).then((response) => {
-          proxy.$modal.msgSuccess("修改成功");
-          handleCancel(); //调用取消按钮
-          useStore.getUser();
-        });
-      },
-      error: (res) => {
-        return false;
-      },
-    });
-  } else if (modalTitle.value == "修改密码") {
     updateUserPwd(oldPassword.value, newPassword.value).then((response) => {
       proxy.$modal.msgSuccess("修改成功");
       handleCancel(); //调用取消按钮
       useStore.getUser();
     });
-  } else if (modalTitle.value == "手机号验证") {
+  }
+
+  if (modalTitle.value == "手机号验证") {
     if (phone.value != user.value.phonenumber) {
       proxy.$modal.msg("请输入正确的手机号");
       return;
@@ -263,8 +253,6 @@ function handleCancel() {
 
   phone.value = undefined;
   verify.value = undefined;
-
-  modalShow.value = false;
 }
 
 /** 点击发送验证码 */

+ 7 - 3
src/static/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 3620854 */
-  src: url('https://at.alicdn.com/t/c/font_3620854_o6ushwiz9vl.woff2?t=1701161701250') format('woff2'),
-       url('https://at.alicdn.com/t/c/font_3620854_o6ushwiz9vl.woff?t=1701161701250') format('woff'),
-       url('https://at.alicdn.com/t/c/font_3620854_o6ushwiz9vl.ttf?t=1701161701250') format('truetype');
+  src: url('https://at.alicdn.com/t/c/font_3620854_qj0jv579lnl.woff2?t=1703828032966') format('woff2'),
+       url('https://at.alicdn.com/t/c/font_3620854_qj0jv579lnl.woff?t=1703828032966') format('woff'),
+       url('https://at.alicdn.com/t/c/font_3620854_qj0jv579lnl.ttf?t=1703828032966') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,10 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.ucicon-oa-upgrade:before {
+  content: "\e61b";
+}
+
 .ucicon-nfc:before {
   content: "\e61a";
 }

BIN
src/static/iconfont/iconfont.ttf


BIN
src/static/images/common/oa-upgrade.png


+ 0 - 7
src/store/modules/setting.js

@@ -118,13 +118,6 @@ const settingStore = defineStore("setting", {
             // #endif
         },
 
-        /**
-         * @检查更新
-         */
-        handleToUpgrade() {
-            modal.showToast("模块建设中~");
-        },
-
         /**
          * @账号与安全
          */

+ 10 - 0
src/utils/request.js

@@ -61,12 +61,22 @@ const request = (config) => {
   if (getToken() && !isToken) {
     config.header["Authorization"] = getToken();
   }
+
   // get请求映射params参数
   if (config.params) {
     let url = config.url + "?" + common.tansParams(config.params);
     url = url.slice(0, -1);
     config.url = url;
   }
+
+  // 外部接口get请求映射params参数
+  if (config.baseUrl) {
+    let url = config.url + "?" + common.tansParams(config.params);
+    url = url.slice(0, -1);
+    config.url = url;
+    config.baseUrl = config.baseUrl + url
+  }
+
   return new Promise((resolve, reject) => {
     uni
       .request({

+ 91 - 0
src/utils/upgrade.js

@@ -0,0 +1,91 @@
+
+/**
+ * @description H5+下载App
+ * @param downloadUrl:App下载链接
+ * @param progressCallBack:下载进度回调
+ */
+export const downloadApp = (downloadUrl, progressCallBack = () => { },) => {
+    return new Promise((resolve, reject) => {
+        //创建下载任务
+        const downloadTask = plus.downloader.createDownload(downloadUrl, {
+            method: "GET"
+        }, (task, status) => {
+            console.log(status, 'status')
+            if (status == 200) { //下载成功
+                resolve(task.filename)
+            } else {
+                reject('fail')
+                uni.showToast({
+                    title: '下载失败',
+                    duration: 1500,
+                    icon: "none"
+                });
+            }
+        })
+        //监听下载过程
+        downloadTask.addEventListener("statechanged", (task, status) => {
+            switch (task.state) {
+                case 1: // 开始  
+                    break;
+                case 2: //已连接到服务器  
+                    break;
+                case 3: // 已接收到数据  
+                    let hasProgress = task.totalSize && task.totalSize > 0 //是否能获取到App大小
+                    if (hasProgress) {
+                        let current = parseInt(100 * task.downloadedSize / task.totalSize); //获取下载进度百分比
+                        progressCallBack(current)
+                    }
+                    break;
+                case 4: // 下载完成       
+                    break;
+            }
+        });
+        //开始执行下载
+        downloadTask.start();
+    })
+
+
+}
+/**
+ * @description H5+安装APP
+ * @param fileName:app文件名
+ * @param callBack:安装成功回调
+ */
+export const installApp = (fileName, callBack = () => { }) => {
+    //注册广播监听app安装情况
+    onInstallListening(callBack);
+    //开始安装
+    plus.runtime.install(plus.io.convertLocalFileSystemURL(fileName), {}, () => {
+        //成功跳转到安装界面
+    }, function (error) {
+        uni.showToast({
+            title: '安装失败',
+            duration: 1500,
+            icon: "none"
+        });
+    })
+
+}
+/**
+ * @description 注册广播监听APP是否安装成功
+ * @param callBack:安装成功回调函数
+ */
+const onInstallListening = (callBack = () => { }) => {
+
+    let mainActivity = plus.android.runtimeMainActivity(); //获取activity
+    //生成广播接收器
+    let receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
+        onReceive: (context, intent) => { //接收广播回调  
+            plus.android.importClass(intent);
+            mainActivity.unregisterReceiver(receiver); //取消监听
+            callBack()
+        }
+    });
+    let IntentFilter = plus.android.importClass('android.content.IntentFilter');
+    let Intent = plus.android.importClass('android.content.Intent');
+    let filter = new IntentFilter();
+    filter.addAction(Intent.ACTION_PACKAGE_ADDED); //监听APP安装     
+    filter.addDataScheme("package");
+    mainActivity.registerReceiver(receiver, filter); //注册广播
+
+}

+ 2 - 3
vite.config.js

@@ -1,7 +1,7 @@
 import { defineConfig } from "vite";
 import path from "path";
 import uni from "@dcloudio/vite-plugin-uni";
-// https://vitejs.dev/config/
+
 export default defineConfig(({ mode, command }) => {
   return {
     base: "./", // 打包路径
@@ -21,8 +21,7 @@ export default defineConfig(({ mode, command }) => {
           //rewrite: (p) => p.replace(/^\/dev-api/, '')
         },
         "/prod-api": {
-          target: "http://mobile.usky.cn:8099",
-          // target: "http://172.16.120.165:13200",
+          target: "http://manager.usky.cn",
           ws: true,
           changeOrigin: true,
           pathRewrite: {