fix(系统设置): 用户组bug修改

This commit is contained in:
RubyLiu 2023-08-28 18:21:23 +08:00 committed by 刘瑞斌
parent 25d3f18875
commit b424da274b
21 changed files with 86 additions and 159 deletions

View File

@ -5,6 +5,7 @@
type="error"
:title="props.title"
:sub-title-tip="props.subTitleTip"
:loading="props.loading"
@confirm="handleOk"
>
<MsButton>{{ t('common.remove') }}</MsButton>
@ -19,6 +20,7 @@
const props = defineProps<{
title: string;
subTitleTip: string;
loading?: boolean;
}>();
const emit = defineEmits<{

View File

@ -1,5 +1,11 @@
<template>
<a-popconfirm v-bind="attrs" :type="props.type" class="w-[352px]" @before-ok="handleConfirm">
<a-popconfirm
v-bind="attrs"
:type="props.type"
class="w-[352px]"
:ok-loading="props.loading"
@before-ok="handleConfirm"
>
<template v-if="props.type === 'error'" #icon>
<MsIcon type="icon-icon_warning_filled" class="mr-[2px] text-xl text-[rgb(var(--danger-6))]" />
</template>
@ -26,6 +32,7 @@
title: string;
subTitleTip: string;
type: types;
loading?: boolean;
}>(),
{
type: 'warning',

View File

@ -46,12 +46,12 @@
class="flex flex-row flex-nowrap items-center"
>
<slot :name="item.titleSlotName">
<div class="title">{{ t(item.title as string) }}</div>
<div class="text-[var(--color-text-3)]">{{ t(item.title as string) }}</div>
</slot>
<ColumnSelector :table-key="(attrs.tableKey as string)" @close="handleColumnSelectorClose" />
</div>
<slot v-else :name="item.titleSlotName">
<div class="title">{{ t(item.title as string) }}</div>
<div class="text-[var(--color-text-3)]">{{ t(item.title as string) }}</div>
</slot>
</template>
<template #cell="{ column, record, rowIndex }">
@ -344,15 +344,9 @@
line-height: 40px;
cursor: pointer;
}
.title {
color: var(--color-text-3);
}
.batch-action {
justify-content: flex-start;
}
.pop-title {
color: var(--color-text-1);
}
.ms-table-edit-active {
color: rgb(var(--primary-5));
}

View File

@ -8,7 +8,6 @@ export enum TableModuleEnum {
export enum TableKeyEnum {
API_TEST = 'apiTest',
USERGROUPUSER = 'userGroupUser',
SYSTEM_USER = 'systemUser',
SYSTEM_RESOURCEPOOL = 'systemResourcePool',
SYSTEM_AUTH = 'systemAuth',
@ -16,6 +15,8 @@ export enum TableKeyEnum {
SYSTEM_ORGANIZATION = 'systemOrganization',
SYSTEM_PROJECT = 'systemProject',
SYSTEM_LOG = 'systemLog',
ORGANIZATION_MEMBER = 'organizationMember',
ORGANIZATION_PROJECT = 'organizationProject',
}
// 具有特殊功能的列

View File

@ -15,6 +15,7 @@
</a-button>
<a-input-search
v-model:model-value="keyword"
allow-clear
:placeholder="t('system.user.searchUser')"
class="w-[230px]"
@search="searchUser"

View File

@ -6,6 +6,7 @@
v-model="keyword"
:placeholder="t('system.user.searchUser')"
class="w-[240px]"
allow-clear
@press-enter="fetchData"
@search="fetchData"
></a-input-search>

View File

@ -58,6 +58,7 @@
}>();
const emit = defineEmits<{
(e: 'cancel', value: boolean): void;
(e: 'search'): void;
}>();
const formRef = ref<FormInstance>();
@ -104,7 +105,7 @@
Message.success(
props.id ? t('system.userGroup.updateUserGroupSuccess') : t('system.userGroup.addUserGroupSuccess')
);
loading.value = false;
emit('search');
handleCancel();
}
} catch (error) {
@ -117,5 +118,6 @@
};
watchEffect(() => {
currentVisible.value = props.visible;
form.name = props.defaultName || '';
});
</script>

View File

