feature: 新增 `个人远程配置` 功能。 (#334)

pull/336/head
王良 2024-08-22 13:59:44 +08:00 committed by GitHub
parent 685aafe3be
commit 8bf5d42b9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 88 additions and 35 deletions

View File

@ -18,12 +18,12 @@ const getDefaultConfigBasePath = function () {
return get().server.setting.userBasePath return get().server.setting.userBasePath
} }
function _getRemoteSavePath (prefix = '') { function _getRemoteSavePath (suffix = '') {
const dir = getDefaultConfigBasePath() const dir = getDefaultConfigBasePath()
if (!fs.existsSync(dir)) { if (!fs.existsSync(dir)) {
fs.mkdirSync(dir) fs.mkdirSync(dir)
} }
return path.join(dir, prefix + 'remote_config.json5') return path.join(dir, `remote_config${suffix}.json5`)
} }
function _getConfigPath () { function _getConfigPath () {
@ -51,11 +51,27 @@ const configApi = {
await download() await download()
timer = setInterval(download, 24 * 60 * 60 * 1000) // 1天 timer = setInterval(download, 24 * 60 * 60 * 1000) // 1天
}, },
downloadRemoteConfig () { async downloadRemoteConfig () {
if (get().app.remoteConfig.enabled !== true) {
// 删除保存的远程配置文件
configApi.deleteRemoteConfigFile()
configApi.deleteRemoteConfigFile('_personal')
return
}
const remoteConfig = get().app.remoteConfig
await configApi.doDownloadCommonRemoteConfig(remoteConfig.url)
await configApi.doDownloadCommonRemoteConfig(remoteConfig.personalUrl, '_personal')
},
doDownloadCommonRemoteConfig (remoteConfigUrl, suffix = '') {
if (get().app.remoteConfig.enabled !== true) { if (get().app.remoteConfig.enabled !== true) {
return return
} }
const remoteConfigUrl = get().app.remoteConfig.url if (!remoteConfigUrl) {
// 删除保存的远程配置文件
configApi.deleteRemoteConfigFile(suffix)
return
}
// eslint-disable-next-line handle-callback-err // eslint-disable-next-line handle-callback-err
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
log.info('开始下载远程配置:', remoteConfigUrl) log.info('开始下载远程配置:', remoteConfigUrl)
@ -89,7 +105,7 @@ const configApi = {
} }
if (remoteConfig != null) { if (remoteConfig != null) {
const remoteSavePath = _getRemoteSavePath() const remoteSavePath = _getRemoteSavePath(suffix)
fs.writeFileSync(remoteSavePath, body) fs.writeFileSync(remoteSavePath, body)
log.info('保存远程配置文件成功:', remoteSavePath) log.info('保存远程配置文件成功:', remoteSavePath)
} else { } else {
@ -111,31 +127,31 @@ const configApi = {
}) })
}) })
}, },
readRemoteConfig () { deleteRemoteConfigFile (suffix = '') {
if (get().app.remoteConfig.enabled !== true) { const remoteSavePath = _getRemoteSavePath(suffix)
return {} if (fs.existsSync(remoteSavePath)) {
fs.unlinkSync(remoteSavePath)
log.info('删除远程配置文件成功:', remoteSavePath)
} }
const path = _getRemoteSavePath()
try {
if (fs.existsSync(path)) {
const file = fs.readFileSync(path)
log.info('读取远程配置文件成功:', path)
return jsonApi.parse(file.toString())
} else {
log.warn('远程配置文件不存在:', path)
}
} catch (e) {
log.error('读取远程配置文件失败:', path, ', error:', e)
}
return {}
}, },
readRemoteConfigStr () { readRemoteConfig (suffix = '') {
return jsonApi.parse(configApi.readRemoteConfigStr(suffix))
},
readRemoteConfigStr (suffix = '') {
if (get().app.remoteConfig.enabled !== true) { if (get().app.remoteConfig.enabled !== true) {
if (suffix === '_personal') {
if (!get().app.remoteConfig.personalUrl) {
return '{}'
}
} else if (suffix === '') {
if (!get().app.remoteConfig.url) {
return '{}'
}
}
return '{}' return '{}'
} }
try { try {
const path = _getRemoteSavePath() const path = _getRemoteSavePath(suffix)
if (fs.existsSync(path)) { if (fs.existsSync(path)) {
const file = fs.readFileSync(path) const file = fs.readFileSync(path)
log.info('读取远程配置文件内容成功:', path) log.info('读取远程配置文件内容成功:', path)
@ -159,8 +175,13 @@ const configApi = {
// 如果开启了远程配置,则读取远程配置,合并到默认配置中 // 如果开启了远程配置,则读取远程配置,合并到默认配置中
if (get().app.remoteConfig.enabled === true) { if (get().app.remoteConfig.enabled === true) {
if (get().app.remoteConfig.url) {
defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig()) defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig())
} }
if (get().app.remoteConfig.personalUrl) {
defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig('_personal'))
}
}
// 计算新配置与默认配置(启用远程配置时,含远程配置)的差异,并保存到 config.json 中 // 计算新配置与默认配置(启用远程配置时,含远程配置)的差异,并保存到 config.json 中
const diffConfig = mergeApi.doDiff(defConfig, newConfig) const diffConfig = mergeApi.doDiff(defConfig, newConfig)
@ -215,7 +236,14 @@ const configApi = {
const merged = newConfig != null ? lodash.cloneDeep(newConfig) : {} const merged = newConfig != null ? lodash.cloneDeep(newConfig) : {}
mergeApi.doMerge(merged, defConfig) // 合并默认配置 mergeApi.doMerge(merged, defConfig) // 合并默认配置
mergeApi.doMerge(merged, configApi.readRemoteConfig()) // 合并远程配置 if (get().app.remoteConfig.enabled === true) {
if (get().app.remoteConfig.url) {
mergeApi.doMerge(merged, configApi.readRemoteConfig()) // 合并共享远程配置
}
if (get().app.remoteConfig.personalUrl) {
mergeApi.doMerge(merged, configApi.readRemoteConfig('_personal')) // 合并个人远程配置
}
}
if (newConfig != null) { if (newConfig != null) {
mergeApi.doMerge(merged, newConfig) // 再合并一次用户配置,使用户配置重新生效 mergeApi.doMerge(merged, newConfig) // 再合并一次用户配置,使用户配置重新生效
} }

View File

@ -21,7 +21,10 @@ module.exports = {
}, },
remoteConfig: { remoteConfig: {
enabled: true, enabled: true,
url: 'https://gitee.com/wangliang181230/dev-sidecar/raw/docmirror/packages/core/src/config/remote_config.json5' // 共享远程配置地址
url: 'https://gitee.com/wangliang181230/dev-sidecar/raw/docmirror/packages/core/src/config/remote_config.json5',
// 个人远程配置地址
personalUrl: ''
}, },
theme: 'dark', // 主题light=亮色, dark=暗色 theme: 'dark', // 主题light=亮色, dark=暗色
autoChecked: true, // 是否自动检查更新 autoChecked: true, // 是否自动检查更新

View File

@ -30,12 +30,16 @@
</a-checkbox> </a-checkbox>
<div class="form-help"> <div class="form-help">
应用启动时会向下面的地址请求配置补丁获得最新的优化后的github访问体验<br/> 应用启动时会向下面的地址请求配置补丁获得最新的优化后的github访问体验<br/>
如果您觉得远程更新配置有安全风险请关闭此功能 如果您觉得远程配置有安全风险请关闭此功能或删除共享远程配置仅使用个人远程配置<br/>
配置优先级本地修改配置 > 个人远程配置 > 共享远程配置
</div> </div>
</a-form-item> </a-form-item>
<a-form-item label="远程配置地址" :label-col="labelCol" :wrapper-col="wrapperCol"> <a-form-item label="共享远程配置地址" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-input v-model="config.app.remoteConfig.url"></a-input> <a-input v-model="config.app.remoteConfig.url"></a-input>
</a-form-item> </a-form-item>
<a-form-item label="个人远程配置地址" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-input v-model="config.app.remoteConfig.personalUrl"></a-input>
</a-form-item>
<a-form-item label="重载远程配置" :label-col="labelCol" :wrapper-col="wrapperCol"> <a-form-item label="重载远程配置" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-button :disabled="config.app.remoteConfig.enabled === false" :loading="reloadLoading" icon="sync" @click="reloadRemoteConfig()"></a-button> <a-button :disabled="config.app.remoteConfig.enabled === false" :loading="reloadLoading" icon="sync" @click="reloadRemoteConfig()"></a-button>
<div class="form-help"> <div class="form-help">
@ -130,7 +134,9 @@ export default {
key: 'app', key: 'app',
removeUserConfigLoading: false, removeUserConfigLoading: false,
reloadLoading: false, reloadLoading: false,
themeBackup: null themeBackup: null,
urlBackup: null,
personalUrlBackup: null
} }
}, },
created () { created () {
@ -141,15 +147,26 @@ export default {
methods: { methods: {
ready (config) { ready (config) {
this.themeBackup = config.app.theme this.themeBackup = config.app.theme
this.urlBackup = config.app.remoteConfig.url
this.personalUrlBackup = config.app.remoteConfig.personalUrl
}, },
async openLog () { async openLog () {
const dir = await this.$api.info.getConfigDir() const dir = await this.$api.info.getConfigDir()
this.$api.ipc.openPath(dir + '/logs/') this.$api.ipc.openPath(dir + '/logs/')
}, },
async applyAfter () { async applyAfter () {
// let reloadLazy = 10
//
if (this.config.app.remoteConfig.url !== this.urlBackup || this.config.app.remoteConfig.personalUrl !== this.personalUrlBackup) {
await this.$api.config.downloadRemoteConfig()
await this.reloadConfigAndRestart()
reloadLazy = 300
}
//
if (this.config.app.theme !== this.themeBackup) { if (this.config.app.theme !== this.themeBackup) {
window.location.reload() setTimeout(() => window.location.reload(), reloadLazy)
} }
}, },
async openExternal (url) { async openExternal (url) {
@ -174,15 +191,20 @@ export default {
} }
}, },
async reloadRemoteConfig () { async reloadRemoteConfig () {
if (this.config.app.remoteConfig.enabled === false) {
return
}
this.reloadLoading = true this.reloadLoading = true
const remoteConfig = {} const remoteConfig = {}
await this.$api.config.readRemoteConfigStr().then((ret) => { remoteConfig.old = ret }) await this.$api.config.readRemoteConfigStr().then((ret) => { remoteConfig.old1 = ret })
await this.$api.config.readRemoteConfigStr('_personal').then((ret) => { remoteConfig.old2 = ret })
await this.$api.config.downloadRemoteConfig() await this.$api.config.downloadRemoteConfig()
await this.$api.config.readRemoteConfigStr().then((ret) => { remoteConfig.new = ret }) await this.$api.config.readRemoteConfigStr().then((ret) => { remoteConfig.new1 = ret })
await this.$api.config.readRemoteConfigStr('_personal').then((ret) => { remoteConfig.new2 = ret })
if (remoteConfig.old === remoteConfig.new) { if (remoteConfig.old1 === remoteConfig.new1 && remoteConfig.old2 === remoteConfig.new2) {
this.$message.info('远程配置没有变化,不做任何处理。') this.$message.info('远程配置没有变化,不做任何处理。')
this.$message.warn('如果您确实修改了远程配置,请稍等片刻再重试!') this.$message.warn('如果您确实修改了远程配置,请稍等片刻再重试!')
} else { } else {