来瓶快乐水
来瓶快乐水
  • 发布:51 分钟前
  • 更新:39 分钟前
  • 阅读:26

三个uts插件,自定义基座正常,云打包失败

分类:uts

我存在三个uts插件,分别负责定位,自动打卡(需要携带认证信息进行发送请求),认证(提供认证信息)。其中自动打卡依赖定位与认证,在写死认证信息时,打包没问题,让他使用认证模块来进行获取认证信息时,云打包就出现了此异常:

Project with path ':uni_modules:luqiao-auth' could not be found in project ':uni_modules:luqiao-auto-sign'.

app.vue部分代码:

<script>  
    // #ifdef APP  
    import * as amapUtil from '@/utils/amapUtils.js'  
    // 强制引用 UTS,避免摇树剔除  
    import '@/services/utsPlugins.js'

utsPlugins.js部分代码:

/**  
 * 强制引用 UTS 插件,避免自定义基座/云打包摇树剔除。  
 */  
import { autoSignLog, autoSignLogError } from '@/services/commonSign/fileLog'  
import { API_BASE_URL, AMAP_ANDROID_LOCATION_KEY } from '@/config/env.js'  

export {  
  startHub,  
  stopHub,  
  getLastLocation,  
  getLastError,  
  isHubRunning,  
} from '@/uni_modules/luqiao-location'  

import {  
  updateAuth,  
  clearAuth,  
  refreshAuthIfNeeded,  
  getAuthSnapshotJson,  
} from '@/uni_modules/luqiao-auth'  

export {  
  updateAuth,  
  clearAuth,  
  refreshAuthIfNeeded,  
  getAuthSnapshotJson,  
}  

import {  
  startAutoSign,  
  stopAutoSign,  
  getSignResultsJson,  
  clearSignResults,  
  isAutoSignRunning,  
  configureAutoSign,  
} from '@/uni_modules/luqiao-auto-sign'  

export {  
  startAutoSign,  
  stopAutoSign,  
  clearSignResults,  
  isAutoSignRunning,  
  configureAutoSign,  
  getSignResultsJson,  
}  

/**  
 * JS 侧解析原生结果(UTS 内禁止 JSON.parse)  
 */  
export function getSignResults() {  
  try {  
    const raw =  
      typeof getSignResultsJson === 'function' ? getSignResultsJson() : '[]'  
    const list = JSON.parse(raw || '[]')  
    return Array.isArray(list) ? list : []  
  } catch (e) {  
    console.warn('[utsPlugins] getSignResults parse failed', e)  
    return []  
  }  
}  

function resolveDeviceType() {  
  let deviceType = '2'  
  try {  
    const platform = uni.getSystemInfoSync().platform  
    if (platform === 'ios') deviceType = '3'  
    else if (platform === 'android') deviceType = '2'  
  } catch (e) {  
    /* ignore */  
  }  
  return deviceType  
}  

/** 从本地 storage 下发鉴权到 luqiao-auth(登录 / bootstrap) */  
export function pushNativeSignAuth() {  
  try {  
    const authorization = uni.getStorageSync('Authorization') || ''  
    const payload = {  
      baseUrl: API_BASE_URL || '',  
      authorization,  
      refreshToken: uni.getStorageSync('RefreshToken') || '',  
      token: uni.getStorageSync('token') || authorization,  
      tenantId: '1',  
      deviceType: resolveDeviceType(),  
    }  
    updateAuth(payload)  
    autoSignLog('utsPlugins', 'updateAuth', {  
      baseUrl: payload.baseUrl,  
      hasAuthorization: !!payload.authorization,  
      hasRefreshToken: !!payload.refreshToken,  
      tenantId: payload.tenantId,  
      deviceType: payload.deviceType,  
    })  
  } catch (e) {  
    autoSignLogError('utsPlugins', 'pushNativeSignAuth failed', e)  
  }  
}  

