#2
whycq
2022-04-08 30b58aa4af12b82252451bca64c6daf30bdf7232
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
'use strict';
exports.main = async (event, context) => {
    /**
     * 检测升级 使用说明
     * 上传包:
     * 1. 根据传参,先检测传参是否完整,appid appVersion wgtVersion 必传
     * 2. 先从数据库取出所有该平台(从上下文读取平台信息,默认 Andriod)的所有线上发行更新
     * 3. 再从所有线上发行更新中取出版本最大的一版。如果可以,尽量先检测wgt的线上发行版更新
     * 4. 使用上步取出的版本包的版本号 和传参 appVersion、wgtVersion 来检测是否有更新,必须同时大于这两项,否则返回暂无更新
     * 5. 如果库中 wgt包 版本大于传参 appVersion,但是不满足 min_uni_version < appVersion,则不会使用wgt更新,会接着判断库中 app包version 是否大于 appVersion
     */
 
    let {
        appid,
        appVersion,
        wgtVersion,
    } = event;
 
    const platform_Android = 'Android';
    const platform_iOS = 'iOS';
    const package_app = 'native_app';
    const package_wgt = 'wgt';
    const app_version_db_name = 'opendb-app-versions'
 
    let platform = platform_Android;
 
    // 云函数URL化请求
    if (event.headers) {
        let body;
        try {
            if (event.httpMethod.toLocaleLowerCase() === 'get') {
                body = event.queryStringParameters;
            } else {
                body = JSON.parse(event.body);
            }
        } catch (e) {
            return {
                code: 500,
                msg: '请求错误'
            };
        }
 
        appid = body.appid;
        appVersion = body.appVersion;
        wgtVersion = body.wgtVersion;
 
        platform = /iPhone|iPad/.test(event.headers) ? platform_iOS : platform_Android;
    } else if (context.OS) {
        platform = context.OS === 'android'
            ? platform_Android
            : context.OS === 'ios'
                ? platform_iOS
                : platform_Android;
    }
 
    if (appid && appVersion && wgtVersion && platform) {
        const collection = uniCloud.database().collection(app_version_db_name);
 
        const record = await collection.where({
                appid,
                platform,
                stable_publish: true
            })
            .orderBy('create_date', 'desc')
            .get();
 
        if (record && record.data && record.data.length > 0) {
            const appVersionInDb = record.data.find(item => item.type === package_app) || {};
            const wgtVersionInDb = record.data.find(item => item.type === package_wgt) || {};
            const hasAppPackage = !!Object.keys(appVersionInDb).length;
            const hasWgtPackage = !!Object.keys(wgtVersionInDb).length;
 
            // 取两个版本中版本号最大的包,版本一样,使用wgt包
            let stablePublishDb = hasAppPackage
                ? hasWgtPackage
                    ? compare(wgtVersionInDb.version, appVersionInDb.version) >= 0
                        ? wgtVersionInDb
                        : appVersionInDb
                    : appVersionInDb
                : wgtVersionInDb;
 
            const {
                version,
                min_uni_version
            } = stablePublishDb;
 
            // 库中的version必须满足同时大于appVersion和wgtVersion才行,因为上次更新可能是wgt更新
            const appUpdate = compare(version, appVersion) === 1; // app包可用更新
            const wgtUpdate = compare(version, wgtVersion) === 1; // wgt包可用更新
 
            if (Object.keys(stablePublishDb).length && appUpdate && wgtUpdate) {
                // 判断是否可用wgt更新
                if (min_uni_version && compare(min_uni_version, appVersion) < 1) {
                    return {
                        code: 101,
                        message: 'wgt更新',
                        ...stablePublishDb
                    };
                } else if (hasAppPackage && compare(appVersionInDb.version, appVersion) === 1) {
                    return {
                        code: 102,
                        message: '整包更新',
                        ...appVersionInDb
                    };
                }
            }
 
            return {
                code: 0,
                message: '当前版本已经是最新的,不需要更新'
            };
        }
 
        return {
            code: -101,
            message: '暂无更新或检查appid是否填写正确'
        };
    }
 
    return {
        code: -102,
        message: '请检查传参是否填写正确'
    };
};
 
/**
 * 对比版本号,如需要,请自行修改判断规则
 * 支持比对    ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")    ("3.0.0.1", "3.0")    ("3.1.1", "3.1.1.1") 之类的
 * @param {Object} v1
 * @param {Object} v2
 * v1 > v2 return 1
 * v1 < v2 return -1
 * v1 == v2 return 0
 */
function compare(v1 = '0', v2 = '0') {
    v1 = String(v1).split('.')
    v2 = String(v2).split('.')
    const minVersionLens = Math.min(v1.length, v2.length);
 
    let result = 0;
    for (let i = 0; i < minVersionLens; i++) {
        const curV1 = Number(v1[i])
        const curV2 = Number(v2[i])
 
        if (curV1 > curV2) {
            result = 1
            break;
        } else if(curV1 < curV2) {
            result = -1
            break;
        }
    }
 
    if (result === 0 && (v1.length !== v2.length)) {
        const v1BiggerThenv2 = v1.length > v2.length;
        const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
        for (let i = minVersionLens; i < maxLensVersion.length; i++) {
            const curVersion = Number(maxLensVersion[i])
            if (curVersion > 0) {
                v1BiggerThenv2 ? result = 1 : result = -1
                break;
            }
        }
    }
 
    return result;
}