UNPKG

uni-packing-wgt

Version:

uniapp wgt多环境打包、调试、发布(七牛云)插件

436 lines (391 loc) 14.8 kB
/** * @author: HZWei * @date: 2024/5/22 * @desc: 公司定制需求,外部用不上 */ const {initConfig, configFilePath, configOutputFilePath, configReleaseFilePath, manifestPath} = require("./file-mgr") if (initConfig()) return; const configRelease = require(configReleaseFilePath) const config = require(configFilePath) const manifest = require(manifestPath) const enableServerLog = config.enableServerLog const uniAppId = manifest.appid const name = manifest.name const description = manifest.description const api = { baseUrl: configRelease.qiniu.baseUrl, login: configRelease.qiniu.api.login, cdn_cache_refresh: configRelease.qiniu.api.cdn_cache_refresh, refresh_history: configRelease.qiniu.api.refresh_history, token: configRelease.qiniu.token, username: configRelease.qiniu.account.username, password: configRelease.qiniu.account.password, configs: { key: configRelease.configs.key, token: configRelease.configs.token, devBaseUrl: configRelease.configs.devBaseUrl, betaBaseUrl: configRelease.configs.betaBaseUrl, releaseBaseUrl: configRelease.configs.releaseBaseUrl, devSign: "cpa4mqkuuf81l1qfgvqg", betaSign: "cpapae1jvotmrd3gcq30", releaseSign: "cpapaln18np8tarnts7g", commonConfig: "common/config", login: "user/login/code", baseUrlArray: [], username: configRelease.configs.account.username, password: configRelease.configs.account.password, android: configRelease.configs.updateAndroid, ios: configRelease.configs.updateIOS, ohos: configRelease.configs.updateOhos, updateDesc: configRelease.configs.updateDesc, dev: false, beta: false, release: false, enable: configRelease.configs.enable } } api.configs?.baseUrlArray.push(api.configs.devBaseUrl) api.configs?.baseUrlArray.push(api.configs.betaBaseUrl) api.configs?.baseUrlArray.push(api.configs.releaseBaseUrl) const fs = require("fs"); const axios = require('axios'); const os = require("os"); const {isEmptyMulti} = require("./utils"); axios.defaults.baseURL = api.baseUrl axios.interceptors.request.use((config) => { // console.log("enableServerLog: ",enableServerLog) if (enableServerLog) { console.log("") console.log("============ request ==============") console.log(`${config.baseURL}${config.url}`, config.method) console.log('data: ', config.data) console.log("") } if (config.baseURL === api.baseUrl) { if (config.url !== api.login) { config.headers["Authorization"] = `bearer ${api.token}` } } if (api.configs.baseUrlArray.includes(config.baseURL)) { if (api.configs.token) config.headers["token"] = `${api.configs.token}` config.headers["platform"] = "android" config.headers["apikey"] = "android" } return config }) axios.interceptors.response.use(async (response) => { const baseURL = response.config.baseURL if (enableServerLog) { console.log("============ response ==============") console.log(`${baseURL}${response.config.url}`, response.config.method, response.status) console.log('data: ', response.data) } switch (response.status) { case 200 : const code = response.data.code if (baseURL === api.baseUrl) { if (code === 200 && response.config.url === api.login) { api.token = response.data.data let data = fs.readFileSync(configReleaseFilePath, "utf-8") const json = JSON.parse(data) json.qiniu.token = api.token; data = JSON.stringify(json, null, 2); fs.writeFileSync(configReleaseFilePath, data, "utf-8"); return response.data?.data ?? {} } if (code === 401) { const max = 3 for (let i = 0; i < max; i++) { api.configs.token = await loginPlatform() if (api.configs.token) break } } } if (api.configs.baseUrlArray.includes(baseURL)) { if (code === 0) { if (response.config.url === api.configs.login) { api.configs.token = response.data.data.token let data = fs.readFileSync(configReleaseFilePath, "utf-8") const json = JSON.parse(data) json.configs.token = api.configs.token; data = JSON.stringify(json, null, 2); fs.writeFileSync(configReleaseFilePath, data, "utf-8"); } return response.data?.data ?? {} } } } return response.data?.data ?? null }, async (err) => { try { const config = err.response?.config const data = err.response?.data if (enableServerLog) { console.error("=========== response err ===========") console.error(`${config.baseURL}${config.url}`, config.method) console.error(data) } const max = 3 if (api.configs.baseUrlArray.includes(config.baseURL)) { if (data.code !== 0) { for (let i = 0; i < max; i++) { api.configs.token = await loginMall() if (api.configs.token) break } } } } catch (e) { } return null }) async function loginMall() { let baseUrl = api.configs.devBaseUrl let sign = api.configs.devSign if (api.configs.dev) { baseUrl = api.configs.devBaseUrl sign = api.configs.devSign } if (api.configs.beta) { baseUrl = api.configs.betaBaseUrl sign = api.configs.betaSign } if (api.configs.release) { baseUrl = api.configs.releaseBaseUrl sign = api.configs.releaseSign } let params = { phone: api.configs.username, code: api.configs.password, area_code: "+86", sign: sign, app_version: "1.0.0" } const data = await axios.post(api.configs.login, params, {baseURL: baseUrl}) return data.token } async function getYiConfig(params = { dev: false, beta: false, release: false }) { let baseUrl = initEnvironment(params) const key = api.configs.key const res = await axios.get(`${api.configs.commonConfig}?key=${key}`, {baseURL: baseUrl}) if (!res || !res.data) { console.log(`========== 检查后台是否有配置: ${key} ==========`) envInfo(baseUrl, params) return } // console.log('getYiConfig: ',res) let data = {} try { data = JSON.parse(res.data) ?? {} } catch (e) { console.error(`========== 检查后台配置异常: ${key} ==========`) console.error(e) } return data } function initEnvironment(params = { dev: false, beta: false, release: false }) { api.configs.dev = params.dev api.configs.beta = params.beta api.configs.release = params.release let baseUrl = api.configs.devBaseUrl if (params.dev) baseUrl = api.configs.devBaseUrl if (params.beta) baseUrl = api.configs.betaBaseUrl if (params.release) baseUrl = api.configs.releaseBaseUrl return baseUrl } function envInfo(baseUrl, params = { dev: false, beta: false, release: false }) { console.log(`key: ${api.configs.key}`) if (params.dev) console.error(`dev: ${params.dev}`) if (params.beta) console.error(`beta: ${params.beta}`) if (params.release) console.error(`release: ${params.release}`) console.error(`baseUrl: ${baseUrl}`) console.error(``) } async function updateConfig(params = { versionCode: 1, versionName: '1.0.0', url: '', dev: false, beta: false, release: false }) { try { let baseUrl = initEnvironment(params) const key = api.configs.key let data = await getYiConfig(params) // 查找对应的内容 插入新配置或替换 let version = params.versionName let code = params.versionCode let url = params.url if (!data || !data.uniModuleArray) { data = { uniModuleArray: [] } } let item = data?.uniModuleArray?.find((value) => value.appid === uniAppId) let os = require('os') let userName = os.userInfo().username || process.env.USER if (item) { // 修改 item.desc = description item.updateTime = new Date().toLocaleString() item.updateUser = userName const versionInfo = { version: version, code: Number.parseInt(code), updateDesc: api.configs.updateDesc, url: url } if (api.configs.android) { item.android = versionInfo } if (api.configs.ios) { item.ios = versionInfo } if (api.configs.ohos){ item.ohos = versionInfo } } else { // 新增 const newItem = { moduleName: name, appid: uniAppId, desc: description } newItem.android = { version: version, code: Number.parseInt(code), updateDesc: api.configs.updateDesc, url: url } newItem.ios = newItem.android newItem.ohos = newItem.android newItem.updateTime = new Date().toLocaleString() newItem.updateUser = userName data?.uniModuleArray?.push(newItem) } // 更新 const updateParam = { option_key: key, data: JSON.stringify(data, null, 2) } const max = 3 for (let i = 0; i < max; i++) { let updateRes = await axios.post(api.configs.commonConfig, updateParam, {baseURL: baseUrl}) if (updateRes) { console.log(`========== 后台配置同步完成 结果如下 ==========`) envInfo(baseUrl, params) console.log(JSON.stringify(data, null, 2)) break } else { console.error(`========== 后台配置同步失败 ==========`) } } taskMgr.notifyListener() } catch (e) { console.error(`========== 后台配置同步失败 ==========`) console.error(e) } } async function loginPlatform() { let username = atob(api.username) let password = atob(api.password) const loginParam = { username, password } return await axios.post(api.login, loginParam, {baseURL: api.baseUrl}) } async function refreshCdnCache(url) { console.log(`========== 缓存刷新中 ==========`) console.log('......') const refreshParam = { urls: url, dirs: "" } const max = 5 let success = false for (let i = 0; i < max; i++) { let res = await axios.post(api.cdn_cache_refresh, refreshParam, {baseURL: api.baseUrl}) if (res) { console.log(`========== 刷新结果 ==========`) console.log(res) console.log('') if (res.toString().includes(url)) { success = true break } else if (i < max) { console.log(`========== 尝试重刷中 ==========`) } } } if (config.enableRefreshHistory) { let res = await axios.get(`${api.refresh_history}?operator_type=qiniu_refresh`, {baseURL: api.baseUrl}) console.log(`========== 刷新历史记录 ==========`) console.log(res) console.log('') } return success } async function syncServer(params = { url: '', dev: false, beta: false, release: false }) { if (!config.refreshUrl) return if (!checkYiConfigExist()) { console.log("========== 检查配置是否正常 ==========") return } const manifest = require(manifestPath) params.versionName = manifest.versionName params.versionCode = manifest.versionCode // 刷新cdn const success = await refreshCdnCache(params.url) if (!success) { console.log("========== 缓存刷新失败,已终止后续流程 ==========") console.log('') return } // 更新配置 await updateConfig(params) } /** * 定制需求,外部不需要 * @returns {boolean} */ function checkYiConfigExist() { return api.configs.enable && !isEmptyMulti(api.baseUrl, api.username, api.password, api.configs.username, api.configs.password, api.configs.key) } async function getConfigVersionInfo() { // if (api.configs.android && api.configs.ios){ // throw new Error('为了确保版本的准确性,不支持android和ios两个平台同时更新') // } let params = {dev: config.runDev, beta: config.runBeta, release: config.runRelease} if ((params.dev && params.beta) || (params.dev && params.release) || (params.beta && params.release)) { throw new Error('不支持多环境(dev、beta、release)同时执行') } let data = await getYiConfig(params) let item = data?.uniModuleArray?.find((value) => value.appid === uniAppId) let versionInfo = {versionName: '', versionCode: 0} const appVersions = [] if (api.configs.android) { versionInfo.versionCode = item?.android?.code ?? 0 versionInfo.versionName = item?.android?.version ?? '' appVersions.push(versionInfo) console.log(`android config code: ${versionInfo.versionCode} name: ${versionInfo.versionName}`) } if (api.configs.ios) { versionInfo.versionCode = item?.ios?.code ?? 0 versionInfo.versionName = item?.ios?.version ?? '' appVersions.push(versionInfo) console.log(`ios config code: ${versionInfo.versionCode} name: ${versionInfo.versionName}`) } if (api.configs.ohos){ versionInfo.versionCode = item?.ohos?.code ?? 0 versionInfo.versionName = item?.ohos?.version ?? '' appVersions.push(versionInfo) console.log(`ohos config code: ${versionInfo.versionCode} name: ${versionInfo.versionName}`) } return appVersions } class TaskMgr { constructor() { this.listeners = [] } addListener(listener) { if (typeof listener === 'function') { this.listeners.push(listener) } else { throw new Error('callback must be a function') } } notifyListener(...args) { this.listeners.forEach(listener => listener(...args)) } } const taskMgr = new TaskMgr() module.exports = {syncServer, checkYiConfigExist, getConfigVersionInfo, taskMgr}