/** 原生鉴权快照 → JS storage(后台 refresh 后回前台对齐) */  
export function pullNativeAuthToStorage() {  
  try {  
    if (typeof getAuthSnapshotJson !== 'function') return false  
    const raw = getAuthSnapshotJson()  
    const snap = JSON.parse(raw || '{}')  
    if (!snap || typeof snap !== 'object') return false  
    const jsAuth = uni.getStorageSync('Authorization') || ''  
    const jsRefresh = uni.getStorageSync('RefreshToken') || ''  
    const nativeUpdated = Number(snap.updatedAt) || 0  
    const shouldApply =  
      (snap.authorization && snap.authorization !== jsAuth) ||  
      (snap.refreshToken && snap.refreshToken !== jsRefresh) ||  
      (nativeUpdated > 0 && !jsAuth)  
    if (!shouldApply) return false  
    if (snap.authorization) {  
      uni.setStorageSync('Authorization', snap.authorization)  
    }  
    if (snap.refreshToken) {  
      uni.setStorageSync('RefreshToken', snap.refreshToken)  
    }  
    autoSignLog('utsPlugins', 'pullNativeAuthToStorage', {  
      updatedAt: snap.updatedAt,  
    })  
    return true  
  } catch (e) {  
    autoSignLogError('utsPlugins', 'pullNativeAuthToStorage failed', e)  
    return false  
  }  
}  

/**  
 * App 场景:委托 luqiao-auth 刷新 token,成功后写 storage。  
 * @returns {Promise<{ok:boolean, accessToken?:string, refreshToken?:string, message?:string}>}  
 */  
export function refreshAuthViaNative() {  
  return new Promise((resolve, reject) => {  
    try {  
      if (typeof refreshAuthIfNeeded !== 'function') {  
        reject(new Error('luqiao-auth unavailable'))  
        return  
      }  
      const raw = refreshAuthIfNeeded()  
      const result = JSON.parse(raw || '{}')  
      if (result && result.ok) {  
        if (result.accessToken) {  
          uni.setStorageSync('Authorization', result.accessToken)  
        }  
        if (result.refreshToken) {  
          uni.setStorageSync('RefreshToken', result.refreshToken)  
        }  
        autoSignLog('utsPlugins', 'refreshAuthViaNative ok', {  
          hasAccessToken: !!result.accessToken,  
        })  
        resolve(result)  
        return  
      }  
      const msg =  
        (result && result.message) || '刷新令牌失败'  
      autoSignLog('utsPlugins', 'refreshAuthViaNative fail', { message: msg })  
      reject(new Error(msg))  
    } catch (e) {  
      autoSignLogError('utsPlugins', 'refreshAuthViaNative', e)  
      reject(e)  
    }  
  })  
}  

/** 登出:清空原生鉴权 */  
export function clearNativeAuth() {  
  try {  
    clearAuth && clearAuth()  
    autoSignLog('utsPlugins', 'clearNativeAuth')  
  } catch (e) {  
    autoSignLogError('utsPlugins', 'clearNativeAuth failed', e)  
  }  
}  

/** 再导出,调用方仍可从本模块取;定义以 config/env.js 为准 */  
export { AMAP_ANDROID_LOCATION_KEY }  

const POST_NOTIFICATIONS = 'android.permission.POST_NOTIFICATIONS'  

/**  
 * Android 13+ 申请通知权限(结果签到通知依赖 NotificationManager.notify)。  
 */  
export function ensurePostNotificationsPermission() {  
  // #ifndef APP-PLUS  
  return Promise.resolve(true)  
  // #endif  
  // #ifdef APP-PLUS  
  return new Promise((resolve) => {  
    try {  
      if (typeof plus === 'undefined' || plus.os.name !== 'Android') {  
        autoSignLog('utsPlugins', 'POST_NOTIFICATIONS skip: not Android')  
        resolve(true)  
        return  
      }  
      const Build = plus.android.importClass('android.os.Build')  
      if (Build.VERSION.SDK_INT < 33) {  
        autoSignLog('utsPlugins', 'POST_NOTIFICATIONS skip: SDK<33')  
        resolve(true)  
        return  
      }  
      const main = plus.android.runtimeMainActivity()  
      const PackageManager = plus.android.importClass(  
        'android.content.pm.PackageManager'  
      )  
      if (  
        main.checkSelfPermission(POST_NOTIFICATIONS) ===  
        PackageManager.PERMISSION_GRANTED  
      ) {  
        autoSignLog('utsPlugins', 'POST_NOTIFICATIONS already granted')  
        resolve(true)  
        return  
      }  
      autoSignLog('utsPlugins', 'POST_NOTIFICATIONS requesting dialog')  
      plus.android.requestPermissions(  
        [POST_NOTIFICATIONS],  
        (e) => {  
          const denied = (e.deniedAlways || []).concat(e.deniedPresent || [])  
          const ok = !(denied && denied.length)  
          autoSignLog('utsPlugins', 'POST_NOTIFICATIONS result', {  
            granted: ok,  
            deniedAlways: e.deniedAlways || [],  
            deniedPresent: e.deniedPresent || [],  
          })  
          resolve(ok)  
        },  
        (err) => {  
          autoSignLogError('utsPlugins', 'POST_NOTIFICATIONS request failed', err)  
          resolve(false)  
        }  
      )  
    } catch (e) {  
      autoSignLogError('utsPlugins', 'ensurePostNotificationsPermission', e)  
      resolve(false)  
    }  
  })  
  // #endif  
}  
51 分钟前 负责人:无 分享
已邀请:
Ask小助手