@ -3,30 +3,30 @@
<a-input-search
class="w-[252px]"
:placeholder="t('system.userGroup.searchHolder')"
allow-clear
@press-enter="enterData"
@search="searchData"
/>
<div class="mt-2 flex flex-col">
<div class="flex h-[38px] items-center px-[8px] leading-[24px]">
<div class="second-color"> {{ t('system.userGroup.global') }}</div>
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div>
</div>
<div>
<div
v-for="element in globalUserGroupList"
:key="element.id"
class="flex h-[38px] cursor-pointer items-center px-[8px]"
:class="{
'flex': true,
'h-[38px]': true,
'items-center': true,
'px-[8px]': true,
'is-active': element.id === currentId,
'bg-[rgb(var(--primary-1))]': element.id === currentId,
}"
@click="handleListItemClick(element)"
>
<div class="flex grow flex-row">
<div class="usergroup-title leading-[24px]">
<span class="n1">{{ element.name }}</span>
<span v-if="element.type" class="n4">{{ t(`system.userGroup.${element.type}`) }}</span>
<div class="leading-[24px] text-[var(--color-text-1)]">
<span class="text-[var(--color-text-1)]">{{ element.name }}</span>
<span v-if="element.type" class="text-[var(--color-text-4)]"
>{{ t(`system.userGroup.${element.type}`) }}</span
>
</div>
</div>
</div>
@ -38,18 +38,21 @@
:visible="addUserGroupVisible"
:list="customUserGroupList"
@cancel="handleAddUserGroupCancel"
@search="initData"
>
<div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]">
<div class="second-color"> {{ t('system.userGroup.custom') }}</div>
<div class="primary-color"><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup" /></div>
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.custom') }}</div>
<div class="cursor-pointer text-[rgb(var(--primary-5))]"
><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup"
/></div>
</div>
</AddOrUpdateUserGroupPopup>
<div>
<div
v-for="element in customUserGroupList"
:key="element.id"
class="flex h-[38px] items-center px-[8px]"
:class="{ 'is-active': element.id === currentId }"
class="flex h-[38px] cursor-pointer items-center px-[8px]"
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
@click="handleListItemClick(element)"
>
<AddOrUpdateUserGroupPopup
@ -59,10 +62,12 @@
:list="customUserGroupList"
@cancel="() => handlePopConfirmCancel(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.type" class="n4">{{ t(`system.userGroup.${element.type}`) }}</span>
<div class="flex grow flex-row justify-between">
<div class="leading-[24px] text-[var(--color-text-1)]">
<span class="text-[var(--color-text-1)]">{{ element.name }}</span>
<span v-if="element.type" class="text-[var(--color-text-4)]"
>{{ t(`system.userGroup.${element.type}`) }}</span
>
</div>
<div v-if="element.id === currentId && !element.internal">
<MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" />
@ -171,7 +176,6 @@
//
const handleAddUserGroupCancel = () => {
addUserGroupVisible.value = false;
initData();
};
//
const handleMoreAction = (item: ActionsItem, id: string) => {
@ -236,49 +240,3 @@
initData();
});
</script>
<style scoped lang="less">
.primary-color {
color: rgb(var(--primary-5));
}
.n1 {
color: var(--color-text-1);
}
.n4 {
color: var(--color-text-4);
}
.second-color {
color: var(--color-text-input-border);
}
.handle {
cursor: move;
opacity: 0.3;
}
.is-active {
background-color: rgb(var(--primary-1));
}
.custom-empty {
padding: 8px;
font-size: 12px;
font-family: 'PingFang SC';
font-weight: 400;
border-radius: 4px;
color: #8f959e;
background: #f7f9fc;
font-style: normal;
line-height: 20px;
overflow-wrap: break-word;
}
.button-icon {
display: flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
color: rgb(var(--primary-5));
background-color: rgb(var(--primary-9));
}
.usergroup-title {
color: var(--color-text-1);
}
</style>

View File

