From 8c2880d07c4d6a76b52bad4e1086fb0485a71cd9 Mon Sep 17 00:00:00 2001 From: LivySara <1936808975@qq.com> Date: Thu, 9 Jul 2026 16:40:40 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E6=A8=A1=E6=9D=BF=E4=B8=8E?= =?UTF-8?q?=E5=8F=98=E9=87=8F-=E5=8F=98=E9=87=8F=E7=AE=A1=E7=90=86-?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=94=B9=E9=80=A0=20--story=3D135438351?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/api/variable.ts | 50 +++++++++++-------- ui/src/components/code-editor/index.vue | 3 +- .../create-version/create-version-slider.vue | 1 + .../config-list/config-table-list/index.vue | 2 +- .../variables/edit-variables.vue | 2 + .../variables/reset-default-value.vue | 3 +- .../space/variables/batch-delete-btn.vue | 3 +- ui/src/views/space/variables/index.vue | 9 ++-- .../views/space/variables/variable-create.vue | 4 +- .../views/space/variables/variable-edit.vue | 4 +- .../variables-content-editor.vue | 8 +-- 11 files changed, 53 insertions(+), 36 deletions(-) diff --git a/ui/src/api/variable.ts b/ui/src/api/variable.ts index 33be8db23..a15ee2020 100644 --- a/ui/src/api/variable.ts +++ b/ui/src/api/variable.ts @@ -5,51 +5,57 @@ import { IVariableEditParams, IVariableImportParams } from '../../types/variable /** * 查询变量列表 * @param biz_id 业务ID + * @param project_id 项目ID * @param params * @returns */ -export const getVariableList = (biz_id: string, params: ICommonQuery) => - http.post(`/config/biz/${biz_id}/template_variables/list`, params).then((res) => res.data); +export const getVariableList = (biz_id: string, project_id: string, params: ICommonQuery) => + http.post(`/config/biz/${biz_id}/projects/${project_id}/template_variables:list`, params).then((res) => res.data); /** * 创建变量 * @param biz_id 业务ID + * @param project_id 项目ID * @param params 创建参数 * @returns */ -export const createVariable = (biz_id: string, params: IVariableEditParams) => - http.post(`/config/biz/${biz_id}/template_variables`, params); +export const createVariable = (biz_id: string, project_id: string, params: IVariableEditParams) => + http.post(`/config/biz/${biz_id}/projects/${project_id}/template_variables`, params); /** * 编辑变量 * @param biz_id 业务ID + * @param project_id 项目ID * @param template_variable_id 变量ID * @param params 编辑参数 * @returns */ export const updateVariable = ( biz_id: string, + project_id: string, template_variable_id: number, params: { default_val: string; memo: string }, -) => http.put(`/config/biz/${biz_id}/template_variables/${template_variable_id}`, params); +) => http.put(`/config/biz/${biz_id}/projects/${project_id}/template_variables/${template_variable_id}`, params); /** * 删除变量 * @param biz_id 业务ID + * @param project_id 项目ID * @param template_variable_id 变量ID * @returns */ -export const deleteVariable = (biz_id: string, template_variable_id: number) => - http.delete(`/config/biz/${biz_id}/template_variables/${template_variable_id}`); +export const deleteVariable = (biz_id: string, project_id: string, template_variable_id: number) => + http.delete(`/config/biz/${biz_id}/projects/${project_id}/template_variables/${template_variable_id}`); /** * 批量删除变量 * @param bizId 业务ID + * @param project_id 项目ID * @param ids 变量ID列表 * @param exclusion_operation 是否跨页 */ -export const batchDeleteVariable = (biz_id: string, ids: number[], exclusion_operation: boolean) => - http.post(`/config/biz/${biz_id}/template_variables/batch_delete`, { ids, exclusion_operation }); +export const batchDeleteVariable = (biz_id: string, project_id: string, ids: number[], exclusion_operation: boolean) => + http.post(`/config/biz/${biz_id}/projects/${project_id}/template_variables:batch_delete`, { ids, exclusion_operation }); /** * 获取未命名版本服务变量列表 @@ -105,38 +111,42 @@ export const getReleasedAppVariablesCitedDetail = (biz_id: string, app_id: numbe /** * 批量导入变量文本 * @param biz_id 业务ID - * @param release_id 服务版本ID + * @param project_id 项目ID + * @param params 导入参数 * @returns */ -export const importVariablesText = (biz_id: string, params: IVariableImportParams) => - http.post(`config/biz/${biz_id}/template_variables/import`, params); +export const importVariablesText = (biz_id: string, project_id: string, params: IVariableImportParams) => + http.post(`config/biz/${biz_id}/projects/${project_id}/template_variables:import`, params); /** * 批量导入JSON * @param biz_id 业务ID - * @param release_id 服务版本ID + * @param project_id 项目ID + * @param content JSON内容 * @returns */ -export const importVariablesJSON = (biz_id: string, content: string) => - http.post(`config/biz/${biz_id}/template_variables/json/import`, { data: content }); +export const importVariablesJSON = (biz_id: string, project_id: string, content: string) => + http.post(`config/biz/${biz_id}/projects/${project_id}/template_variables:import/json`, { data: content }); /** * 批量导入YAML * @param biz_id 业务ID - * @param release_id 服务版本ID + * @param project_id 项目ID + * @param content YAML内容 * @returns */ -export const importVariablesYaml = (biz_id: string, content: string) => - http.post(`config/biz/${biz_id}/template_variables/yaml/import`, { data: content }); +export const importVariablesYaml = (biz_id: string, project_id: string, content: string) => + http.post(`config/biz/${biz_id}/projects/${project_id}/template_variables:import/yaml`, { data: content }); /** * 导出变量 * @param biz_id 业务ID + * @param project_id 项目ID * @param type 导出格式 * @returns */ -export const exportVariables = (biz_id: string, type: string) => - http.get(`config/biz/${biz_id}/variables/export?format=${type}`); +export const exportVariables = (biz_id: string, project_id: string, type: string) => + http.get(`config/biz/${biz_id}/projects/${project_id}/variables/export?format=${type}`); /** * 导出未命名版本变量 diff --git a/ui/src/components/code-editor/index.vue b/ui/src/components/code-editor/index.vue index f6d6c4bd4..3f3d030be 100644 --- a/ui/src/components/code-editor/index.vue +++ b/ui/src/components/code-editor/index.vue @@ -100,6 +100,7 @@ const localVal = ref(props.modelValue); const route = useRoute(); const bkBizId = ref(String(route.params.spaceId)); + const projectId = ref(String(route.params.projectId || '')); const appId = ref(Number(route.params.appId)); const variableNameList = ref(['']); const privateVariableNameList = ref(['']); @@ -265,7 +266,7 @@ // 获取全局变量和私有变量列表 const handleVariableList = async () => { - const variableList = await getVariableList(bkBizId.value, { start: 0, limit: 1000 }); + const variableList = await getVariableList(bkBizId.value, projectId.value, { start: 0, limit: 1000 }); variableNameList.value = variableList.details.map((item: any) => ` .${item.spec.name} `); if (appId.value) { const privateVariableList = await getUnReleasedAppVariables(bkBizId.value, appId.value); diff --git a/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue b/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue index 95913fd22..5bef274a8 100644 --- a/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue +++ b/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue @@ -38,6 +38,7 @@ diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/index.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/index.vue index 0bee87f8a..25987658b 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/index.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/index.vue @@ -27,7 +27,7 @@ :current="allExistConfigCount" :is-temp="false" :is-file-type="isFileType" /> - + @@ -65,6 +66,7 @@ const props = defineProps<{ bkBizId: string; + projectId: string; appId: number; }>(); diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/variables/reset-default-value.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/variables/reset-default-value.vue index 94c2c9c6a..1905e362f 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/variables/reset-default-value.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/variables/reset-default-value.vue @@ -22,6 +22,7 @@ const props = defineProps<{ list: IVariableEditParams[]; bkBizId: string; + projectId: string; }>(); const emits = defineEmits(['reset']); @@ -45,7 +46,7 @@ start: 0, all: true, }; - const res = await getVariableList(props.bkBizId, params); + const res = await getVariableList(props.bkBizId, props.projectId, params); variableList.value = res.details; }; diff --git a/ui/src/views/space/variables/batch-delete-btn.vue b/ui/src/views/space/variables/batch-delete-btn.vue index db1692679..778fec64c 100644 --- a/ui/src/views/space/variables/batch-delete-btn.vue +++ b/ui/src/views/space/variables/batch-delete-btn.vue @@ -30,6 +30,7 @@ const props = defineProps<{ bkBizId: string; + projectId: string; selectedIds: number[]; isAcrossChecked: boolean; dataCount: number; @@ -42,7 +43,7 @@ const handleBatchDeleteConfirm = async () => { batchDeletePending.value = true; - await batchDeleteVariable(props.bkBizId, props.selectedIds, props.isAcrossChecked); + await batchDeleteVariable(props.bkBizId, props.projectId, props.selectedIds, props.isAcrossChecked); Message({ theme: 'success', message: t('批量删除变量成功'), diff --git a/ui/src/views/space/variables/index.vue b/ui/src/views/space/variables/index.vue index f4842b333..4fe09f1ed 100644 --- a/ui/src/views/space/variables/index.vue +++ b/ui/src/views/space/variables/index.vue @@ -18,6 +18,7 @@ 0) { params.top_ids = topIds.value; } - const res = await getVariableList(spaceId.value, params); + const res = await getVariableList(spaceId.value, projectId.value, params); list.value = res.details; pagination.value.count = res.count; } catch (error) { @@ -225,7 +226,7 @@ // 导出变量 const handleExport = async (type: string) => { - const res = await exportVariables(spaceId.value, type); + const res = await exportVariables(spaceId.value, projectId.value, type); let content: any; let mimeType: string; let extension: string; @@ -274,7 +275,7 @@ }; const handleDeleteVarConfirm = async () => { - await deleteVariable(spaceId.value, deleteVariableItem.value!.id); + await deleteVariable(spaceId.value, projectId.value, deleteVariableItem.value!.id); BkMessage({ message: t('删除变量成功'), theme: 'success', diff --git a/ui/src/views/space/variables/variable-create.vue b/ui/src/views/space/variables/variable-create.vue index 914565723..0026290b3 100644 --- a/ui/src/views/space/variables/variable-create.vue +++ b/ui/src/views/space/variables/variable-create.vue @@ -25,7 +25,7 @@ import { IVariableEditParams } from '../../../../types/variable'; import EditingForm from './editing-form.vue'; - const { spaceId } = storeToRefs(useGlobalStore()); + const { spaceId, projectId } = storeToRefs(useGlobalStore()); const { t } = useI18n(); const props = defineProps<{ @@ -73,7 +73,7 @@ try { pending.value = true; const params = { ...variableConfig.value, name: `${prefix.value}${variableConfig.value.name}` }; - const res = await createVariable(spaceId.value, params); + const res = await createVariable(spaceId.value, projectId.value, params); close(); emits('created', res.data.id); Message({ diff --git a/ui/src/views/space/variables/variable-edit.vue b/ui/src/views/space/variables/variable-edit.vue index 26fd54c41..a63b38c5f 100644 --- a/ui/src/views/space/variables/variable-edit.vue +++ b/ui/src/views/space/variables/variable-edit.vue @@ -25,7 +25,7 @@ import { IVariableEditParams } from '../../../../types/variable'; import EditingForm from './editing-form.vue'; - const { spaceId } = storeToRefs(useGlobalStore()); + const { spaceId, projectId } = storeToRefs(useGlobalStore()); const { t } = useI18n(); const props = defineProps<{ @@ -76,7 +76,7 @@ try { pending.value = true; const { default_val, memo } = variableConfig.value; - await updateVariable(spaceId.value, props.id, { default_val, memo }); + await updateVariable(spaceId.value, projectId.value, props.id, { default_val, memo }); close(); emits('edited'); Message({ diff --git a/ui/src/views/space/variables/variable-import/variables-content-editor.vue b/ui/src/views/space/variables/variable-import/variables-content-editor.vue index ba57f5dc4..96b22821f 100644 --- a/ui/src/views/space/variables/variable-import/variables-content-editor.vue +++ b/ui/src/views/space/variables/variable-import/variables-content-editor.vue @@ -98,7 +98,7 @@ const { t } = useI18n(); - const { spaceId } = storeToRefs(useGlobalStore()); + const { spaceId, projectId } = storeToRefs(useGlobalStore()); const props = defineProps<{ modelValue: boolean; @@ -229,11 +229,11 @@ separator: separator.value === ' ' ? 'white-space' : separator.value, variables: editorContent.value, }; - res = await importVariablesText(spaceId.value, params); + res = await importVariablesText(spaceId.value, projectId.value, params); } else if (props.format === 'json') { - res = await importVariablesJSON(spaceId.value, editorContent.value); + res = await importVariablesJSON(spaceId.value, projectId.value, editorContent.value); } else { - res = await importVariablesYaml(spaceId.value, editorContent.value); + res = await importVariablesYaml(spaceId.value, projectId.value, editorContent.value); } return res.data.ids; }; From ce06c7520a8bd9f797d2bee1cab689a4e9518e0d Mon Sep 17 00:00:00 2001 From: LivySara <1936808975@qq.com> Date: Mon, 13 Jul 2026 11:37:57 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=E7=8E=AF=E5=A2=83=E9=A1=B6?= =?UTF-8?q?=E6=A0=8F&=E6=9C=8D=E5=8A=A1=E7=AE=A1=E7=90=86=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=94=B9=E9=80=A0=20--story=3D135438264?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/api/env.ts | 2 +- ui/src/api/index.ts | 54 ++- ui/src/api/project.ts | 2 +- ui/src/components/biz-project-selector.vue | 16 +- ui/src/components/env-alert-bar.vue | 150 +++++++ ui/src/components/env-selector.vue | 393 ++++++++++++++++++ ui/src/components/head.vue | 7 +- ui/src/utils/project.ts | 27 +- ui/src/views/space/index.vue | 14 +- .../list/components/clone-service/index.vue | 18 +- .../list/components/create-service.vue | 18 +- .../service/list/components/edit-service.vue | 10 +- .../service/list/components/service-form.vue | 115 ++++- .../list/components/service-list-content.vue | 33 +- ui/src/views/space/service/list/index.vue | 28 +- ui/types/app.ts | 2 + ui/types/service.ts | 2 + 17 files changed, 811 insertions(+), 80 deletions(-) create mode 100644 ui/src/components/env-alert-bar.vue create mode 100644 ui/src/components/env-selector.vue diff --git a/ui/src/api/env.ts b/ui/src/api/env.ts index fc3a74ad1..f489824ed 100644 --- a/ui/src/api/env.ts +++ b/ui/src/api/env.ts @@ -5,7 +5,7 @@ import type { IUpdateEnvItem, IEnvQuery } from '../../types/env'; * 获取环境列表 */ export function getEnvList(biz_id: string, project_id: string, query: IEnvQuery) { - return http.post(`/config/biz/${biz_id}/projects/${project_id}/envs/list`, { + return http.post(`/config/biz/${biz_id}/projects/${project_id}/envs:list`, { ...query, }); } diff --git a/ui/src/api/index.ts b/ui/src/api/index.ts index d54c5e8eb..7a3c9e8e8 100644 --- a/ui/src/api/index.ts +++ b/ui/src/api/index.ts @@ -41,11 +41,13 @@ export const getSpaceFeatureFlag = (biz: string) => /** * 获取服务列表 * @param biz_id 业务ID - * @param params 查询过滤条件 + * @param projectId 项目ID + * @param envId 环境ID + * @param query 查询过滤条件 * @returns */ -export const getAppList = (biz_id: string, query: IAppListQuery = {}) => - http.post(`config/list/app/app/biz_id/${biz_id}`, query).then((resp) => { +export const getAppList = (biz_id: string, projectId: string, envId: string, query: IAppListQuery = {}) => + http.post(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps:list`, query).then((resp) => { resp.data.details.forEach((item: IAppItem) => { // @ts-ignore item.permissions = resp.web_annotations.perms[item.id] || {}; @@ -53,56 +55,70 @@ export const getAppList = (biz_id: string, query: IAppListQuery = {}) => return resp.data; }); -/** + /** * 获取服务下配置文件数量、更新时间等信息 + * @param biz_id 业务ID + * @param projectId 项目ID + * @param envId 环境ID + * @param app_id 服务ID数组 + * @returns */ -export const getAppsConfigData = (biz_id: string, app_id: number[]) => - http.post(`/config/config_item_count/biz_id/${biz_id}`, { biz_id, app_id }).then((resp) => resp.data); +export const getAppsConfigData = (biz_id: string, projectId: string, envId: string, app_id: number[]) => + http.post(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/config_items/count`, { biz_id, app_id }).then((resp) => resp.data); /** * 获取服务详情 * @param biz_id 业务ID + * @param projectId 项目ID + * @param envId 环境ID * @param app_id 服务ID * @returns */ -export const getAppDetail = (biz_id: string, app_id: number) => - http.get(`config/biz/${biz_id}/apps/${app_id}`).then((resp) => resp.data); +export const getAppDetail = (biz_id: string, projectId: string, envId: string, app_id: number) => + http.get(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}`).then((resp) => resp.data); /** * 删除服务 - * @param id 服务ID * @param biz_id 业务ID + * @param projectId 项目ID + * @param envId 环境ID + * @param id 服务ID * @returns */ -export const deleteApp = (id: number, biz_id: number) => - http.delete(`config/delete/app/app/app_id/${id}/biz_id/${biz_id}`); +export const deleteApp = (biz_id: string, projectId: string, envId: string, id: number) => + http.delete(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${id}`); /** * 创建服务 * @param biz_id 业务ID - * @param params + * @param projectId 项目ID + * @param envId 环境ID + * @param params 服务参数 * @returns */ -export const createApp = (biz_id: string, params: any) => - http.post(`config/create/app/app/biz_id/${biz_id}`, { biz_id, ...params }).then((resp) => resp.data); +export const createApp = (biz_id: string, projectId: string, envId: string, params: any) => + http.post(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps`, { ...params, biz_id }).then((resp) => resp.data); /** * 更新服务 - * @param params { id, biz_id, name?, memo?, reload_type?, reload_file_path? } + * @param params { id, biz_id, projectId, envId, name?, memo?, reload_type?, reload_file_path? } * @returns */ export const updateApp = (params: any) => { - const { id, biz_id, data } = params; - return http.put(`config/update/app/app/app_id/${id}/biz_id/${biz_id}`, data).then((resp) => resp.data); + const { biz_id, projectId, envId, id, data } = params; + return http.put(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${id}`, data).then((resp) => resp.data); }; /** * 克隆服务 + * @param biz_id 业务ID + * @param projectId 项目ID + * @param envId 环境ID * @param params { id, biz_id, name?, memo?, reload_type?, reload_file_path? } * @returns */ -export const cloneApp = (biz_id: string, params: any) => { - return http.post(`config/biz/${biz_id}/clone_app`, { biz_id, ...params }).then((resp) => resp.data); +export const cloneApp = (biz_id: string, projectId: string, envId: string, params: any) => { + return http.post(`config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps:clone`, { ...params, biz_id }).then((resp) => resp.data); }; /** diff --git a/ui/src/api/project.ts b/ui/src/api/project.ts index 69debed00..ce480e2b6 100644 --- a/ui/src/api/project.ts +++ b/ui/src/api/project.ts @@ -8,7 +8,7 @@ import { IProjectQuery, IProjectEditArg } from '../../types/project'; * @returns */ export const getProjectList = (biz_id: string, params: IProjectQuery) => - http.post(`/config/biz/${biz_id}/projects/list`, params); + http.post(`/config/biz/${biz_id}/projects:list`, params); /** * 创建项目 diff --git a/ui/src/components/biz-project-selector.vue b/ui/src/components/biz-project-selector.vue index 1fb0e41be..657a3812b 100644 --- a/ui/src/components/biz-project-selector.vue +++ b/ui/src/components/biz-project-selector.vue @@ -117,9 +117,8 @@ import useTemplateStore from '../store/template'; import useGlobalStore from '../store/global'; import { ISpaceDetail } from '../../types/index'; - import { getProjectList } from '../api/project'; import type { IProjectItem } from '../../types/project'; - import { hasProjectConcept, saveSpaceToProjectId } from '../utils/project'; + import { hasProjectConcept, getCachedProjectList } from '../utils/project'; const { t } = useI18n(); const route = useRoute(); @@ -159,17 +158,11 @@ // 当前正在加载项目列表的业务ID const projectLoading = ref(false); - // 获取指定业务的项目列表(公共方法,消除重复逻辑) + // 获取指定业务的项目列表(走模块级共享缓存,避免重复请求) const fetchProjectList = async (bizId: string) => { - // 如果已缓存且不为空,直接返回缓存数据 - if (bizProjectsMap.value[bizId]?.length > 0) { - return bizProjectsMap.value[bizId]; - } - projectLoading.value = true; try { - const res = await getProjectList(bizId, { all: true }); - const projects = res.data?.projects || []; + const projects = await getCachedProjectList(bizId); // 使用 Vue 3 的响应式 API 正确更新 bizProjectsMap.value = { ...bizProjectsMap.value, @@ -361,9 +354,6 @@ selectedProjectId.value = strProjectId; tempSelectedBizId.value = ''; - // 保存 spaceId 到 projectId 的映射 - saveSpaceToProjectId(selectedBizId.value, strProjectId); - const bizItem = optionList.value.find((b) => String(b.space_id) === selectedBizId.value); if (bizItem) { // 跳转到当前模块,并带上 projectId 参数 diff --git a/ui/src/components/env-alert-bar.vue b/ui/src/components/env-alert-bar.vue new file mode 100644 index 000000000..17dd28522 --- /dev/null +++ b/ui/src/components/env-alert-bar.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/ui/src/components/env-selector.vue b/ui/src/components/env-selector.vue new file mode 100644 index 000000000..a77e65634 --- /dev/null +++ b/ui/src/components/env-selector.vue @@ -0,0 +1,393 @@ + + + + + + + diff --git a/ui/src/components/head.vue b/ui/src/components/head.vue index 32e5b008a..98e34765d 100644 --- a/ui/src/components/head.vue +++ b/ui/src/components/head.vue @@ -260,14 +260,9 @@ if (lastAccessedServiceDetail) { const detail = JSON.parse(lastAccessedServiceDetail); if (detail.spaceId === spaceId.value) { - const targetParams: any = { spaceId: detail.spaceId, appId: detail.appId }; - // 如果目标路由有项目概念,添加 projectId - if (targetHasProjectConcept && params.projectId) { - targetParams.projectId = params.projectId; - } router.push({ name: navId === 'service-all' && !showPermApplyPage.value ? 'service-config' : (navId as RouteRecordName), - params: targetParams, + params: { spaceId: detail.spaceId, projectId: detail.projectId, appId: detail.appId }, }); return; } diff --git a/ui/src/utils/project.ts b/ui/src/utils/project.ts index ecfcd7d24..c993e6b39 100644 --- a/ui/src/utils/project.ts +++ b/ui/src/utils/project.ts @@ -1,6 +1,28 @@ import { getProjectList } from '../api/project'; import type { ISpaceProject, IProjectItem } from '../../types/project'; +/** + * 模块级缓存:某空间的全部项目列表 + */ +const projectListCache: Record = {}; + +/** + * 共享数据入口:所有需要"某空间全部项目"的逻辑统一走这里 + * 同一 spaceId 只发一次请求,后续直接复用缓存 + * @param spaceId 空间ID + * @returns 项目列表 + */ +export const getCachedProjectList = (spaceId: string): Promise => { + if (projectListCache[spaceId]?.length > 0) { + return Promise.resolve(projectListCache[spaceId]); + } + return getProjectList(spaceId, { all: true }).then((res) => { + const projects = res.data?.projects || []; + projectListCache[spaceId] = projects; + return projects; + }); +}; + /** * 无项目概念的模块列表 * 这些模块不需要 projectId 参数 @@ -64,9 +86,8 @@ export const getDefaultProjectId = async (spaceId: string): Promise => { // 1. 先从 localStorage 获取上次使用的 projectId const lastProjectId = getSpaceToProjectId(spaceId); - // 2. 获取项目列表 - const res = await getProjectList(spaceId, { all: true }); - const projects = res.data?.projects || []; + // 2. 获取项目列表(走共享缓存入口) + const projects = await getCachedProjectList(spaceId); // 3. 如果 localStorage 中有值,且存在于项目列表中,则使用它 if (lastProjectId) { diff --git a/ui/src/views/space/index.vue b/ui/src/views/space/index.vue index 37000c654..3bbd41be8 100644 --- a/ui/src/views/space/index.vue +++ b/ui/src/views/space/index.vue @@ -13,6 +13,7 @@ import { getSpaceFeatureFlag } from '../../api'; import whitelistApplyPage from './whitelist-apply-page.vue'; import applyPermPage from './apply-perm-page.vue'; + import { saveSpaceToProjectId } from '../../utils/project'; const { spaceId, projectId, spaceFeatureFlags, showPermApplyPage } = storeToRefs(useGlobalStore()); @@ -34,13 +35,16 @@ watch( () => route.params, (params) => { - if (params.spaceId) { - spaceId.value = params.spaceId as string; - setLastAccessedSpace(params.spaceId as string); + const pSpaceId = params.spaceId as string; + const pProjectId = params.projectId as string; + if (pSpaceId) { + spaceId.value = pSpaceId; + setLastAccessedSpace(pSpaceId); getFeatureFlagsData(); } - if (params.projectId) { - projectId.value = params.projectId as string; + if (pProjectId) { + projectId.value = pProjectId; + saveSpaceToProjectId(pSpaceId, pProjectId); } }, { immediate: true }, diff --git a/ui/src/views/space/service/list/components/clone-service/index.vue b/ui/src/views/space/service/list/components/clone-service/index.vue index 9ebdf211b..73f70ca04 100644 --- a/ui/src/views/space/service/list/components/clone-service/index.vue +++ b/ui/src/views/space/service/list/components/clone-service/index.vue @@ -77,7 +77,7 @@ const isFormChange = ref(false); const pending = ref(false); - const { spaceId } = storeToRefs(useGlobalStore()); + const { spaceId, projectId } = storeToRefs(useGlobalStore()); const serviceEditForm = ref({ name: '', alias: '', @@ -87,6 +87,8 @@ is_approve: true, approver: '', approve_type: 'or_sign', + projectId: '', + envId: '', }); const scriptIds = ref({ pre_hook_id: 0, post_hook_id: 0 }); const serviceFormRef = ref(); @@ -115,7 +117,7 @@ stepsStatus.value.objectSteps = isFileType.value ? [{ title: t('填写服务信息') }, { title: t('导入配置项') }, { title: t('导入脚本') }] : [{ title: t('填写服务信息') }, { title: t('导入配置项') }]; - const { spec } = props.service; + const { spec, env_id } = props.service; const { name, memo, config_type, data_type, alias, is_approve, approver, approve_type } = spec; serviceEditForm.value = { name: `${name}_copy`, @@ -126,6 +128,8 @@ is_approve, approver, approve_type, + projectId: projectId.value, + envId: String(env_id), }; configList.value = []; templateConfigList.value = []; @@ -210,22 +214,24 @@ ...rest, }); }); + const { projectId, envId, ...other } = serviceEditForm.value; const query = { - ...serviceEditForm.value, + ...other, bindings: allTemplateConfigList, config_items: allConfigList, variables: allVariables, ...scriptIds.value, }; - const res = await cloneApp(spaceId.value, query); + const res = await cloneApp(spaceId.value, projectId, envId, query); appId.value = res.id; } else { await configRef.value.validate(); + const { projectId, envId, ...other } = serviceEditForm.value; const query = { - ...serviceEditForm.value, + ...other, kv_items: kvConfigList.value, }; - const res = await cloneApp(spaceId.value, query); + const res = await cloneApp(spaceId.value, projectId, envId, query); appId.value = res.id; } emits('reload'); diff --git a/ui/src/views/space/service/list/components/create-service.vue b/ui/src/views/space/service/list/components/create-service.vue index 3f4ad7791..ef6f2db7f 100644 --- a/ui/src/views/space/service/list/components/create-service.vue +++ b/ui/src/views/space/service/list/components/create-service.vue @@ -39,10 +39,11 @@ const props = defineProps<{ show: boolean; + envId: string; }>(); const emits = defineEmits(['update:show', 'reload']); - const { spaceId } = storeToRefs(useGlobalStore()); + const { spaceId, projectId } = storeToRefs(useGlobalStore()); const serviceData = ref({ name: '', @@ -53,6 +54,8 @@ is_approve: true, approver: '', approve_type: 'or_sign', + projectId: '', + envId: '', // encryptionSwtich: false, // encryptionKey: '', }); @@ -76,8 +79,8 @@ is_approve: true, approver: '', approve_type: 'or_sign', - // encryptionSwtich: false, - // encryptionKey: '', + projectId: projectId.value, + envId: props.envId, }; } }, @@ -93,7 +96,12 @@ await formCompRef.value.validate(); pending.value = false; try { - const resp = await createApp(spaceId.value, serviceData.value); + const { projectId, envId, ...other } = serviceData.value; + const resp = await createApp( + spaceId.value, + projectId, + envId, + other); appId.value = resp.id; emits('reload'); isShowConfirmDialog.value = true; @@ -119,7 +127,7 @@ diff --git a/ui/types/app.ts b/ui/types/app.ts index d9d814d79..2a27997c3 100644 --- a/ui/types/app.ts +++ b/ui/types/app.ts @@ -11,6 +11,8 @@ export interface IAppListQuery { export interface IAppItem { id?: number; biz_id: number; + project_id: number; + env_id: number; space_id: string; spec: { name: string; diff --git a/ui/types/service.ts b/ui/types/service.ts index 5d7bedd37..04401cf0a 100644 --- a/ui/types/service.ts +++ b/ui/types/service.ts @@ -10,6 +10,8 @@ export interface IServiceEditForm { is_approve: boolean; approver: string; approve_type: string; + projectId: string; + envId: string; // encryptionSwtich: boolean; // encryptionKey: string; } From 8002597628e3d887855e574d701e4a85557ec78c Mon Sep 17 00:00:00 2001 From: LivySara <1936808975@qq.com> Date: Mon, 13 Jul 2026 12:12:23 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=E5=88=86=E7=BB=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9B=B8=E5=85=B3=E9=A1=B5=E9=9D=A2=E6=94=B9=E9=80=A0?= =?UTF-8?q?=20--story=3D135438336?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/api/group.ts | 43 +++++---- ui/src/components/env-selector.vue | 10 +- ui/src/utils/env.ts | 15 +++ .../views/space/groups/batch-delete-btn.vue | 3 +- .../groups/components/group-edit-form.vue | 93 +++++++++++++------ .../space/groups/components/tag-selector.vue | 3 +- ui/src/views/space/groups/create-group.vue | 11 ++- ui/src/views/space/groups/edit-group.vue | 9 +- ui/src/views/space/groups/index.vue | 14 ++- .../space/groups/services-to-published.vue | 21 ++++- ui/types/group.ts | 2 + 11 files changed, 158 insertions(+), 66 deletions(-) create mode 100644 ui/src/utils/env.ts diff --git a/ui/src/api/group.ts b/ui/src/api/group.ts index 121f5d088..8d3aa3e0d 100644 --- a/ui/src/api/group.ts +++ b/ui/src/api/group.ts @@ -34,10 +34,12 @@ export const delCategory = (app_id: number, group_category_id: number) => * 获取服务下分组列表 * @param biz_id 空间ID * @param app_id 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ -export const getServiceGroupList = (biz_id: string, app_id: number) => - http.get(`/config/biz/${biz_id}/apps/${app_id}/groups`).then((res) => { +export const getServiceGroupList = (biz_id: string, app_id: number, projectId?: string, envId?: string) => + http.get(`/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}/groups`).then((res) => { const defaultGroup = res.data.details.find((item: IGroupItemInService) => item.group_id === 0); if (defaultGroup) { defaultGroup.group_name = localT('全部实例'); @@ -48,63 +50,70 @@ export const getServiceGroupList = (biz_id: string, app_id: number) => /** * 获取空间下分组 * @param biz_id 空间ID + * @param projectId 项目ID * @returns */ -export const getSpaceGroupList = (biz_id: string, topId?: number) => - http.get(`/config/biz/${biz_id}/groups`, { params: { top_ids: topId } }).then((res) => res.data); +export const getSpaceGroupList = (biz_id: string, projectId?: string, topId?: number) => + http.get(`/config/biz/${biz_id}/projects/${projectId}/groups`, { params: { top_ids: topId } }).then((res) => res.data); /** * 新增分组 - * @param app_id 应用ID + * @param biz_id 空间ID + * @param projectId 项目ID * @param params 分组编辑参数 * @returns */ -export const createGroup = (biz_id: string, params: IGroupEditArg) => - http.post(`/config/biz/${biz_id}/groups`, params).then((res) => res.data); +export const createGroup = (biz_id: string, projectId?: string, params: IGroupEditArg) => + http.post(`/config/biz/${biz_id}/projects/${projectId}/groups`, params).then((res) => res.data); /** * 编辑分组 * @param biz_id 空间ID * @param group_id 分组ID + * @param projectId 项目ID * @param params 分组编辑参数 * @returns */ -export const updateGroup = (biz_id: string, group_id: number, params: IGroupEditArg) => - http.put(`/config/biz/${biz_id}/groups/${group_id}`, params).then((res) => res.data); +export const updateGroup = (biz_id: string, group_id: number, projectId?: string, params: IGroupEditArg) => + http.put(`/config/biz/${biz_id}/projects/${projectId}/groups/${group_id}`, params).then((res) => res.data); /** * 删除分组 * @param biz_id 空间ID * @param group_id 分组ID + * @param projectId 项目ID * @returns */ -export const deleteGroup = (biz_id: string, group_id: number) => - http.delete(`/config/biz/${biz_id}/groups/${group_id}`); +export const deleteGroup = (biz_id: string, group_id: number, projectId?: string) => + http.delete(`/config/biz/${biz_id}/projects/${projectId}/groups/${group_id}`); /** * 批量删除分组 * @param biz_id 空间ID + * @param projectId 项目ID * @param ids 分组ID列表 * @returns */ -export const batchDeleteGroup = (biz_id: string, ids: number[]) => - http.post(`/config/biz/${biz_id}/groups/batch_delete`, { ids }); +export const batchDeleteGroup = (biz_id: string, projectId?: string, ids: number[]) => + http.post(`/config/biz/${biz_id}/projects/${projectId}/groups:batch_delete`, { ids }); /** * 获取分组已上线服务 * @param biz_id 空间ID * @param group_id 分组ID * @param params 查询参数 + * @param projectId 项目ID * @returns */ -export const getGroupReleasedApps = (biz_id: string, group_id: number, params: ICommonQuery) => - http.get(`/config/biz/${biz_id}/groups/${group_id}/released_apps`, { params }).then((res) => res.data); +export const getGroupReleasedApps = (biz_id: string, group_id: number, params: ICommonQuery, projectId?: string) => + http.get(`/config/biz/${biz_id}/projects/${projectId}/groups/${group_id}/released_apps`, { params }).then((res) => res.data); /** * 获取分组选择器 * @param biz_id 空间ID * @param label_name 标签名称 + * @param projectId 项目ID * @returns */ -export const getGroupSelector = (biz_id: string, label_name: string) => - http.get(`/config/biz/${biz_id}/groups/selector/${label_name}`).then((res) => res.data); +export const getGroupSelector = (biz_id: string, label_name: string, projectId?: string) => + http.get(`/config/biz/${biz_id}/projects/${projectId}/groups:selector/${label_name}`).then((res) => res.data); diff --git a/ui/src/components/env-selector.vue b/ui/src/components/env-selector.vue index a77e65634..22a075ffe 100644 --- a/ui/src/components/env-selector.vue +++ b/ui/src/components/env-selector.vue @@ -8,7 +8,7 @@ :input-search="false" :disabled="props.disabled" :popover-min-width="240" - @change="handleChange" + @change="(value: string) => handleChange(value)" @toggle="handleToggle"> @@ -91,6 +93,7 @@ const { t } = useI18n(); const props = defineProps<{ spaceId: string; + projectId: string; templateSpaceId: number; templateId: number; list: ITemplateVersionItem[]; diff --git a/ui/types/template.ts b/ui/types/template.ts index a11d2071d..db092ef4a 100644 --- a/ui/types/template.ts +++ b/ui/types/template.ts @@ -24,6 +24,7 @@ export interface ITemplatePackageItem { memo: string; template_ids: number[]; public: boolean; + env_id: string; bound_apps: number[]; }; attachment: { @@ -52,6 +53,7 @@ export interface ITemplatePackageEditParams { memo: string; template_ids?: number[]; public: boolean; + env_id: string; bound_apps: number[]; force?: boolean; } From 1c194b0465f9847cd190fa283f80d80b7e82216a Mon Sep 17 00:00:00 2001 From: LivySara <1936808975@qq.com> Date: Wed, 15 Jul 2026 11:48:31 +0800 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E7=AE=A1?= =?UTF-8?q?=E7=90=86-=E9=A1=B9=E7=9B=AE=E4=B8=8E=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E6=94=B9=E9=80=A0=20--story=3D135438311=20#=20Reviewed,=20tran?= =?UTF-8?q?saction=20id:=2083218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/api/config.ts | 427 ++++++++++++++---- ui/src/api/group.ts | 2 +- ui/src/api/template.ts | 9 +- ui/src/api/variable.ts | 74 ++- ui/src/components/code-editor/index.vue | 8 +- ui/src/components/env-alert-bar.vue | 6 +- ui/src/components/head.vue | 6 +- ui/src/components/service-selector.vue | 4 +- ui/src/router.ts | 12 +- .../create-version/create-version-slider.vue | 7 +- .../components/create-version/index.vue | 6 +- .../detail/components/detail-header.vue | 12 +- .../components/modify-group-publish.vue | 18 +- .../components/publish-version-diff.vue | 9 + .../publish-version/confirm-dialog.vue | 13 +- .../components/publish-version/index.vue | 16 +- .../detail/components/service-selector.vue | 6 +- .../components/version-approve-status.vue | 9 +- .../components/config-content-editor.vue | 3 + .../components/kv-config-content-editor.vue | 3 + .../config/components/kv-import-editor.vue | 16 +- .../components/released-group-viewer.vue | 7 +- .../version-diff/aside-menu/configs-kv.vue | 8 +- .../version-diff/aside-menu/configs.vue | 29 +- .../version-diff/aside-menu/scripts.vue | 9 +- .../config/components/version-diff/index.vue | 11 +- .../config-list-kv-with-template.vue | 20 +- .../config-list-with-templates.vue | 28 +- .../config-simple-list/config-list.vue | 16 +- .../config-list/config-simple-list/index.vue | 16 +- .../config-table-list/batch-operation-btn.vue | 38 +- .../config-table-list/config-export.vue | 5 +- .../config-table-list/config-form.vue | 2 + .../import-file/import-form-other-service.vue | 6 +- .../import-file/import-from-local-file.vue | 3 +- .../import-file/import-from-templates.vue | 10 +- .../create-config/import-file/index.vue | 11 +- .../import-file/pkg-templates-table.vue | 5 +- .../create-config/import-kv/index.vue | 18 +- .../create-config/import-kv/text-import.vue | 2 + .../config-table-list/create-config/index.vue | 14 +- .../create-config/manual-create-kv.vue | 6 +- .../create-config/manual-create.vue | 2 + .../config-table-list/download-config-btn.vue | 21 +- .../config-table-list/edit-config-kv.vue | 4 +- .../config-table-list/edit-config.vue | 13 +- .../config-list/config-table-list/index.vue | 21 +- .../replace-template-version.vue | 14 +- .../tables/table-with-kv.vue | 31 +- .../tables/table-with-templates.vue | 54 ++- .../variables/edit-variables.vue | 14 +- .../variables/view-variables.vue | 15 +- .../config-table-list/view-config-kv.vue | 7 +- .../config-table-list/view-config.vue | 39 +- .../detail/config/config-list/index.vue | 17 +- .../space/service/detail/config/index.vue | 9 +- .../config/version-list-aside/index.vue | 16 +- .../version-simple-list.vue | 28 +- .../version-list-aside/version-table-list.vue | 24 +- ui/src/views/space/service/detail/index.vue | 61 ++- .../service/detail/init-script/index.vue | 21 +- .../space/service/list/components/card.vue | 3 +- .../clone-service/import-config.vue | 20 +- .../list/components/clone-service/index.vue | 8 +- .../list/components/create-service.vue | 1 + .../list/components/create-success-dialog.vue | 2 + .../service/list/components/edit-service.vue | 7 +- .../list/components/service-list-content.vue | 2 + .../service/list/components/service-table.vue | 3 +- .../list/package-detail/use-package-apps.vue | 12 +- 70 files changed, 1098 insertions(+), 301 deletions(-) diff --git a/ui/src/api/config.ts b/ui/src/api/config.ts index 9cddf9f31..c755439fd 100644 --- a/ui/src/api/config.ts +++ b/ui/src/api/config.ts @@ -23,30 +23,46 @@ export const getDefaultConfigScriptData = () => ({ * 获取未命名版本的配置文件列表 * @param biz_id 空间ID * @param app_id 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param query 查询参数 * @returns */ -export const getConfigList = (biz_id: string, app_id: number, query: ICommonQuery) => +export const getConfigList = (biz_id: string, app_id: number, projectId: string, envId: string, query: ICommonQuery) => http - .post(`/config/biz/${biz_id}/apps/${app_id}/config_items`, { ...query, with_status: true }) + .post(`/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}/config_items`, { ...query, with_status: true }) .then((res) => res.data); /** * 获取已发布版本的非模板配置文件列表 * @param biz_id 空间ID * @param app_id 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param release_id 版本ID * @param params 查询参数 * @returns */ -export const getReleasedConfigList = (biz_id: string, app_id: number, release_id: number, params: ICommonQuery) => - http.post(`/config/biz/${biz_id}/apps/${app_id}/releases/${release_id}/config_items`, params).then((res) => { - res.data.details.forEach((item: any) => { +export const getReleasedConfigList = ( + biz_id: string, + app_id: number, + projectId: string, + envId: string, + release_id: number, + params: ICommonQuery, +) => + http + .post( + `/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}/releases/${release_id}/config_items`, + params, + ) + .then((res) => { + res.data.details.forEach((item: any) => { // 接口返回的config_item_id为实际的配置文件id,id字段没有到,统一替换 - item.id = item.config_item_id; + item.id = item.config_item_id; + }); + return res.data; }); - return res.data; - }); /** * 新增配置 @@ -83,26 +99,41 @@ export const deleteServiceConfigItem = (id: number, bizId: string, appId: number * 批量删除非模板配置 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param ids 配置项ID列表 * @returns */ -export const batchDeleteServiceConfigs = (bizId: string, appId: number, ids: number[]) => - http.post(`/config/biz/${bizId}/apps/${appId}/config_items/batch_delete`, { ids }); +export const batchDeleteServiceConfigs = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + ids: number[], +) => + http.post( + `/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items/batch_delete`, + { ids }, + ); /** * 获取未命名版本配置文件详情 * @param biz_id 空间ID * @param id 配置ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ -export const getConfigItemDetail = (biz_id: string, id: number, appId: number) => - http.get(`/config/biz/${biz_id}/apps/${appId}/config_items/${id}`).then((resp) => resp.data); +export const getConfigItemDetail = (biz_id: string, id: number, appId: number, projectId: string, envId: string) => + http.get(`/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items/${id}`).then((resp) => resp.data); /** * 获取已发布版本配置文件详情 * @param biz_id 空间ID * @param app_id 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param release_id 版本ID * @param config_item_id 配置文件ID * @returns @@ -110,11 +141,13 @@ export const getConfigItemDetail = (biz_id: string, id: number, appId: number) = export const getReleasedConfigItemDetail = ( biz_id: string, app_id: number, + projectId: string, + envId: string, release_id: number, config_item_id: number, ) => http - .get(`/config/biz/${biz_id}/apps/${app_id}/releases/${release_id}/config_items/${config_item_id}`) + .get(`/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}/releases/${release_id}/config_items/${config_item_id}`) .then((resp) => { resp.data.config_item.id = resp.data.config_item_id; return resp.data; @@ -211,73 +244,98 @@ export const createVersion = (bizId: string, appId: number, params: ICreateVersi * 废弃版本 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本ID * @returns */ -export const deprecateVersion = (bizId: string, appId: number, releaseId: number) => - http.put(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}/deprecate`); +export const deprecateVersion = (bizId: string, appId: number, projectId: string, envId: string, releaseId: number) => + http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/deprecate`); /** * 恢复版本 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本ID * @returns */ -export const undeprecateVersion = (bizId: string, appId: number, releaseId: number) => - http.put(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}/undeprecate`); +export const undeprecateVersion = (bizId: string, appId: number, projectId: string, envId: string, releaseId: number) => + http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/undeprecate`); /** * 删除版本 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本ID * @returns */ -export const deleteVersion = (bizId: string, appId: number, releaseId: number) => - http.delete(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}`); +export const deleteVersion = (bizId: string, appId: number, projectId: string, envId: string, releaseId: number) => + http.delete(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}`); /** * 获取版本列表 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param params 查询参数 * @returns */ -export const getConfigVersionList = (bizId: string, appId: number, params: IConfigVersionQueryParams) => - http.get(`config/biz/${bizId}/apps/${appId}/releases`, { params }).then((res) => { - res.data.details.forEach((item: IConfigVersion) => { - const defaultGroup = item.status.released_groups.find((group) => group.id === 0); - if (defaultGroup) { - defaultGroup.name = localT('全部实例'); - } +export const getConfigVersionList = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + params: IConfigVersionQueryParams, +) => + http + .get( + `config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases`, + { params }, + ) + .then((res) => { + res.data.details.forEach((item: IConfigVersion) => { + const defaultGroup = item.status.released_groups.find((group) => group.id === 0); + if (defaultGroup) { + defaultGroup.name = localT('全部实例'); + } + }); + return res; }); - return res; - }); /** * 发布版本 * @param bizId 业务ID * @param appId 应用ID - * @param name 版本名称 + * @param projectId 项目ID + * @param envId 环境ID + * @param releaseId 版本ID * @param data 参数 * @returns */ export const publishVersion = ( bizId: string, appId: number, + projectId: string, + envId: string, releaseId: number, data: { groups: Array; all: boolean; memo: string; }, -) => http.post(`/config/update/strategy/publish/publish/release_id/${releaseId}/app_id/${appId}/biz_id/${bizId}`, data); +) => http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/publish`, data); /** * 发布版本(增加审批) * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param data 参数 * @param publish_type 上线方式 * @param publish_time 定时上线时间 @@ -287,6 +345,8 @@ export const publishVersion = ( export const publishVerSubmit = ( bizId: string, appId: number, + projectId: string, + envId: string, releaseId: number, data: { groups: Array; @@ -296,17 +356,19 @@ export const publishVerSubmit = ( publish_time: Date | string; is_compare: boolean; }, -) => http.post(`/config/biz_id/${bizId}/app_id/${appId}/release_id/${releaseId}/submit`, data); +) => http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/submit`, data); /** * 获取服务下初始化脚本引用配置 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本ID * @returns */ -export const getConfigScript = (bizId: string, appId: number, releaseId: number) => - http.get(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}/hooks`).then((response) => { +export const getConfigScript = (bizId: string, appId: number, projectId: string, envId: string, releaseId: number) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/hooks`).then((response) => { const { pre_hook, post_hook } = response.data; const data = { pre_hook: getDefaultConfigScriptData(), @@ -325,27 +387,35 @@ export const getConfigScript = (bizId: string, appId: number, releaseId: number) * 更新服务下初始化脚本引用配置 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param params 配置数据 * @returns */ export const updateConfigInitScript = ( bizId: string, appId: number, + projectId: string, + envId: string, params: { pre_hook_id: number | undefined; post_hook_id: number | undefined }, -) => http.put(`/config/biz/${bizId}/apps/${appId}/config_hooks`, params); +) => http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_hooks`, params); /** * 检测导入模板与已存在配置文件的冲突详情 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ export const checkAppTemplateBinding = ( bizId: string, appId: number, + projectId: string, + envId: string, params: { bindings: ITemplateBoundByAppData[] }, ) => - http.post(`/config/biz/${bizId}/apps/${appId}/template_bindings/conflict_check`, params).then((res) => { + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_bindings/conflict_check`, params).then((res) => { const conflictData: { [key: number]: number[] } = {}; res.data.details.forEach( (item: { template_id: number; template_name: string; template_set_id: number; template_set_name: string }) => { @@ -363,19 +433,25 @@ export const checkAppTemplateBinding = ( * 新建模板配置文件和服务绑定关系 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param params 查询参数 * @returns */ export const importTemplateConfigPkgs = ( bizId: string, appId: number, + projectId: string, + envId: string, params: { bindings: ITemplateBoundByAppData[] }, -) => http.post(`/config/biz/${bizId}/apps/${appId}/template_bindings`, params); +) => http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_bindings`, params); /** * 更新模板配置文件和服务绑定关系 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param bindingId 模板和服务绑定关系ID * @param params 更新参数 * @returns @@ -383,38 +459,65 @@ export const importTemplateConfigPkgs = ( export const updateTemplateConfigPkgs = ( bizId: string, appId: number, + projectId: string, + envId: string, bindingId: number, params: { bindings: ITemplateBoundByAppData[] }, -) => http.put(`/config/biz/${bizId}/apps/${appId}/template_bindings/${bindingId}`, params); +) => http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_bindings/${bindingId}`, params); /** * 获取服务下未命名版本绑定的模板配置文件列表 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param query 查询参数 * @returns */ -export const getBoundTemplates = (bizId: string, appId: number, query: ICommonQuery) => +export const getBoundTemplates = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + query: ICommonQuery, +) => http - .post(`/config/biz/${bizId}/apps/${appId}/template_revisions`, { ...query, with_status: true }) + .post( + `/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_revisions`, + { ...query, with_status: true }, + ) .then((res) => res.data); /** * 获取服务下已命名版本绑定的模板配置文件列表 * @param bizId * @param appId + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId * @returns */ -export const getBoundTemplatesByAppVersion = (bizId: string, appId: number, releaseId: number, query: ICommonQuery) => +export const getBoundTemplatesByAppVersion = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + releaseId: number, + query: ICommonQuery, +) => http - .post(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}/template_revisions`, query) + .post( + `/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/template_revisions`, + query, + ) .then((res) => res.data); /** * 更新服务下模板配置文件版本 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param bindingId 模板和服务绑定关系ID * @param params 更新参数 * @returns @@ -422,9 +525,11 @@ export const getBoundTemplatesByAppVersion = (bizId: string, appId: number, rele export const updateBoundTemplateVersion = ( bizId: string, appId: number, + projectId: string, + envId: string, bindingId: number, params: { bindings: ITemplateBoundByAppData[] }, -) => http.put(`/config/biz/${bizId}/apps/${appId}/template_bindings/${bindingId}/template_revisions`, params); +) => http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_bindings/${bindingId}/template_revisions`, params); /** * 删除服务下绑定的模板套餐 @@ -443,11 +548,13 @@ export const deleteBoundPkg = (bizId: string, appId: number, bindingId: number, * 删除服务下绑定的模板套餐 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param id 配置ID * @returns */ -export const deleteCurrBoundPkg = (bizId: string, appId: number, id: number) => - http.delete(`/config/biz/${bizId}/apps/${appId}/template_set/${id}`); +export const deleteCurrBoundPkg = (bizId: string, appId: number, projectId: string, envId: string, id: number) => + http.delete(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_set/${id}`); /** * 导入非模板配置文件压缩包 @@ -479,36 +586,44 @@ export const importNonTemplateConfigFile = ( * 批量添加非模板配置列表 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param bindingId 模板和服务绑定关系ID * @param template_set_ids 模板套餐ID列表 * @returns */ -export const batchAddConfigList = (bizId: string, appId: number, query: any) => - http.put(`/config/biz/${bizId}/apps/${appId}/config_items`, query).then((res) => res.data); +export const batchAddConfigList = (bizId: string, appId: number, projectId: string, envId: string, query: any) => + http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items`, query).then((res) => res.data); /** * 创建kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kv 配置键值类型 * @returns */ -export const createKv = (bizId: string, appId: number, kv: any) => - http.post(`/config/biz/${bizId}/apps/${appId}/kvs`, kv); +export const createKv = (bizId: string, appId: number, projectId: string, envId: string, kv: any) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs`, kv); /** * 获取kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ -export const getKvList = (bizId: string, appId: number, query: ICommonQuery) => - http.post(`/config/biz/${bizId}/apps/${appId}/kvs/list`, query).then((res) => res.data); +export const getKvList = (bizId: string, appId: number, projectId: string, envId: string, query: ICommonQuery) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/list`, query).then((res) => res.data); /** * 更新kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param key 配置键 * @param value 配置值 * @returns @@ -516,115 +631,182 @@ export const getKvList = (bizId: string, appId: number, query: ICommonQuery) => export const updateKv = ( bizId: string, appId: number, + projectId: string, + envId: string, key: string, editContent: { value: string; memo: string; secret_hidden?: boolean }, -) => http.put(`/config/biz/${bizId}/apps/${appId}/kvs/${key}`, editContent); +) => http.put(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/${key}`, editContent); /** * 删除kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param configId 配置项ID * @returns */ -export const deleteKv = (bizId: string, appId: number, configId: number) => - http.delete(`/config/biz/${bizId}/apps/${appId}/kvs/${configId}`); +export const deleteKv = (bizId: string, appId: number, projectId: string, envId: string, configId: number) => + http.delete(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/${configId}`); /** * 批量删除kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param ids 配置项ID列表 * @param exclusion_operation 是否跨页 */ -export const batchDeleteKv = (bizId: string, appId: number, ids: number[], exclusion_operation: boolean) => - http.post(`config/biz/${bizId}/apps/${appId}/kvs/batch_delete`, { ids, exclusion_operation }); +export const batchDeleteKv = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + ids: number[], + exclusion_operation: boolean, +) => + http.post( + `config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/batch_delete`, + { ids, exclusion_operation }, + ); /** * 获取已发布kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本id * @param key 配置键 * @returns */ -export const getReleaseKv = (bizId: string, appId: number, releaseId: number, key: string) => - http.get(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}/kvs/${key}`).then((res) => res.data); +export const getReleaseKv = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + releaseId: number, + key: string, +) => + http + .get( + `/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/kvs/${key}`, + ) + .then((res) => res.data); /** * 获取已发布kv列表 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本id * @returns */ -export const getReleaseKvList = (bizId: string, appId: number, releaseId: number, query: ICommonQuery) => - http.post(`/config/biz/${bizId}/apps/${appId}/releases/${releaseId}/kvs`, query).then((res) => res.data); +export const getReleaseKvList = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + releaseId: number, + query: ICommonQuery, +) => + http + .post( + `/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/kvs`, + query, + ) + .then((res) => res.data); /** * 撤销删除kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kv 配置键值类型 * @returns */ -export const undeleteKv = (bizId: string, appId: number, key: string) => - http.post(`/config/biz/${bizId}/apps/${appId}/kvs/${key}/undelete`); +export const undeleteKv = (bizId: string, appId: number, projectId: string, envId: string, key: string) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/${key}/undelete`); /** * 恢复修改kv * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kv 配置键值类型 * @returns */ -export const unModifyKv = (bizId: string, appId: number, key: string) => - http.post(`/config/biz/${bizId}/apps/${appId}/kvs/${key}/undo`); +export const unModifyKv = (bizId: string, appId: number, projectId: string, envId: string, key: string) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/${key}/undo`); /** * 批量导入kv配置文件 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param File 配置文件 * @returns */ -export const batchImportKvFile = (bizId: string, appId: number, File: any) => - http.post(`/biz/${bizId}/apps/${appId}/kvs/import`, File); +export const batchImportKvFile = (bizId: string, appId: number, projectId: string, envId: string, File: any) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/import`, File); /** * 导出kv配置文件 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 发布版本ID * @returns */ -export const getExportKvFile = (bizId: string, appId: number, releaseId: number, format: string) => - http.get(`biz/${bizId}/apps/${appId}/releases/${releaseId}/kvs/export`, { params: { format } }); +export const getExportKvFile = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + releaseId: number, + format: string, +) => + http.get( + `config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/kvs/export`, + { params: { format } }, + ); /** * 撤销修改配置文件 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param id 配置文件ID * @returns */ -export const unModifyConfigItem = (bizId: string, appId: number, id: number) => - http.post(`/config/undo/config_item/config_item/config_item_id/${id}/app_id/${appId}/biz_id/${bizId}`); +export const unModifyConfigItem = (bizId: string, appId: number, projectId: string, envId: string, id: number) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items/${id}/undo`); /** * 恢复删除配置文件 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param id 配置文件ID * @returns */ -export const unDeleteConfigItem = (bizId: string, appId: number, id: number) => - http.post(`/config/undelete/config_item/config_item/config_item_id/${id}/app_id/${appId}/biz_id/${bizId}`); +export const unDeleteConfigItem = (bizId: string, appId: number, projectId: string, envId: string, id: number) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items/${id}/undelete`); /** * 从历史版本导入配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param other_app_id 导入服务id * @param release_id 版本id * @returns @@ -632,13 +814,17 @@ export const unDeleteConfigItem = (bizId: string, appId: number, id: number) => export const importFromHistoryVersion = ( bizId: string, appId: number, + projectId: string, + envId: string, params: { other_app_id: number; release_id: number }, -) => http.get(`/config/biz/${bizId}/apps/${appId}/config_items/compare_conflicts`, { params }); +) => http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items/compare_conflicts`, { params }); /** * 从历史版本导入kv配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param other_app_id 导入服务id * @param release_id 版本id * @returns @@ -646,122 +832,167 @@ export const importFromHistoryVersion = ( export const importKvFromHistoryVersion = ( bizId: string, appId: number, + projectId: string, + envId: string, params: { other_app_id: number; release_id: number }, -) => http.get(`/config/biz/${bizId}/apps/${appId}/kvs/compare_conflicts`, { params }); +) => http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/compare_conflicts`, { params }); /** * 简单文本导入kv配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kvs 上传kv列表 * @returns */ -export const importKvFormText = (bizId: string, appId: number, kvs: any, replace_all: boolean) => - http.put(`/config/biz/${bizId}/apps/${appId}/kvs`, { kvs, replace_all }); +export const importKvFormText = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + kvs: any, + replace_all: boolean, +) => + http.put( + `/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs`, + { kvs, replace_all }, + ); /** * json文本导入kv配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kvs 上传kv列表 * @returns */ -export const importKvFormJson = (bizId: string, appId: number, content: string) => - http.post(`/config/biz/${bizId}/apps/${appId}/kvs/json/import`, { data: content }); +export const importKvFormJson = (bizId: string, appId: number, projectId: string, envId: string, content: string) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/json/import`, { data: content }); /** * yaml文本导入kv配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kvs 上传kv列表 * @returns */ -export const importKvFormYaml = (bizId: string, appId: number, content: string) => - http.post(`/config/biz/${bizId}/apps/${appId}/kvs/yaml/import`, { data: content }); +export const importKvFormYaml = (bizId: string, appId: number, projectId: string, envId: string, content: string) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/yaml/import`, { data: content }); /** * 判断生成版本名称是否重名 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param kvs 上传kv列表 * @returns */ -export const createVersionNameCheck = (bizId: string, appId: number, name: string) => - http.get(`/config/biz_id/${bizId}/app_id/${appId}/release/${name}/check`); +export const createVersionNameCheck = (bizId: string, appId: number, projectId: string, envId: string, name: string) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/name/${name}/check`); /** * 从配置模板导入配置文件 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param bindingId 模板和服务绑定关系ID * @param params 更新参数 * @returns */ -export const importConfigFromTemplate = (bizId: string, appId: number, query: any) => - http.post(`/config/biz/${bizId}/apps/${appId}/template_bindings/import_template_set`, query); +export const importConfigFromTemplate = (bizId: string, appId: number, projectId: string, envId: string, query: any) => + http.post(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/template_bindings/import_template_set`, query); /** * 上次上线方式查询 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ -export const publishType = (bizId: string, appId: number) => - http.get(`/config/biz_id/${bizId}/app_id/${appId}/last/select`); +export const publishType = (bizId: string, appId: number, projectId: string, envId: string) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/last/select`); /** * 当前版本状态查询 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param releaseId 版本ID * @returns */ -export const versionStatusQuery = (bizId: string, appId: number, releaseId: number) => - http.get(`/config/biz_id/${bizId}/app_id/${appId}/release_id/${releaseId}/status`); +export const versionStatusQuery = (bizId: string, appId: number, projectId: string, envId: string, releaseId: number) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/releases/${releaseId}/status`); /** * 当前服务下 所有版本上线状态检查 * @param bizId 业务ID * @param appId 应用ID - * @param releaseId 版本ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ -export const versionStatusCheck = (bizId: string, appId: number) => - http.get(`/config/biz_id/${bizId}/app_id/${appId}/last/publish`); +export const versionStatusCheck = (bizId: string, appId: number, projectId: string, envId: string) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/last/publish`); /** * 批量恢复kv配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param ids 恢复的id列表 * @returns */ -export const batchUndeleteKv = (bizId: string, appId: number, keys: string[], exclusion_operation: boolean) => - http.post(`config/biz/${bizId}/apps/${appId}/kvs/batch_undelete`, { keys, exclusion_operation }); +export const batchUndeleteKv = ( + bizId: string, + appId: number, + projectId: string, + envId: string, + keys: string[], + exclusion_operation: boolean, +) => + http.post( + `config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/batch_undelete`, + { keys, exclusion_operation }, + ); /** * 批量恢复服务型配置项 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @param ids 恢复的id列表 * @returns */ -export const batchUndeleteFile = (bizId: string, appId: number, ids: number[]) => - http.post(`config/biz_id/${bizId}/app_id/${appId}/config_items/batch_undelete`, { ids }); +export const batchUndeleteFile = (bizId: string, appId: number, projectId: string, envId: string, ids: number[]) => + http.post(`config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/config_items/batch_undelete`, { ids }); /** * 获取即将过期证书列表 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID * @returns */ -export const getUnExpiredCertList = (bizId: string, appId: number, params: any) => - http.get(`/config/biz/${bizId}/apps/${appId}/kvs/near_certificate`, { params }); +export const getUnExpiredCertList = (bizId: string, appId: number, projectId: string, envId: string, params: any) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/kvs/near_certificate`, { params }); /** * 获取所有发布版本配置项列表 * @param bizId 业务ID * @param appId 应用ID + * @param projectId 项目ID + * @param envId 环境ID */ -export const getAllReleasedConfigList = (bizId: string, appId: number) => - http.get(`/config/biz/${bizId}/apps/${appId}/published/all`); +export const getAllReleasedConfigList = (bizId: string, appId: number, projectId: string, envId: string) => + http.get(`/config/biz/${bizId}/projects/${projectId}/envs/${envId}/apps/${appId}/published/all`); diff --git a/ui/src/api/group.ts b/ui/src/api/group.ts index 8d3aa3e0d..6facec16f 100644 --- a/ui/src/api/group.ts +++ b/ui/src/api/group.ts @@ -38,7 +38,7 @@ export const delCategory = (app_id: number, group_category_id: number) => * @param envId 环境ID * @returns */ -export const getServiceGroupList = (biz_id: string, app_id: number, projectId?: string, envId?: string) => +export const getServiceGroupList = (biz_id: string, app_id: number, projectId: string, envId: string) => http.get(`/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}/groups`).then((res) => { const defaultGroup = res.data.details.find((item: IGroupItemInService) => item.group_id === 0); if (defaultGroup) { diff --git a/ui/src/api/template.ts b/ui/src/api/template.ts index 1975ed09c..aa7a334f1 100644 --- a/ui/src/api/template.ts +++ b/ui/src/api/template.ts @@ -650,7 +650,6 @@ export const getTemplateVersionDetail = ( /** * 删除模板版本 * @param biz_id 业务ID - * @param projectId 项目ID * @param template_space_id 空间ID * @param template_id 模板ID * @param template_revision_id 版本ID @@ -658,13 +657,12 @@ export const getTemplateVersionDetail = ( */ export const deleteTemplateVersion = ( biz_id: string, - projectId: string, template_space_id: number, template_id: number, template_revision_id: number, ) => http.delete( - `/config/biz/${biz_id}/projects/${projectId}/template_spaces/${template_space_id}/templates/${template_id}/template_revisions/${template_revision_id}`, + `/config/biz/${biz_id}/template_spaces/${template_space_id}/templates/${template_id}/template_revisions/${template_revision_id}`, ); /** @@ -764,11 +762,12 @@ export const getAppsVersionBoundByTemplateVersion = ( * 查询模板套餐和服务的绑定关系 * @param biz_id 业务ID * @param projectId 项目ID + * @param envId 环境ID * @param app_id 应用ID * @returns */ -export const getAppPkgBindingRelations = (biz_id: string, projectId: string, app_id: number) => - http.get(`/config/biz/${biz_id}/projects/${projectId}/apps/${app_id}/template_bindings`).then((res) => res.data); +export const getAppPkgBindingRelations = (biz_id: string, projectId: string, envId: string, app_id: number) => + http.get(`/config/biz/${biz_id}/projects/${projectId}/envs/${envId}/apps/${app_id}/template_bindings`).then((res) => res.data); /** * 批量查询模板的版本名称 diff --git a/ui/src/api/variable.ts b/ui/src/api/variable.ts index a15ee2020..f12c2fd02 100644 --- a/ui/src/api/variable.ts +++ b/ui/src/api/variable.ts @@ -60,52 +60,82 @@ export const batchDeleteVariable = (biz_id: string, project_id: string, ids: num /** * 获取未命名版本服务变量列表 * @param biz_id 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param app_id 应用ID * @returns */ -export const getUnReleasedAppVariables = (biz_id: string, app_id: number) => - http.get(`/config/biz/${biz_id}/apps/${app_id}/template_variables`).then((res) => res.data); +export const getUnReleasedAppVariables = (biz_id: string, project_id: string, env_id: string, app_id: number) => + http.get(`/config/biz/${biz_id}/projects/${project_id}/envs/${env_id}/apps/${app_id}/template_variables`).then((res) => res.data); /** * 更新未命名版本服务变量列表 * @param biz_id 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param app_id 应用ID * @returns */ -export const updateUnReleasedAppVariables = (biz_id: string, app_id: number, variables: IVariableEditParams[]) => - http.put(`/config/biz/${biz_id}/apps/${app_id}/template_variables`, { variables }).then((res) => res.data); +export const updateUnReleasedAppVariables = ( + biz_id: string, + project_id: string, + env_id: string, + app_id: number, + variables: IVariableEditParams[] +) => + http.put(`/config/biz/${biz_id}/projects/${project_id}/envs/${env_id}/apps/${app_id}/template_variables`, { variables }).then((res) => res.data); /** * 获取服务某个版本的变量列表 * @param biz_id 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param app_id 应用ID * @param release_id 服务版本ID * @returns */ -export const getReleasedAppVariables = (biz_id: string, app_id: number, release_id: number) => +export const getReleasedAppVariables = ( + biz_id: string, + project_id: string, + env_id: string, + app_id: number, + release_id: number) => http - .get(`/config/biz/${biz_id}/apps/${app_id}/releases/${release_id}/template_variables`, { params: {} }) + .get(`/config/biz/${biz_id}/projects/${project_id}/envs/${env_id}/apps/${app_id}/releases/${release_id}/template_variables`, { params: {} }) .then((res) => res.data); /** * 查询未命名版本服务中变量被配置文件引用详情 * @param biz_id 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param app_id 应用ID * @returns */ -export const getUnReleasedAppVariablesCitedDetail = (biz_id: string, app_id: number) => - http.get(`/config/biz/${biz_id}/apps/${app_id}/template_variables_references`).then((res) => res.data); +export const getUnReleasedAppVariablesCitedDetail = ( + biz_id: string, + project_id: string, + env_id: string, + app_id: number) => + http.get(`/config/biz/${biz_id}/projects/${project_id}/envs/${env_id}/apps/${app_id}/template_variables_references`).then((res) => res.data); /** * 查询服务某个版本的变量被配置文件引用详情 * @param biz_id 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param app_id 应用ID * @param release_id 服务版本ID * @returns */ -export const getReleasedAppVariablesCitedDetail = (biz_id: string, app_id: number, release_id: number) => +export const getReleasedAppVariablesCitedDetail = ( + biz_id: string, + project_id: string, + env_id: string, + app_id: number, + release_id: number) => http - .get(`/config/biz/${biz_id}/apps/${app_id}/releases/${release_id}/template_variables_references`) + .get(`/config/biz/${biz_id}/projects/${project_id}/envs/${env_id}/apps/${app_id}/releases/${release_id}/template_variables_references`) .then((res) => res.data); /** @@ -151,20 +181,36 @@ export const exportVariables = (biz_id: string, project_id: string, type: string /** * 导出未命名版本变量 * @param bizId 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param appId 应用ID * @param format 导出格式 * @returns */ -export const exportUnReleasedVariables = (bizId: string, appId: number, format: string) => - http.get(`config/biz/${bizId}/apps/${appId}/variables/export`, { params: { format } }); +export const exportUnReleasedVariables = ( + bizId: string, + project_id: string, + env_id: string, + appId: number, + format: string) => + http.get(`config/biz/${bizId}/projects/${project_id}/envs/${env_id}/apps/${appId}/variables/export`, { params: { format } }); /** * 导出已发布版本变量 * @param bizId 业务ID + * @param project_id 项目ID + * @param env_id 环境ID * @param appId 应用ID * @param release_id 服务版本ID * @param format 导出格式 * @returns */ -export const exportReleasedVaribles = (bizId: string, appId: number, release_id: number, format: string) => - http.get(`config/biz/${bizId}/apps/${appId}/releases/${release_id}/variables/export`, { params: { format } }); +export const exportReleasedVaribles = ( + bizId: string, + project_id: string, + env_id: string, + appId: number, + release_id: number, + format: string +) => + http.get(`config/biz/${bizId}/projects/${project_id}/envs/${env_id}/apps/${appId}/releases/${release_id}/variables/export`, { params: { format } }); diff --git a/ui/src/components/code-editor/index.vue b/ui/src/components/code-editor/index.vue index 3f3d030be..43fbd6a84 100644 --- a/ui/src/components/code-editor/index.vue +++ b/ui/src/components/code-editor/index.vue @@ -72,6 +72,7 @@ alwaysConsumeMouseWheel?: boolean; contextmenu?: boolean; fileEditor?: boolean; + envId?: string }>(), { variables: () => [], @@ -88,6 +89,7 @@ alwaysConsumeMouseWheel: true, contextmenu: true, fileEditor: true, + envId: '0' }, ); @@ -269,7 +271,11 @@ const variableList = await getVariableList(bkBizId.value, projectId.value, { start: 0, limit: 1000 }); variableNameList.value = variableList.details.map((item: any) => ` .${item.spec.name} `); if (appId.value) { - const privateVariableList = await getUnReleasedAppVariables(bkBizId.value, appId.value); + const privateVariableList = await getUnReleasedAppVariables( + bkBizId.value, + projectId.value, + props.envId, + appId.value); privateVariableNameList.value = privateVariableList.details.map((item: any) => ` .${item.name} `); variableNameList.value!.filter((item) => !privateVariableNameList.value!.includes(item)); } diff --git a/ui/src/components/env-alert-bar.vue b/ui/src/components/env-alert-bar.vue index 17dd28522..61355ba71 100644 --- a/ui/src/components/env-alert-bar.vue +++ b/ui/src/components/env-alert-bar.vue @@ -51,15 +51,15 @@ // eslint-disable-next-line func-call-spacing const emit = defineEmits<{ - (e: 'change', env: IEnvItem): void; + (e: 'change', env: IEnvItem, isManual?: boolean): void; }>(); const envType = ref(EnvType.PRODUCTION); const envName = ref(''); - const handleChange = (env: IEnvItem) => { + const handleChange = (env: IEnvItem, isManual?: boolean) => { envType.value = env.spec.type; envName.value = env.spec.name || ''; - emit('change', env); + emit('change', env, isManual); }; diff --git a/ui/src/components/head.vue b/ui/src/components/head.vue index 98e34765d..cb91e113f 100644 --- a/ui/src/components/head.vue +++ b/ui/src/components/head.vue @@ -260,9 +260,11 @@ if (lastAccessedServiceDetail) { const detail = JSON.parse(lastAccessedServiceDetail); if (detail.spaceId === spaceId.value) { + const routeName = navId === 'service-all' && !showPermApplyPage.value ? 'service-config' : (navId as RouteRecordName); + const { envId, ...other } = detail; router.push({ - name: navId === 'service-all' && !showPermApplyPage.value ? 'service-config' : (navId as RouteRecordName), - params: { spaceId: detail.spaceId, projectId: detail.projectId, appId: detail.appId }, + name: routeName, + params: routeName === 'service-config' ? { envId, ...other} : other, }); return; } diff --git a/ui/src/components/service-selector.vue b/ui/src/components/service-selector.vue index 282d99728..29d3ceb12 100644 --- a/ui/src/components/service-selector.vue +++ b/ui/src/components/service-selector.vue @@ -56,10 +56,12 @@ const { showApplyPermDialog, permissionQuery } = storeToRefs(useGlobalStore()); const bizId = route.params.spaceId as string; + const projectId = route.params.projectId as string; const props = withDefaults( defineProps<{ value?: number; + envId: string; customTrigger?: boolean; isRecord?: boolean; }>(), @@ -118,7 +120,7 @@ start: 0, all: true, }; - const resp = await getAppList(bizId, query); + const resp = await getAppList(bizId, projectId, props.envId, query); serviceList.value = resp.details; } catch (e) { console.error(e); diff --git a/ui/src/router.ts b/ui/src/router.ts index dbab53bc3..1d6b03ea9 100644 --- a/ui/src/router.ts +++ b/ui/src/router.ts @@ -3,7 +3,7 @@ import useGlobalStore from './store/global'; import { ISpaceDetail } from '../types/index'; import { getSpaceFeatureFlag } from './api'; import { storeToRefs } from 'pinia'; -import { hasProjectConcept, getDefaultProjectId, saveSpaceToProjectId, getSpaceToProjectId } from './utils/project'; +import { hasProjectConcept, getDefaultProjectId, getSpaceToProjectId } from './utils/project'; const routes = [ { @@ -47,7 +47,7 @@ const routes = [ component: () => import('./views/space/service/list/index.vue'), }, { - path: ':appId(\\d+)', + path: ':appId(\\d+)/:envId', component: () => import('./views/space/service/detail/index.vue'), children: [ { @@ -312,7 +312,7 @@ router.afterEach(() => { router.beforeEach(async (to, _from, next) => { const globalStore = storeToRefs(useGlobalStore()); - const { spaceFeatureFlags, projectId } = globalStore; + const { spaceFeatureFlags } = globalStore; // 页面刷新后 spaceFeatureFlags会重置,重新获取权限信息 if (!spaceFeatureFlags.value.BIZ_VIEW) { @@ -331,8 +331,6 @@ router.beforeEach(async (to, _from, next) => { // 获取默认 projectId:优先 localStorage,没有则取项目列表第一个 const targetProjectId = await getDefaultProjectId(currentSpaceId); if (targetProjectId) { - projectId.value = targetProjectId; - saveSpaceToProjectId(currentSpaceId, targetProjectId); // 重定向到带 projectId 的路由 const params: Record = { ...to.params, projectId: targetProjectId }; next({ @@ -345,10 +343,6 @@ router.beforeEach(async (to, _from, next) => { } catch (error) { console.error('获取项目列表失败', error); } - } else { - // projectId 已存在,同步到全局状态并保存映射 - projectId.value = currentProjectId; - saveSpaceToProjectId(currentSpaceId, currentProjectId); } } diff --git a/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue b/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue index 5bef274a8..27dc90b96 100644 --- a/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue +++ b/ui/src/views/space/service/detail/components/create-version/create-version-slider.vue @@ -68,6 +68,8 @@ const props = defineProps<{ show: boolean; bkBizId: string; + projectId: string; + envId: string; appId: number; isDiffSliderShow: boolean; }>(); @@ -104,7 +106,7 @@ { validator: async (value: string) => { if (value.length > 0) { - const res = await createVersionNameCheck(props.bkBizId, props.appId, value); + const res = await createVersionNameCheck(props.bkBizId, props.appId, props.projectId, props.envId, value); return !res.data.exist; } return true; @@ -136,7 +138,8 @@ const getVariableList = async () => { loading.value = true; - const res = await getUnReleasedAppVariables(props.bkBizId, props.appId); + const { bkBizId, appId, projectId, envId} = props; + const res = await getUnReleasedAppVariables(bkBizId, projectId, envId, appId); initialVariables.value = res.details.slice(); variableList.value = res.details.slice(); loading.value = false; diff --git a/ui/src/views/space/service/detail/components/create-version/index.vue b/ui/src/views/space/service/detail/components/create-version/index.vue index 7c40b020a..22d3cdd2d 100644 --- a/ui/src/views/space/service/detail/components/create-version/index.vue +++ b/ui/src/views/space/service/detail/components/create-version/index.vue @@ -18,6 +18,8 @@ v-model:show="isVersionSliderShow" ref="createSliderRef" :bk-biz-id="props.bkBizId" + :project-id="projectId" + :env-id="envId" :app-id="props.appId" :is-diff-slider-show="isDiffSliderShow" @created="handleCreated" /> @@ -40,6 +42,8 @@ const props = defineProps<{ bkBizId: string; + projectId: string; + envId: string; appId: number; permCheckLoading: boolean; hasPerm: boolean; @@ -122,7 +126,7 @@ try { const { bkBizId, appId } = props; const queryParams = { days: 30, all: true }; - const res = await getUnExpiredCertList(bkBizId, appId, queryParams); + const res = await getUnExpiredCertList(bkBizId, appId, props.projectId, props.envId, queryParams); unExpiredCertList.value = res.data.details.map((item: IConfigKvType) => { const { spec: { key: name, certificate_expiration_date }, diff --git a/ui/src/views/space/service/detail/components/detail-header.vue b/ui/src/views/space/service/detail/components/detail-header.vue index 6904241f8..f5c644155 100644 --- a/ui/src/views/space/service/detail/components/detail-header.vue +++ b/ui/src/views/space/service/detail/components/detail-header.vue @@ -24,6 +24,8 @@ @@ -50,6 +52,8 @@ @send-data="getVerApproveStatus" /> (); @@ -262,7 +272,7 @@ const tab = tabs.value.find((item) => item.name === val); if (tab) { const params = route.params.versionId ? { versionId: route.params.versionId } : {}; - router.push({ name: tab.routeName, params }); + router.push({ name: tab.routeName, params: { ...route.params, ...params}}); } }; diff --git a/ui/src/views/space/service/detail/components/modify-group-publish.vue b/ui/src/views/space/service/detail/components/modify-group-publish.vue index b3ee82949..dd013240e 100644 --- a/ui/src/views/space/service/detail/components/modify-group-publish.vue +++ b/ui/src/views/space/service/detail/components/modify-group-publish.vue @@ -94,6 +94,8 @@ { try { versionListLoading.value = true; - const res = await getConfigVersionList(props.bkBizId, props.appId, { start: 0, all: true }); + const res = await getConfigVersionList( + props.bkBizId, + props.appId, + props.projectId, + props.envId, + { start: 0, all: true }, + ); versionList.value = res.data.details.filter((item: IConfigVersion) => { return item.status.publish_status !== 'not_released'; }); @@ -311,7 +323,7 @@ // 获取所有分组,并组装tree组件节点需要的数据 const getAllGroupData = async () => { groupListLoading.value = true; - const res = await getServiceGroupList(props.bkBizId, appData.value.id as number); + const res = await getServiceGroupList(props.bkBizId, appData.value.id as number, props.projectId, props.envId,); groupList.value = res.details; treeNodeGroups.value = res.details.map((group: IGroupItemInService) => { const { group_id, group_name, release_id, release_name } = group; @@ -480,7 +492,7 @@ // 检查是否有正在上线的版本 或 2小时内有无其他版本上线 const checkVersionStatus = async () => { - const resp = await versionStatusCheck(props.bkBizId, props.appId); + const resp = await versionStatusCheck(props.bkBizId, props.appId, props.projectId, props.envId); const { data } = resp; warnDialogData.value = data; if (data?.is_publishing) { diff --git a/ui/src/views/space/service/detail/components/publish-version-diff.vue b/ui/src/views/space/service/detail/components/publish-version-diff.vue index 33a3904b1..2cb2a68f5 100644 --- a/ui/src/views/space/service/detail/components/publish-version-diff.vue +++ b/ui/src/views/space/service/detail/components/publish-version-diff.vue @@ -3,6 +3,9 @@ ref="diffRef" :btn-loading="props.btnLoading" :show="props.show" + :bk-biz-id="props.bkBizId" + :project-id="props.projectId" + :env-id="props.envId" :current-version="props.currentVersion" :base-version-id="baseVersionId" :show-publish-btn="true" @@ -23,6 +26,8 @@ @@ -42,6 +47,8 @@ @@ -60,6 +67,8 @@ const props = defineProps<{ bkBizId: string; + projectId: string; + envId: string; appId: number; show: boolean; currentVersion: IConfigVersion; // 当前版本详情信息 diff --git a/ui/src/views/space/service/detail/components/publish-version/confirm-dialog.vue b/ui/src/views/space/service/detail/components/publish-version/confirm-dialog.vue index d24c540d4..9a688bcc3 100644 --- a/ui/src/views/space/service/detail/components/publish-version/confirm-dialog.vue +++ b/ui/src/views/space/service/detail/components/publish-version/confirm-dialog.vue @@ -181,6 +181,8 @@ defineProps<{ show: boolean; bkBizId: string; + projectId: string; + envId: string; appId: number; groupList: IGroupToPublish[]; releaseType: string; @@ -320,7 +322,14 @@ // 非定时上线,publishTime清空 params.publish_time = localVal.value.publish_type === 'scheduled' ? convertTime(params.publish_time as string, 'utc', false) : ''; - const resp = await publishVerSubmit(props.bkBizId, props.appId, versionData.value.id, params); + const resp = await publishVerSubmit( + props.bkBizId, + props.appId, + props.projectId, + props.envId, + versionData.value.id, + params, + ); handleClose(); // 目前组件库dialog关闭自带250ms的延迟,所以这里延时300ms setTimeout(() => { @@ -370,7 +379,7 @@ const loadPublishType = async () => { try { pending.value = true; - const resp = await publishType(props.bkBizId, props.appId); + const resp = await publishType(props.bkBizId, props.appId, props.projectId, props.envId); const { is_approve, publish_type } = resp.data; isApprove.value = is_approve; // 需要审批 diff --git a/ui/src/views/space/service/detail/components/publish-version/index.vue b/ui/src/views/space/service/detail/components/publish-version/index.vue index 217434b02..fcc6fa8b7 100644 --- a/ui/src/views/space/service/detail/components/publish-version/index.vue +++ b/ui/src/views/space/service/detail/components/publish-version/index.vue @@ -90,6 +90,8 @@ { groupListLoading.value = true; - const res = await getServiceGroupList(props.bkBizId, appData.value.id as number); + console.log('getAllGroupData', appData.value); + const res = await getServiceGroupList(props.bkBizId, appData.value.id as number, props.projectId, props.envId,); groupList.value = res.details; treeNodeGroups.value = res.details.map((group: IGroupItemInService) => { const { group_id, group_name, release_id, release_name } = group; @@ -293,7 +300,10 @@ const getVersionList = async () => { try { versionListLoading.value = true; - const res = await getConfigVersionList(props.bkBizId, props.appId, { start: 0, all: true }); + const res = await getConfigVersionList(props.bkBizId, props.appId, props.projectId, props.envId, { + start: 0, + all: true, + }); versionList.value = res.data.details.filter((item: IConfigVersion) => { const { id, status } = item; return id !== versionData.value.id && status.publish_status !== 'not_released'; @@ -427,7 +437,7 @@ // 检查是否有正在上线的版本 或 2小时内有无其他版本上线 const checkVersionStatus = async () => { - const resp = await versionStatusCheck(props.bkBizId, props.appId); + const resp = await versionStatusCheck(props.bkBizId, props.appId, props.projectId, props.envId); const { data } = resp; warnDialogData.value = data; if (data?.is_publishing) { diff --git a/ui/src/views/space/service/detail/components/service-selector.vue b/ui/src/views/space/service/detail/components/service-selector.vue index 649a5842a..7292c01e9 100644 --- a/ui/src/views/space/service/detail/components/service-selector.vue +++ b/ui/src/views/space/service/detail/components/service-selector.vue @@ -62,9 +62,11 @@ const { showApplyPermDialog, permissionQuery } = storeToRefs(useGlobalStore()); const bizId = route.params.spaceId as string; + const projectId = route.params.projectId as string; const props = defineProps<{ value: number; + envId: string; }>(); const emits = defineEmits(['change']); @@ -103,7 +105,7 @@ start: 0, all: true, }; - const resp = await getAppList(bizId, query); + const resp = await getAppList(bizId, projectId, props.envId, query); serviceList.value = resp.details; } catch (e) { console.error(e); @@ -147,7 +149,7 @@ name = 'service-config'; } - router.push({ name, params: { spaceId: service.space_id, appId: id } }); + router.push({ name, params: { spaceId: service.space_id, envId: props.envId, appId: id } }); emits('change', service); } }; diff --git a/ui/src/views/space/service/detail/components/version-approve-status.vue b/ui/src/views/space/service/detail/components/version-approve-status.vue index 1e7f0692b..3a0d1cc05 100644 --- a/ui/src/views/space/service/detail/components/version-approve-status.vue +++ b/ui/src/views/space/service/detail/components/version-approve-status.vue @@ -122,9 +122,14 @@ clearInterval(interval); } if (route.params.versionId) { - const { spaceId, appId, versionId } = route.params; + const { spaceId, projectId, appId, envId, versionId } = route.params; try { - const resp = await versionStatusQuery(String(spaceId), Number(appId), Number(versionId)); + const resp = await versionStatusQuery( + String(spaceId), + Number(appId), + String(projectId), + String(envId), + Number(versionId)); const { app, spec, diff --git a/ui/src/views/space/service/detail/config/components/config-content-editor.vue b/ui/src/views/space/service/detail/config/components/config-content-editor.vue index bd9359707..82ce24577 100644 --- a/ui/src/views/space/service/detail/config/components/config-content-editor.vue +++ b/ui/src/views/space/service/detail/config/components/config-content-editor.vue @@ -52,6 +52,7 @@ :variables="props.variables" :editable="editable" :language="props.language" + :env-id="envId" @update:model-value="emits('change', $event)" /> @@ -77,6 +78,7 @@ language?: string; showTips?: boolean; height?: number; + envId?: string; }>(), { variables: () => [], @@ -85,6 +87,7 @@ language: '', showTips: true, height: 640, + envId: '0' }, ); diff --git a/ui/src/views/space/service/detail/config/components/kv-config-content-editor.vue b/ui/src/views/space/service/detail/config/components/kv-config-content-editor.vue index d61e4e50b..8010cd4ee 100644 --- a/ui/src/views/space/service/detail/config/components/kv-config-content-editor.vue +++ b/ui/src/views/space/service/detail/config/components/kv-config-content-editor.vue @@ -33,6 +33,7 @@ :language="languages" :always-consume-mouse-wheel="false" :file-editor="false" + :env-id="envId" @update:model-value="emits('change', $event)" /> @@ -52,10 +53,12 @@ languages: string; editable?: boolean; height?: number; + envId?: string; }>(), { editable: true, height: 640, + envId: '0', }, ); diff --git a/ui/src/views/space/service/detail/config/components/kv-import-editor.vue b/ui/src/views/space/service/detail/config/components/kv-import-editor.vue index 8a7e12658..5074f7403 100644 --- a/ui/src/views/space/service/detail/config/components/kv-import-editor.vue +++ b/ui/src/views/space/service/detail/config/components/kv-import-editor.vue @@ -71,6 +71,7 @@ :error-line="errorLine" :language="format" :file-editor="false" + :env-id="envId" @enter="separatorShow = true" @paste="handlePaste" @update:model-value="handleContentChange" /> @@ -85,6 +86,7 @@ diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/batch-operation-btn.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/batch-operation-btn.vue index e74dc6c6e..e54d631a8 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/batch-operation-btn.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/batch-operation-btn.vue @@ -98,6 +98,8 @@ const props = defineProps<{ bkBizId: string; + projectId: string; + envId: string; appId: number; selectedIds: number[]; selectedKeys: string[]; @@ -122,9 +124,22 @@ loading.value = true; try { if (props.isFileType) { - await batchDeleteServiceConfigs(props.bkBizId, props.appId, props.selectedIds); + await batchDeleteServiceConfigs( + props.bkBizId, + props.appId, + props.projectId, + props.envId, + props.selectedIds, + ); } else { - await batchDeleteKv(props.bkBizId, props.appId, props.selectedIds, props.isAcrossChecked); + await batchDeleteKv( + props.bkBizId, + props.appId, + props.projectId, + props.envId, + props.selectedIds, + props.isAcrossChecked, + ); } Message({ theme: 'success', @@ -145,9 +160,22 @@ loading.value = true; try { if (props.isFileType) { - await batchUndeleteFile(props.bkBizId, props.appId, props.selectedIds); + await batchUndeleteFile( + props.bkBizId, + props.appId, + props.projectId, + props.envId, + props.selectedIds, + ); } else { - await batchUndeleteKv(props.bkBizId, props.appId, props.selectedKeys, props.isAcrossChecked); + await batchUndeleteKv( + props.bkBizId, + props.appId, + props.projectId, + props.envId, + props.selectedKeys, + props.isAcrossChecked, + ); } Message({ theme: 'success', @@ -194,7 +222,7 @@ sign: commit_spec.content.signature, }; }); - await batchAddConfigList(props.bkBizId, props.appId, { items: editConfigList }); + await batchAddConfigList(props.bkBizId, props.appId, props.projectId, props.envId, { items: editConfigList }); Message({ theme: 'success', message: t('配置文件权限批量修改成功'), diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/config-export.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/config-export.vue index a113456c6..1c9f9035d 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/config-export.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/config-export.vue @@ -33,13 +33,16 @@ import { storeToRefs } from 'pinia'; import useServiceStore from '../../../../../../../store/service'; import useConfigStore from '../../../../../../../store/config'; + import useGlobalStore from '../../../../../../../store/global'; const serviceStore = useServiceStore(); + const { projectId } = storeToRefs(useGlobalStore()); const configStore = useConfigStore(); const { appData, isFileType } = storeToRefs(serviceStore); const { allExistConfigCount, conflictFileCount } = storeToRefs(configStore); const props = defineProps<{ bkBizId: string; + envId: string; appId: number; versionId: number; versionName: string; @@ -60,7 +63,7 @@ ]); const handleExportKv = async (type: string) => { - const res = await getExportKvFile(props.bkBizId, props.appId, props.versionId, type); + const res = await getExportKvFile(props.bkBizId, props.appId, projectId.value, props.envId, props.versionId, type); let content: any; let mimeType: string; let extension: string; diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/config-form.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/config-form.vue index 3b9fbb397..706d164e1 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/config-form.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/config-form.vue @@ -149,6 +149,7 @@ :editable="true" :variables="props.variables" :size-limit="props.fileSizeLimit" + :env-id="envId" @change="handleStringContentChange" /> @@ -207,6 +208,7 @@ content?: string | IFileConfigContentSummary; variables?: IVariableEditParams[]; bkBizId: string; + envId: string; id: number; // 服务ID或者模板空间ID fileUploading?: boolean; fileSizeLimit?: number; diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-form-other-service.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-form-other-service.vue index e9a063c20..0e48dce50 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-form-other-service.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-form-other-service.vue @@ -57,6 +57,8 @@ const props = defineProps<{ bkBizId: string; + projectId: string; + envId: string; appId: number; }>(); const emits = defineEmits(['selectVersion', 'clear']); @@ -84,7 +86,7 @@ start: 0, all: true, }; - const resp = await getAppList(props.bkBizId, query); + const resp = await getAppList(props.bkBizId, props.projectId, props.envId, query); serviceList.value = resp.details.filter((app: IAppItem) => { if (isFileType.value) { return app.spec.config_type === 'file' && app.id !== props.appId; @@ -123,7 +125,7 @@ start: 0, all: true, }; - const res = await getConfigVersionList(props.bkBizId, selectAppId.value, params); + const res = await getConfigVersionList(props.bkBizId, selectAppId.value, props.projectId, props.envId, params); versionList.value = res.data.details; } catch (e) { console.error(e); diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-local-file.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-local-file.vue index aeba498ff..8ce27cfc7 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-local-file.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-local-file.vue @@ -86,7 +86,7 @@ } const { t } = useI18n(); - const { spaceFeatureFlags } = storeToRefs(useGlobalStore()); + const { spaceFeatureFlags, projectId } = storeToRefs(useGlobalStore()); const props = defineProps<{ isTemplate: boolean; // 是否是配置模板导入 @@ -189,6 +189,7 @@ if (props.isTemplate) { res = await importTemplateFile( props.spaceId!, + projectId.value, props.currentTemplateSpace!, option.file, isDecompression.value, diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-templates.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-templates.vue index 62544ec5f..e6fd7c5cb 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-templates.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/import-from-templates.vue @@ -72,6 +72,8 @@ import { ref, onMounted, computed, watch } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import { Share } from 'bkui-vue/lib/icon'; + import { storeToRefs } from 'pinia'; + import useGlobalStore from '../../../../../../../../../store/global'; import { ITemplatePkgs, ITemplateRevision } from '../../../../../../../../../../types/config'; import { IAllPkgsGroupBySpaceInBiz } from '../../../../../../../../../../types/template'; import { importConfigFromTemplate } from '../../../../../../../../../api/config'; @@ -81,9 +83,11 @@ const route = useRoute(); const router = useRouter(); + const { projectId } = storeToRefs(useGlobalStore()); const props = defineProps<{ bkBizId: string; + envId: string; appId: number; }>(); @@ -134,14 +138,14 @@ const getPkgList = async () => { pkgListLoading.value = true; - const res = await getAllPackagesGroupBySpace(props.bkBizId, { app_id: props.appId }); + const res = await getAllPackagesGroupBySpace(props.bkBizId, projectId.value, { app_id: props.appId }); pkgList.value = res.details; pkgListLoading.value = false; }; const getImportedPkgsData = async () => { importedPkgsLoading.value = true; - const res = await getAppPkgBindingRelations(props.bkBizId, props.appId); + const res = await getAppPkgBindingRelations(props.bkBizId, projectId.value, props.envId, props.appId); if (res.details.length === 1) { bindingId.value = res.details[0].id; importedPkgs.value = res.details[0].spec.bindings; @@ -205,7 +209,7 @@ }; const handleImportConfirm = async () => { - await importConfigFromTemplate(props.bkBizId, props.appId, { + await importConfigFromTemplate(props.bkBizId, props.appId, projectId.value, props.envId, { bindings: [...selectedPkgs.value, ...importedPkgs.value], }); close(); diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/index.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/index.vue index c42b5362d..5a504794b 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/index.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/index.vue @@ -34,6 +34,7 @@ @@ -56,6 +57,8 @@
@@ -171,6 +174,8 @@ const props = defineProps<{ show: boolean; bkBizId: string; + projectId: string; + envId: string; appId: number; }>(); const emits = defineEmits(['update:show', 'confirm']); @@ -310,7 +315,7 @@ replace_all: isClearDraft.value, variables: allVariables, }; - const res = await batchAddConfigList(props.bkBizId, props.appId, query); + const res = await batchAddConfigList(props.bkBizId, props.appId, props.projectId, props.envId, query); serviceStore.$patch((state) => { state.topIds = res.ids; }); @@ -336,7 +341,7 @@ start: 0, all: true, }; - const res = await getConfigVersionList(props.bkBizId, props.appId, params); + const res = await getConfigVersionList(props.bkBizId, props.appId, props.projectId, props.envId, params); versionList.value = res.data.details; } catch (e) { console.error(e); @@ -351,7 +356,7 @@ try { handleClearTable(); const params = { other_app_id, release_id }; - const res = await importFromHistoryVersion(props.bkBizId, props.appId, params); + const res = await importFromHistoryVersion(props.bkBizId, props.appId, props.projectId, props.envId, params); res.data.non_template_configs.forEach((item: any) => { const config = { ...item, diff --git a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/pkg-templates-table.vue b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/pkg-templates-table.vue index 735adb0a1..2bc89f831 100644 --- a/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/pkg-templates-table.vue +++ b/ui/src/views/space/service/detail/config/config-list/config-table-list/create-config/import-file/pkg-templates-table.vue @@ -53,10 +53,12 @@ diff --git a/ui/src/views/space/service/detail/config/index.vue b/ui/src/views/space/service/detail/config/index.vue index 67f116143..858bf4090 100644 --- a/ui/src/views/space/service/detail/config/index.vue +++ b/ui/src/views/space/service/detail/config/index.vue @@ -1,6 +1,11 @@ diff --git a/ui/src/views/space/service/detail/config/version-list-aside/index.vue b/ui/src/views/space/service/detail/config/version-list-aside/index.vue index 241002634..54462af44 100644 --- a/ui/src/views/space/service/detail/config/version-list-aside/index.vue +++ b/ui/src/views/space/service/detail/config/version-list-aside/index.vue @@ -1,7 +1,17 @@ diff --git a/ui/src/views/space/service/detail/config/version-list-aside/version-simple-list.vue b/ui/src/views/space/service/detail/config/version-list-aside/version-simple-list.vue index 5b62e477d..5cdcfbce0 100644 --- a/ui/src/views/space/service/detail/config/version-list-aside/version-simple-list.vue +++ b/ui/src/views/space/service/detail/config/version-list-aside/version-simple-list.vue @@ -1,7 +1,7 @@