吉安感知网项目-前端
罗广辉
2026-02-12 67eead570d15378b8b5ae937f2265c6d4f3cbe6d
feat: app语音
7 files modified
121 ■■■■ changed files
uniapps/work-app/src/App.vue 20 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/api/user/index.js 1 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/hooks/useGlobalWS.js 7 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/manifest.json 8 ●●●●● patch | view | raw | blame | history
uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts 2 ●●●●● patch | view | raw | blame | history
uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts 75 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/utils/websocket.js 8 ●●●●● patch | view | raw | blame | history
uniapps/work-app/src/App.vue
@@ -28,6 +28,12 @@
// 假设五秒后来电
// #endif
// #ifdef APP-PLUS
//显示悬浮窗权限
allowFloat()
// #endif
useGlobalWS()
onShow(async () => {
@@ -50,14 +56,18 @@
    }
})
function setKeepFun() {
    // #ifdef APP-PLUS
    keepAliveStart()
    // 请求用户允许忽略电池优化(重要:用于保活)
    setTimeout(requestIgnoreBatteryOptimization, 120000)
    // #endif
}
onLaunch(() => {
    // 初始化系统信息
    appStore.initSystemInfo()
    // #ifdef APP-PLUS
    // keepAliveStart()
    // 请求用户允许忽略电池优化(重要:用于保活)
    // setTimeout(requestIgnoreBatteryOptimization, 2000)
    // #endif
    setKeepFun()
    if (!userStore.userInfo) {
        //不存在则跳转至登录页
        uni.reLaunch({
uniapps/work-app/src/api/user/index.js
@@ -44,6 +44,7 @@
      grant_type: 'password',
      scope: 'all',
      type,
            belongSystem: 'dilab-brain',
    },
  })
}
uniapps/work-app/src/hooks/useGlobalWS.js
@@ -17,12 +17,9 @@
    // 消息处理
  function messageHandler(payload) {
    // console.log('🌐 全局WebSocket收到消息111111111111111111111:', payload)
    // 先尝试直接处理消息(适用于mobile-web-view的voiceCallDetail页面的消息格式)
    const t = (payload.type || '').toString()
    // const bizCode = payload.biz_code || ''
    callStatus.value = t
    // console.log('📋 消息分析:type=' + t )
    // 处理语音通话请求
    if (t === 'call') {
      console.log('📞 全局收到来电 call,来自', payload.from)
@@ -82,16 +79,16 @@
    const userStore = useUserStore()
    accessToken.value =userStore?.userInfo.access_token
    try {
      websocketService.setOnMessageCallback(messageHandler);
      // 获取当前用户ID,优先使用store中的用户信息
      const userId = userStore.userInfo?.id || defaultUserId;
            console.log('🌐 全局WebSocket初始化开始,用户ID:', userId)
      // 检查是否已经有活跃的WebSocket连接
      if (!websocketService.getConnected() || websocketService.userId !== userId) {
        // 使用用户ID初始化WebSocket连接
        websocketService.init(userId, WS_BASE);
        websocketService.init(userId, WS_BASE, accessToken.value);
        // console.log('🌐 全局WebSocket初始化成功,用户ID:', userId);
      } else {
        websocketService.connect();
uniapps/work-app/src/manifest.json
@@ -2,8 +2,8 @@
    "name" : "吉安低空",
    "appid" : "__UNI__FFA6B4D",
    "description" : "",
    "versionName" : "1.0.1",
    "versionCode" : 101,
    "versionName" : "1.0.2",
    "versionCode" : 102,
    "transformPx" : false,
    /* 5+App特有相关 */
    "app-plus" : {
@@ -114,5 +114,7 @@
            "mode" : "hash",
            "base" : "/work-app/"
        }
    }
    },
    "locale" : "zh-Hans",
    "fallbackLocale" : "zh-Hans"
}
uniapps/work-app/src/uni_modules/keep-app/utssdk/app-android/index.uts
@@ -118,6 +118,8 @@
    const packageName = context.getPackageName()
    if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
      // 给个提示
      uni.showToast({  title: '请将应用添加到电池优化白名单'})
      try {
        const intent = new Intent()
        intent.setAction('android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS')
uniapps/work-app/src/uni_modules/lgh-dialog/utssdk/app-android/index.uts
@@ -3,7 +3,7 @@
import Intent from 'android.content.Intent'
import Settings from 'android.provider.Settings'
import { UTSAndroid } from 'io.dcloud.uts'
import BatteryManager from "android.os.BatteryManager";
import BatteryManager from 'android.os.BatteryManager'
// 拉起应用
export function openDialog(): void {
@@ -26,17 +26,58 @@
    const context = UTSAndroid.getAppContext()
    if (context == null) return
    // 1. 检查悬浮窗权限 (Android 6.0+)
    if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)) {
        try {
            // 无权限,跳转到权限设置页面
            const intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
    const noneFloat = Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)
    if (noneFloat) {
        uni.showToast({ title: '请允许应用悬浮在屏幕上', icon: 'none' })
    } else {
        setTimeout(() => {
            try {
                // 无权限,跳转到权限设置页面
                const intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
                intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                context.startActivity(intent)
            } catch (e) {
                console.error(e)
            }
        }, 2000)
    }
}
// 跳到后台弹出界面权限页面(应用详情设置)
export function allowBackgroundPopup() {
    const context = UTSAndroid.getAppContext()
    if (context == null) return
    try {
        const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(intent)
    } catch (e) {
        console.error(e)
    }
}
// 跳到锁屏显示权限页面(通知设置)
export function allowLockScreen() {
    const context = UTSAndroid.getAppContext()
    if (context == null) return
    try {
        if (Build.VERSION.SDK_INT >= 26) {
            // Android 8.0+ 跳转到应用通知设置
            const intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName())
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
        } else {
            // 低版本跳转到应用详情
            const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
            intent.setData(android.net.Uri.parse('package:' + context.getPackageName()))
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
        } catch (e) {
            console.error(e)
        }
        return
    } catch (e) {
        console.error(e)
    }
}
@@ -50,16 +91,12 @@
 */
export function getBatteryCapacity(): string {
    // 获取android系统 application上下文
    const context = UTSAndroid.getAppContext();
    if (context != null) {
        const manager = context.getSystemService(
            Context.BATTERY_SERVICE
        ) as BatteryManager;
        const currentLevel: number = manager.getIntProperty(
            BatteryManager.BATTERY_PROPERTY_CAPACITY
        );
        return '' + currentLevel + '%';
    }
    return "0%";
    const context = UTSAndroid.getAppContext()
    if (context != null) {
        const manager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
        const currentLevel: number = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
        return '' + currentLevel + '%'
    }
    return '0%'
}
uniapps/work-app/src/utils/websocket.js
@@ -5,6 +5,7 @@
    this.connected = false
    this.url = ''
    this.userId = ''
    this.token = ''
    this.onMessageCallback = null
    this.onOpenCallback = null
    this.onCloseCallback = null
@@ -13,14 +14,15 @@
  }
  // 初始化WebSocket连接
  init(userId, url) {
  init(userId, url, token) {
    if (!url) {
      console.error('WebSocket初始化失败:缺少url')
      return
    }
    this.userId = userId || ''
    this.url = url + encodeURIComponent(this.userId)
    this.token = token || ''
    this.url = url
    this.connect()
  }
@@ -29,10 +31,10 @@
    try {
      // 关闭现有连接
      this.close()
      // 使用uni-app的WebSocket API
      this.socketTask = uni.connectSocket({
        url: this.url,
                protocols: [this.token],
        success: () => {
          // console.log('WebSocket连接已请求')
        },