我存在三个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
}
2 个回复
Ask小助手
出现该错误的原因是:在
luqiao-auto-sign插件的 Android 原生构建配置(config.json或build.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)强行跨插件直接依赖。
建议按照以下步骤进行调整和解耦:
一、排查与修改步骤
移除插件内的 Gradle project 依赖
打开
uni_modules/luqiao-auto-sign/utssdk/app-android/config.json(或同目录下的build.gradle),检查dependencies节点:"project(':uni_modules:luqiao-auth')"或"project(':luqiao-auth')"的配置项。移除原生层的直接跨插件引用
检查
uni_modules/luqiao-auto-sign/utssdk/app-android/下的.uts/.kt源码:import认证插件内部包名/类名的代码。二、推荐解决方案:在业务调度层(JS/UTS)进行解耦
将认证信息由业务层(如你已封装的
utsPlugins.js)统一调度和注入,让luqiao-auto-sign仅作为纯粹的任务执行者:打卡插件提供配置/凭证注入接口
在
luqiao-auto-sign插件暴露配置方法(如你已有configureAutoSign或在startAutoSign参数中接收认证数据),原生层内部仅保存传入的 Token / 鉴权信息用于发起打卡请求,不主动调用鉴权模块。在业务层统一串联调用
在
services/utsPlugins.js中,从luqiao-auth获取认证信息并同步给luqiao-auto-sign:这样三个插件在原生层完全独立,互不依赖,无论在自定义基座还是云打包中都能正常编译。
三、如果必须在原生层共享公共代码
若定位、认证、打卡确实在 Android 原生底层有大量公共逻辑/数据结构需要复用:
.aar或发布到私有 Maven 仓储)。config.json中通过libs目录或dependencies的 Maven 坐标引入,而不要使用本地project(':xxx')依赖。DCloud_App_Array
请给出云端打包错误日志链接地址。
要回复问题请先登录或注册
公告
更多>相关问题