'use strict'; const platformAndroid = 'Android'; const platformIOS = 'iOS'; const platformHarmony = 'Harmony'; const packageApp = 'native_app'; const packageWgt = 'wgt'; const appVersionDbName = 'opendb-app-versions'; function errorResult(code, message) { return { code, message }; } function isNonEmptyString(value) { return typeof value === 'string' && value.trim().length > 0; } function isValidVersion(value) { return isNonEmptyString(value) && /^\d+(?:\.\d+)*$/.test(value.trim()); } function parseHttpEvent(event) { if (!event || typeof event !== 'object' || Array.isArray(event)) { return { error: errorResult(-102, '请求参数必须是对象') }; } if (!event.headers) return { data: event, isHttp: false }; const method = String(event.httpMethod || 'GET').toLowerCase(); let body; try { if (method === 'get') { body = event.queryStringParameters || {}; if (typeof body === 'string') body = JSON.parse(body || '{}'); } else if (event.body && typeof event.body === 'object') { body = event.body; } else { body = JSON.parse(event.body || '{}'); } } catch (e) { return { error: errorResult(-102, '请求参数格式错误') }; } if (!body || typeof body !== 'object' || Array.isArray(body)) { return { error: errorResult(-102, '请求参数必须是对象') }; } return { data: { ...event, ...body }, isHttp: true }; } function detectPlatform(event, context, isHttp) { if (isHttp) { const headers = typeof event.headers === 'string' ? event.headers : JSON.stringify(event.headers || {}); if (/iPhone|iPad/i.test(headers)) return platformIOS; if (/Android/i.test(headers)) return platformAndroid; if (/HarmonyOS|Harmony/i.test(headers)) return platformHarmony; } const os = context && typeof context.OS === 'string' ? context.OS.toLowerCase() : ''; if (os === 'ios') return platformIOS; if (os === 'harmonyos') return platformHarmony; return platformAndroid; } module.exports = async (event, context) => { const parsed = parseHttpEvent(event); if (parsed.error) return parsed.error; const request = parsed.data; const appid = request.appid; const appVersion = request.appVersion; const wgtVersion = request.wgtVersion; const isUniappX = request.is_uniapp_x === undefined ? false : request.is_uniapp_x; if (!isNonEmptyString(appid) || !isValidVersion(appVersion) || !isValidVersion(wgtVersion)) { return errorResult(-102, '请检查appid、appVersion、wgtVersion是否填写正确'); } if (isUniappX !== true && isUniappX !== false) { return errorResult(-102, 'is_uniapp_x必须是布尔值'); } const platform = detectPlatform(request, context, parsed.isHttp); try { const collection = uniCloud.database().collection(appVersionDbName); const record = await collection.where({ appid: appid.trim(), platform, stable_publish: true }).orderBy('create_date', 'desc').get(); if (!record || !Array.isArray(record.data) || record.data.length === 0) { return errorResult(-101, '暂无更新或检查appid是否填写正确'); } const appVersionInDb = record.data.find(item => item && item.type === packageApp) || {}; const wgtVersionInDb = record.data.find(item => item && item.type === packageWgt) || {}; const hasAppPackage = isValidVersion(appVersionInDb.version); const hasWgtPackage = isValidVersion(wgtVersionInDb.version); let stablePublishDb = {}; if (isUniappX === true && platform === platformAndroid) { if (hasAppPackage) stablePublishDb = appVersionInDb; } else if (hasAppPackage && hasWgtPackage) { stablePublishDb = compare(wgtVersionInDb.version, appVersionInDb.version) >= 0 ? wgtVersionInDb : appVersionInDb; } else if (hasAppPackage) { stablePublishDb = appVersionInDb; } else if (hasWgtPackage) { stablePublishDb = wgtVersionInDb; } if (Object.keys(stablePublishDb).length > 0) { const { version, min_uni_version: minUniVersion } = stablePublishDb; const appUpdate = compare(version, appVersion) === 1; const wgtUpdate = compare(version, wgtVersion) === 1; if (appUpdate && wgtUpdate) { if (isValidVersion(minUniVersion) && compare(minUniVersion, appVersion) < 1) { return { code: 101, message: 'wgt更新', ...stablePublishDb }; } if (hasAppPackage && compare(appVersionInDb.version, appVersion) === 1) { return { code: 102, message: '整包更新', ...appVersionInDb }; } } } return { code: 0, message: '当前版本已经是最新的,不需要更新' }; } catch (e) { console.error('[checkVersion]', e); return errorResult(-500, '检查版本失败'); } }; /** * 对比版本号。v1 > v2 返回 1,v1 < v2 返回 -1,版本相同返回 0。 */ function compare(v1 = '0', v2 = '0') { const left = String(v1).split('.').map(Number); const right = String(v2).split('.').map(Number); const length = Math.max(left.length, right.length); for (let i = 0; i < length; i++) { const leftPart = Number.isFinite(left[i]) ? left[i] : 0; const rightPart = Number.isFinite(right[i]) ? right[i] : 0; if (leftPart > rightPart) return 1; if (leftPart < rightPart) return -1; } return 0; } module.exports.compare = compare;