Ask小助手

欢迎到专业群( uni-app x技术交流群 ) 咨询,群中有相关专业的管理员和群友。

出现该错误的原因是:luqiao-auto-sign 插件的 Android 原生构建配置(config.jsonbuild.gradle)中,直接使用了 Gradle 的 project(':uni_modules:luqiao-auth') 进行跨模块项目依赖。

在本地自定义基座编译与云打包环境下,Gradle 构建工程的模块组织结构和构建上下文不同。云打包系统在编译 UTS 插件时,各插件是作为独立模块或特定层级进行编译组装的,Gradle 无法通过 :uni_modules:luqiao-auth 这个工程路径找到对应的子模块,因此报出 Project with path ':uni_modules:luqiao-auth' could not be found in project ':uni_modules:luqiao-auto-sign'

此外,UTS 原生插件在设计上属于相互解耦的独立功能模块,不建议在 Android 原生层(Kotlin/Gradle project)强行跨插件直接依赖

建议按照以下步骤进行调整和解耦:


一、排查与修改步骤

  1. 移除插件内的 Gradle project 依赖
    打开 uni_modules/luqiao-auto-sign/utssdk/app-android/config.json(或同目录下的 build.gradle),检查 dependencies 节点:

    • 移除类似 "project(':uni_modules:luqiao-auth')""project(':luqiao-auth')" 的配置项。
  2. 移除原生层的直接跨插件引用
    检查 uni_modules/luqiao-auto-sign/utssdk/app-android/ 下的 .uts / .kt 源码:

    • 移除直接 import 认证插件内部包名/类名的代码。

二、推荐解决方案:在业务调度层(JS/UTS)进行解耦

将认证信息由业务层(如你已封装的 utsPlugins.js)统一调度和注入,让 luqiao-auto-sign 仅作为纯粹的任务执行者:

  1. 打卡插件提供配置/凭证注入接口
    luqiao-auto-sign 插件暴露配置方法(如你已有 configureAutoSign 或在 startAutoSign 参数中接收认证数据),原生层内部仅保存传入的 Token / 鉴权信息用于发起打卡请求,不主动调用鉴权模块。

  2. 在业务层统一串联调用
    services/utsPlugins.js 中,从 luqiao-auth 获取认证信息并同步给 luqiao-auto-sign

import { getAuthSnapshotJson } from '@/uni_modules/luqiao-auth'  
import { configureAutoSign, startAutoSign } from '@/uni_modules/luqiao-auto-sign'  

// 启动打卡或刷新凭据时,由业务层把 auth 数据注入给 auto-sign  
export function syncAuthToSignPlugin() {  
  const rawAuth = getAuthSnapshotJson()  
  const authData = JSON.parse(rawAuth || '{}')  

  // 将鉴权信息配置到打卡插件中  
  configureAutoSign({  
    baseUrl: authData.baseUrl || '',  
    token: authData.token || authData.authorization || '',  
    deviceType: authData.deviceType || '2'  
  })  
}

本助手使用国产模型,生成代码准确率较低。强烈建议使用uni-agent生成代码

这样三个插件在原生层完全独立,互不依赖,无论在自定义基座还是云打包中都能正常编译。


三、如果必须在原生层共享公共代码

若定位、认证、打卡确实在 Android 原生底层有大量公共逻辑/数据结构需要复用:

  • 将公共部分封装为独立的 Android 原生库(.aar 或发布到私有 Maven 仓储)。
  • 在各插件的 config.json 中通过 libs 目录或 dependencies 的 Maven 坐标引入,而不要使用本地 project(':xxx') 依赖。
内容为 AI 生成,仅供参考
DCloud_App_Array

DCloud_App_Array

请给出云端打包错误日志链接地址。

要回复问题请先登录注册