feature: 新增 `个人远程配置` 功能。 (#334)
							parent
							
								
									685aafe3be
								
							
						
					
					
						commit
						8bf5d42b9a
					
				| 
						 | 
				
			
			@ -18,12 +18,12 @@ const getDefaultConfigBasePath = function () {
 | 
			
		|||
  return get().server.setting.userBasePath
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _getRemoteSavePath (prefix = '') {
 | 
			
		||||
function _getRemoteSavePath (suffix = '') {
 | 
			
		||||
  const dir = getDefaultConfigBasePath()
 | 
			
		||||
  if (!fs.existsSync(dir)) {
 | 
			
		||||
    fs.mkdirSync(dir)
 | 
			
		||||
  }
 | 
			
		||||
  return path.join(dir, prefix + 'remote_config.json5')
 | 
			
		||||
  return path.join(dir, `remote_config${suffix}.json5`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _getConfigPath () {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,11 +51,27 @@ const configApi = {
 | 
			
		|||
    await download()
 | 
			
		||||
    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) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    const remoteConfigUrl = get().app.remoteConfig.url
 | 
			
		||||
    if (!remoteConfigUrl) {
 | 
			
		||||
      // 删除保存的远程配置文件
 | 
			
		||||
      configApi.deleteRemoteConfigFile(suffix)
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    // eslint-disable-next-line handle-callback-err
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
      log.info('开始下载远程配置:', remoteConfigUrl)
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +105,7 @@ const configApi = {
 | 
			
		|||
          }
 | 
			
		||||
 | 
			
		||||
          if (remoteConfig != null) {
 | 
			
		||||
            const remoteSavePath = _getRemoteSavePath()
 | 
			
		||||
            const remoteSavePath = _getRemoteSavePath(suffix)
 | 
			
		||||
            fs.writeFileSync(remoteSavePath, body)
 | 
			
		||||
            log.info('保存远程配置文件成功:', remoteSavePath)
 | 
			
		||||
          } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -111,31 +127,31 @@ const configApi = {
 | 
			
		|||
      })
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  readRemoteConfig () {
 | 
			
		||||
    if (get().app.remoteConfig.enabled !== true) {
 | 
			
		||||
      return {}
 | 
			
		||||
  deleteRemoteConfigFile (suffix = '') {
 | 
			
		||||
    const remoteSavePath = _getRemoteSavePath(suffix)
 | 
			
		||||
    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 (suffix === '_personal') {
 | 
			
		||||
        if (!get().app.remoteConfig.personalUrl) {
 | 
			
		||||
          return '{}'
 | 
			
		||||
        }
 | 
			
		||||
      } else if (suffix === '') {
 | 
			
		||||
        if (!get().app.remoteConfig.url) {
 | 
			
		||||
          return '{}'
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return '{}'
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
      const path = _getRemoteSavePath()
 | 
			
		||||
      const path = _getRemoteSavePath(suffix)
 | 
			
		||||
      if (fs.existsSync(path)) {
 | 
			
		||||
        const file = fs.readFileSync(path)
 | 
			
		||||
        log.info('读取远程配置文件内容成功:', path)
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +175,12 @@ const configApi = {
 | 
			
		|||
 | 
			
		||||
    // 如果开启了远程配置,则读取远程配置,合并到默认配置中
 | 
			
		||||
    if (get().app.remoteConfig.enabled === true) {
 | 
			
		||||
      defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig())
 | 
			
		||||
      if (get().app.remoteConfig.url) {
 | 
			
		||||
        defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig())
 | 
			
		||||
      }
 | 
			
		||||
      if (get().app.remoteConfig.personalUrl) {
 | 
			
		||||
        defConfig = mergeApi.doMerge(defConfig, configApi.readRemoteConfig('_personal'))
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 计算新配置与默认配置(启用远程配置时,含远程配置)的差异,并保存到 config.json 中
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +236,14 @@ const configApi = {
 | 
			
		|||
    const merged = newConfig != null ? lodash.cloneDeep(newConfig) : {}
 | 
			
		||||
 | 
			
		||||
    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) {
 | 
			
		||||
      mergeApi.doMerge(merged, newConfig) // 再合并一次用户配置,使用户配置重新生效
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,10 @@ module.exports = {
 | 
			
		|||
    },
 | 
			
		||||
    remoteConfig: {
 | 
			
		||||
      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=暗色
 | 
			
		||||
    autoChecked: true, // 是否自动检查更新
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,12 +30,16 @@
 | 
			
		|||
        </a-checkbox>
 | 
			
		||||
        <div class="form-help">
 | 
			
		||||
          应用启动时会向下面的地址请求配置补丁,获得最新的优化后的github访问体验。<br/>
 | 
			
		||||
          如果您觉得远程更新配置有安全风险,请关闭此功能。
 | 
			
		||||
          如果您觉得远程配置有安全风险,请关闭此功能,或删除共享远程配置,仅使用个人远程配置。<br/>
 | 
			
		||||
          配置优先级:本地修改配置  >  个人远程配置  >  共享远程配置
 | 
			
		||||
        </div>
 | 
			
		||||
      </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-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-button :disabled="config.app.remoteConfig.enabled === false" :loading="reloadLoading" icon="sync" @click="reloadRemoteConfig()">重载远程配置</a-button>
 | 
			
		||||
        <div class="form-help">
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +134,9 @@ export default {
 | 
			
		|||
      key: 'app',
 | 
			
		||||
      removeUserConfigLoading: false,
 | 
			
		||||
      reloadLoading: false,
 | 
			
		||||
      themeBackup: null
 | 
			
		||||
      themeBackup: null,
 | 
			
		||||
      urlBackup: null,
 | 
			
		||||
      personalUrlBackup: null
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created () {
 | 
			
		||||
| 
						 | 
				
			
			@ -141,15 +147,26 @@ export default {
 | 
			
		|||
  methods: {
 | 
			
		||||
    ready (config) {
 | 
			
		||||
      this.themeBackup = config.app.theme
 | 
			
		||||
      this.urlBackup = config.app.remoteConfig.url
 | 
			
		||||
      this.personalUrlBackup = config.app.remoteConfig.personalUrl
 | 
			
		||||
    },
 | 
			
		||||
    async openLog () {
 | 
			
		||||
      const dir = await this.$api.info.getConfigDir()
 | 
			
		||||
      this.$api.ipc.openPath(dir + '/logs/')
 | 
			
		||||
    },
 | 
			
		||||
    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) {
 | 
			
		||||
        window.location.reload()
 | 
			
		||||
        setTimeout(() => window.location.reload(), reloadLazy)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    async openExternal (url) {
 | 
			
		||||
| 
						 | 
				
			
			@ -174,15 +191,20 @@ export default {
 | 
			
		|||
      }
 | 
			
		||||
    },
 | 
			
		||||
    async reloadRemoteConfig () {
 | 
			
		||||
      if (this.config.app.remoteConfig.enabled === false) {
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      this.reloadLoading = true
 | 
			
		||||
 | 
			
		||||
      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.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.warn('如果您确实修改了远程配置,请稍等片刻再重试!')
 | 
			
		||||
      } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue