feat(系统设置): 用户组管理删除用户
This commit is contained in:
parent
cc2c29f7b8
commit
70874bab31
|
@ -1,16 +1,16 @@
|
|||
import MSR from '@/api/http/index';
|
||||
import { GetApiTestList, GetApiTestListUrl } from '@/api/requrls/api-test';
|
||||
import { TableQueryParams } from '@/models/common';
|
||||
import { CommonList } from '@/models/api-test';
|
||||
import { TableQueryParams, CommonList } from '@/models/common';
|
||||
import { APIListItemI } from '@/models/api-test';
|
||||
|
||||
export function getTableList(params: TableQueryParams) {
|
||||
const { current, pageSize, sort, filter, keyword } = params;
|
||||
return MSR.post<CommonList>({
|
||||
return MSR.post<CommonList<APIListItemI>>({
|
||||
url: GetApiTestList,
|
||||
data: { current, pageSize, sort, filter, keyword, projectId: 'test-project-id' },
|
||||
});
|
||||
}
|
||||
|
||||
export function getlist() {
|
||||
return MSR.get<CommonList>({ url: GetApiTestListUrl });
|
||||
return MSR.get<CommonList<APIListItemI>>({ url: GetApiTestListUrl });
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import MSR from '@/api/http/index';
|
||||
import { updateUserGroupU, getUserGroupU, addUserGroupU, deleteUserGroupU } from '@/api/requrls/usergroup';
|
||||
// import { QueryParams, CommonList } from '@/models/common';
|
||||
import { UserGroupItem } from '@/components/bussiness/usergroup/type';
|
||||
|
||||
export function updateOrAddUserGroup(data: Partial<UserGroupItem>) {
|
||||
return MSR.post<UserGroupItem>({
|
||||
url: data.id ? updateUserGroupU : addUserGroupU,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateSocpe(data: Partial<UserGroupItem>) {
|
||||
return MSR.post<UserGroupItem>({
|
||||
url: updateUserGroupU,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function getUserGroupList() {
|
||||
return MSR.get<UserGroupItem[]>({ url: getUserGroupU });
|
||||
}
|
||||
|
||||
export function deleteUserGroup(id: string) {
|
||||
return MSR.get<string>({ url: `${deleteUserGroupU}${id}` });
|
||||
}
|
||||
|
||||
export function getUsergroupInfo(id: string) {
|
||||
return MSR.get<UserGroupItem>({ url: `${getUserGroupU}${id}` });
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/** 修改用户组 */
|
||||
export const updateUserGroupU = `/user/role/global/update`;
|
||||
/** 编辑用户组对应的权限配置 */
|
||||
export const editGlobalUSetting = `/user/role/global/permission/update`;
|
||||
/** 添加用户组 */
|
||||
export const addUserGroupU = `/user/role/global/add`;
|
||||
/** 获取用户组对应的权限配置 */
|
||||
export const getGlobalUSetting = `/user/role/global/permission/list`;
|
||||
/** 获取用户组 */
|
||||
export const getUserGroupU = `/user/role/global/list`;
|
||||
/** 获取单个用户组信息 */
|
||||
export const getUsergroupInfoU = `/user/role/global/get/`;
|
||||
/** 删除用户组 */
|
||||
export const deleteUserGroupU = `/user/role/global/delete/`;
|
||||
|
||||
/** 根据用户组获取用户列表 */
|
||||
export const getUserByUserGroupU = `/user/role/relation/global/list/`;
|
||||
/** 创建用户组添加用户 */
|
||||
export const addUserToUserGroupU = `/user/role/relation/global/add/`;
|
||||
/** 删除用户组用户 */
|
||||
export const deleteUserFromUserGroupU = `/user/role/relation/global/delete/`;
|
|
@ -0,0 +1,58 @@
|
|||
<template>
|
||||
<a-modal v-model:visible="currentVisible" modal-class="ug-delete">
|
||||
<template #title>
|
||||
<div class="flex w-full items-center">
|
||||
<icon-exclamation-circle-fill class="danger" />
|
||||
<span class="n1"> {{ t('system.userGroup.isDeleteUserGroup', { name: store.currentName }) }} </span>
|
||||
</div>
|
||||
</template>
|
||||
<div>{{ t('system.userGroup.beforeDeleteUserGroup') }}</div>
|
||||
<template #footer>
|
||||
<a-button @click="emit('cancel')">{{ t('cancel') }}</a-button>
|
||||
<a-button type="primary" @click="emit('ok')">{{ t('confirmDelete') }}</a-button>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { ref, watchEffect } from 'vue';
|
||||
import useUserGroupStore from '@/store/modules/system/usergroup';
|
||||
|
||||
const { t } = useI18n();
|
||||
const store = useUserGroupStore();
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
}>();
|
||||
|
||||
const currentVisible = ref(props.visible);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'cancel'): void;
|
||||
(e: 'ok'): void;
|
||||
}>();
|
||||
|
||||
watchEffect(() => {
|
||||
currentVisible.value = props.visible;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.ug-delete {
|
||||
.danger {
|
||||
font-size: 20px;
|
||||
color: rgb(var(--danger-6));
|
||||
}
|
||||
.n1 {
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
.arco-modal-header {
|
||||
border-bottom: none;
|
||||
}
|
||||
:deep(.arco-modal-title-align-center) {
|
||||
justify-content: flex-start;
|
||||
border: 1px solid red;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -13,7 +13,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<div
|
||||
v-for="element in customList"
|
||||
v-for="element in userGroupList"
|
||||
:key="element.id"
|
||||
:class="{
|
||||
'flex': true,
|
||||
|
@ -28,13 +28,15 @@
|
|||
:visible="popVisible[element.id]"
|
||||
:type="popType"
|
||||
:default-name="popDefaultName"
|
||||
:list="userGroupList"
|
||||
position="bl"
|
||||
@cancel="() => handlePopConfirmCancel(element.id)"
|
||||
@submit="(value: CustomMoreActionItem) => handlePopConfirmSubmit(value,element.id)"
|
||||
>
|
||||
<div class="draglist-item flex grow flex-row justify-between">
|
||||
<div class="usergroup-title leading-[24px]">
|
||||
<span class="n1">{{ element.name }}</span>
|
||||
<span v-if="element.title" class="n4">{{ `(${element.title})` }}</span>
|
||||
<span v-if="element.type" class="n4">({{ t(`system.userGroup.${element.type}`) }})</span>
|
||||
</div>
|
||||
<div v-if="element.id === currentId">
|
||||
<MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" />
|
||||
|
@ -47,43 +49,38 @@
|
|||
</div>
|
||||
<AddUserModal :visible="addUserVisible" @cancel="addUserVisible = false" />
|
||||
<AddUserGroupModal :visible="addUserGroupVisible" @cancel="addUserGroupVisible = false" />
|
||||
<DeleteUserGroupModal :visible="deleteUserGroupVisible" @cancel="deleteUserGroupVisible = false" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onBeforeMount } from 'vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { PopVisibleItem, RenameType, UserGroupListItem } from './type';
|
||||
import { CustomMoreActionItem, PopVisibleItem, RenameType, UserGroupItem } from './type';
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import AddUserModal from './addUserModal.vue';
|
||||
import AddUserGroupModal from './addUserGroupModal.vue';
|
||||
import DeleteUserGroupModal from './deleteUserGroupModal.vue';
|
||||
import popconfirm from './popconfirm.vue';
|
||||
import useUserGroupStore from '@/store/modules/system/usergroup';
|
||||
import { getUserGroupList, updateOrAddUserGroup } from '@/api/modules/system/usergroup';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const searchKey = ref('');
|
||||
const store = useUserGroupStore();
|
||||
// 请求loading
|
||||
const currentId = ref(0);
|
||||
const currentId = ref('');
|
||||
const addUserVisible = ref(false);
|
||||
const addUserGroupVisible = ref(false);
|
||||
const deleteUserGroupVisible = ref(false);
|
||||
// 修改用户组名字,权限范围
|
||||
const popVisible = ref<PopVisibleItem>({});
|
||||
// 用户组和权限范围的状态
|
||||
const popType = ref<RenameType>('rename');
|
||||
const popDefaultName = ref('');
|
||||
// 用户列表
|
||||
const customList = ref<UserGroupListItem[]>([
|
||||
{ name: '系统管理员', title: '', id: 1, authScope: 'system' },
|
||||
{ name: '系统成员', title: '', id: 2, authScope: 'system' },
|
||||
{ name: '组织管理员', title: '', id: 3, authScope: 'system' },
|
||||
{ name: '组织成员', title: '', id: 4, authScope: 'system' },
|
||||
{ name: '项目管理员', title: '', id: 5, authScope: 'system' },
|
||||
{ name: '项目成员', title: '', id: 6, authScope: 'system' },
|
||||
{ name: '自定义用户组1', title: '项目', id: 7, authScope: 'project' },
|
||||
{ name: '自定义用户组2', title: '组织', id: 8, authScope: 'oraganation' },
|
||||
]);
|
||||
const userGroupList = ref<UserGroupItem[]>([]);
|
||||
|
||||
const customAction: ActionsItem[] = [
|
||||
{
|
||||
|
@ -105,44 +102,99 @@
|
|||
eventTag: 'delete',
|
||||
},
|
||||
];
|
||||
|
||||
// 新增用户组
|
||||
const addUserGroup = () => {
|
||||
// eslint-disable-next-line no-console
|
||||
addUserGroupVisible.value = true;
|
||||
};
|
||||
|
||||
function searchData(keyword: string) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(keyword);
|
||||
}
|
||||
|
||||
const handleMoreAction = (item: ActionsItem, id: number) => {
|
||||
// 点击更多操作
|
||||
const handleMoreAction = (item: ActionsItem, id: string) => {
|
||||
if (item.eventTag !== 'delete') {
|
||||
popType.value = item.eventTag as RenameType;
|
||||
const tmpObj = customList.value.filter((ele) => ele.id === id)[0];
|
||||
const tmpObj = userGroupList.value.filter((ele) => ele.id === id)[0];
|
||||
popVisible.value = { ...popVisible.value, [id]: true };
|
||||
if (item.eventTag === 'rename') {
|
||||
popDefaultName.value = tmpObj.name;
|
||||
} else {
|
||||
popDefaultName.value = tmpObj.authScope;
|
||||
popDefaultName.value = tmpObj.scopeId;
|
||||
}
|
||||
} else {
|
||||
// 删除用户组
|
||||
deleteUserGroupVisible.value = true;
|
||||
}
|
||||
};
|
||||
const handlePopConfirmCancel = (id: number) => {
|
||||
|
||||
// 点击用户组列表
|
||||
const handleListItemClick = (element: UserGroupItem) => {
|
||||
const { id, name, type } = element;
|
||||
currentId.value = id;
|
||||
store.setInfo({ currentName: name, currentTitle: type });
|
||||
};
|
||||
|
||||
// 用户组数据初始化
|
||||
const initData = async () => {
|
||||
try {
|
||||
const res = await getUserGroupList();
|
||||
if (res.length > 0) {
|
||||
userGroupList.value = res;
|
||||
handleListItemClick(res[0]);
|
||||
// 弹窗赋值
|
||||
const tmpObj: PopVisibleItem = {};
|
||||
res.forEach((element) => {
|
||||
tmpObj[element.id] = false;
|
||||
});
|
||||
popVisible.value = tmpObj;
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
// 关闭confirm 弹窗
|
||||
const handlePopConfirmCancel = (id: string) => {
|
||||
popVisible.value = { ...popVisible.value, [id]: false };
|
||||
};
|
||||
onBeforeMount(() => {
|
||||
const tmpObj: PopVisibleItem = {};
|
||||
customList.value.forEach((element) => {
|
||||
tmpObj[element.id] = false;
|
||||
});
|
||||
popVisible.value = tmpObj;
|
||||
});
|
||||
const handleListItemClick = (element: UserGroupListItem) => {
|
||||
const { id, name, title } = element;
|
||||
currentId.value = id;
|
||||
store.setInfo({ currentName: name, currentTitle: title });
|
||||
// 修改用户组名字,权限范围
|
||||
const handlePopConfirmSubmit = async (item: CustomMoreActionItem, id: string) => {
|
||||
popVisible.value = { ...popVisible.value, [id]: false };
|
||||
if (item.eventKey === 'rename') {
|
||||
// 修改用户组名字
|
||||
try {
|
||||
const res = await updateOrAddUserGroup({ id, name: item.name });
|
||||
if (res) {
|
||||
initData();
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
} else {
|
||||
// 修改权限范围
|
||||
try {
|
||||
const res = await updateOrAddUserGroup({ id, scopeId: item.name });
|
||||
if (res) {
|
||||
initData();
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
initData();
|
||||
};
|
||||
|
||||
function searchData(eve: Event) {
|
||||
if (!(eve.target as HTMLInputElement).value) {
|
||||
initData();
|
||||
return;
|
||||
}
|
||||
const keyword = (eve.target as HTMLInputElement).value;
|
||||
const tmpArr = userGroupList.value.filter((ele) => ele.name.includes(keyword));
|
||||
userGroupList.value = tmpArr;
|
||||
}
|
||||
onMounted(() => {
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
|
|
@ -3,21 +3,23 @@
|
|||
:popup-visible="renameVisible"
|
||||
:ok-text="t('system.userGroup.confirm')"
|
||||
:cancel-text="t('system.userGroup.cancel')"
|
||||
:blur-to-close="false"
|
||||
:click-to-close="false"
|
||||
:click-outside-to-close="false"
|
||||
@ok="handleSubmit('rename')"
|
||||
@cancel="handleRenameCancel"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
@popup-visible-change="() => (form.name = '')"
|
||||
>
|
||||
<template #icon>{{ null }}</template>
|
||||
<template #content>
|
||||
<a-form :model="form" :label-col-props="{ span: 0 }" :wrapper-col-props="{ span: 24 }">
|
||||
<a-form ref="formRef" :model="form" :label-col-props="{ span: 0 }" :wrapper-col-props="{ span: 24 }">
|
||||
<a-form-item>
|
||||
<div class="title">{{ message.title }}</div>
|
||||
</a-form-item>
|
||||
<a-form-item field="name" :rules="[{ required: true, message: message.rule }]">
|
||||
<a-input v-model="form.name" />
|
||||
<a-form-item field="name" :rules="[{ validator: validateName }]">
|
||||
<a-input v-if="props.type === 'rename'" v-model="form.name" />
|
||||
<a-select v-else v-model="form.name" class="w-[176px]">
|
||||
<a-option value="SYSTEM">{{ t('system.userGroup.SYSTEM') }}</a-option>
|
||||
<a-option value="ORGANIZATION">{{ t('system.userGroup.ORGANIZATION') }}</a-option>
|
||||
<a-option value="PROJECT">{{ t('system.userGroup.PROJECT') }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
@ -27,20 +29,48 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { watchEffect, reactive, ref, computed } from 'vue';
|
||||
import { CustomMoreActionItem, RenameType } from './type';
|
||||
import { watchEffect, reactive, ref, computed, onUnmounted } from 'vue';
|
||||
import { CustomMoreActionItem, RenameType, UserGroupItem } from './type';
|
||||
import { ValidatedError } from '@arco-design/web-vue';
|
||||
import useUserGroupStore from '@/store/modules/system/usergroup';
|
||||
|
||||
const { t } = useI18n();
|
||||
const formRef = ref();
|
||||
const form = reactive({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const store = useUserGroupStore();
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
defaultName: string;
|
||||
type: RenameType;
|
||||
list: UserGroupItem[];
|
||||
}>();
|
||||
|
||||
const validateName = (value: string, callback: (error?: string) => void) => {
|
||||
if (props.type === 'rename') {
|
||||
if (value === '') {
|
||||
callback(t('system.userGroup.userGroupNameIsNotNone'));
|
||||
} else {
|
||||
if (value === props.defaultName) {
|
||||
callback();
|
||||
} else {
|
||||
const isExist = props.list.some((item) => item.name === value);
|
||||
if (isExist) {
|
||||
callback(t('system.userGroup.userGroupNameIsExist', { name: value }));
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
} else if (value === '') {
|
||||
callback(t('system.userGroup.userGroupAuthScopeIsNotNone'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const message = computed(() => {
|
||||
if (props.type === 'rename') {
|
||||
return {
|
||||
|
@ -55,22 +85,31 @@
|
|||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'submit', value: CustomMoreActionItem): void;
|
||||
(e: 'submit', value: CustomMoreActionItem): Promise<void>;
|
||||
(e: 'cancel'): void;
|
||||
}>();
|
||||
|
||||
const renameVisible = ref(props.visible);
|
||||
|
||||
const handleSubmit = (type: string) => {
|
||||
// eslint-disable-next-line no-console
|
||||
emit('submit', { eventKey: type, name: form.name });
|
||||
const handleSubmit = () => {
|
||||
formRef.value.validate((errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (!errors) {
|
||||
emit('submit', { eventKey: props.type, name: form.name });
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleRenameCancel = () => {
|
||||
const handleCancel = () => {
|
||||
form.name = '';
|
||||
emit('cancel');
|
||||
};
|
||||
watchEffect(() => {
|
||||
renameVisible.value = props.visible;
|
||||
form.name = props.defaultName;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
handleCancel();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -14,7 +14,28 @@ export interface CustomMoreActionItem {
|
|||
name: string;
|
||||
}
|
||||
export interface PopVisibleItem {
|
||||
[key: number]: boolean;
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
||||
export type RenameType = 'rename' | 'auth';
|
||||
|
||||
export interface UserGroupItem {
|
||||
// 组ID
|
||||
id: string;
|
||||
// 组名称
|
||||
name: string;
|
||||
// 组描述
|
||||
description: string;
|
||||
// 是否是内置用户组
|
||||
internal: true;
|
||||
// 所属类型
|
||||
type: string;
|
||||
createTime: number;
|
||||
updateTime: number;
|
||||
// 创建人
|
||||
createUser: string;
|
||||
// 应用范围
|
||||
scopeId: string;
|
||||
// 自定义排序
|
||||
pos: number;
|
||||
}
|
||||
|
|
|
@ -17,17 +17,11 @@
|
|||
<slot :name="key" v-bind="{ rowIndex, record, column }"></slot>
|
||||
</template>
|
||||
</a-table>
|
||||
<div v-if="selectCurrent > 0" class="mt-[21px]">
|
||||
<div v-if="selectCurrent > 0 && attrs.showSelectAll" class="mt-[21px]">
|
||||
<batch-action
|
||||
:select-row-count="selectCurrent"
|
||||
@batch-export="emit('batchExport')"
|
||||
@batch-edit="emit('batchEdit')"
|
||||
@batch-move="emit('batchMoveTo')"
|
||||
@batch-copy="emit('batchCopyTo')"
|
||||
@batch-related="emit('batchRelated')"
|
||||
@batch-generate="emit('batchGenerate')"
|
||||
@batch-add-public="emit('batchAddPublic')"
|
||||
@batch-delete="emit('batchDelete')"
|
||||
:action-config="props.actionConfig"
|
||||
@batch-action="(item: BatchActionParams) => emit('batchAction', item)"
|
||||
@clear="selectionChange([], true)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -37,28 +31,19 @@
|
|||
<script lang="ts" setup>
|
||||
import { useSlots, useAttrs, computed, ref, onMounted } from 'vue';
|
||||
import selectAll from './select-all.vue';
|
||||
import { MsTableProps, SelectAllEnum, MsPaginationI } from './type';
|
||||
import { MsTableProps, SelectAllEnum, MsPaginationI, BatchActionParams, BatchActionConfig } from './type';
|
||||
import BatchAction from './batchAction.vue';
|
||||
|
||||
import type { TableData } from '@arco-design/web-vue';
|
||||
|
||||
const batchleft = ref('10px');
|
||||
const props = defineProps({
|
||||
selectedKeys: {
|
||||
type: Array as unknown as () => (string | number)[],
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
const props = defineProps<{
|
||||
selectedKeys?: (string | number)[];
|
||||
actionConfig?: BatchActionConfig;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'selectedChange', value: (string | number)[]): void;
|
||||
(e: 'batchExport'): void;
|
||||
(e: 'batchEdit'): void;
|
||||
(e: 'batchMoveTo'): void;
|
||||
(e: 'batchCopyTo'): void;
|
||||
(e: 'batchRelated'): void;
|
||||
(e: 'batchGenerate'): void;
|
||||
(e: 'batchAddPublic'): void;
|
||||
(e: 'batchDelete'): void;
|
||||
(e: 'batchAction', value: BatchActionParams): void;
|
||||
}>();
|
||||
const isSelectAll = ref(false);
|
||||
// 全选按钮-当前的条数
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
<template>
|
||||
<div class="ms-table__patch-action">
|
||||
<div v-if="props.actionConfig" class="ms-table__patch-action">
|
||||
<span class="title">{{ t('msTable.batch.selected', { count: props.selectRowCount }) }}</span>
|
||||
<a-button class="ml-4" type="outline" @click="emit('batchExport')">{{ t('msTable.batch.export') }}</a-button>
|
||||
<a-button class="ml-3" type="outline" @click="emit('batchEdit')">{{ t('msTable.batch.edit') }}</a-button>
|
||||
<a-button class="ml-3" type="outline" @click="emit('batchMoveTo')">{{ t('msTable.batch.moveTo') }}</a-button>
|
||||
<a-button class="ml-3" type="outline" @click="emit('batchCopyTo')">{{ t('msTable.batch.copyTo') }}</a-button>
|
||||
<div class="relative top-[2px] ml-3 inline-block">
|
||||
<template v-for="element in props.actionConfig.baseAction" :key="element.label">
|
||||
<a-divider v-if="element.isDivider" class="mx-0 my-[6px]" />
|
||||
<a-button
|
||||
v-else
|
||||
:class="{
|
||||
'delete': element.danger,
|
||||
'ml-4': true,
|
||||
}"
|
||||
type="outline"
|
||||
@click="emit('batchAction', element)"
|
||||
>{{ t(element.label as string) }}</a-button
|
||||
>
|
||||
</template>
|
||||
<div v-if="props.actionConfig.moreAction" class="relative top-[2px] ml-3 inline-block">
|
||||
<a-dropdown position="tr">
|
||||
<a-button type="outline"><a-icon-more /></a-button>
|
||||
<template #content>
|
||||
<a-doption @click="emit('batchRelated')">{{ t('msTable.batch.related') }}</a-doption>
|
||||
<a-doption @click="emit('batchGenerate')">{{ t('msTable.batch.generateDep') }}</a-doption>
|
||||
<a-doption @click="emit('batchAddTo')">{{ t('msTable.batch.addPublic') }}</a-doption>
|
||||
<a-divider margin="0" />
|
||||
<a-doption class="delete" @click="emit('batchExport')">{{ t('msTable.batch.delete') }}</a-doption>
|
||||
<template v-for="element in props.actionConfig.moreAction" :key="element.label">
|
||||
<a-divider v-if="element.isDivider" margin="0" />
|
||||
<a-doption v-else :value="element" :class="{ delete: element.danger }">{{
|
||||
t(element.label as string)
|
||||
}}</a-doption>
|
||||
</template>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
|
@ -23,22 +33,15 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { BatchActionConfig, BatchActionParams } from './type';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
selectRowCount: {
|
||||
type: Number,
|
||||
},
|
||||
});
|
||||
const props = defineProps<{
|
||||
selectRowCount?: number;
|
||||
actionConfig?: BatchActionConfig;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'batchExport'): void;
|
||||
(e: 'batchEdit'): void;
|
||||
(e: 'batchMoveTo'): void;
|
||||
(e: 'batchCopyTo'): void;
|
||||
(e: 'batchRelated'): void;
|
||||
(e: 'batchGenerate'): void;
|
||||
(e: 'batchAddTo'): void;
|
||||
(e: 'batchDelete'): void;
|
||||
(e: 'batchAction', value: BatchActionParams): void;
|
||||
(e: 'clear'): void;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
@ -70,3 +70,14 @@ export enum SelectAllEnum {
|
|||
export interface SortItem {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface BatchActionParams {
|
||||
label?: string;
|
||||
eventTag?: string;
|
||||
isDivider?: boolean;
|
||||
danger?: boolean;
|
||||
}
|
||||
export interface BatchActionConfig {
|
||||
baseAction: BatchActionParams[];
|
||||
moreAction?: BatchActionParams[];
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export interface ListItemI {
|
||||
export interface APIListItemI {
|
||||
id: number;
|
||||
type: string;
|
||||
receiver: string;
|
||||
|
@ -19,10 +19,3 @@ export interface SortItem {
|
|||
export interface FilterItem {
|
||||
[key: string]: any;
|
||||
}
|
||||
export interface CommonList {
|
||||
[x: string]: any;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
current: number;
|
||||
list: ListItemI;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,7 @@ export interface TableQueryParams {
|
|||
keyword?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface TableResult<T> {
|
||||
export interface CommonList<T> {
|
||||
[x: string]: any;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
|
|
|
@ -2,4 +2,5 @@ export interface UserGroupState {
|
|||
// 当前用户组名字
|
||||
currentName: string;
|
||||
currentTitle: string;
|
||||
currentId: string;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ const useUserGroupStore = defineStore('userGroup', {
|
|||
state: (): UserGroupState => ({
|
||||
currentName: '',
|
||||
currentTitle: '',
|
||||
currentId: '',
|
||||
}),
|
||||
getters: {
|
||||
userGroupInfo(state: UserGroupState): UserGroupState {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="h-[100vh] bg-white px-[20px] py-[16px] pb-0">
|
||||
<ms-base-table v-bind="propsRes" v-on="propsEvent"> </ms-base-table>
|
||||
<ms-base-table v-bind="propsRes" :action-config="actionConfig" v-on="propsEvent"> </ms-base-table>
|
||||
</div>
|
||||
<a-divider />
|
||||
</template>
|
||||
|
@ -8,7 +8,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import { BatchActionConfig, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import { getTableList } from '@/api/modules/api-test/index';
|
||||
|
||||
|
@ -92,6 +92,64 @@
|
|||
},
|
||||
];
|
||||
|
||||
const actionConfig: BatchActionConfig = {
|
||||
baseAction: [
|
||||
{
|
||||
label: 'msTable.batch.export',
|
||||
eventTag: 'batchExport',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
{
|
||||
label: 'msTable.batch.edit',
|
||||
eventTag: 'batchEdit',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
{
|
||||
label: 'msTable.batch.moveTo',
|
||||
eventTag: 'batchMoveTo',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
{
|
||||
label: 'msTable.batch.copyTo',
|
||||
eventTag: 'batchCopyTo',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
],
|
||||
moreAction: [
|
||||
{
|
||||
label: 'msTable.batch.related',
|
||||
eventTag: 'batchRelated',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
{
|
||||
label: 'msTable.batch.generateDep',
|
||||
eventTag: 'batchGenerate',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
{
|
||||
label: 'msTable.batch.addPublic',
|
||||
eventTag: 'batchAddTo',
|
||||
isDivider: false,
|
||||
danger: false,
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
{
|
||||
label: 'msTable.batch.delete',
|
||||
eventTag: 'batchDelete',
|
||||
isDivider: false,
|
||||
danger: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const { propsRes, propsEvent, loadList } = useTable(getTableList, {
|
||||
columns,
|
||||
scroll: { y: 750, x: 2000 },
|
||||
|
|
|
@ -25,6 +25,7 @@ export default {
|
|||
revoke: 'revoke',
|
||||
pleaseSelectUser: 'Please select user',
|
||||
pleaseInputUserGroupName: 'Please input user group name,and not equal to system user group name',
|
||||
userGroupNameIsExist: `Usergroup {name} is exist`,
|
||||
pleaseSelectAuthScope: 'Please select auth scope',
|
||||
userGroupNameIsNotNone: 'User group name is not none',
|
||||
authScopeIsNotNone: 'Auth scope is not none',
|
||||
|
@ -32,6 +33,13 @@ export default {
|
|||
confirm: 'Confirm',
|
||||
global: 'Global',
|
||||
searchPlacehoder: 'Search by ID/Name',
|
||||
SYSTEM: '系统',
|
||||
PROJECT: '项目',
|
||||
ORGANIZATION: '组织',
|
||||
isDeleteUserGroup: 'Delete or not: {name}?',
|
||||
beforeDeleteUserGroup:
|
||||
'After deletion, the project data under the organization will be deleted together. Please operate with caution!',
|
||||
confirmDelete: 'Confirm delete',
|
||||
},
|
||||
},
|
||||
'system.user.createUser': 'Create User',
|
||||
|
|
|
@ -30,8 +30,15 @@ export default {
|
|||
authScopeIsNotNone: '权限范围不能为空',
|
||||
userIsNotNone: '成员不能为空',
|
||||
pleaseInputUserGroupName: '请输入用户组名称,且不与其他用户组名称重复',
|
||||
userGroupNameIsExist: `用户组{name}已存在`,
|
||||
pleaseSelectAuthScope: '请选择用户组所属的权限范围',
|
||||
searchPlacehoder: '通过ID/名称搜索',
|
||||
SYSTEM: '系统',
|
||||
PROJECT: '项目',
|
||||
ORGANIZATION: '组织',
|
||||
isDeleteUserGroup: '是否删除: {name}?',
|
||||
beforeDeleteUserGroup: '删除后,该组织下的项目数据将一起删除,请谨慎操作!',
|
||||
confirmDelete: '确认删除',
|
||||
},
|
||||
},
|
||||
'system.user.createUser': '创建用户',
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<div class="user-group-left">
|
||||
<UserGroupLeft />
|
||||
</div>
|
||||
<div class="grow-1 overflow-x-scroll p-[24px]">
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<div class="grow-1 w-[100%] overflow-x-scroll p-[24px]">
|
||||
<div class="grow-1 flex flex-row items-center justify-between">
|
||||
<div class="title">{{ store.userGroupInfo.currentName }}</div>
|
||||
<div class="flex items-center">
|
||||
<a-input class="w-[240px]" :placeholder="t('system.userGroup.searchPlacehoder')">
|
||||
|
@ -18,7 +18,7 @@
|
|||
</a-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-[16px]">
|
||||
<div class="grow-1 mt-[16px]">
|
||||
<user-table v-if="currentTable === 'user'" />
|
||||
<auth-table v-if="currentTable === 'auth'" />
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue