feat: bugs
This commit is contained in:
parent
e8f80094ce
commit
cf674ec981
@ -261,4 +261,25 @@ export default {
|
|||||||
])
|
])
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'app-user-chat': {
|
||||||
|
iconReader: () => {
|
||||||
|
return h('i', [
|
||||||
|
h(
|
||||||
|
'svg',
|
||||||
|
{
|
||||||
|
style: { height: '100%', width: '100%' },
|
||||||
|
viewBox: '0 0 1024 1024',
|
||||||
|
version: '1.1',
|
||||||
|
xmlns: 'http://www.w3.org/2000/svg',
|
||||||
|
},
|
||||||
|
[
|
||||||
|
h('path', {
|
||||||
|
d: 'M426.666667 512a213.333333 213.333333 0 1 1 0.085333-426.752A213.333333 213.333333 0 0 1 426.666667 512z m0-85.333333a128 128 0 0 0 0-256 128 128 0 0 0 0 256z m-384 384a256 256 0 0 1 256-256h256a256 256 0 0 1 256 256v108.330666c0 23.552-19.2 42.666667-42.666667 42.666667H85.333333c-23.466667 0-42.666667-19.114667-42.666666-42.666667V810.666667z m682.666666 0a170.666667 170.666667 0 0 0-170.666666-170.666667H298.666667a170.666667 170.666667 0 0 0-170.666667 170.666667v65.664h597.333333V810.666667z m21.333334-426.666667h213.333333a21.333333 21.333333 0 0 1 21.333333 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333333 21.333333h-213.333333a21.333333 21.333333 0 0 1-21.333334-21.333333v-42.666667a21.333333 21.333333 0 0 1 21.333334-21.333333z m128 170.666667h85.333333a21.333333 21.333333 0 0 1 21.333333 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333333 21.333333h-85.333333a21.333333 21.333333 0 0 1-21.333334-21.333333v-42.666667a21.333333 21.333333 0 0 1 21.333334-21.333333z',
|
||||||
|
fill: 'currentColor',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -192,8 +192,8 @@ const systemRouter = {
|
|||||||
path: '/system/chat',
|
path: '/system/chat',
|
||||||
name: 'SystemChat',
|
name: 'SystemChat',
|
||||||
meta: {
|
meta: {
|
||||||
icon: 'app-shared',
|
icon: 'app-user-chat',
|
||||||
iconActive: 'app-shared-active',
|
iconActive: 'app-user-chat',
|
||||||
title: 'views.chatUser.title',
|
title: 'views.chatUser.title',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
@ -225,7 +225,7 @@ const systemRouter = {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
component: () => import('@/views/system-chat-user/user-manage/index.vue'),
|
component: () => import('@/views/system-chat-user/chat-user/index.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/system/chat/group',
|
path: '/system/chat/group',
|
||||||
|
|||||||
@ -71,7 +71,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import workFlowVersionApi from '@/api/application/work-flow-version'
|
import workFlowVersionApi from '@/api/application/workflow-version'
|
||||||
import { datetimeFormat } from '@/utils/time'
|
import { datetimeFormat } from '@/utils/time'
|
||||||
import { MsgSuccess, MsgError } from '@/utils/message'
|
import { MsgSuccess, MsgError } from '@/utils/message'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
|
|||||||
460
ui/src/views/system-chat-user/chat-user/index.vue
Normal file
460
ui/src/views/system-chat-user/chat-user/index.vue
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chat-user p-24">
|
||||||
|
<el-breadcrumb separator-icon="ArrowRight" class="mb-16">
|
||||||
|
<el-breadcrumb-item>{{ t('views.chatUser.title') }}</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item>
|
||||||
|
<h5 class="ml-4 color-text-primary">{{ t('views.chatUser.title') }}</h5>
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<el-card>
|
||||||
|
<div class="flex-between mb-16">
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="createUser()"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[
|
||||||
|
RoleConst.ADMIN,
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
],
|
||||||
|
[PermissionConst.WORKSPACE_CHAT_USER_CREATE.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ t('views.userManage.createUser') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="syncUsers">
|
||||||
|
{{ $t('views.chatUser.syncUsers') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
:disabled="multipleSelection.length === 0"
|
||||||
|
@click="setUserGroups"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[
|
||||||
|
RoleConst.ADMIN,
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
],
|
||||||
|
[PermissionConst.WORKSPACE_CHAT_USER_GROUP.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t('views.chatUser.setUserGroups') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
:disabled="multipleSelection.length === 0"
|
||||||
|
@click="handleBatchDelete"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[
|
||||||
|
RoleConst.ADMIN,
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
],
|
||||||
|
[PermissionConst.WORKSPACE_CHAT_USER_DELETE.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t('common.delete') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="flex-between complex-search">
|
||||||
|
<el-select
|
||||||
|
class="complex-search__left"
|
||||||
|
v-model="search_type"
|
||||||
|
style="width: 120px"
|
||||||
|
@change="search_type_change"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
||||||
|
<el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name" />
|
||||||
|
</el-select>
|
||||||
|
<el-input
|
||||||
|
v-if="search_type === 'username'"
|
||||||
|
v-model="search_form.username"
|
||||||
|
@change="getList"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
<el-input
|
||||||
|
v-if="search_type === 'nick_name'"
|
||||||
|
v-model="search_form.nick_name"
|
||||||
|
@change="getList"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<app-table
|
||||||
|
class="mt-16"
|
||||||
|
:data="userTableData"
|
||||||
|
:pagination-config="paginationConfig"
|
||||||
|
@sizeChange="handleSizeChange"
|
||||||
|
@changePage="getList"
|
||||||
|
v-loading="loading"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="handleSortChange"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column
|
||||||
|
prop="nick_name"
|
||||||
|
:label="$t('views.userManage.userForm.nick_name.label')"
|
||||||
|
/>
|
||||||
|
<el-table-column prop="username" :label="$t('common.username')" />
|
||||||
|
<el-table-column prop="is_active" :label="$t('common.status.label')" width="100">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="row.is_active" class="flex align-center">
|
||||||
|
<el-icon class="color-success mr-8" style="font-size: 16px">
|
||||||
|
<SuccessFilled />
|
||||||
|
</el-icon>
|
||||||
|
<span class="color-secondary">
|
||||||
|
{{ $t('common.status.enabled') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex align-center">
|
||||||
|
<AppIcon iconName="app-disabled" class="color-secondary mr-8"></AppIcon>
|
||||||
|
<span class="color-secondary">
|
||||||
|
{{ $t('common.status.disabled') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="email"
|
||||||
|
:label="$t('views.login.loginForm.email.label')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.email || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="phone"
|
||||||
|
:label="$t('views.userManage.userForm.phone.label')"
|
||||||
|
width="120"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.phone || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="user_group_names"
|
||||||
|
:label="$t('views.chatUser.group.title')"
|
||||||
|
min-width="110"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<TagGroup :tags="row.user_group_names" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="source" :label="$t('views.userManage.source.label')">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{
|
||||||
|
row.source === 'LOCAL'
|
||||||
|
? $t('views.userManage.source.localCreate')
|
||||||
|
: row.source === 'wecom'
|
||||||
|
? $t('views.userManage.source.wecom')
|
||||||
|
: row.source === 'lark'
|
||||||
|
? $t('views.userManage.source.lark')
|
||||||
|
: row.source === 'dingtalk'
|
||||||
|
? $t('views.userManage.source.dingtalk')
|
||||||
|
: row.source === 'OAUTH2' || row.source === 'OAuth2'
|
||||||
|
? 'OAuth2'
|
||||||
|
: row.source
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="$t('common.createTime')" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ datetimeFormat(row.create_time) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="$t('common.operation')" width="160" align="left" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span @click.stop>
|
||||||
|
<el-switch
|
||||||
|
size="small"
|
||||||
|
v-model="row.is_active"
|
||||||
|
:before-change="() => changeState(row)"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
<span class="mr-8">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
@click.stop="editUser(row)"
|
||||||
|
:title="$t('common.edit')"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[
|
||||||
|
RoleConst.ADMIN,
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
],
|
||||||
|
[PermissionConst.WORKSPACE_CHAT_USER_EDIT.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="mr-8">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
@click.stop="editPwdUser(row)"
|
||||||
|
:title="$t('views.userManage.setting.updatePwd')"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[
|
||||||
|
RoleConst.ADMIN,
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
],
|
||||||
|
[PermissionConst.WORKSPACE_CHAT_USER_EDIT.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-icon>
|
||||||
|
<Lock />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<el-button
|
||||||
|
:disabled="row.role === 'ADMIN'"
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
@click.stop="deleteUserManage(row)"
|
||||||
|
:title="$t('common.delete')"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[
|
||||||
|
RoleConst.ADMIN,
|
||||||
|
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||||
|
RoleConst.USER.getWorkspaceRole,
|
||||||
|
],
|
||||||
|
[PermissionConst.WORKSPACE_CHAT_USER_DELETE.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</app-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<UserDrawer
|
||||||
|
:title="title"
|
||||||
|
:optionLoading="optionLoading"
|
||||||
|
:chatGroupList="chatGroupList"
|
||||||
|
ref="UserDrawerRef"
|
||||||
|
@refresh="refresh"
|
||||||
|
/>
|
||||||
|
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" />
|
||||||
|
<SetUserGroupsDialog
|
||||||
|
:optionLoading="optionLoading"
|
||||||
|
:chatGroupList="chatGroupList"
|
||||||
|
ref="setUserGroupsRef"
|
||||||
|
@refresh="refresh"
|
||||||
|
/>
|
||||||
|
<SyncUsersDialog ref="syncUsersDialogRef" @refresh="refresh" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref, reactive } from 'vue'
|
||||||
|
import UserDrawer from './component/UserDrawer.vue'
|
||||||
|
import UserPwdDialog from './component/UserPwdDialog.vue'
|
||||||
|
import SetUserGroupsDialog from './component/SetUserGroupsDialog.vue'
|
||||||
|
import SyncUsersDialog from './component/SyncUsersDialog.vue'
|
||||||
|
import userManageApi from '@/api/system/chat-user'
|
||||||
|
import { datetimeFormat } from '@/utils/time'
|
||||||
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import type { ChatUserItem } from '@/api/type/systemChatUser'
|
||||||
|
import SystemGroupApi from '@/api/system/user-group'
|
||||||
|
import type { ListItem } from '@/api/type/common'
|
||||||
|
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||||
|
import { ComplexPermission } from '@/utils/permission/type'
|
||||||
|
|
||||||
|
const search_type = ref('username')
|
||||||
|
const search_form = ref<{
|
||||||
|
username: string
|
||||||
|
nick_name?: string
|
||||||
|
}>({
|
||||||
|
username: '',
|
||||||
|
nick_name: '',
|
||||||
|
})
|
||||||
|
const search_type_change = () => {
|
||||||
|
search_form.value = { username: '', nick_name: '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const multipleSelection = ref<any[]>([])
|
||||||
|
|
||||||
|
function handleSelectionChange(val: any[]) {
|
||||||
|
multipleSelection.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
const paginationConfig = reactive({
|
||||||
|
current_page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
const userTableData = ref<ChatUserItem[]>([])
|
||||||
|
|
||||||
|
function getList() {
|
||||||
|
const params = {
|
||||||
|
[search_type.value]: search_form.value[search_type.value as keyof typeof search_form.value],
|
||||||
|
}
|
||||||
|
return userManageApi.getUserManage(paginationConfig, params, loading).then((res) => {
|
||||||
|
userTableData.value = res.data.records
|
||||||
|
paginationConfig.total = res.data.total
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const orderBy = ref<string>('')
|
||||||
|
|
||||||
|
function handleSortChange({ prop, order }: { prop: string; order: string }) {
|
||||||
|
orderBy.value = order === 'ascending' ? prop : `-${prop}`
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSizeChange() {
|
||||||
|
paginationConfig.current_page = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeState(row: ChatUserItem) {
|
||||||
|
const obj = {
|
||||||
|
...row,
|
||||||
|
is_active: !row.is_active,
|
||||||
|
}
|
||||||
|
const str = obj.is_active ? t('common.status.enableSuccess') : t('common.status.disableSuccess')
|
||||||
|
userManageApi
|
||||||
|
.putUserManage(row.id, obj, loading)
|
||||||
|
.then(() => {
|
||||||
|
getList()
|
||||||
|
MsgSuccess(str)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = ref('')
|
||||||
|
const UserDrawerRef = ref()
|
||||||
|
|
||||||
|
function editUser(row: ChatUserItem) {
|
||||||
|
title.value = t('views.userManage.editUser')
|
||||||
|
UserDrawerRef.value.open(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
function createUser() {
|
||||||
|
title.value = t('views.userManage.createUser')
|
||||||
|
UserDrawerRef.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteUserManage(row: ChatUserItem) {
|
||||||
|
MsgConfirm(`${t('views.userManage.delete.confirmTitle')}${row.nick_name} ?`, '', {
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
confirmButtonClass: 'danger',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true
|
||||||
|
userManageApi.delUserManage(row.id, loading).then(() => {
|
||||||
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
const UserPwdDialogRef = ref()
|
||||||
|
|
||||||
|
function editPwdUser(row: ChatUserItem) {
|
||||||
|
UserPwdDialogRef.value.open(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getChatGroupList()
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
|
||||||
|
const optionLoading = ref(false)
|
||||||
|
const chatGroupList = ref<ListItem[]>([])
|
||||||
|
|
||||||
|
async function getChatGroupList() {
|
||||||
|
try {
|
||||||
|
const res = await SystemGroupApi.getUserGroup(optionLoading)
|
||||||
|
chatGroupList.value = res.data
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBatchDelete() {
|
||||||
|
MsgConfirm(t('views.chatUser.batchDeleteUser', { count: multipleSelection.value.length }), '', {
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
confirmButtonClass: 'danger',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
userManageApi
|
||||||
|
.batchDelete(
|
||||||
|
multipleSelection.value.map((item) => item.id),
|
||||||
|
loading,
|
||||||
|
)
|
||||||
|
.then(async () => {
|
||||||
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
|
await getList()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
const setUserGroupsRef = ref<InstanceType<typeof SetUserGroupsDialog>>()
|
||||||
|
|
||||||
|
function setUserGroups() {
|
||||||
|
setUserGroupsRef.value?.open(multipleSelection.value.map((item) => item.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
const syncUsersDialogRef = ref<InstanceType<typeof SyncUsersDialog>>()
|
||||||
|
|
||||||
|
function syncUsers() {
|
||||||
|
syncUsersDialogRef.value?.open()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -1,39 +1,61 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-full">
|
<div class="group p-24">
|
||||||
<ContentContainer>
|
<el-breadcrumb separator-icon="ArrowRight" class="mb-16">
|
||||||
<template #header>
|
<el-breadcrumb-item>{{ t('views.chatUser.title') }}</el-breadcrumb-item>
|
||||||
<div class="shared-header">
|
<el-breadcrumb-item>
|
||||||
<span class="title">{{ t('views.chatUser.title') }}</span>
|
<h5 class="ml-4 color-text-primary">{{ t('views.chatUser.group.title') }}</h5>
|
||||||
<el-icon size="12">
|
</el-breadcrumb-item>
|
||||||
<rightOutlined></rightOutlined>
|
</el-breadcrumb>
|
||||||
</el-icon>
|
<el-card style="--el-card-padding: 0">
|
||||||
<span class="sub-title">{{ t('views.chatUser.group.title') }}</span>
|
<div class="flex">
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-card style="--el-card-padding: 0" class="user-card">
|
|
||||||
<div class="flex h-full">
|
|
||||||
<div class="user-left border-r p-16">
|
<div class="user-left border-r p-16">
|
||||||
<div class="user-left_title flex-between">
|
<div class="p-8 pb-0 mb-12">
|
||||||
|
<div class="flex-between mb-16">
|
||||||
<h4 class="medium">{{ $t('views.chatUser.group.title') }}</h4>
|
<h4 class="medium">{{ $t('views.chatUser.group.title') }}</h4>
|
||||||
<el-tooltip effect="dark" :content="`${$t('common.create')}${$t('views.chatUser.group.title')}`"
|
<el-tooltip
|
||||||
placement="top">
|
effect="dark"
|
||||||
<el-button type="primary" text @click="createOrUpdate()"
|
:content="`${$t('common.create')}${$t('views.chatUser.group.title')}`"
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
placement="top"
|
||||||
[PermissionConst.WORKSPACE_USER_GROUP_CREATE.getWorkspacePermission], [], 'OR')">
|
>
|
||||||
<AppIcon iconName="app-copy"></AppIcon>
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
text
|
||||||
|
@click="createOrUpdate()"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||||
|
[PermissionConst.WORKSPACE_USER_GROUP_CREATE.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-icon :size="18"><Plus /></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-8">
|
<el-input
|
||||||
<el-input v-model="filterText" :placeholder="$t('common.search')" prefix-icon="Search" clearable />
|
v-model="filterText"
|
||||||
|
:placeholder="$t('common.search')"
|
||||||
|
prefix-icon="Search"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="list-height-left">
|
<div class="list-height-left">
|
||||||
<el-scrollbar v-loading="loading">
|
<el-scrollbar v-loading="loading">
|
||||||
<common-list :data="filterList" @click="clickUserGroup" :default-active="current?.id">
|
<common-list
|
||||||
|
:data="filterList"
|
||||||
|
@click="clickUserGroup"
|
||||||
|
:default-active="current?.id"
|
||||||
|
@mouseenter="mouseenter"
|
||||||
|
@mouseleave="mouseId = ''"
|
||||||
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<span class="ellipsis" style="max-width: initial;">{{ row.name }}</span>
|
<span class="ellipsis">{{ row.name }}</span>
|
||||||
|
<div @click.stop v-show="mouseId === row.id">
|
||||||
<el-dropdown :teleported="false">
|
<el-dropdown :teleported="false">
|
||||||
<el-button text>
|
<el-button text>
|
||||||
<el-icon class="color-secondary">
|
<el-icon class="color-secondary">
|
||||||
@ -42,30 +64,54 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu style="min-width: 80px">
|
<el-dropdown-menu style="min-width: 80px">
|
||||||
<el-dropdown-item @click.stop="createOrUpdate(row)" class="p-8"
|
<el-dropdown-item
|
||||||
v-if="hasPermission(new ComplexPermission(
|
@click.stop="createOrUpdate(row)"
|
||||||
|
class="p-8"
|
||||||
|
v-if="
|
||||||
|
hasPermission(
|
||||||
|
new ComplexPermission(
|
||||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||||
[PermissionConst.WORKSPACE_USER_GROUP_EDIT.getWorkspacePermission], [], 'OR'), 'OR')">
|
[
|
||||||
<AppIcon iconName="app-copy"></AppIcon>
|
PermissionConst.WORKSPACE_USER_GROUP_EDIT
|
||||||
{{
|
.getWorkspacePermission,
|
||||||
$t('common.rename')
|
],
|
||||||
}}
|
[],
|
||||||
</el-dropdown-item>
|
'OR',
|
||||||
<el-dropdown-item @click.stop="deleteGroup(row)" class="border-t p-8"
|
),
|
||||||
v-if="row.id !== 'default'&&
|
'OR',
|
||||||
hasPermission(new ComplexPermission(
|
)
|
||||||
[RoleConst.ADMIN,RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
"
|
||||||
[PermissionConst.WORKSPACE_USER_GROUP_DELETE.getWorkspacePermission], [], 'OR'), 'OR')"
|
|
||||||
>
|
>
|
||||||
<AppIcon iconName="app-copy"></AppIcon>
|
<el-icon><EditPen /></el-icon>
|
||||||
{{
|
{{ $t('common.rename') }}
|
||||||
$t('common.delete')
|
</el-dropdown-item>
|
||||||
}}
|
<el-dropdown-item
|
||||||
|
@click.stop="deleteGroup(row)"
|
||||||
|
class="border-t p-8"
|
||||||
|
v-if="
|
||||||
|
row.id !== 'default' &&
|
||||||
|
hasPermission(
|
||||||
|
new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||||
|
[
|
||||||
|
PermissionConst.WORKSPACE_USER_GROUP_DELETE
|
||||||
|
.getWorkspacePermission,
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
),
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
{{ $t('common.delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<span></span>
|
<span></span>
|
||||||
@ -80,23 +126,43 @@
|
|||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
<h4 class="medium">{{ current?.name }}</h4>
|
<h4 class="medium">{{ current?.name }}</h4>
|
||||||
<el-divider direction="vertical" class="mr-8 ml-8" />
|
<el-divider direction="vertical" class="mr-8 ml-8" />
|
||||||
<AppIcon iconName="app-workspace" style="font-size: 16px" class="color-input-placeholder"></AppIcon>
|
<AppIcon
|
||||||
|
iconName="app-workspace"
|
||||||
|
style="font-size: 16px"
|
||||||
|
class="color-input-placeholder"
|
||||||
|
></AppIcon>
|
||||||
<span class="color-input-placeholder ml-4">
|
<span class="color-input-placeholder ml-4">
|
||||||
{{ paginationConfig.total }}
|
{{ paginationConfig.total }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-between mb-16" style="margin-top: 20px;">
|
<div class="flex-between mb-16" style="margin-top: 20px">
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" @click="createUser()"
|
<el-button
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
type="primary"
|
||||||
[PermissionConst.WORKSPACE_USER_GROUP_ADD_MEMBER.getWorkspacePermission], [], 'OR')"
|
@click="createUser()"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||||
|
[PermissionConst.WORKSPACE_USER_GROUP_ADD_MEMBER.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ t('views.role.member.add') }}
|
{{ t('views.role.member.add') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button :disabled="multipleSelection.length === 0" @click="handleDeleteUser()"
|
<el-button
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
:disabled="multipleSelection.length === 0"
|
||||||
[PermissionConst.WORKSPACE_USER_GROUP_DELETE.getWorkspacePermission], [], 'OR')"
|
@click="handleDeleteUser()"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||||
|
[PermissionConst.WORKSPACE_USER_GROUP_DELETE.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t('common.remove') }}
|
{{ $t('common.remove') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -105,15 +171,29 @@
|
|||||||
<el-select class="complex-search__left" v-model="searchType" style="width: 120px">
|
<el-select class="complex-search__left" v-model="searchType" style="width: 120px">
|
||||||
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input v-if="searchType === 'username'" v-model="searchForm.username" @change="getList"
|
<el-input
|
||||||
:placeholder="$t('common.searchBar.placeholder')" style="width: 220px" clearable />
|
v-if="searchType === 'username'"
|
||||||
|
v-model="searchForm.username"
|
||||||
|
@change="getList"
|
||||||
|
:placeholder="$t('common.searchBar.placeholder')"
|
||||||
|
style="width: 220px"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<app-table :data="tableData" :pagination-config="paginationConfig" @sizeChange="handleSizeChange"
|
<app-table
|
||||||
@changePage="getList" @selection-change="handleSelectionChange">
|
:data="tableData"
|
||||||
|
:pagination-config="paginationConfig"
|
||||||
|
@sizeChange="handleSizeChange"
|
||||||
|
@changePage="getList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')" />
|
<el-table-column
|
||||||
|
prop="nick_name"
|
||||||
|
:label="$t('views.userManage.userForm.nick_name.label')"
|
||||||
|
/>
|
||||||
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" />
|
<el-table-column prop="username" :label="$t('views.login.loginForm.username.label')" />
|
||||||
<el-table-column prop="source" :label="$t('views.userManage.source.label')">
|
<el-table-column prop="source" :label="$t('views.userManage.source.label')">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@ -135,9 +215,18 @@
|
|||||||
<el-table-column :label="$t('common.operation')" width="100" fixed="right">
|
<el-table-column :label="$t('common.operation')" width="100" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tooltip effect="dark" :content="`${$t('common.remove')}`" placement="top">
|
<el-tooltip effect="dark" :content="`${$t('common.remove')}`" placement="top">
|
||||||
<el-button type="primary" text @click.stop="handleDeleteUser(row)"
|
<el-button
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
type="primary"
|
||||||
[PermissionConst.WORKSPACE_USER_GROUP_REMOVE_MEMBER.getWorkspacePermission], [], 'OR')"
|
text
|
||||||
|
@click.stop="handleDeleteUser(row)"
|
||||||
|
v-hasPermission="
|
||||||
|
new ComplexPermission(
|
||||||
|
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||||
|
[PermissionConst.WORKSPACE_USER_GROUP_REMOVE_MEMBER.getWorkspacePermission],
|
||||||
|
[],
|
||||||
|
'OR',
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<EditPen />
|
<EditPen />
|
||||||
@ -150,7 +239,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</ContentContainer>
|
|
||||||
<CreateOrUpdateGroupDialog ref="createOrUpdateGroupDialogRef" @refresh="refresh" />
|
<CreateOrUpdateGroupDialog ref="createOrUpdateGroupDialogRef" @refresh="refresh" />
|
||||||
<CreateGroupUserDialog ref="createGroupUserDialogRef" @refresh="getList" />
|
<CreateGroupUserDialog ref="createGroupUserDialogRef" @refresh="getList" />
|
||||||
</div>
|
</div>
|
||||||
@ -161,7 +250,6 @@ import { onMounted, ref, watch, reactive } from 'vue'
|
|||||||
import SystemGroupApi from '@/api/system/user-group'
|
import SystemGroupApi from '@/api/system/user-group'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
import type { ChatUserGroupUserItem } from '@/api/type/systemChatUser'
|
import type { ChatUserGroupUserItem } from '@/api/type/systemChatUser'
|
||||||
import iconMap from '@/components/app-icon/icons/common'
|
|
||||||
import CreateOrUpdateGroupDialog from './component/CreateOrUpdateGroupDialog.vue'
|
import CreateOrUpdateGroupDialog from './component/CreateOrUpdateGroupDialog.vue'
|
||||||
import CreateGroupUserDialog from './component/CreateGroupUserDialog.vue'
|
import CreateGroupUserDialog from './component/CreateGroupUserDialog.vue'
|
||||||
import type { ListItem } from '@/api/type/common'
|
import type { ListItem } from '@/api/type/common'
|
||||||
@ -176,8 +264,6 @@ const list = ref<ListItem[]>([])
|
|||||||
const filterList = ref<ListItem[]>([]) // 搜索过滤后列表
|
const filterList = ref<ListItem[]>([]) // 搜索过滤后列表
|
||||||
const current = ref<ListItem>()
|
const current = ref<ListItem>()
|
||||||
|
|
||||||
const rightOutlined = iconMap['right-outlined'].iconReader()
|
|
||||||
|
|
||||||
async function getUserGroupList() {
|
async function getUserGroupList() {
|
||||||
try {
|
try {
|
||||||
const res = await SystemGroupApi.getUserGroup(loading)
|
const res = await SystemGroupApi.getUserGroup(loading)
|
||||||
@ -197,9 +283,7 @@ function filter(list: ListItem[], filterText: string) {
|
|||||||
if (!filterText.length) {
|
if (!filterText.length) {
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
return list.filter((v: ListItem) =>
|
return list.filter((v: ListItem) => v.name.toLowerCase().includes(filterText.toLowerCase()))
|
||||||
v.name.toLowerCase().includes(filterText.toLowerCase()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(filterText, (val: string) => {
|
watch(filterText, (val: string) => {
|
||||||
@ -213,7 +297,7 @@ function clickUserGroup(item: ListItem) {
|
|||||||
const createOrUpdateGroupDialogRef = ref<InstanceType<typeof CreateOrUpdateGroupDialog>>()
|
const createOrUpdateGroupDialogRef = ref<InstanceType<typeof CreateOrUpdateGroupDialog>>()
|
||||||
|
|
||||||
function createOrUpdate(item?: ListItem) {
|
function createOrUpdate(item?: ListItem) {
|
||||||
createOrUpdateGroupDialogRef.value?.open(item);
|
createOrUpdateGroupDialogRef.value?.open(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteGroup(item: ListItem) {
|
function deleteGroup(item: ListItem) {
|
||||||
@ -232,12 +316,11 @@ function deleteGroup(item: ListItem) {
|
|||||||
current.value = item.id === current.value?.id ? list.value[0] : current.value
|
current.value = item.id === current.value?.id ? list.value[0] : current.value
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refresh(group?: ListItem) {
|
async function refresh(group?: ListItem) {
|
||||||
await getUserGroupList();
|
await getUserGroupList()
|
||||||
// 创建角色后选中新建的角色
|
// 创建角色后选中新建的角色
|
||||||
current.value = group ? group : current.value
|
current.value = group ? group : current.value
|
||||||
}
|
}
|
||||||
@ -259,7 +342,12 @@ const tableData = ref<ChatUserGroupUserItem[]>([])
|
|||||||
async function getList() {
|
async function getList() {
|
||||||
if (!current.value?.id) return
|
if (!current.value?.id) return
|
||||||
try {
|
try {
|
||||||
const res = await SystemGroupApi.getUserListByGroup(current.value?.id, paginationConfig, searchForm.value.username, rightLoading)
|
const res = await SystemGroupApi.getUserListByGroup(
|
||||||
|
current.value?.id,
|
||||||
|
paginationConfig,
|
||||||
|
searchForm.value.username,
|
||||||
|
rightLoading,
|
||||||
|
)
|
||||||
tableData.value = res.data.records
|
tableData.value = res.data.records
|
||||||
paginationConfig.total = res.data.total
|
paginationConfig.total = res.data.total
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -272,14 +360,17 @@ function handleSizeChange() {
|
|||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => current.value?.id, () => {
|
watch(
|
||||||
|
() => current.value?.id,
|
||||||
|
() => {
|
||||||
getList()
|
getList()
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const createGroupUserDialogRef = ref<InstanceType<typeof CreateGroupUserDialog>>()
|
const createGroupUserDialogRef = ref<InstanceType<typeof CreateGroupUserDialog>>()
|
||||||
|
|
||||||
function createUser() {
|
function createUser() {
|
||||||
createGroupUserDialogRef.value?.open(current.value?.id as string);
|
createGroupUserDialogRef.value?.open(current.value?.id as string)
|
||||||
}
|
}
|
||||||
|
|
||||||
const multipleSelection = ref<any[]>([])
|
const multipleSelection = ref<any[]>([])
|
||||||
@ -290,7 +381,9 @@ function handleSelectionChange(val: any[]) {
|
|||||||
|
|
||||||
function handleDeleteUser(item?: ChatUserGroupUserItem) {
|
function handleDeleteUser(item?: ChatUserGroupUserItem) {
|
||||||
MsgConfirm(
|
MsgConfirm(
|
||||||
item ? `${t('views.workspace.member.delete.confirmTitle')}${item.nick_name} ?` : t('views.chatUser.group.batchDeleteMember', { count: multipleSelection.value.length }),
|
item
|
||||||
|
? `${t('views.workspace.member.delete.confirmTitle')}${item.nick_name} ?`
|
||||||
|
: t('views.chatUser.group.batchDeleteMember', { count: multipleSelection.value.length }),
|
||||||
'',
|
'',
|
||||||
{
|
{
|
||||||
confirmButtonText: t('common.confirm'),
|
confirmButtonText: t('common.confirm'),
|
||||||
@ -298,66 +391,36 @@ function handleDeleteUser(item?: ChatUserGroupUserItem) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
SystemGroupApi.postRemoveMember(current.value?.id as string, { group_relation_ids: item ? [item.user_group_relation_id] : multipleSelection.value.map(item => (item.user_group_relation_id)) }, loading).then(async () => {
|
SystemGroupApi.postRemoveMember(
|
||||||
|
current.value?.id as string,
|
||||||
|
{
|
||||||
|
group_relation_ids: item
|
||||||
|
? [item.user_group_relation_id]
|
||||||
|
: multipleSelection.value.map((item) => item.user_group_relation_id),
|
||||||
|
},
|
||||||
|
loading,
|
||||||
|
).then(async () => {
|
||||||
MsgSuccess(t('common.removeSuccess'))
|
MsgSuccess(t('common.removeSuccess'))
|
||||||
await getList()
|
await getList()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {})
|
||||||
})
|
}
|
||||||
|
const mouseId = ref('')
|
||||||
|
|
||||||
|
function mouseenter(row: any) {
|
||||||
|
mouseId.value = row.id
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.shared-header {
|
|
||||||
color: #646a73;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
:deep(.el-icon i) {
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-title {
|
|
||||||
color: #1f2329;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-container {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
:deep(.content-container__main) {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.user-card) {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-left {
|
.user-left {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: var(--setting-left-width);
|
width: var(--setting-left-width);
|
||||||
min-width: var(--setting-left-width);
|
min-width: var(--setting-left-width);
|
||||||
|
|
||||||
.user-left_title {
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-height-left {
|
.list-height-left {
|
||||||
height: calc(100vh - 271px);
|
height: calc(100vh - 271px);
|
||||||
|
|
||||||
:deep(.common-list li) {
|
|
||||||
padding-right: 4px;
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,388 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="h-full">
|
|
||||||
<ContentContainer>
|
|
||||||
<template #header>
|
|
||||||
<div class="shared-header">
|
|
||||||
<span class="title">{{ t('views.chatUser.title') }}</span>
|
|
||||||
<el-icon size="12">
|
|
||||||
<rightOutlined></rightOutlined>
|
|
||||||
</el-icon>
|
|
||||||
<span class="sub-title">{{ t('views.chatUser.title') }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-card class="h-full">
|
|
||||||
<div class="flex-between mb-16">
|
|
||||||
<div>
|
|
||||||
<el-button type="primary" @click="createUser()"
|
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, RoleConst.USER.getWorkspaceRole,],
|
|
||||||
[PermissionConst.WORKSPACE_CHAT_USER_CREATE.getWorkspacePermission],[],'OR')"
|
|
||||||
>
|
|
||||||
{{ t('views.userManage.createUser') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="syncUsers">
|
|
||||||
{{ $t('views.chatUser.syncUsers') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button :disabled="multipleSelection.length === 0" @click="setUserGroups"
|
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, RoleConst.USER.getWorkspaceRole,],
|
|
||||||
[PermissionConst.WORKSPACE_CHAT_USER_GROUP.getWorkspacePermission],[],'OR')"
|
|
||||||
>
|
|
||||||
{{ $t('views.chatUser.setUserGroups') }}
|
|
||||||
</el-button>
|
|
||||||
<el-button :disabled="multipleSelection.length === 0" @click="handleBatchDelete"
|
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, RoleConst.USER.getWorkspaceRole,],
|
|
||||||
[PermissionConst.WORKSPACE_CHAT_USER_DELETE.getWorkspacePermission],[],'OR')"
|
|
||||||
>
|
|
||||||
{{ $t('common.delete') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<div class="flex-between complex-search">
|
|
||||||
<el-select class="complex-search__left" v-model="search_type" style="width: 120px"
|
|
||||||
@change="search_type_change">
|
|
||||||
<el-option :label="$t('views.login.loginForm.username.label')" value="username"/>
|
|
||||||
<el-option :label="$t('views.userManage.userForm.nick_name.label')"
|
|
||||||
value="nick_name"/>
|
|
||||||
</el-select>
|
|
||||||
<el-input v-if="search_type === 'username'" v-model="search_form.username"
|
|
||||||
@change="getList"
|
|
||||||
style="width: 220px"
|
|
||||||
clearable/>
|
|
||||||
<el-input v-if="search_type === 'nick_name'" v-model="search_form.nick_name"
|
|
||||||
@change="getList"
|
|
||||||
style="width: 220px" clearable/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<app-table class="mt-16" :data="userTableData" :pagination-config="paginationConfig"
|
|
||||||
@sizeChange="handleSizeChange" @changePage="getList" v-loading="loading"
|
|
||||||
@selection-change="handleSelectionChange" @sort-change="handleSortChange">
|
|
||||||
<el-table-column type="selection" width="55"/>
|
|
||||||
<el-table-column prop="nick_name"
|
|
||||||
:label="$t('views.userManage.userForm.nick_name.label')"/>
|
|
||||||
<el-table-column prop="username" :label="$t('common.username')"/>
|
|
||||||
<el-table-column prop="is_active" :label="$t('common.status.label')">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<div v-if="row.is_active" class="flex align-center">
|
|
||||||
<el-icon class="color-success mr-8" style="font-size: 16px">
|
|
||||||
<SuccessFilled/>
|
|
||||||
</el-icon>
|
|
||||||
<span class="color-secondary">
|
|
||||||
{{ $t('common.status.enabled') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div v-else class="flex align-center">
|
|
||||||
<AppIcon iconName="app-disabled" class="color-secondary mr-8"></AppIcon>
|
|
||||||
<span class="color-secondary">
|
|
||||||
{{ $t('common.status.disabled') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column prop="email" :label="$t('views.login.loginForm.email.label')"
|
|
||||||
show-overflow-tooltip>
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.email || '-' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="phone" :label="$t('views.userManage.userForm.phone.label')">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.phone || '-' }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="user_group_names" :label="$t('views.chatUser.group.title')"
|
|
||||||
min-width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<TagGroup :tags="row.user_group_names"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="source" :label="$t('views.userManage.source.label')">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{
|
|
||||||
row.source === 'LOCAL'
|
|
||||||
? $t('views.userManage.source.localCreate')
|
|
||||||
: row.source === 'wecom'
|
|
||||||
? $t('views.userManage.source.wecom')
|
|
||||||
: row.source === 'lark'
|
|
||||||
? $t('views.userManage.source.lark')
|
|
||||||
: row.source === 'dingtalk'
|
|
||||||
? $t('views.userManage.source.dingtalk')
|
|
||||||
: row.source === 'OAUTH2' || row.source === 'OAuth2'
|
|
||||||
? 'OAuth2'
|
|
||||||
: row.source
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column :label="$t('common.createTime')" width="180">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ datetimeFormat(row.create_time) }}
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column :label="$t('common.operation')" width="160" align="left" fixed="right">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<span @click.stop>
|
|
||||||
<el-switch size="small" v-model="row.is_active"
|
|
||||||
:before-change="() => changeState(row)"/>
|
|
||||||
</span>
|
|
||||||
<el-divider direction="vertical"/>
|
|
||||||
<span class="mr-8">
|
|
||||||
<el-button type="primary" text @click.stop="editUser(row)"
|
|
||||||
:title="$t('common.edit')"
|
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, RoleConst.USER.getWorkspaceRole,],
|
|
||||||
[PermissionConst.WORKSPACE_CHAT_USER_EDIT.getWorkspacePermission],[],'OR')"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<EditPen/>
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="mr-8">
|
|
||||||
<el-button type="primary" text @click.stop="editPwdUser(row)"
|
|
||||||
:title="$t('views.userManage.setting.updatePwd')"
|
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, RoleConst.USER.getWorkspaceRole,],
|
|
||||||
[PermissionConst.WORKSPACE_CHAT_USER_EDIT.getWorkspacePermission],[],'OR')"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<Lock/>
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<el-button :disabled="row.role === 'ADMIN'" type="primary" text
|
|
||||||
@click.stop="deleteUserManage(row)"
|
|
||||||
:title="$t('common.delete')"
|
|
||||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, RoleConst.USER.getWorkspaceRole,],
|
|
||||||
[PermissionConst.WORKSPACE_CHAT_USER_DELETE.getWorkspacePermission],[],'OR')"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<Delete/>
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</app-table>
|
|
||||||
</el-card>
|
|
||||||
</ContentContainer>
|
|
||||||
|
|
||||||
<UserDrawer :title="title" :optionLoading="optionLoading" :chatGroupList="chatGroupList"
|
|
||||||
ref="UserDrawerRef"
|
|
||||||
@refresh="refresh"/>
|
|
||||||
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh"/>
|
|
||||||
<SetUserGroupsDialog :optionLoading="optionLoading" :chatGroupList="chatGroupList"
|
|
||||||
ref="setUserGroupsRef"
|
|
||||||
@refresh="refresh"/>
|
|
||||||
<SyncUsersDialog ref="syncUsersDialogRef" @refresh="refresh"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import {onMounted, ref, reactive} from 'vue'
|
|
||||||
import UserDrawer from './component/UserDrawer.vue'
|
|
||||||
import UserPwdDialog from './component/UserPwdDialog.vue'
|
|
||||||
import SetUserGroupsDialog from './component/SetUserGroupsDialog.vue'
|
|
||||||
import SyncUsersDialog from './component/SyncUsersDialog.vue'
|
|
||||||
import userManageApi from '@/api/system/chat-user'
|
|
||||||
import {datetimeFormat} from '@/utils/time'
|
|
||||||
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
|
||||||
import {t} from '@/locales'
|
|
||||||
import iconMap from '@/components/app-icon/icons/common'
|
|
||||||
import type {ChatUserItem} from '@/api/type/systemChatUser'
|
|
||||||
import SystemGroupApi from '@/api/system/user-group'
|
|
||||||
import type {ListItem} from '@/api/type/common'
|
|
||||||
import {PermissionConst, RoleConst} from '@/utils/permission/data'
|
|
||||||
import {ComplexPermission} from '@/utils/permission/type'
|
|
||||||
|
|
||||||
const rightOutlined = iconMap['right-outlined'].iconReader()
|
|
||||||
|
|
||||||
const search_type = ref('name')
|
|
||||||
const search_form = ref<{
|
|
||||||
username: string,
|
|
||||||
nick_name?: string,
|
|
||||||
}>({
|
|
||||||
username: '',
|
|
||||||
nick_name: '',
|
|
||||||
})
|
|
||||||
const search_type_change = () => {
|
|
||||||
search_form.value = {username: '', nick_name: ''}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
|
|
||||||
const multipleSelection = ref<any[]>([])
|
|
||||||
|
|
||||||
function handleSelectionChange(val: any[]) {
|
|
||||||
multipleSelection.value = val
|
|
||||||
}
|
|
||||||
|
|
||||||
const paginationConfig = reactive({
|
|
||||||
current_page: 1,
|
|
||||||
page_size: 20,
|
|
||||||
total: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
const userTableData = ref<ChatUserItem[]>([])
|
|
||||||
|
|
||||||
function getList() {
|
|
||||||
const params = {
|
|
||||||
[search_type.value]: search_form.value[search_type.value as keyof typeof search_form.value],
|
|
||||||
}
|
|
||||||
return userManageApi
|
|
||||||
.getUserManage(paginationConfig, params, loading)
|
|
||||||
.then((res) => {
|
|
||||||
userTableData.value = res.data.records
|
|
||||||
paginationConfig.total = res.data.total
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const orderBy = ref<string>('')
|
|
||||||
|
|
||||||
function handleSortChange({prop, order}: { prop: string; order: string }) {
|
|
||||||
orderBy.value = order === 'ascending' ? prop : `-${prop}`
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSizeChange() {
|
|
||||||
paginationConfig.current_page = 1
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeState(row: ChatUserItem) {
|
|
||||||
const obj = {
|
|
||||||
...row,
|
|
||||||
is_active: !row.is_active,
|
|
||||||
}
|
|
||||||
const str = obj.is_active ? t('common.status.enableSuccess') : t('common.status.disableSuccess')
|
|
||||||
userManageApi
|
|
||||||
.putUserManage(row.id, obj, loading)
|
|
||||||
.then(() => {
|
|
||||||
getList()
|
|
||||||
MsgSuccess(str)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const title = ref('')
|
|
||||||
const UserDrawerRef = ref()
|
|
||||||
|
|
||||||
function editUser(row: ChatUserItem) {
|
|
||||||
title.value = t('views.userManage.editUser')
|
|
||||||
UserDrawerRef.value.open(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
function createUser() {
|
|
||||||
title.value = t('views.userManage.createUser')
|
|
||||||
UserDrawerRef.value.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteUserManage(row: ChatUserItem) {
|
|
||||||
MsgConfirm(
|
|
||||||
`${t('views.userManage.delete.confirmTitle')}${row.nick_name} ?`,
|
|
||||||
'',
|
|
||||||
{
|
|
||||||
confirmButtonText: t('common.confirm'),
|
|
||||||
confirmButtonClass: 'danger',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
loading.value = true
|
|
||||||
userManageApi.delUserManage(row.id, loading).then(() => {
|
|
||||||
MsgSuccess(t('common.deleteSuccess'))
|
|
||||||
getList()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const UserPwdDialogRef = ref()
|
|
||||||
|
|
||||||
function editPwdUser(row: ChatUserItem) {
|
|
||||||
UserPwdDialogRef.value.open(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
function refresh() {
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getChatGroupList()
|
|
||||||
getList()
|
|
||||||
})
|
|
||||||
|
|
||||||
const optionLoading = ref(false)
|
|
||||||
const chatGroupList = ref<ListItem[]>([])
|
|
||||||
|
|
||||||
async function getChatGroupList() {
|
|
||||||
try {
|
|
||||||
const res = await SystemGroupApi.getUserGroup(optionLoading)
|
|
||||||
chatGroupList.value = res.data
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleBatchDelete() {
|
|
||||||
MsgConfirm(
|
|
||||||
t('views.chatUser.batchDeleteUser', {count: multipleSelection.value.length}),
|
|
||||||
'',
|
|
||||||
{
|
|
||||||
confirmButtonText: t('common.confirm'),
|
|
||||||
confirmButtonClass: 'danger',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
userManageApi.batchDelete(multipleSelection.value.map(item => (item.id)), loading).then(async () => {
|
|
||||||
MsgSuccess(t('common.deleteSuccess'))
|
|
||||||
await getList()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const setUserGroupsRef = ref<InstanceType<typeof SetUserGroupsDialog>>()
|
|
||||||
|
|
||||||
function setUserGroups() {
|
|
||||||
setUserGroupsRef.value?.open(multipleSelection.value.map(item => (item.id)))
|
|
||||||
}
|
|
||||||
|
|
||||||
const syncUsersDialogRef = ref<InstanceType<typeof SyncUsersDialog>>()
|
|
||||||
|
|
||||||
function syncUsers() {
|
|
||||||
syncUsersDialogRef.value?.open()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.shared-header {
|
|
||||||
color: #646a73;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
:deep(.el-icon i) {
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-title {
|
|
||||||
color: #1f2329;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-container {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
:deep(.content-container__main) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -2,9 +2,9 @@
|
|||||||
<div class="role-manage p-16-24">
|
<div class="role-manage p-16-24">
|
||||||
<h2 class="mb-16">{{ $t('views.role.title') }}</h2>
|
<h2 class="mb-16">{{ $t('views.role.title') }}</h2>
|
||||||
<el-card style="--el-card-padding: 0">
|
<el-card style="--el-card-padding: 0">
|
||||||
<div class="flex h-full">
|
<div class="flex main-calc-height">
|
||||||
<div class="role-left border-r">
|
<div class="role-left border-r p-16">
|
||||||
<div class="p-24 pb-0">
|
<div class="p-8 pb-0 mb-12">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="filterText"
|
v-model="filterText"
|
||||||
:placeholder="$t('common.search')"
|
:placeholder="$t('common.search')"
|
||||||
@ -14,7 +14,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="list-height-left">
|
<div class="list-height-left">
|
||||||
<el-scrollbar v-loading="loading">
|
<el-scrollbar v-loading="loading">
|
||||||
<div class="p-16">
|
|
||||||
<div class="color-secondary lighter ml-8 mb-8">
|
<div class="color-secondary lighter ml-8 mb-8">
|
||||||
<span>{{ $t('views.role.internalRole') }}</span>
|
<span>{{ $t('views.role.internalRole') }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -122,7 +121,6 @@
|
|||||||
<span></span>
|
<span></span>
|
||||||
</template>
|
</template>
|
||||||
</common-list>
|
</common-list>
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -242,7 +240,9 @@ function deleteRole(item: RoleItem) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loadPermissionApi('role').deleteRole(item.id, loading).then(async () => {
|
loadPermissionApi('role')
|
||||||
|
.deleteRole(item.id, loading)
|
||||||
|
.then(async () => {
|
||||||
MsgSuccess(t('common.deleteSuccess'))
|
MsgSuccess(t('common.deleteSuccess'))
|
||||||
await getRole()
|
await getRole()
|
||||||
currentRole.value =
|
currentRole.value =
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
<div class="workspace-manage p-16-24">
|
<div class="workspace-manage p-16-24">
|
||||||
<h2 class="mb-16">{{ $t('views.workspace.title') }}</h2>
|
<h2 class="mb-16">{{ $t('views.workspace.title') }}</h2>
|
||||||
<el-card style="--el-card-padding: 0">
|
<el-card style="--el-card-padding: 0">
|
||||||
<div class="flex h-full">
|
<div class="flex main-calc-height">
|
||||||
<div class="workspace-left border-r">
|
<div class="workspace-left border-r p-16">
|
||||||
<div class="p-24 pb-0">
|
<div class="p-8 pb-0 mt-8 mb-12">
|
||||||
<div class="flex-between mb-12">
|
<div class="flex-between mb-12">
|
||||||
<h4 class="medium">{{ $t('views.workspace.list') }}</h4>
|
<h4 class="medium">{{ $t('views.workspace.list') }}</h4>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
@ -31,7 +31,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="list-height-left">
|
<div class="list-height-left">
|
||||||
<el-scrollbar v-loading="loading">
|
<el-scrollbar v-loading="loading">
|
||||||
<div class="p-16">
|
|
||||||
<common-list
|
<common-list
|
||||||
:data="filterList"
|
:data="filterList"
|
||||||
@click="clickWorkspace"
|
@click="clickWorkspace"
|
||||||
@ -88,7 +87,6 @@
|
|||||||
<span></span>
|
<span></span>
|
||||||
</template>
|
</template>
|
||||||
</common-list>
|
</common-list>
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user