diff --git a/webfe/package_vue/src/language/lang/en.js b/webfe/package_vue/src/language/lang/en.js index eb73170c77..2b65f88a2c 100644 --- a/webfe/package_vue/src/language/lang/en.js +++ b/webfe/package_vue/src/language/lang/en.js @@ -2595,4 +2595,5 @@ export default { '增强服务实例已分配,不能再修改配置信息': 'The enhanced service instance has been allocated and configuration information cannot be modified anymore.', 新建测试版本: 'Create Test Version', 提交并开始测试: 'Submit and Start Testing', + '环境变量不生效,KEY 与{s}增强服务的内置环境变量冲突': 'Environmental variables do not take effect, KEY conflicts with the built-in environmental variables of the {s} enhanced service', }; diff --git a/webfe/package_vue/src/language/lang/zh.js b/webfe/package_vue/src/language/lang/zh.js index 2adeb8eb83..6af9c25494 100644 --- a/webfe/package_vue/src/language/lang/zh.js +++ b/webfe/package_vue/src/language/lang/zh.js @@ -2735,4 +2735,5 @@ export default { '增强服务实例已分配,不能再修改配置信息': '增强服务实例已分配,不能再修改配置信息', 新建测试版本: '新建测试版本', 提交并开始测试: '提交并开始测试', + '环境变量不生效,KEY 与{s}增强服务的内置环境变量冲突': '环境变量不生效,KEY 与{s}增强服务的内置环境变量冲突', }; diff --git a/webfe/package_vue/src/store/modules/var.js b/webfe/package_vue/src/store/modules/var.js index c51c42a076..0586e55199 100644 --- a/webfe/package_vue/src/store/modules/var.js +++ b/webfe/package_vue/src/store/modules/var.js @@ -28,67 +28,66 @@ export default { mutations: {}, actions: { /** - * 获取所有运行时基础镜像 - */ - getAllImages({ }, { appCode, moduleId }) { + * 获取所有运行时基础镜像 + */ + getAllImages({}, { appCode, moduleId }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/runtime/list/`; return http.get(url); }, /** - * 获取运行时基础信息 - */ - getRuntimeInfo({ }, { appCode, moduleId }) { + * 获取运行时基础信息 + */ + getRuntimeInfo({}, { appCode, moduleId }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/runtime/`; return http.get(url); }, /** - * 保存运行时基础信息 - */ - updateRuntimeInfo({ }, { appCode, moduleId, data }) { + * 保存运行时基础信息 + */ + updateRuntimeInfo({}, { appCode, moduleId, data }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/runtime/`; return http.post(url, data); }, /** - * 从模块导入环境变量 - * @param {Object} params 包括appCode, moduleId, sourceModuleName - */ - exportModuleEnv({ }, { appCode, moduleId, sourceModuleName }) { + * 从模块导入环境变量 + * @param {Object} params 包括appCode, moduleId, sourceModuleName + */ + exportModuleEnv({}, { appCode, moduleId, sourceModuleName }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/config_vars/clone_from/${sourceModuleName}`; return http.post(url, {}); }, /** - * 应用基本信息 - */ - getBasicInfo({ }, { appCode }) { + * 应用基本信息 + */ + getBasicInfo({}, { appCode }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/config_vars/builtin/app/`; return http.get(url); }, /** - * 应用运行时信息 - */ - getBkPlatformInfo({ }, { appCode }) { + * 应用运行时信息 + */ + getBkPlatformInfo({}, { appCode }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/config_vars/builtin/bk_platform/`; return http.get(url); }, /** - * 蓝鲸体系内平台信息 - */ - getAppRuntimeInfo({ }, { appCode }) { + * 蓝鲸体系内平台信息 + */ + getAppRuntimeInfo({}, { appCode }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/config_vars/builtin/runtime/`; return http.get(url); }, - /** * 保存环境变量数据 */ - saveEnvItem({ }, { appCode, moduleId, data }) { + saveEnvItem({}, { appCode, moduleId, data }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/config_vars/batch/`; return http.post(url, data); }, @@ -96,7 +95,7 @@ export default { /** * 新增单个环境变量 */ - createdEnvVariable({ }, { appCode, moduleId, data }) { + createdEnvVariable({}, { appCode, moduleId, data }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/config_vars/`; return http.post(url, data); }, @@ -104,7 +103,7 @@ export default { /** * 修改单个环境变量 */ - updateEnvVariable({ }, { appCode, moduleId, varId, data }) { + updateEnvVariable({}, { appCode, moduleId, varId, data }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/config_vars/${varId}/`; return http.put(url, data); }, @@ -112,9 +111,17 @@ export default { /** * 删除单个环境变量 */ - deleteEnvVariable({ }, { appCode, moduleId, varId }) { + deleteEnvVariable({}, { appCode, moduleId, varId }) { const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/config_vars/${varId}/`; return http.delete(url, {}); }, + + /** + * 获取增强服务内置环境变量 + */ + getConfigVarKeys({}, { appCode, moduleId }) { + const url = `${BACKEND_URL}/api/bkapps/applications/${appCode}/modules/${moduleId}/services/config_var_keys/`; + return http.get(url, {}); + }, }, }; diff --git a/webfe/package_vue/src/views/dev-center/app/basic-config/module-manage.vue b/webfe/package_vue/src/views/dev-center/app/basic-config/module-manage.vue index 452e9c509f..630427c00a 100644 --- a/webfe/package_vue/src/views/dev-center/app/basic-config/module-manage.vue +++ b/webfe/package_vue/src/views/dev-center/app/basic-config/module-manage.vue @@ -983,17 +983,17 @@ export default { watch: { appInfo() { // 云原生应用无需请求模块接口 - if (this.curAppModule.repo && this.curAppModule.repo.type) { + if (!this.isCloudNativeApp) { this.init(); } }, '$route'() { this.resetParams(); - if (this.curAppModule.repo && this.curAppModule.repo.type) { + if (!this.isCloudNativeApp) { this.init(); } }, - 'curAppModule.name'(val) { + 'curAppModule.name'() { this.getLessCode(); }, 'curAppModule.repo'(repo) { diff --git a/webfe/package_vue/src/views/dev-center/app/engine/cloud-deploy-manage/comps/deploy-dialog.vue b/webfe/package_vue/src/views/dev-center/app/engine/cloud-deploy-manage/comps/deploy-dialog.vue index caf1722c55..50fd7b2713 100644 --- a/webfe/package_vue/src/views/dev-center/app/engine/cloud-deploy-manage/comps/deploy-dialog.vue +++ b/webfe/package_vue/src/views/dev-center/app/engine/cloud-deploy-manage/comps/deploy-dialog.vue @@ -757,6 +757,10 @@ export default { this.isLoading = false; } }, + // 排序 + sortingRules(a, b) { + return new Date(b.last_update).getTime() - new Date(a.last_update).getTime(); + }, async getModuleBranches(favBranchName) { this.isBranchesLoading = true; this.branchErrorTips = ''; @@ -771,10 +775,14 @@ export default { moduleId: this.curModuleId, }); + // last_update有值,根据时间排序 + if (res.results[0]?.last_update) { + res.results.sort(this.sortingRules); + } + // Smart 应用(预发布/生产)显示最新分支 if (this.isSmartApp) { - const sortList = res.results.sort(this.sortData); - this.branchValue = `${sortList[0].type}:${sortList[0].name}`; + this.branchValue = res.results.length ? `${res.results[0]?.type}:${res.results[0]?.name}` : ''; } this.branchesData = res.results; const branchesList = []; diff --git a/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/app-services.vue b/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/app-services.vue index 07f8924392..2ae83f7db3 100644 --- a/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/app-services.vue +++ b/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/app-services.vue @@ -332,7 +332,7 @@ export default { theme: 'light', content: '#switcher-tooltip', placement: 'bottom', - extCls: 'tips-cls', + extCls: 'services-tips-cls', }, startData: [{ value: 'start', label: this.$t('直接启用') }, { value: 'shared', label: this.$t('从其他模块共享') }], isShowDialog: false, @@ -796,7 +796,6 @@ export default { } } #switcher-tooltip{ - padding: 4px 0px; border: 1px solid #DCDEE5; border-radius: 2px; .item{ @@ -809,16 +808,23 @@ export default { &:hover { background: #F5F7FA; } + &:first-child { + margin-top: 4px; + } + &:last-child { + margin-bottom: 4px; + } } } </style> <style lang="scss"> - .tips-cls{ + .services-tips-cls{ .tippy-arrow{ display: none !important; } - .tippy-tooltip{ + .tippy-tooltip, + .tippy-content{ padding: 0 !important; } } diff --git a/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/deploy-env.vue b/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/deploy-env.vue index 9bb9da2ca1..490f18cb4a 100644 --- a/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/deploy-env.vue +++ b/webfe/package_vue/src/views/dev-center/app/engine/cloud-deployment/deploy-env.vue @@ -117,32 +117,44 @@ prop="key" > <template slot-scope="{ row, $index }"> - <div - v-if="isPageEdit || row.isEdit" - class="table-colum-cls" - > - <bk-form - :label-width="0" - form-type="inline" - :ref="`envRefKey${$index}`" - class="env-from-cls" - :model="row" + <div class="var-key-wrapper"> + <div + v-if="isPageEdit || row.isEdit" + class="table-colum-cls" > - <bk-form-item - :required="true" - :property="'key'" - :rules="rules.key" + <bk-form + :label-width="0" + form-type="inline" + :ref="`envRefKey${$index}`" + class="env-from-cls" + :model="row" > - <bk-input - v-model="row.key" - class="env-input-cls" - @enter="handleInputEvent(row, $index)" - @blur="handleInputEvent(row, $index)" - ></bk-input> - </bk-form-item> - </bk-form> + <bk-form-item + :required="true" + :property="'key'" + :rules="rules.key" + > + <bk-input + v-model="row.key" + class="env-input-cls" + @enter="handleInputEvent(row, $index)" + @blur="handleInputEvent(row, $index)" + ></bk-input> + </bk-form-item> + </bk-form> + </div> + <template v-else> + <div>{{ row.key }}</div> + <i + v-if="row.isPresent" + class="paasng-icon paasng-remind" + v-bk-tooltips="{ + content: $t('环境变量不生效,KEY 与{s}增强服务的内置环境变量冲突', { s: row.conflictingService }), + width: 200 + }"> + </i> + </template> </div> - <div v-else>{{ row.key }}</div> </template> </bk-table-column> @@ -648,6 +660,7 @@ export default { envEnums: ENV_ENUM, isBatchEdit: false, activeEnvValue: 'all', + builtInEnvVars: {}, }; }, computed: { @@ -671,20 +684,49 @@ export default { this.init(); }, methods: { - init() { + async init() { this.isLoading = true; + await this.getConfigVarKeys(); this.getEnvVarList(); }, - getEnvVarList() { + // 是否已存在该环境变量 + isEnvVarAlreadyExists(varKey) { + let flag = false; + let services = ''; + // 检查是否已存在该环境变量 + for (const key in this.builtInEnvVars) { + if (this.builtInEnvVars[key].includes(varKey)) { + flag = true; + services = key; + break; + } + } + return { + flag, + services, + }; + }, + getEnvVarList(isUpdate = true) { this.isTableLoading = true; this.$http.get(`${BACKEND_URL}/api/bkapps/applications/${this.appCode}/modules/${this.curModuleId}/config_vars/?order_by=${this.curSortKey}`).then((response) => { - this.envVarList = [...response]; + if (isUpdate) this.envVarList = [...response]; // 添加自定义属性 this.envVarList.forEach((v) => { this.$set(v, 'isEdit', false); + const { flag, services } = this.isEnvVarAlreadyExists(v.key); + this.$set(v, 'isPresent', flag); + this.$set(v, 'conflictingService', services); + if (!v.id) { + const id = response.find(item => item.key === v.key)?.id; + this.$set(v, 'id', id); + } }); this.envLocalVarList = cloneDeep(this.envVarList); - this.handleFilterEnv(this.activeEnvValue); + if (isUpdate) { + this.handleFilterEnv(this.activeEnvValue); + } else { + this.$store.commit('cloudApi/updatePageEdit', false); + } }, (errRes) => { const errorMsg = errRes.message; this.$paasMessage({ @@ -772,6 +814,8 @@ export default { // 删除冗余数据 delete data.isEdit; delete data.isAdd; + delete data.isPresent; + delete data.conflictingService; try { await this.$store.dispatch('envVar/createdEnvVariable', { appCode: this.appCode, @@ -798,6 +842,7 @@ export default { async updateEnvVariable(data, i) { // 删除冗余数据 delete data.isEdit; + delete data.isPresent; try { await this.$store.dispatch('envVar/updateEnvVariable', { appCode: this.appCode, @@ -829,6 +874,8 @@ export default { params.forEach((v) => { delete v.is_global; delete v.isEdit; + delete v.isPresent; + delete v.conflictingService; }); await this.$store.dispatch('envVar/saveEnvItem', { appCode: this.appCode, moduleId: this.curModuleId, data: params }); @@ -841,12 +888,8 @@ export default { theme: 'success', message: this.$t(`${tipsType}环境变量成功`), }); - this.envVarList.forEach((v) => { - this.$set(v, 'isEdit', false); - }); - // 更新本地数据 - this.envLocalVarList = cloneDeep(this.envVarList); - this.$store.commit('cloudApi/updatePageEdit', false); + // 批量更新不打乱当前顺序,重新复制当前新建id + this.getEnvVarList(false); } catch (error) { const errorMsg = error.message; this.$paasMessage({ @@ -1363,6 +1406,22 @@ export default { this.getEnvVarList(); } }, + + // 获取增强服务内置环境变量 + async getConfigVarKeys() { + try { + const varKeys = await this.$store.dispatch('envVar/getConfigVarKeys', { + appCode: this.appCode, + moduleId: this.curModuleId, + }); + this.builtInEnvVars = varKeys; + } catch (e) { + this.$paasMessage({ + theme: 'error', + message: e.detail || e.message || this.$t('接口异常'), + }); + } + }, }, }; </script> @@ -1864,6 +1923,16 @@ a.is-disabled { /deep/ .bk-table-empty-block { display: none; } + .var-key-wrapper { + display: flex; + align-items: center; + i { + margin-left: 5px; + font-size: 14px; + color: #EA3636; + transform: translateY(0); + } + } } .mr6 { margin-right: 6px; diff --git a/webfe/package_vue/src/views/plugin-center/plugin/version-manager/index.vue b/webfe/package_vue/src/views/plugin-center/plugin/version-manager/index.vue index 93f881e538..f917733c3e 100644 --- a/webfe/package_vue/src/views/plugin-center/plugin/version-manager/index.vue +++ b/webfe/package_vue/src/views/plugin-center/plugin/version-manager/index.vue @@ -636,6 +636,12 @@ export default { const res = await this.$store.dispatch('plugin/getPluginAccessEntry', { pluginId: this.pluginId, }); + // 已下架 + if (res.is_offlined) { + this.isAccessDisabled = true; + this.accessDisabledTips = this.$t('该插件已下架。如需继续使用,请创建新版本。'); + return; + } this.pluginDefaultInfo = res; this.isAccessDisabled = false; } catch (e) {