feat(项目管理): 环境管理全局参数接口对接

This commit is contained in:
RubyLiu 2024-01-19 18:53:31 +08:00 committed by rubylliu
parent f42075ceb9
commit 74aee959c6
17 changed files with 394 additions and 89 deletions

View File

@ -1,3 +1,5 @@
import { FileItem } from '@arco-design/web-vue';
import MSR from '@/api/http/index'; import MSR from '@/api/http/index';
import * as envURL from '@/api/requrls/project-management/envManagement'; import * as envURL from '@/api/requrls/project-management/envManagement';
@ -6,6 +8,7 @@ import type {
EnvGroupListItem, EnvGroupListItem,
EnvGroupProjectListItem, EnvGroupProjectListItem,
EnvListItem, EnvListItem,
GlobalParams,
} from '@/models/projectManagement/environmental'; } from '@/models/projectManagement/environmental';
import { OptionsItem } from '@/models/setting/log'; import { OptionsItem } from '@/models/setting/log';
@ -15,7 +18,7 @@ export function updateEnv(data: EnvListItem) {
export function listEnv(data: { projectId: string; keyword: string }) { export function listEnv(data: { projectId: string; keyword: string }) {
return MSR.post<EnvListItem[]>({ url: envURL.listEnvUrl, data }); return MSR.post<EnvListItem[]>({ url: envURL.listEnvUrl, data });
} }
export function importEnv(data: { request: EnvListItem; fileList: File[] }) { export function importEnv(data: { request: EnvListItem; fileList: FileItem[] }) {
return MSR.uploadFile({ url: envURL.importEnvUrl }, data, '', true); return MSR.uploadFile({ url: envURL.importEnvUrl }, data, '', true);
} }
export function getEntryEnv(data: EnvListItem) { export function getEntryEnv(data: EnvListItem) {
@ -67,3 +70,20 @@ export function groupDeleteEnv(data: EnvListItem) {
export function groupProjectEnv(data: EnvGroupProjectListItem) { export function groupProjectEnv(data: EnvGroupProjectListItem) {
return MSR.post<EnvListItem>({ url: envURL.groupProjectEnvUrl, data }); return MSR.post<EnvListItem>({ url: envURL.groupProjectEnvUrl, data });
} }
/** 项目管理-环境-全局参数-更新or新增 */
export function updateOrAddGlobalParam(data: GlobalParams) {
return MSR.post<EnvListItem>({ url: data.id ? envURL.updateGlobalParamUrl : envURL.addGlobalParamUrl, data });
}
/** 项目管理-环境-全局参数-导入 */
export function importGlobalParam(data: { request: any; fileList: FileItem[] }) {
return MSR.uploadFile<EnvListItem>({ url: envURL.importGlobalParamUrl }, data, '', false);
}
/** 项目管理-环境-全局参数-详情 */
export function getGlobalParamDetail(id: string) {
return MSR.get<GlobalParams>({ url: envURL.detailGlobalParamUrl + id });
}
/** 项目管理-环境-全局参数-导出 */
export function exportGlobalParam(id: string) {
return MSR.get<BlobPart>({ url: envURL.exportGlobalParamUrl + id });
}

View File

@ -16,3 +16,9 @@ export const groupAddEnvUrl = '/project/environment/group/add';
export const groupDetailEnvUrl = '/project/environment/group/get/'; export const groupDetailEnvUrl = '/project/environment/group/get/';
export const groupDeleteEnvUrl = '/project/environment/group/delete/'; export const groupDeleteEnvUrl = '/project/environment/group/delete/';
export const groupProjectEnvUrl = '/project/environment/group/get-project'; export const groupProjectEnvUrl = '/project/environment/group/get-project';
// 全局参数
export const updateGlobalParamUrl = '/project/global/params/update';
export const addGlobalParamUrl = '/project/global/params/add';
export const importGlobalParamUrl = '/project/global/params/import';
export const detailGlobalParamUrl = '/project/global/params/get/';
export const exportGlobalParamUrl = '/project/global/params/export/';

View File

@ -72,6 +72,10 @@ export const FileIconMap: FileIconMapping = {
[UploadStatus.init]: 'icon-icon_file-unknow_colorful1', [UploadStatus.init]: 'icon-icon_file-unknow_colorful1',
[UploadStatus.done]: 'icon-icon_file-unknow_colorful1', [UploadStatus.done]: 'icon-icon_file-unknow_colorful1',
}, },
json: {
[UploadStatus.init]: 'icon-icon_file-json_colorful_ash',
[UploadStatus.done]: 'icon-icon_file-json_colorful1',
},
}; };
/** /**

View File

@ -50,6 +50,8 @@ export enum TableKeyEnum {
PROJECT_MANAGEMENT_ENV_ALL_PARAM = 'projectManagementEnvAllParam', PROJECT_MANAGEMENT_ENV_ALL_PARAM = 'projectManagementEnvAllParam',
PROJECT_MANAGEMENT_ENV_ENV_PARAM = 'projectManagementEnvEnvParam', PROJECT_MANAGEMENT_ENV_ENV_PARAM = 'projectManagementEnvEnvParam',
PROJECT_MANAGEMENT_ENV_ENV_HTTP = 'projectManagementEnvEnvHttp', PROJECT_MANAGEMENT_ENV_ENV_HTTP = 'projectManagementEnvEnvHttp',
PROJECT_MANAGEMENT_ENV_ALL_PARAM_HEADER = 'projectManagementEnvAllParamHeader',
PROJECT_MANAGEMENT_ENV_ALL_PARAM_VARIABLE = 'projectManagementEnvAllParamVariable',
} }
// 具有特殊功能的列 // 具有特殊功能的列

View File

@ -15,6 +15,7 @@ export enum UploadAcceptEnum {
sketch = '.sketch', sketch = '.sketch',
none = 'none', none = 'none',
unknown = 'unknown', unknown = 'unknown',
json = '.json',
} }
export enum UploadStatus { export enum UploadStatus {

View File

@ -88,6 +88,8 @@ export default {
'common.number': '数字', 'common.number': '数字',
'common.boolean': '布尔', 'common.boolean': '布尔',
'common.array': '数组', 'common.array': '数组',
'common.list': '列表',
'common.constant': '常量',
'common.json': '对象', 'common.json': '对象',
'common.integer': '整数', 'common.integer': '整数',
'common.file': '文件', 'common.file': '文件',

View File

@ -50,3 +50,12 @@ export interface EnvDetailItem {
mock?: string; mock?: string;
description?: string; description?: string;
} }
export interface GlobalParamsItem {
headers: EnvConfigItem[];
commonVariables: EnvConfigItem[];
}
export interface GlobalParams {
id?: string;
projectId: string;
globalParams: GlobalParamsItem;
}

View File

@ -1,8 +1,9 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { getDetailEnv } from '@/api/modules/project-management/envManagement'; import { getDetailEnv, getGlobalParamDetail } from '@/api/modules/project-management/envManagement';
import { useAppStore } from '@/store';
import { EnvDetailItem, EnvGroupListItem } from '@/models/projectManagement/environmental'; import { EnvDetailItem, GlobalParams } from '@/models/projectManagement/environmental';
export const ALL_PARAM = 'allParam'; export const ALL_PARAM = 'allParam';
export const NEW_ENV_PARAM = 'newEnvParam'; export const NEW_ENV_PARAM = 'newEnvParam';
@ -10,30 +11,37 @@ export const NEW_ENV_PARAM = 'newEnvParam';
const useProjectEnvStore = defineStore( const useProjectEnvStore = defineStore(
'projectEnv', 'projectEnv',
() => { () => {
const currentId = ref<string>(''); const currentId = ref<string>(ALL_PARAM); // 当前选中的key值
const currentEnvDetailInfo = ref<EnvDetailItem>(); const currentEnvDetailInfo = ref<EnvDetailItem>(); // 当前选中的环境详情
const allParamDetailInfo = ref<GlobalParams>(); // 全局参数详情
const httpNoWarning = ref(true); const httpNoWarning = ref(true);
const envGroupList = ref<EnvGroupListItem[]>([]);
const getCurrentId = computed(() => currentId.value);
const getHttpNoWarning = computed(() => httpNoWarning.value); const getHttpNoWarning = computed(() => httpNoWarning.value);
const getGroupLength = computed(() => 1); const groupLength = ref(0); // 环境分组数据
// 设置选中项
const getDatabaseList = computed(() => [{ id: 1, name: 'test' }]);
function setCurrentId(id: string) { function setCurrentId(id: string) {
currentId.value = id; currentId.value = id;
} }
// 设置http提醒
function setHttpNoWarning(noWarning: boolean) { function setHttpNoWarning(noWarning: boolean) {
httpNoWarning.value = noWarning; httpNoWarning.value = noWarning;
} }
// 设置环境详情
function setEnvDetailInfo(item: EnvDetailItem) { function setEnvDetailInfo(item: EnvDetailItem) {
currentEnvDetailInfo.value = item; currentEnvDetailInfo.value = item;
} }
// 设置全局参数
function setAllParamDetailInfo(item: GlobalParams) {
allParamDetailInfo.value = item;
}
// 初始化环境详情
async function initEnvDetail() { async function initEnvDetail() {
const id = currentId.value; const id = currentId.value;
const appStore = useAppStore();
try { try {
if (id === NEW_ENV_PARAM) { if (id === NEW_ENV_PARAM) {
currentEnvDetailInfo.value = undefined; currentEnvDetailInfo.value = undefined;
} else if (id === ALL_PARAM) {
allParamDetailInfo.value = await getGlobalParamDetail(appStore.currentProjectId);
} else if (id !== ALL_PARAM && id) { } else if (id !== ALL_PARAM && id) {
currentEnvDetailInfo.value = await getDetailEnv(id); currentEnvDetailInfo.value = await getDetailEnv(id);
} }
@ -44,16 +52,15 @@ const useProjectEnvStore = defineStore(
} }
return { return {
getCurrentId,
currentId, currentId,
getHttpNoWarning,
httpNoWarning, httpNoWarning,
allParamDetailInfo,
groupLength,
setCurrentId, setCurrentId,
setHttpNoWarning, setHttpNoWarning,
setEnvDetailInfo, setEnvDetailInfo,
getHttpNoWarning, setAllParamDetailInfo,
getDatabaseList,
envGroupList,
getGroupLength,
initEnvDetail, initEnvDetail,
}; };
}, },

View File

@ -28,18 +28,18 @@
</div> </div>
</template> </template>
<!-- 表格列 slot --> <!-- 表格列 slot -->
<template #name="{ record }"> <template #name="{ record, columnConfig }">
<a-popover position="tl" :disabled="!record.name || record.name.trim() === ''" class="ms-params-input-popover"> <a-popover position="tl" :disabled="!record.name || record.name.trim() === ''" class="ms-params-input-popover">
<template #content> <template #content>
<div class="param-popover-title"> <div class="param-popover-title">
{{ t('apiTestDebug.paramName') }} {{ t('apiTestDebug.paramName') }}
</div> </div>
<div class="param-popover-value"> <div class="param-popover-value">
{{ record.name }} {{ record[columnConfig.dataIndex as string] }}
</div> </div>
</template> </template>
<a-input <a-input
v-model:model-value="record.name" v-model:model-value="record[columnConfig.dataIndex as string]"
:placeholder="t('apiTestDebug.paramNamePlaceholder')" :placeholder="t('apiTestDebug.paramNamePlaceholder')"
class="param-input" class="param-input"
@input="(val) => addTableLine(val)" @input="(val) => addTableLine(val)"
@ -116,22 +116,31 @@
></a-input-number> ></a-input-number>
</div> </div>
</template> </template>
<template #tag="{ record }"> <template #tag="{ record, columnConfig }">
<a-popover position="tl" :disabled="record.tag.length === 0" class="ms-params-input-popover"> <a-popover
position="tl"
:disabled="record[columnConfig.dataIndex as string].length === 0"
class="ms-params-input-popover"
>
<template #content> <template #content>
<div class="param-popover-title"> <div class="param-popover-title">
{{ t('common.tag') }} {{ t('common.tag') }}
</div> </div>
<div class="param-popover-value"> <div class="param-popover-value">
<MsTagsGroup is-string-tag :tag-list="record.tag" /> <MsTagsGroup is-string-tag :tag-list="record[columnConfig.dataIndex as string]" />
</div> </div>
</template> </template>
<MsTagsInput v-model:model-value="record.tag" :max-tag-count="1" class="param-input" @change="addTableLine" /> <MsTagsInput
v-model:model-value="record[columnConfig.dataIndex as string]"
:max-tag-count="1"
class="param-input"
@change="addTableLine"
/>
</a-popover> </a-popover>
</template> </template>
<template #desc="{ record }"> <template #desc="{ record, columnConfig }">
<paramDescInput <paramDescInput
v-model:desc="record.desc" v-model:desc="record[columnConfig.dataIndex as string]"
@input="addTableLine" @input="addTableLine"
@dblclick="quickInputDesc(record)" @dblclick="quickInputDesc(record)"
@change="handleDescChange" @change="handleDescChange"
@ -146,8 +155,8 @@
@change="(val) => addTableLine(val.toString())" @change="(val) => addTableLine(val.toString())"
/> />
</template> </template>
<template #mustContain="{ record }"> <template #mustContain="{ record, columnConfig }">
<a-checkbox v-model:model-value="record.mustContain" @change="(val) => addTableLine(val)" /> <a-checkbox v-model:model-value="record[columnConfig.dataIndex as string]" @change="(val) => addTableLine(val)" />
</template> </template>
<template #operation="{ record, rowIndex, columnConfig }"> <template #operation="{ record, rowIndex, columnConfig }">
<a-trigger <a-trigger

View File

@ -1,41 +1,115 @@
<template> <template>
<div class="p-[24px]"> <div class="page">
<a-tabs v-model:active-key="activeKey" class="no-content"> <a-tabs v-model:active-key="activeKey" class="no-content">
<a-tab-pane v-for="item of contentTabList" :key="item.value" :title="item.label" /> <a-tab-pane v-for="item of contentTabList" :key="item.value" :title="item.label" />
</a-tabs> </a-tabs>
<a-divider :margin="0" class="!mb-[16px]" /> <a-divider :margin="0" class="!mb-[16px]" />
<RequestHeader v-if="activeKey === 'requestHeader'" v-model:params="headerParams" /> <RequestHeader v-if="activeKey === 'requestHeader'" v-model:params="headerParams" @change="canSave = true" />
<AllPrams v-if="activeKey === 'allParams'" v-model:params="AllParams" /> <AllPrams
v-else-if="activeKey === 'globalVariable'"
v-model:params="GlobalVariable"
:table-key="TableKeyEnum.PROJECT_MANAGEMENT_ENV_ALL_PARAM_VARIABLE"
@change="canSave = true"
/>
<div class="footer" :style="{ width: '100%' }">
<a-button :disabled="!canSave" type="primary" @click="handleSave">{{ t('common.save') }}</a-button>
</div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Message } from '@arco-design/web-vue';
import AllPrams from './allParams/index.vue'; import AllPrams from './allParams/index.vue';
import RequestHeader from './requestHeader/index.vue'; import RequestHeader from './requestHeader/index.vue';
import { updateOrAddGlobalParam } from '@/api/modules/project-management/envManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
const activeKey = ref('requestHeader'); import { EnvConfigItem } from '@/models/projectManagement/environmental';
const headerParams = ref<[]>([]); import { TableKeyEnum } from '@/enums/tableEnum';
const AllParams = ref<[]>([]);
const projectEnvStore = useProjectEnvStore();
const appStore = useAppStore();
const activeKey = ref('globalVariable');
const headerParams = ref<EnvConfigItem[]>([]);
const GlobalVariable = ref<EnvConfigItem[]>([]);
const { t } = useI18n(); const { t } = useI18n();
const canSave = ref(false);
const loading = ref(false);
const contentTabList = [ const contentTabList = [
{ {
value: 'requestHeader', value: 'requestHeader',
label: t('project.environmental.requestHeader'), label: t('project.environmental.requestHeader'),
}, },
{ {
value: 'allParams', value: 'globalVariable',
label: t('project.environmental.allParams'), label: t('project.environmental.globalVariable'),
}, },
]; ];
const handleSave = async () => {
try {
loading.value = true;
const params = {
id: projectEnvStore.allParamDetailInfo?.id,
projectId: appStore.currentProjectId,
globalParams: {
headers: headerParams.value,
commonVariables: GlobalVariable.value.map((item) => {
return {
key: item.key,
value: item.value,
description: item.description,
tags: item.tags || [],
};
}),
},
};
await updateOrAddGlobalParam(params);
Message.success(t('common.saveSuccess'));
canSave.value = false;
} catch (error) {
Message.error(t('common.saveFailed'));
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
};
onBeforeMount(() => {
projectEnvStore.initEnvDetail().then(() => {
headerParams.value = projectEnvStore.allParamDetailInfo?.globalParams.headers || [];
GlobalVariable.value = projectEnvStore.allParamDetailInfo?.globalParams.commonVariables || [];
});
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.page {
transform: scale3d(1, 1, 1);
padding: 24px;
.no-content { .no-content {
:deep(.arco-tabs-content) { :deep(.arco-tabs-content) {
padding-top: 0; padding-top: 0;
} }
} }
.footer {
gap: 16px;
position: fixed;
right: 0;
bottom: 0;
z-index: 999;
display: flex;
justify-content: flex-end;
padding: 24px;
box-shadow: 0 -1px 4px rgb(2 2 2 / 10%);
}
}
</style> </style>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="page"> <div class="page">
<template v-if="store.getGroupLength"> <template v-if="store.groupLength">
<div class="header"> <div class="header">
<a-form ref="envGroupForm" layout="vertical" :model="form"> <a-form ref="envGroupForm" layout="vertical" :model="form">
<a-form-item <a-form-item

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="mb-[8px] flex items-center justify-between"> <div class="mb-[8px] flex items-center justify-between">
<a-input <a-input-search
v-model:value="searchValue" v-model="searchValue"
:placeholder="t('project.environmental.searchParamsHolder')" :placeholder="t('project.environmental.searchParamsHolder')"
allow-clear allow-clear
class="w-[240px]" class="w-[240px]"
@blur="handleSearch" @search="handleSearch"
@press-enter="handleSearch" @press-enter="handleSearch"
> >
<template #prefix> <template #prefix>
@ -13,7 +13,7 @@
<icon-search class="cursor-pointer" @click="handleSearch" /> <icon-search class="cursor-pointer" @click="handleSearch" />
</span> </span>
</template> </template>
</a-input> </a-input-search>
<batchAddKeyVal :params="innerParams" @apply="handleBatchParamApply" /> <batchAddKeyVal :params="innerParams" @apply="handleBatchParamApply" />
</div> </div>
<paramsTable <paramsTable
@ -21,6 +21,8 @@
:table-key="props.tableKey" :table-key="props.tableKey"
:columns="columns" :columns="columns"
show-setting show-setting
:selectable="false"
:default-param-item="defaultParamItem"
@change="handleParamTableChange" @change="handleParamTableChange"
/> />
</template> </template>
@ -35,6 +37,8 @@
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
defineOptions({ name: 'EnvManagementAllParams' });
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
params: any[]; params: any[];
@ -54,11 +58,21 @@
const { t } = useI18n(); const { t } = useI18n();
const innerParams = useVModel(props, 'params', emit); const innerParams = useVModel(props, 'params', emit);
const backupParmas = ref(props.params);
const firstSearch = ref(true);
const defaultParamItem = {
key: '',
type: '',
value: '',
description: '',
tags: [],
};
const columns: ParamTableColumn[] = [ const columns: ParamTableColumn[] = [
{ {
title: 'project.environmental.paramName', title: 'project.environmental.paramName',
dataIndex: 'name', dataIndex: 'key',
slotName: 'name', slotName: 'name',
showInTable: true, showInTable: true,
showDrag: true, showDrag: true,
@ -73,28 +87,16 @@
columnSelectorDisabled: true, columnSelectorDisabled: true,
typeOptions: [ typeOptions: [
{ {
label: t('common.string'), label: t('common.constant'),
value: 'string', value: 'CONSTANT',
}, },
{ {
label: t('common.integer'), label: t('common.list'),
value: 'integer', value: 'LIST',
},
{
label: t('common.number'),
value: 'number',
},
{
label: t('common.array'),
value: 'array',
}, },
{ {
label: t('common.json'), label: t('common.json'),
value: 'json', value: 'JSON',
},
{
label: t('common.file'),
value: 'file',
}, },
], ],
titleSlotName: 'typeTitle', titleSlotName: 'typeTitle',
@ -110,7 +112,7 @@
}, },
{ {
title: 'project.environmental.tag', title: 'project.environmental.tag',
dataIndex: 'tag', dataIndex: 'tags',
slotName: 'tag', slotName: 'tag',
width: 200, width: 200,
showInTable: true, showInTable: true,
@ -118,19 +120,16 @@
}, },
{ {
title: 'project.environmental.desc', title: 'project.environmental.desc',
dataIndex: 'desc', dataIndex: 'description',
slotName: 'desc', slotName: 'desc',
showInTable: true, showInTable: true,
showDrag: true, showDrag: true,
}, },
{ {
title: '', title: '',
columnTitle: 'common.operation',
slotName: 'operation', slotName: 'operation',
dataIndex: 'operation', dataIndex: 'operation',
width: 50, width: 50,
showInTable: true,
showDrag: true,
}, },
]; ];
@ -150,19 +149,22 @@
innerParams.value = [...resultArr]; innerParams.value = [...resultArr];
if (!isInit) { if (!isInit) {
emit('change'); emit('change');
firstSearch.value = true;
} }
} }
function handleSearch() { function handleSearch() {
if (searchValue.value.length === 0) { if (firstSearch.value) {
return; backupParmas.value = [...innerParams.value];
} firstSearch.value = false;
const result = innerParams.value.filter((item) => item.name.includes(searchValue.value));
if (result.length === 0) {
return;
} }
if (!searchValue.value) {
innerParams.value = [...backupParmas.value];
} else {
const result = backupParmas.value.filter((item) => item.key.includes(searchValue.value));
innerParams.value = [...result]; innerParams.value = [...result];
} }
}
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped></style>

View File

@ -0,0 +1,102 @@
<template>
<a-modal
v-model:visible="visible"
title-align="start"
class="ms-modal-form ms-modal-medium"
:ok-text="t('common.import')"
:ok-loading="confirmLoading"
:ok-button-props="{ disabled: fileList.length === 0 }"
unmount-on-close
@cancel="handleCancel(false)"
@ok="confirmHandler"
>
<template #title>
<span>{{ t('common.import') + t(`project.environmental.${props.type}`) }}</span>
</template>
<template #default>
<div class="title">
<icon-exclamation-circle-fill :size="20" class="text-[rgb(var(--primary-5))]" />
<span class="text-[var(--color-text-1)]"> {{ t('project.environmental.importTile') }}</span>
</div>
<MsUpload
v-model:file-list="fileList"
class="w-full"
accept="json"
:max-size="50"
size-unit="MB"
main-text="system.user.importModalDragText"
:sub-text="t('project.environmental.supportFormat')"
:show-file-list="false"
:auto-upload="false"
:multiple="false"
:disabled="confirmLoading"
@change="handleChange"
/>
</template>
</a-modal>
</template>
<script lang="ts" setup>
import { type FileItem, Message } from '@arco-design/web-vue';
import MsUpload from '@/components/pure/ms-upload/index.vue';
import { importGlobalParam } from '@/api/modules/project-management/envManagement';
import { useI18n } from '@/hooks/useI18n';
import { EnvAuthTypeEnum } from '@/enums/envEnum';
const props = defineProps<{
type: EnvAuthTypeEnum;
}>();
const confirmLoading = ref<boolean>(false);
const emit = defineEmits<{
(e: 'submit', shouldSearch: boolean): void;
}>();
const { t } = useI18n();
const visible = defineModel<boolean>('visible', { required: true, default: false });
const fileList = ref<FileItem[]>([]);
const handleCancel = (shouldSearch = false) => {
visible.value = false;
emit('submit', shouldSearch);
};
const handleChange = (_fileList: FileItem[]) => {
fileList.value = _fileList;
};
const confirmHandler = async () => {
try {
confirmLoading.value = true;
const params = {
request: null,
fileList: fileList.value,
};
await importGlobalParam(params);
Message.success(t('common.importSuccess'));
handleCancel(true);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;
}
};
</script>
<style lang="less" scoped>
.title {
display: flex;
align-items: center;
margin-bottom: 24px;
padding: 16px;
width: 632px;
border: 1px solid rgb(var(--primary-5));
border-radius: 6px;
background: rgb(var(--primary-1));
gap: 8px;
}
</style>

View File

@ -155,10 +155,7 @@
const handleAdd = () => { const handleAdd = () => {
addVisible.value = true; addVisible.value = true;
}; };
const fetchData = () => { const fetchData = () => {};
const list = store.getDatabaseList;
console.log(list);
};
const handleNoWarning = () => { const handleNoWarning = () => {
store.setHttpNoWarning(false); store.setHttpNoWarning(false);
}; };

View File

@ -3,7 +3,15 @@
<div class="font-medium">{{ t('apiTestDebug.header') }}</div> <div class="font-medium">{{ t('apiTestDebug.header') }}</div>
<batchAddKeyVal :params="innerParams" @apply="handleBatchParamApply" /> <batchAddKeyVal :params="innerParams" @apply="handleBatchParamApply" />
</div> </div>
<paramsTable v-model:params="innerParams" :show-setting="false" :columns="columns" @change="handleParamTableChange" /> <paramsTable
v-model:params="innerParams"
:selectable="false"
:show-setting="false"
:columns="columns"
:table-key="TableKeyEnum.PROJECT_MANAGEMENT_ENV_ALL_PARAM_HEADER"
:default-param-item="defaultParamItem"
@change="handleParamTableChange"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -14,6 +22,12 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { TableKeyEnum } from '@/enums/tableEnum';
defineOptions({
name: 'EnvManangeGloblaRequestHeader',
});
const props = defineProps<{ const props = defineProps<{
params: any[]; params: any[];
}>(); }>();
@ -25,22 +39,27 @@
const { t } = useI18n(); const { t } = useI18n();
const innerParams = useVModel(props, 'params', emit); const innerParams = useVModel(props, 'params', emit);
const defaultParamItem = {
key: '',
value: '',
description: '',
};
const columns: ParamTableColumn[] = [ const columns: ParamTableColumn[] = [
{ {
title: 'apiTestDebug.paramName', title: 'apiTestDebug.paramName',
dataIndex: 'name', dataIndex: 'key',
slotName: 'name', slotName: 'name',
}, },
{ {
title: 'apiTestDebug.desc', title: 'apiTestDebug.paramValue',
dataIndex: 'desc', dataIndex: 'value',
slotName: 'desc', slotName: 'value',
}, },
{ {
title: 'project.environmental.mustContain', title: 'apiTestDebug.desc',
dataIndex: 'mustContain', dataIndex: 'description',
slotName: 'mustContain', slotName: 'desc',
}, },
{ {
title: '', title: '',

View File

@ -20,15 +20,15 @@
{{ t('project.environmental.allParam') }} {{ t('project.environmental.allParam') }}
</div> </div>
<div <div
class="env-item justify-between font-medium text-[rgb(var(--primary-5))] hover:bg-[rgb(var(--primary-1))]" class="env-item justify-between font-medium text-[var(--color-text-1)] hover:bg-[rgb(var(--primary-1))]"
:class="{ 'bg-[rgb(var(--primary-1))]': activeKey === ALL_PARAM }" :class="{ 'bg-[rgb(var(--primary-1))] !text-[rgb(var(--primary-5))]': activeKey === ALL_PARAM }"
@click="handleListItemClick({ id: 'allParam', name: 'allParam' })" @click="handleListItemClick({ id: 'allParam', name: 'allParam' })"
> >
{{ t('project.environmental.allParam') }} {{ t('project.environmental.allParam') }}
<div class="node-extra"> <div class="node-extra">
<MsMoreAction <MsMoreAction
:list="allMoreAction" :list="allMoreAction"
@select="(value) => handleMoreAction(value, 'all', EnvAuthTypeEnum.GLOBAL)" @select="(value) => handleMoreAction(value, 'allParams', EnvAuthTypeEnum.GLOBAL)"
/> />
</div> </div>
</div> </div>
@ -180,6 +180,7 @@
</template> </template>
</MsSplitBox> </MsSplitBox>
</div> </div>
<CommonImportPop v-model:visible="importVisible" :type="importAuthType" @submit="handleSubmit" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -191,14 +192,16 @@
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue'; import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
import { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import AllParamBox from './components/AllParamBox.vue'; import AllParamBox from './components/AllParamBox.vue';
import CommonImportPop from './components/common/CommonImportPop.vue';
import EnvGroupBox from './components/EnvGroupBox.vue'; import EnvGroupBox from './components/EnvGroupBox.vue';
import EnvParamBox from './components/EnvParamBox.vue'; import EnvParamBox from './components/EnvParamBox.vue';
import RenamePop from './components/RenamePop.vue'; import RenamePop from './components/RenamePop.vue';
import { listEnv } from '@/api/modules/project-management/envManagement'; import { exportGlobalParam, listEnv } from '@/api/modules/project-management/envManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
import useProjectEnvStore, { ALL_PARAM, NEW_ENV_PARAM } from '@/store/modules/setting/useProjectEnvStore'; import useProjectEnvStore, { ALL_PARAM, NEW_ENV_PARAM } from '@/store/modules/setting/useProjectEnvStore';
import { downloadByteFile } from '@/utils';
import { EnvListItem } from '@/models/projectManagement/environmental'; import { EnvListItem } from '@/models/projectManagement/environmental';
import { PopVisible } from '@/models/setting/usergroup'; import { PopVisible } from '@/models/setting/usergroup';
@ -218,6 +221,10 @@
// //
const popVisible = ref<PopVisible>({}); const popVisible = ref<PopVisible>({});
//
const importVisible = ref<boolean>(false);
//
const importAuthType = ref<EnvAuthTypeEnum>(EnvAuthTypeEnum.GLOBAL);
// MoreAction // MoreAction
const envMoreAction: ActionsItem[] = [ const envMoreAction: ActionsItem[] = [
@ -250,6 +257,35 @@
}, },
]; ];
//
const handleGlobalImport = () => {
importVisible.value = true;
importAuthType.value = EnvAuthTypeEnum.GLOBAL;
};
//
const handleGlobalExport = async () => {
try {
const blob = await exportGlobalParam(appStore.currentProjectId);
downloadByteFile(blob, 'globalParam.json');
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
};
const handleSubmit = (shouldSearch: boolean) => {
if (shouldSearch) {
if (importAuthType.value === EnvAuthTypeEnum.GLOBAL && store.currentId === ALL_PARAM) {
store.initEnvDetail();
} else if (importAuthType.value === EnvAuthTypeEnum.ENVIRONMENT && store.currentId !== ALL_PARAM) {
store.initEnvDetail();
}
}
};
//
const handleEnvImport = () => {};
// MoreAction // MoreAction
const handleMoreAction = (item: ActionsItem, id: string, scopeType: EnvAuthTypeEnum) => { const handleMoreAction = (item: ActionsItem, id: string, scopeType: EnvAuthTypeEnum) => {
const { eventTag } = item; const { eventTag } = item;
@ -257,15 +293,24 @@
case 'rename': case 'rename':
break; break;
case 'export': case 'export':
if (scopeType === EnvAuthTypeEnum.GLOBAL) {
handleGlobalExport();
} else if (scopeType === EnvAuthTypeEnum.ENVIRONMENT) {
handleEnvImport();
}
break; break;
case 'delete': case 'delete':
break; break;
case 'import': case 'import':
if (scopeType === EnvAuthTypeEnum.GLOBAL) {
handleGlobalImport();
} else if (scopeType === EnvAuthTypeEnum.ENVIRONMENT) {
handleEnvImport();
}
break; break;
default: default:
break; break;
} }
console.log(item, id, scopeType);
}; };
const handleCreateEnv = () => { const handleCreateEnv = () => {

View File

@ -8,6 +8,12 @@ export default {
'project.environmental.envListIsNull': '暂无数据,请点击上方“+”创建环境', 'project.environmental.envListIsNull': '暂无数据,请点击上方“+”创建环境',
'project.environmental.requestHeader': '请求头', 'project.environmental.requestHeader': '请求头',
'project.environmental.allParams': '全局参数', 'project.environmental.allParams': '全局参数',
'project.environmental.GLOBAL': '全局参数',
'project.environmental.ENVIRONMENT': '全局参数',
'project.environmental.ENVIRONMENT_PARAM': '全局参数',
'project.environmental.globalVariable': '全局变量',
'project.environmental.supportFormat': '仅支持MeterSphere导出的Json文件单个大小不超过 50M',
'project.environmental.importTile': '注意!导入后会覆盖原全局参数',
'project.environmental.mustContain': '必含', 'project.environmental.mustContain': '必含',
'project.environmental.searchParamsHolder': '通过名称或标签搜索', 'project.environmental.searchParamsHolder': '通过名称或标签搜索',
'project.environmental.paramName': '参数名称', 'project.environmental.paramName': '参数名称',