@ -16,19 +16,17 @@
import { useI18n } from '@/hooks/useI18n';
import useTable from '@/components/pure/ms-table/useTable';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import { useTableStore, useAppStore } from '@/store';
import { useAppStore } from '@/store';
import useUserGroupStore from '@/store/modules/setting/organization/usergroup';
import { watchEffect, ref, watch, computed } from 'vue';
import { watchEffect, ref, computed } from 'vue';
import { postOrgUserByUserGroup, deleteOrgUserFromUserGroup } from '@/api/modules/setting/usergroup';
import { UserTableItem } from '@/models/setting/usergroup';
import { TableKeyEnum } from '@/enums/tableEnum';
import { MsTableColumn } from '@/components/pure/ms-table/type';
import AddUserModal from './addUserModal.vue';
import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue';
const { t } = useI18n();
const store = useUserGroupStore();
const tableStore = useTableStore();
const appStore = useAppStore();
const currentOrgId = computed(() => appStore.currentOrgId);
const userVisible = ref(false);
@ -57,13 +55,13 @@
},
];
tableStore.initColumn(TableKeyEnum.USERGROUPUSER, userGroupUsercolumns, 'drawer');
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postOrgUserByUserGroup, {
tableKey: TableKeyEnum.USERGROUPUSER,
scroll: { x: '600px' },
selectable: true,
noDisable: true,
columns: userGroupUsercolumns,
scroll: { y: 'auto', x: '600px' },
selectable: false,
noDisable: false,
size: 'default',
showSetting: false,
});
const fetchData = async () => {

View File

@ -16,6 +16,7 @@
v-if="currentTable === 'user'"
:placeholder="t('system.user.searchUser')"
class="w-[240px]"
allow-clear
@press-enter="handleEnter"
@search="handleSearch"
></a-input-search>
@ -56,7 +57,7 @@
import MsButton from '@/components/pure/ms-button/index.vue';
import { useAppStore } from '@/store';
const currentTable = ref('auth');
const currentTable = ref('user');
const { t } = useI18n();
const currentKeyword = ref('');

View File

@ -14,6 +14,7 @@
v-model:model-value="keyword"
:placeholder="t('system.user.searchUser')"
class="w-[230px]"
allow-clear
@search="searchUser"
@press-enter="searchUser"
></a-input-search>

View File

@ -17,6 +17,7 @@
v-model:model-value="keyword"
:placeholder="t('system.user.searchUser')"
class="w-[230px]"
allow-clear
@search="searchUser"
@press-enter="searchUser"
></a-input-search>

View File

@ -12,6 +12,7 @@
<a-input-search
:placeholder="t('system.user.searchUser')"
class="w-[240px]"
allow-clear
@press-enter="handleEnter"
@search="handleSearch"
></a-input-search>

View File

@ -66,5 +66,5 @@ export default {
'system.project.projectNameRequired': '项目名称不能为空',
'system.project.createTip': '项目启用后,将展示在项目切换列表',
'system.project.affiliatedOrgRequired': '所属组织不能为空',
'system.project.revokeDeleteToolTip': '该项目将30 天后自动删除',
'system.project.revokeDeleteToolTip': '该项目将30 天后自动删除',
};

View File

@ -15,6 +15,7 @@
v-model="searchKeys.name"
:max-length="250"
:placeholder="t('system.plugin.searchPlugin')"
allow-clear
@search="searchHandler"
@press-enter="searchHandler"
></a-input-search>

View File

@ -1,6 +1,7 @@
<template>
<div class="user-group-left">
<a-input-search
allow-clear
class="w-[252px]"
:placeholder="t('system.userGroup.searchHolder')"
@press-enter="enterData"
@ -8,24 +9,22 @@
/>
<div class="mt-2 flex flex-col">
<div class="flex h-[38px] items-center justify-between px-[8px] leading-[24px]">
<div class="second-color"> {{ t('system.userGroup.global') }}</div>
<div class="primary-color"><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup" /></div>
<div class="text-[var(--color-text-input-border)]"> {{ t('system.userGroup.global') }}</div>
<div class="cursor-pointer text-[rgb(var(--primary-5))]"
><icon-plus-circle-fill style="font-size: 20px" @click="addUserGroup"
/></div>
</div>
<div>
<div
v-for="element in userGroupList"
:key="element.id"
:class="{
'flex': true,
'h-[38px]': true,
'items-center': true,
'px-[8px]': true,
'is-active': element.id === currentId,
}"
class="flex h-[38px] cursor-pointer items-center px-[8px]"
:class="{ 'bg-[rgb(var(--primary-1))]': element.id === currentId }"
@click="handleListItemClick(element)"
>
<popconfirm
:visible="popVisible[element.id]"
:loading="popLoading[element.id]"
:type="popType"
:default-name="popDefaultName"
:list="userGroupList"
@ -34,9 +33,11 @@
@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.type" class="n4">{{ t(`system.userGroup.${element.type}`) }}</span>
<div class="leading-[24px] text-[var(--color-text-1)]">
<span class="text-[var(--color-text-1)]">{{ element.name }}</span>
<span v-if="element.type" class="text-[var(--color-text-4)]"
>{{ t(`system.userGroup.${element.type}`) }}</span
>
</div>
<div v-if="element.id === currentId && !element.internal">
<MsTableMoreAction :list="customAction" @select="(value) => handleMoreAction(value, element.id)" />
@ -83,6 +84,7 @@
const addUserGrouploading = ref(false);
//
const popVisible = ref<PopVisibleItem>({});
const popLoading = ref<PopVisibleItem>({});
//
const popType = ref<RenameType>('rename');
const popDefaultName = ref('');
@ -95,11 +97,6 @@
danger: false,
eventTag: 'rename',
},
{
label: 'system.userGroup.changeAuthScope',
danger: false,
eventTag: 'changeAuthScope',
},
{
isDivider: true,
},
@ -135,7 +132,8 @@
res.forEach((element) => {
tmpObj[element.id] = false;
});
popVisible.value = tmpObj;
popVisible.value = { ...tmpObj };
popLoading.value = { ...tmpObj };
}
} catch (error) {
// eslint-disable-next-line no-console
@ -192,6 +190,7 @@
if (item.eventKey === 'rename') {
//
try {
popLoading.value = { ...popLoading.value, [id]: true };
const res = await updateOrAddUserGroup({ id, name: item.name });
if (res) {
initData();
@ -199,6 +198,8 @@
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
} finally {
popLoading.value = { ...popLoading.value, [id]: false };
}
} else {
//
@ -256,50 +257,3 @@
initData();
});
</script>
<style scoped lang="less">
.primary-color {
color: rgb(var(--primary-5));
}
.n1 {
color: var(--color-text-1);
}
.n4 {
color: var(--color-text-4);
}
.second-color {
color: var(--color-text-input-border);
}
.handle {
cursor: move;
opacity: 0.3;
}
.is-active {
background-color: rgb(var(--primary-1));
}
.custom-empty {
padding: 8px;
font-size: 12px;
font-family: 'PingFang SC';
font-weight: 400;
border-radius: 4px;
color: #8f959e;
background: #f7f9fc;
font-style: normal;
line-height: 20px;
overflow-wrap: break-word;
}
.button-icon {
display: flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
color: rgb(var(--primary-5));
background-color: rgb(var(--primary-9));
}
.usergroup-title {
color: var(--color-text-1);
}
</style>
@/models/setting/usergroup @/api/modules/setting/usergroup @/store/modules/setting/system/usergroup

View File

@ -3,6 +3,7 @@
:popup-visible="renameVisible"
:ok-text="t('system.userGroup.confirm')"
:cancel-text="t('system.userGroup.cancel')"
:ok-loading="props.loading"
@before-ok="handleSubmit"
@cancel="handleCancel"
@popup-visible-change="() => (form.name = '')"
@ -44,6 +45,7 @@
defaultName: string;
type: RenameType;
list: UserGroupItem[];
loading: boolean;
}>();
const validateName = (value: string | undefined, callback: (error?: string) => void) => {

View File

@ -5,6 +5,7 @@
<MsRemoveButton
:title="t('system.userGroup.removeName', { name: record.name })"
:sub-title-tip="t('system.userGroup.removeTip')"
:loading="removeLoading"
@ok="handleRemove(record)"
/>
</template>
@ -16,20 +17,18 @@
import { useI18n } from '@/hooks/useI18n';
import useTable from '@/components/pure/ms-table/useTable';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import { useTableStore } from '@/store';
import useUserGroupStore from '@/store/modules/setting/system/usergroup';
import { watchEffect, ref } from 'vue';
import { postUserByUserGroup, deleteUserFromUserGroup } from '@/api/modules/setting/usergroup';
import { UserTableItem } from '@/models/setting/usergroup';
import { TableKeyEnum } from '@/enums/tableEnum';
import { MsTableColumn } from '@/components/pure/ms-table/type';
import AddUserModal from './addUserModal.vue';
import MsRemoveButton from '@/components/business/ms-remove-button/MsRemoveButton.vue';
const { t } = useI18n();
const store = useUserGroupStore();
const tableStore = useTableStore();
const userVisible = ref(false);
const removeLoading = ref(false);
const props = defineProps<{
keyword: string;
}>();
@ -55,12 +54,9 @@
},
];
tableStore.initColumn(TableKeyEnum.USERGROUPUSER, userGroupUsercolumns, 'drawer');
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postUserByUserGroup, {
tableKey: TableKeyEnum.USERGROUPUSER,
columns: userGroupUsercolumns,
scroll: { x: '600px' },
selectable: true,
noDisable: true,
});
@ -70,11 +66,14 @@
};
const handleRemove = async (record: UserTableItem) => {
try {
removeLoading.value = true;
await deleteUserFromUserGroup(record.id);
await fetchData();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
removeLoading.value = false;
}
};
const handleAddUser = () => {

View File

@ -16,6 +16,7 @@
v-if="currentTable === 'user'"
:placeholder="t('system.user.searchUser')"
class="w-[240px]"
allow-clear
@press-enter="handleEnter"
@search="handleSearch"
></a-input-search>

View File

@ -2,6 +2,7 @@ export default {
system: {
userGroup: {
addUserGroupSuccess: 'Add user group success',
updateUserGroupSuccess: 'Update user group success',
searchHolder: 'Please input user group name',
inSystem: 'In system',
customUserGroup: 'Custom user group',

View File

@ -2,6 +2,7 @@ export default {
system: {
userGroup: {
addUserGroupSuccess: '添加用户组成功',
updateUserGroupSuccess: '更新用户组成功',
global: '全局用户组',
searchHolder: '请输入用户组名称',
inSystem: '系统内置',