feat(系统管理): 成员和项目添加下拉检索
This commit is contained in:
parent
aef40e0a8d
commit
99fd8437c7
|
@ -46,6 +46,6 @@ export function getProjectUserGroup(projectId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 项目成员下拉选项
|
// 项目成员下拉选项
|
||||||
export function getProjectMemberOptions(projectId: string) {
|
export function getProjectMemberOptions(projectId: string, keyword?: string) {
|
||||||
return MSR.get({ url: ProjectMemberOptions, params: projectId });
|
return MSR.get({ url: `${ProjectMemberOptions}/${projectId}`, params: { keyword } });
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,10 @@ export function getGlobalUserGroup(organizationId: string) {
|
||||||
return MSR.get({ url: getUserGroupList, params: organizationId });
|
return MSR.get({ url: getUserGroupList, params: organizationId });
|
||||||
}
|
}
|
||||||
// 获取系统用户下拉
|
// 获取系统用户下拉
|
||||||
export function getUser(organizationId: string) {
|
export function getUser(organizationId: string, keyword: string) {
|
||||||
return MSR.get<LinkItem[]>({ url: getUserList, params: organizationId });
|
return MSR.get<LinkItem[]>({ url: `${getUserList}/${organizationId}`, params: { keyword } });
|
||||||
}
|
}
|
||||||
// 获取组织下边的项目
|
// 获取组织下边的项目
|
||||||
export function getProjectList(organizationId: string) {
|
export function getProjectList(organizationId: string, keyword?: string) {
|
||||||
return MSR.get<LinkItem[]>({ url: getProjectListUrl, params: organizationId });
|
return MSR.get<LinkItem[]>({ url: `${getProjectListUrl}/${organizationId}`, params: { keyword } });
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import {
|
||||||
getUserByProjectByOrg,
|
getUserByProjectByOrg,
|
||||||
} from '@/api/modules/setting/organizationAndProject';
|
} from '@/api/modules/setting/organizationAndProject';
|
||||||
import { getOrgUserGroupOption, getSystemUserGroupOption } from '@/api/modules/setting/usergroup';
|
import { getOrgUserGroupOption, getSystemUserGroupOption } from '@/api/modules/setting/usergroup';
|
||||||
|
import { getUser, getProjectList } from '@/api/modules/setting/member';
|
||||||
|
import { getProjectMemberOptions } from '@/api/modules/project-management/projectMember';
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
export enum UserRequesetTypeEnum {
|
export enum UserRequesetTypeEnum {
|
||||||
|
@ -17,6 +19,9 @@ export enum UserRequesetTypeEnum {
|
||||||
ORGANIZATION_USER_GROUP_ADMIN = 'ORGANIZATION_USER_GROUP_ADMIN',
|
ORGANIZATION_USER_GROUP_ADMIN = 'ORGANIZATION_USER_GROUP_ADMIN',
|
||||||
ORGANIZATION_PROJECT = 'ORGANIZATION_PROJECT',
|
ORGANIZATION_PROJECT = 'ORGANIZATION_PROJECT',
|
||||||
ORGANIZATION_PROJECT_ADMIN = 'ORGANIZATION_PROJECT_ADMIN',
|
ORGANIZATION_PROJECT_ADMIN = 'ORGANIZATION_PROJECT_ADMIN',
|
||||||
|
SYSTEM_ORGANIZATION_PROJECT = 'SYSTEM_ORGANIZATION_PROJECT',
|
||||||
|
SYSTEM_ORGANIZATION_MEMBER = 'SYSTEM_ORGANIZATION_MEMBER',
|
||||||
|
PROJECT_PERMISSION_MEMBER = 'PROJECT_PERMISSION_MEMBER',
|
||||||
}
|
}
|
||||||
export default function initOptionsFunc(type: string, params: Record<string, any>) {
|
export default function initOptionsFunc(type: string, params: Record<string, any>) {
|
||||||
if (type === UserRequesetTypeEnum.SYSTEM_USER_GROUP) {
|
if (type === UserRequesetTypeEnum.SYSTEM_USER_GROUP) {
|
||||||
|
@ -43,4 +48,16 @@ export default function initOptionsFunc(type: string, params: Record<string, any
|
||||||
// 组织 - 项目-添加管理员-下拉选项
|
// 组织 - 项目-添加管理员-下拉选项
|
||||||
return getAdminByProjectByOrg(params.organizationId, params.keyword);
|
return getAdminByProjectByOrg(params.organizationId, params.keyword);
|
||||||
}
|
}
|
||||||
|
if (type === UserRequesetTypeEnum.SYSTEM_ORGANIZATION_PROJECT) {
|
||||||
|
// 系统-组织-组织项目
|
||||||
|
return getProjectList(params.organizationId, params.keyword);
|
||||||
|
}
|
||||||
|
if (type === UserRequesetTypeEnum.SYSTEM_ORGANIZATION_MEMBER) {
|
||||||
|
// 系统-组织-组织成员
|
||||||
|
return getUser(params.organizationId, params.keyword);
|
||||||
|
}
|
||||||
|
if (type === UserRequesetTypeEnum.PROJECT_PERMISSION_MEMBER) {
|
||||||
|
// 系统-组织-项目成员
|
||||||
|
return getProjectMemberOptions(params.projectId, params.keyword);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,6 +416,9 @@
|
||||||
border-color: rgb(var(--primary-5));
|
border-color: rgb(var(--primary-5));
|
||||||
background: rgb(var(--primary-1));
|
background: rgb(var(--primary-1));
|
||||||
}
|
}
|
||||||
|
.arco-icon-hover:hover::before {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep(.ms-table-select-all) {
|
:deep(.ms-table-select-all) {
|
||||||
.arco-checkbox {
|
.arco-checkbox {
|
||||||
|
@ -426,5 +429,14 @@
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
&:hover {
|
||||||
|
border-color: rgb(var(--primary-5));
|
||||||
|
}
|
||||||
|
&::before {
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.arco-checkbox:hover .arco-checkbox-icon-hover::before) {
|
||||||
|
background: none !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,9 +15,13 @@
|
||||||
asterisk-position="end"
|
asterisk-position="end"
|
||||||
:rules="[{ required: true, message: t('project.member.selectMemberEmptyTip') }]"
|
:rules="[{ required: true, message: t('project.member.selectMemberEmptyTip') }]"
|
||||||
>
|
>
|
||||||
<a-select v-model="form.userIds" multiple :placeholder="t('project.member.selectMemberScope')" allow-clear>
|
<MsUserSelector
|
||||||
<a-option v-for="item of memberList" :key="item.id" :value="item.id">{{ item.name }}</a-option>
|
v-model:value="form.userIds"
|
||||||
</a-select>
|
:load-option-params="{ projectId: lastProjectId }"
|
||||||
|
:type="UserRequesetTypeEnum.PROJECT_PERMISSION_MEMBER"
|
||||||
|
placeholder="project.member.selectMemberScope"
|
||||||
|
disabled-key="memberFlag"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
field="roleIds"
|
field="roleIds"
|
||||||
|
@ -40,8 +44,14 @@
|
||||||
import { getProjectMemberOptions, addOrUpdateProjectMember } from '@/api/modules/project-management/projectMember';
|
import { getProjectMemberOptions, addOrUpdateProjectMember } from '@/api/modules/project-management/projectMember';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useUserStore } from '@/store';
|
import { useUserStore } from '@/store';
|
||||||
|
import MsUserSelector from '@/components/business/ms-user-selector/index.vue';
|
||||||
import { FormInstance, Message } from '@arco-design/web-vue';
|
import { FormInstance, Message } from '@arco-design/web-vue';
|
||||||
import type { ProjectUserOption, ActionProjectMember } from '@/models/projectManagement/projectAndPermission';
|
import type {
|
||||||
|
ProjectUserOption,
|
||||||
|
ActionProjectMember,
|
||||||
|
AddProjectMember,
|
||||||
|
} from '@/models/projectManagement/projectAndPermission';
|
||||||
|
import { UserRequesetTypeEnum } from '@/components/business/ms-user-selector/utils';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
@ -58,13 +68,13 @@
|
||||||
|
|
||||||
const visible = ref<boolean>(false);
|
const visible = ref<boolean>(false);
|
||||||
|
|
||||||
const initFormValue: ActionProjectMember = {
|
const initFormValue: AddProjectMember = {
|
||||||
roleIds: ['project_member'],
|
roleIds: ['project_member'],
|
||||||
userIds: [],
|
userIds: [],
|
||||||
projectId: lastProjectId,
|
projectId: lastProjectId as string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const form = ref<ActionProjectMember>({ ...initFormValue });
|
const form = ref<AddProjectMember>({ ...initFormValue });
|
||||||
|
|
||||||
const memberFormRef = ref<FormInstance | null>(null);
|
const memberFormRef = ref<FormInstance | null>(null);
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
v-else
|
v-else
|
||||||
v-model="record.selectUserList"
|
v-model="record.selectUserList"
|
||||||
multiple
|
multiple
|
||||||
|
class="w-[260px]"
|
||||||
:max-tag-count="2"
|
:max-tag-count="2"
|
||||||
@popup-visible-change="(value) => userGroupChange(value, record)"
|
@popup-visible-change="(value) => userGroupChange(value, record)"
|
||||||
>
|
>
|
||||||
|
@ -62,6 +63,7 @@
|
||||||
position="br"
|
position="br"
|
||||||
:title="t('project.member.deleteMemberTip', { name: characterLimit(record.name) })"
|
:title="t('project.member.deleteMemberTip', { name: characterLimit(record.name) })"
|
||||||
:sub-title-tip="t('project.member.subTitle')"
|
:sub-title-tip="t('project.member.subTitle')"
|
||||||
|
:loading="deleteLoading"
|
||||||
@ok="removeMember(record)"
|
@ok="removeMember(record)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -157,7 +159,7 @@
|
||||||
title: 'project.member.tableColumnActions',
|
title: 'project.member.tableColumnActions',
|
||||||
slotName: 'action',
|
slotName: 'action',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 80,
|
width: 100,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -244,7 +246,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// 移除项目成员
|
// 移除项目成员
|
||||||
|
const deleteLoading = ref<boolean>(false);
|
||||||
|
|
||||||
const removeMember = async (record: ProjectMemberItem) => {
|
const removeMember = async (record: ProjectMemberItem) => {
|
||||||
|
deleteLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (lastProjectId && record.id) {
|
if (lastProjectId && record.id) {
|
||||||
await removeProjectMember(lastProjectId, record.id);
|
await removeProjectMember(lastProjectId, record.id);
|
||||||
|
@ -253,6 +258,8 @@
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
deleteLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,16 @@
|
||||||
</template>
|
</template>
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<a-form ref="memberFormRef" :model="form" size="large" layout="vertical">
|
<a-form ref="memberFormRef" :model="form" size="large" layout="vertical">
|
||||||
|
<!-- 编辑项目 -->
|
||||||
<a-form-item v-if="type === 'edit'" :label="t('organization.member.project')" asterisk-position="end">
|
<a-form-item v-if="type === 'edit'" :label="t('organization.member.project')" asterisk-position="end">
|
||||||
<a-select
|
<MsUserSelector
|
||||||
v-model="form.projectIds"
|
v-model:value="form.projectIds"
|
||||||
multiple
|
:load-option-params="{ organizationId: lastOrganizationId }"
|
||||||
:placeholder="t('organization.member.selectProjectScope')"
|
:type="UserRequesetTypeEnum.SYSTEM_ORGANIZATION_PROJECT"
|
||||||
allow-clear
|
placeholder="organization.member.selectProjectScope"
|
||||||
>
|
/>
|
||||||
<a-option v-for="item of props.projectList" :key="item.id" :value="item.id">{{ item.name }}</a-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<!-- 添加成员 -->
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-else
|
v-else
|
||||||
field="memberIds"
|
field="memberIds"
|
||||||
|
@ -33,14 +33,12 @@
|
||||||
asterisk-position="end"
|
asterisk-position="end"
|
||||||
:rules="[{ required: true, message: t('organization.member.selectMemberEmptyTip') }]"
|
:rules="[{ required: true, message: t('organization.member.selectMemberEmptyTip') }]"
|
||||||
>
|
>
|
||||||
<a-select
|
<MsUserSelector
|
||||||
v-model="form.memberIds"
|
v-model:value="form.memberIds"
|
||||||
multiple
|
:load-option-params="{ organizationId: lastOrganizationId }"
|
||||||
:placeholder="t('organization.member.selectMemberScope')"
|
:type="UserRequesetTypeEnum.SYSTEM_ORGANIZATION_MEMBER"
|
||||||
allow-clear
|
placeholder="organization.member.selectMemberScope"
|
||||||
>
|
/>
|
||||||
<a-option v-for="item of memberList" :key="item.id" :value="item.id">{{ item.name }}</a-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
field="userRoleIds"
|
field="userRoleIds"
|
||||||
|
@ -72,9 +70,11 @@
|
||||||
import { ref, watchEffect, watch } from 'vue';
|
import { ref, watchEffect, watch } from 'vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
|
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
|
||||||
import { addOrUpdate, getUser } from '@/api/modules/setting/member';
|
import { addOrUpdate } from '@/api/modules/setting/member';
|
||||||
import { useUserStore } from '@/store';
|
import { useUserStore } from '@/store';
|
||||||
import type { AddorUpdateMemberModel, MemberItem, LinkList } from '@/models/setting/member';
|
import MsUserSelector from '@/components/business/ms-user-selector/index.vue';
|
||||||
|
import type { MemberItem, LinkList } from '@/models/setting/member';
|
||||||
|
import { UserRequesetTypeEnum } from '@/components/business/ms-user-selector/utils';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
@ -82,10 +82,8 @@
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
userGroupOptions: LinkList;
|
userGroupOptions: LinkList;
|
||||||
projectList: LinkList;
|
|
||||||
}>();
|
}>();
|
||||||
const dialogVisible = ref<boolean>(false);
|
const dialogVisible = ref<boolean>(false);
|
||||||
const memberList = ref<LinkList>([]);
|
|
||||||
const title = ref<string>('');
|
const title = ref<string>('');
|
||||||
const type = ref<string>('');
|
const type = ref<string>('');
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
|
@ -95,13 +93,20 @@
|
||||||
|
|
||||||
const confirmLoading = ref<boolean>(false);
|
const confirmLoading = ref<boolean>(false);
|
||||||
const memberFormRef = ref<FormInstance | null>(null);
|
const memberFormRef = ref<FormInstance | null>(null);
|
||||||
const initFormValue = {
|
export interface InitFromType {
|
||||||
|
organizationId?: string;
|
||||||
|
userRoleIds: string[];
|
||||||
|
memberIds: string[];
|
||||||
|
projectIds: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const initFormValue: InitFromType = {
|
||||||
organizationId: userStore.$state?.lastOrganizationId,
|
organizationId: userStore.$state?.lastOrganizationId,
|
||||||
userRoleIds: ['org_member'],
|
userRoleIds: ['org_member'],
|
||||||
memberIds: [],
|
memberIds: [],
|
||||||
projectIds: [],
|
projectIds: [],
|
||||||
};
|
};
|
||||||
const form = ref<AddorUpdateMemberModel>({ ...initFormValue });
|
const form = ref({ ...initFormValue });
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
memberFormRef.value?.resetFields();
|
memberFormRef.value?.resetFields();
|
||||||
form.value = { ...initFormValue };
|
form.value = { ...initFormValue };
|
||||||
|
@ -157,12 +162,9 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const getUserOptions = async () => {
|
|
||||||
memberList.value = await getUser(lastOrganizationId);
|
|
||||||
};
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
dialogVisible.value = props.visible;
|
dialogVisible.value = props.visible;
|
||||||
if (props.visible) getUserOptions();
|
|
||||||
});
|
});
|
||||||
watch(
|
watch(
|
||||||
() => dialogVisible.value,
|
() => dialogVisible.value,
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
multiple
|
multiple
|
||||||
:max-tag-count="2"
|
:max-tag-count="2"
|
||||||
size="small"
|
size="small"
|
||||||
|
class="w-[260px]"
|
||||||
@change="(value) => selectUserOrProject(value, record, 'project')"
|
@change="(value) => selectUserOrProject(value, record, 'project')"
|
||||||
@popup-visible-change="visibleChange($event, record, 'project')"
|
@popup-visible-change="visibleChange($event, record, 'project')"
|
||||||
>
|
>
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
v-model="record.selectUserList"
|
v-model="record.selectUserList"
|
||||||
multiple
|
multiple
|
||||||
:max-tag-count="2"
|
:max-tag-count="2"
|
||||||
|
class="w-[260px]"
|
||||||
@change="(value) => selectUserOrProject(value, record, 'user')"
|
@change="(value) => selectUserOrProject(value, record, 'user')"
|
||||||
@popup-visible-change="(value) => visibleChange(value, record, 'user')"
|
@popup-visible-change="(value) => visibleChange(value, record, 'user')"
|
||||||
>
|
>
|
||||||
|
@ -79,6 +81,7 @@
|
||||||
position="br"
|
position="br"
|
||||||
:title="t('organization.member.deleteMemberTip', { name: characterLimit(record.name) })"
|
:title="t('organization.member.deleteMemberTip', { name: characterLimit(record.name) })"
|
||||||
:sub-title-tip="t('organization.member.subTitle')"
|
:sub-title-tip="t('organization.member.subTitle')"
|
||||||
|
:loading="deleteLoading"
|
||||||
@ok="deleteMember(record)"
|
@ok="deleteMember(record)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -126,7 +129,7 @@
|
||||||
import { useTableStore, useUserStore } from '@/store';
|
import { useTableStore, useUserStore } from '@/store';
|
||||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import type { MemberItem, AddorUpdateMemberModel, LinkList, BatchAddProjectModel } from '@/models/setting/member';
|
import type { MemberItem, AddorUpdateMemberModel, LinkList, BatchAddProjectModel } from '@/models/setting/member';
|
||||||
import { characterLimit } from '@/utils';
|
import { characterLimit, findNodeByKey } from '@/utils';
|
||||||
import MsTagGroup from '@/components/pure/ms-tag/ms-tag-group.vue';
|
import MsTagGroup from '@/components/pure/ms-tag/ms-tag-group.vue';
|
||||||
|
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
|
@ -230,13 +233,18 @@
|
||||||
AddMemberRef.value.edit(record);
|
AddMemberRef.value.edit(record);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deleteLoading = ref<boolean>(false);
|
||||||
const deleteMember = async (record: MemberItem) => {
|
const deleteMember = async (record: MemberItem) => {
|
||||||
|
deleteLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (lastOrganizationId) await deleteMemberReq(lastOrganizationId, record.id);
|
if (lastOrganizationId) await deleteMemberReq(lastOrganizationId, record.id);
|
||||||
Message.success(t('organization.member.deleteMemberSuccess'));
|
Message.success(t('organization.member.deleteMemberSuccess'));
|
||||||
initData();
|
initData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
deleteLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleTableSelect = (selectArr: (string | number)[]) => {
|
const handleTableSelect = (selectArr: (string | number)[]) => {
|
||||||
|
|
Loading…
Reference in New Issue