feat(项目管理): 环境管理环境组查询

This commit is contained in:
RubyLiu 2024-02-06 20:25:54 +08:00 committed by Craftsman
parent bf19d03d24
commit a100078e46
7 changed files with 159 additions and 36 deletions

View File

@ -9,6 +9,7 @@ import type {
EnvGroupProjectListItem, EnvGroupProjectListItem,
EnvListItem, EnvListItem,
GlobalParams, GlobalParams,
ProjectOptionItem,
} from '@/models/projectManagement/environmental'; } from '@/models/projectManagement/environmental';
import { OptionsItem } from '@/models/setting/log'; import { OptionsItem } from '@/models/setting/log';
@ -57,8 +58,8 @@ export function deleteEnv(data: EnvListItem) {
export function groupUpdateEnv(data: EnvListItem) { export function groupUpdateEnv(data: EnvListItem) {
return MSR.post<EnvListItem>({ url: envURL.groupUpdateEnvUrl, data }); return MSR.post<EnvListItem>({ url: envURL.groupUpdateEnvUrl, data });
} }
export function groupListEnv(data: EnvGroupListItem) { export function groupListEnv(data: { projectId: string; keyword: string }) {
return MSR.post<EnvListItem>({ url: envURL.groupListEnvUrl, data }); return MSR.post<EnvListItem[]>({ url: envURL.groupListEnvUrl, data });
} }
export function groupEditPosEnv(data: EnvGroupListItem) { export function groupEditPosEnv(data: EnvGroupListItem) {
return MSR.post<EnvListItem>({ url: envURL.groupEditPosEnvUrl, data }); return MSR.post<EnvListItem>({ url: envURL.groupEditPosEnvUrl, data });
@ -66,14 +67,16 @@ export function groupEditPosEnv(data: EnvGroupListItem) {
export function groupAddEnv(data: EnvGroupListItem) { export function groupAddEnv(data: EnvGroupListItem) {
return MSR.post<EnvListItem>({ url: envURL.groupAddEnvUrl, data }); return MSR.post<EnvListItem>({ url: envURL.groupAddEnvUrl, data });
} }
export function groupDetailEnv(data: EnvListItem) { // 项目管理-项目组-详情
return MSR.post<EnvListItem>({ url: envURL.groupDetailEnvUrl, data }); export function groupDetailEnv(id: string) {
return MSR.get<EnvDetailItem>({ url: `${envURL.groupDetailEnvUrl}${id}` });
} }
export function groupDeleteEnv(data: EnvListItem) { export function groupDeleteEnv(data: EnvListItem) {
return MSR.post<EnvListItem>({ url: envURL.groupDeleteEnvUrl, data }); return MSR.post<EnvListItem>({ url: envURL.groupDeleteEnvUrl, data });
} }
export function groupProjectEnv(data: EnvGroupProjectListItem) { // 获取项目组的项目
return MSR.post<EnvListItem>({ url: envURL.groupProjectEnvUrl, data }); export function groupProjectEnv() {
return MSR.get<ProjectOptionItem[]>({ url: envURL.groupProjectEnvUrl });
} }
/** 项目管理-环境-全局参数-更新or新增 */ /** 项目管理-环境-全局参数-更新or新增 */

View File

@ -15,6 +15,7 @@ export const groupEditPosEnvUrl = '/project/environment/group/edit/pos';
export const groupAddEnvUrl = '/project/environment/group/add'; 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 updateGlobalParamUrl = '/project/global/params/update';

View File

@ -71,3 +71,8 @@ export interface ContentTabsMap {
tabList: ContentTabItem[]; tabList: ContentTabItem[];
backupTabList: ContentTabItem[]; backupTabList: ContentTabItem[];
} }
export interface ProjectOptionItem {
id: string;
name: string;
}

View File

@ -1,7 +1,7 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import localforage from 'localforage'; import localforage from 'localforage';
import { getDetailEnv, getGlobalParamDetail } from '@/api/modules/project-management/envManagement'; import { getDetailEnv, getGlobalParamDetail, groupDetailEnv } from '@/api/modules/project-management/envManagement';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
import { isArraysEqualWithOrder } from '@/utils/equal'; import { isArraysEqualWithOrder } from '@/utils/equal';
@ -9,6 +9,7 @@ import { ContentTabItem, ContentTabsMap, EnvDetailItem, GlobalParams } from '@/m
export const ALL_PARAM = 'allParam'; export const ALL_PARAM = 'allParam';
export const NEW_ENV_PARAM = 'newEnvParam'; export const NEW_ENV_PARAM = 'newEnvParam';
export const NEW_ENV_GROUP = 'newEnvGroup';
const useProjectEnvStore = defineStore( const useProjectEnvStore = defineStore(
'projectEnv', 'projectEnv',
@ -21,7 +22,7 @@ const useProjectEnvStore = defineStore(
const backupEnvDetailInfo = ref<EnvDetailItem>({ projectId: '', name: '', config: {} }); // 当前选中的环境详情-备份 const backupEnvDetailInfo = ref<EnvDetailItem>({ projectId: '', name: '', config: {} }); // 当前选中的环境详情-备份
const allParamDetailInfo = ref<GlobalParams>(); // 全局参数详情 const allParamDetailInfo = ref<GlobalParams>(); // 全局参数详情
// 当前选中的项目组详情 // 当前选中的项目组详情
const groupDetailInfo = ref<GlobalParams>(); const groupDetailInfo = ref<EnvDetailItem>();
const httpNoWarning = ref(true); const httpNoWarning = ref(true);
const getHttpNoWarning = computed(() => httpNoWarning.value); const getHttpNoWarning = computed(() => httpNoWarning.value);
@ -29,6 +30,10 @@ const useProjectEnvStore = defineStore(
function setCurrentId(id: string) { function setCurrentId(id: string) {
currentId.value = id; currentId.value = id;
} }
// 设置选中项目组
function setCurrentGroupId(id: string) {
currentGroupId.value = id;
}
// 设置http提醒 // 设置http提醒
function setHttpNoWarning(noWarning: boolean) { function setHttpNoWarning(noWarning: boolean) {
httpNoWarning.value = noWarning; httpNoWarning.value = noWarning;
@ -57,6 +62,16 @@ const useProjectEnvStore = defineStore(
console.log(e); console.log(e);
} }
} }
// 初始化项目组详情
async function initGroupDetail() {
try {
const id = currentGroupId.value;
groupDetailInfo.value = await groupDetailEnv(id);
} catch (e) {
// eslint-disable-next-line no-console
console.log(e);
}
}
// 初始化内容tab列表 // 初始化内容tab列表
async function initContentTabList(arr: ContentTabItem[]) { async function initContentTabList(arr: ContentTabItem[]) {
@ -114,9 +129,11 @@ const useProjectEnvStore = defineStore(
backupEnvDetailInfo, backupEnvDetailInfo,
groupDetailInfo, groupDetailInfo,
setCurrentId, setCurrentId,
setCurrentGroupId,
setHttpNoWarning, setHttpNoWarning,
setAllParamDetailInfo, setAllParamDetailInfo,
initEnvDetail, initEnvDetail,
initGroupDetail,
initContentTabList, initContentTabList,
getContentTabList, getContentTabList,
setContentTabList, setContentTabList,

View File

@ -231,6 +231,20 @@
<template #matchValue="{ record }"> <template #matchValue="{ record }">
<a-input v-model="record.matchValue" class="param-input" @change="(val) => addTableLine(val)" /> <a-input v-model="record.matchValue" class="param-input" @change="(val) => addTableLine(val)" />
</template> </template>
<template #project="{ record, columnConfig }">
<a-select
v-model="record.projectId"
class="param-input"
@change="(val) => handelProjectChange(val as string, record.projectId)"
>
<a-option v-for="item in columnConfig.options" :key="item.id">{{ item.name }}</a-option>
</a-select>
</template>
<template #environment="{ record, columnConfig }">
<a-select v-model="record.environmentId" class="param-input">
<a-option v-for="item in columnConfig.options" :key="item.id">{{ item.name }}</a-option>
</a-select>
</template>
</MsBaseTable> </MsBaseTable>
<a-modal <a-modal
v-model:visible="showQuickInputParam" v-model:visible="showQuickInputParam"
@ -374,6 +388,7 @@
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'change', data: any[], isInit?: boolean): void; // (e: 'change', data: any[], isInit?: boolean): void; //
(e: 'moreActionSelect', event: ActionsItem, record: Record<string, any>): void; (e: 'moreActionSelect', event: ActionsItem, record: Record<string, any>): void;
(e: 'projectChange', projectId: string): void;
}>(); }>();
const { t } = useI18n(); const { t } = useI18n();
@ -568,6 +583,11 @@
emit('moreActionSelect', event, record); emit('moreActionSelect', event, record);
} }
function handelProjectChange(val: string, projectId: string) {
emit('projectChange', projectId);
addTableLine(val as string, 'projectId');
}
defineExpose({ defineExpose({
addTableLine, addTableLine,
}); });

View File

@ -46,7 +46,7 @@
</template> </template>
<template v-else> <template v-else>
<div class="flex h-[400px] items-center justify-center"> <div class="flex h-[400px] items-center justify-center">
<a-empty description="暂无数据" /> <a-empty :description="t('common.noData')" />
</div> </div>
</template> </template>
</div> </div>
@ -55,25 +55,41 @@
<script lang="ts" setup> <script lang="ts" setup>
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue'; import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
import { groupProjectEnv, listEnv } 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'; import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
import { EnvListItem, ProjectOptionItem } from '@/models/projectManagement/environmental';
const { t } = useI18n();
const envGroupForm = ref(); const envGroupForm = ref();
const form = reactive({ const form = reactive({
name: '', name: '',
description: '', description: '',
}); });
const store = useProjectEnvStore(); const store = useProjectEnvStore();
const columns: ParamTableColumn[] = [ const appStore = useAppStore();
const sourceProjectOptions = ref<ProjectOptionItem[]>([]);
const projectOptions = computed(() => {
return sourceProjectOptions.value;
});
const environmentOptions = ref<EnvListItem[]>([]);
const columns = computed<ParamTableColumn[]>(() => [
{ {
title: 'project.environmental.project', title: 'project.environmental.project',
dataIndex: 'project', dataIndex: 'projectId',
slotName: 'project', slotName: 'project',
options: projectOptions.value,
}, },
{ {
title: 'project.environmental.env', title: 'project.environmental.env',
dataIndex: 'env', dataIndex: 'environmentId',
slotName: 'env', slotName: 'environment',
options: environmentOptions.value,
}, },
{ {
title: 'project.environmental.host', title: 'project.environmental.host',
@ -90,7 +106,7 @@
slotName: 'operation', slotName: 'operation',
width: 50, width: 50,
}, },
]; ]);
const innerParams = ref<any[]>([]); const innerParams = ref<any[]>([]);
@ -107,12 +123,24 @@
} }
}); });
}; };
// options
const initProjectOptions = async () => {
const res = await groupProjectEnv();
sourceProjectOptions.value = res;
};
// options
const initEnvOptions = async () => {
const res = await listEnv({ projectId: appStore.currentProjectId, keyword: '' });
environmentOptions.value = res;
};
function handleParamTableChange(resultArr: any[]) { function handleParamTableChange(resultArr: any[]) {
innerParams.value = [...resultArr]; innerParams.value = [...resultArr];
} }
onMounted(() => {
const { t } = useI18n(); initProjectOptions();
initEnvOptions();
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -110,7 +110,7 @@
<div class="env-row mt-[8px] p-[8px]"> <div class="env-row mt-[8px] p-[8px]">
<div class="text-[var(--color-text-4)]">{{ t('project.environmental.group.envGroup') }}</div> <div class="text-[var(--color-text-4)]">{{ t('project.environmental.group.envGroup') }}</div>
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<MsButton type="icon" class="!mr-0 p-[2px]"> <MsButton type="icon" class="!mr-0 p-[2px]" @click="handleCreateGroup">
<MsIcon <MsIcon
type="icon-icon_create_planarity" type="icon-icon_create_planarity"
size="18" size="18"
@ -120,26 +120,26 @@
</div> </div>
</div> </div>
<!-- 环境组list--> <!-- 环境组list-->
<div v-if="envList.length"> <div v-if="evnGroupList.length">
<VueDraggable v-model="envList" ghost-class="ghost" handle=".drag-handle"> <VueDraggable v-model="evnGroupList" ghost-class="ghost" handle=".drag-handle">
<div <div
v-for="element in envList" v-for="element in evnGroupList"
:key="element.id" :key="element.id"
class="env-item hover:bg-[rgb(var(--primary-1))]" class="env-item hover:bg-[rgb(var(--primary-1))]"
@click="handleListItemClick(element)" @click="handleListItemClickGroup(element)"
> >
<RenamePop <RenamePop
:list="envList" :list="evnGroupList"
:type="(showType as EnvAuthScopeEnum)" :type="(showType as EnvAuthScopeEnum)"
v-bind="popVisible[element.id]" v-bind="groupPopVisible[element.id]"
@cancel="handleRenameCancel(element)" @cancel="handleRenameCancelGroup(element)"
@submit="handleRenameCancel(element, true)" @submit="handleRenameCancelGroup(element, true)"
> >
<div class="flex max-w-[100%] grow flex-row items-center justify-between"> <div class="flex max-w-[100%] grow flex-row items-center justify-between">
<a-tooltip :content="element.name"> <a-tooltip :content="element.name">
<div <div
class="one-line-text" class="one-line-text"
:class="{ 'font-medium text-[rgb(var(--primary-5))]': element.id === activeKey }" :class="{ 'font-medium text-[rgb(var(--primary-5))]': element.id === activeGroupKey }"
>{{ element.name }}</div >{{ element.name }}</div
> >
</a-tooltip> </a-tooltip>
@ -197,10 +197,14 @@
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 { exportGlobalParam, listEnv } from '@/api/modules/project-management/envManagement'; import { exportGlobalParam, groupListEnv, 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_GROUP,
NEW_ENV_PARAM,
} from '@/store/modules/setting/useProjectEnvStore';
import { downloadByteFile } from '@/utils'; import { downloadByteFile } from '@/utils';
import { EnvListItem } from '@/models/projectManagement/environmental'; import { EnvListItem } from '@/models/projectManagement/environmental';
@ -211,16 +215,21 @@
const store = useProjectEnvStore(); const store = useProjectEnvStore();
const envList = ref<EnvListItem[]>([]); // const envList = ref<EnvListItem[]>([]); //
const evnGroupList = ref<EnvListItem[]>([]); //
const showType = ref<EnvAuthScopeEnum>(EnvAuthScopeEnum.PROJECT); // const showType = ref<EnvAuthScopeEnum>(EnvAuthScopeEnum.PROJECT); //
const activeKey = computed(() => store.currentId); // id const activeKey = computed(() => store.currentId); // id
const activeGroupKey = computed(() => store.currentGroupId); // group id
const keyword = ref<string>(''); // const keyword = ref<string>(''); //
const appStore = useAppStore(); const appStore = useAppStore();
// //
const popVisible = ref<PopVisible>({}); const popVisible = ref<PopVisible>({});
// group
const groupPopVisible = ref<PopVisible>({});
// //
const importVisible = ref<boolean>(false); const importVisible = ref<boolean>(false);
// //
@ -312,7 +321,7 @@
break; break;
} }
}; };
//
const handleCreateEnv = () => { const handleCreateEnv = () => {
const tmpArr = envList.value; const tmpArr = envList.value;
tmpArr.unshift({ tmpArr.unshift({
@ -322,21 +331,45 @@
store.setCurrentId(NEW_ENV_PARAM); store.setCurrentId(NEW_ENV_PARAM);
envList.value = tmpArr; envList.value = tmpArr;
}; };
//
const handleCreateGroup = () => {
const tmpArr = evnGroupList.value;
tmpArr.unshift({
id: NEW_ENV_GROUP,
name: t('project.environmental.newEnv'),
});
store.setCurrentGroupId(NEW_ENV_GROUP);
evnGroupList.value = tmpArr;
};
function changeShowType(value: string | number | boolean) { const initGroupList = async (keywordStr = '') => {
console.log(value);
}
//
const initData = async (keywordStr = '') => {
try { try {
envList.value = await listEnv({ projectId: appStore.currentProjectId, keyword: keywordStr }); evnGroupList.value = await groupListEnv({ projectId: appStore.currentProjectId, keyword: keywordStr });
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
}; };
const initData = async (keywordStr = '') => {
try {
envList.value = await listEnv({ projectId: appStore.currentProjectId, keyword: keywordStr });
if (showType.value === 'PROJECT_GROUP') {
initGroupList(keywordStr);
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
};
function changeShowType(value: string | number | boolean) {
if (value === 'PROJECT_GROUP') {
initGroupList();
store.setCurrentGroupId('');
}
}
const handleRenameCancel = (element: EnvListItem, shouldSearch?: boolean) => { const handleRenameCancel = (element: EnvListItem, shouldSearch?: boolean) => {
if (shouldSearch) { if (shouldSearch) {
initData(); initData();
@ -344,11 +377,27 @@
popVisible.value[element.id].visible = false; popVisible.value[element.id].visible = false;
}; };
const handleRenameCancelGroup = (element: EnvListItem, shouldSearch?: boolean) => {
if (shouldSearch) {
initGroupList();
}
groupPopVisible.value[element.id].visible = false;
};
const handleListItemClick = (element: EnvListItem) => { const handleListItemClick = (element: EnvListItem) => {
const { id } = element; const { id } = element;
store.setCurrentId(id); store.setCurrentId(id);
}; };
const handleListItemClickGroup = (element: EnvListItem) => {
const { id } = element;
store.setCurrentGroupId(id);
if (id !== NEW_ENV_GROUP) {
//
store.initGroupDetail();
}
};
function searchData() { function searchData() {
initData(keyword.value); initData(keyword.value);
} }