mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-30 00:22:46 +00:00
feat: systemChatUserGroup
This commit is contained in:
parent
e4a8f371ab
commit
63b783c8f5
|
|
@ -19,12 +19,12 @@ const getUserGroupUserList: (
|
|||
resource: ChatUserResourceParams,
|
||||
user_group_id: string,
|
||||
page: pageRequest,
|
||||
param: any,
|
||||
username_or_nickname: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<PageList<ChatUserGroupUserItem[]>>> = (resource, user_group_id, page, param, loading) => {
|
||||
) => Promise<Result<PageList<ChatUserGroupUserItem[]>>> = (resource, user_group_id, page, username_or_nickname, loading) => {
|
||||
return get(
|
||||
`${prefix}/${resource.resource_type}/${resource.resource_id}/user_group_id/${user_group_id}/${page.current_page}/${page.page_size}`,
|
||||
param,
|
||||
username_or_nickname ? { username_or_nickname } : undefined,
|
||||
loading,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
import { Result } from '@/request/Result'
|
||||
import { get, put, post, del } from '@/request/index'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
import type { ChatUserItem } from '@/api/type/systemChatUser'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
const prefix = '/system/chat_user'
|
||||
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*/
|
||||
const getChatUserList: (loading?: Ref<boolean>) => Promise<Result<ChatUserItem[]>> = (loading) => {
|
||||
return get(`${prefix}/list`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户分页列表
|
||||
* @query 参数
|
||||
|
|
@ -71,4 +80,5 @@ export default {
|
|||
delUserManage,
|
||||
postUserManage,
|
||||
putUserManagePassword,
|
||||
getChatUserList
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import {Result} from '@/request/Result'
|
||||
import {get, post, del, put} from '@/request/index'
|
||||
import type {Ref} from 'vue'
|
||||
import { Result } from '@/request/Result'
|
||||
import { get, post, del } from '@/request/index'
|
||||
import type { Ref } from 'vue'
|
||||
import type { ChatUserGroupUserItem, } from '@/api/type/systemChatUser'
|
||||
import type { pageRequest, PageList, ListItem } from '@/api/type/common'
|
||||
|
||||
const prefix = '/system/group'
|
||||
|
||||
/**
|
||||
* 获取用户组列表
|
||||
*/
|
||||
const getUserGroup: (loading?: Ref<boolean>) => Promise<Result<any[]>> = () => {
|
||||
const getUserGroup: (loading?: Ref<boolean>) => Promise<Result<ListItem[]>> = () => {
|
||||
return get(`${prefix}`)
|
||||
}
|
||||
|
||||
|
|
@ -19,7 +21,7 @@ const getUserGroup: (loading?: Ref<boolean>) => Promise<Result<any[]>> = () => {
|
|||
"name": "string"
|
||||
}
|
||||
*/
|
||||
const postUserGroup: (data: any, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||
const postUserGroup: (data: ListItem, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||
data,
|
||||
loading,
|
||||
) => {
|
||||
|
|
@ -30,7 +32,7 @@ const postUserGroup: (data: any, loading?: Ref<boolean>) => Promise<Result<boole
|
|||
* 删除用户组
|
||||
* @param 参数 user_group_id
|
||||
*/
|
||||
const delUserGroup: (user_group_id: String, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||
const delUserGroup: (user_group_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||
user_group_id,
|
||||
loading,
|
||||
) => {
|
||||
|
|
@ -48,7 +50,7 @@ const delUserGroup: (user_group_id: String, loading?: Ref<boolean>) => Promise<R
|
|||
*/
|
||||
const postAddMember: (
|
||||
user_group_id: string,
|
||||
body: any,
|
||||
body: Record<string, any>,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (user_group_id, body, loading) => {
|
||||
return post(`${prefix}/${user_group_id}/add_member`, body, {}, loading)
|
||||
|
|
@ -64,16 +66,32 @@ const postAddMember: (
|
|||
*/
|
||||
const postRemoveMember: (
|
||||
user_group_id: string,
|
||||
body: any,
|
||||
body: Record<string, any>,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (user_group_id, body, loading) => {
|
||||
return post(`${prefix}/${user_group_id}`, body, {}, loading)
|
||||
return post(`${prefix}/${user_group_id}/remove_member`, body, {}, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户组的成员列表
|
||||
*/
|
||||
const getUserListByGroup: (
|
||||
user_group_id: string,
|
||||
page: pageRequest,
|
||||
username: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<PageList<ChatUserGroupUserItem[]>>> = (user_group_id, page, username, loading) => {
|
||||
return get(
|
||||
`${prefix}/${user_group_id}/user_list/${page.current_page}/${page.page_size}`,
|
||||
username ? { username } : undefined,
|
||||
loading,
|
||||
)
|
||||
}
|
||||
export default {
|
||||
getUserGroup,
|
||||
postUserGroup,
|
||||
delUserGroup,
|
||||
postAddMember,
|
||||
postRemoveMember,
|
||||
getUserListByGroup
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,4 +18,8 @@ interface PageList<T> {
|
|||
records: T
|
||||
}
|
||||
|
||||
export type { KeyValue, Dict, pageRequest, PageList }
|
||||
interface ListItem {
|
||||
name: string,
|
||||
id?: string,
|
||||
}
|
||||
export type { KeyValue, Dict, pageRequest, PageList, ListItem }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
interface ChatUserItem {
|
||||
create_time: string,
|
||||
email: string,
|
||||
id: string,
|
||||
nick_name: string,
|
||||
phone: string,
|
||||
source: string,
|
||||
update_time: string,
|
||||
username: string,
|
||||
is_active: boolean,
|
||||
user_group_ids?: string[],
|
||||
user_group_names?: string[],
|
||||
}
|
||||
|
||||
// TODO
|
||||
interface ChatUserGroupUserItem {
|
||||
id: string,
|
||||
is_auth: boolean,
|
||||
email: string,
|
||||
phone: string,
|
||||
nick_name: string,
|
||||
username: string,
|
||||
password: string,
|
||||
source: string,
|
||||
is_active: boolean,
|
||||
create_time: string,
|
||||
update_time: string,
|
||||
}
|
||||
export type { ChatUserGroupUserItem, ChatUserItem }
|
||||
|
|
@ -6,5 +6,10 @@ export default {
|
|||
authorization: '授权',
|
||||
group: {
|
||||
title: '用户组',
|
||||
name: '用户组名称',
|
||||
delete: {
|
||||
confirmTitle: '是否删除用户组:',
|
||||
confirmMessage: '删除后,该用户组下的成员将全部移除,请谨慎操作!',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
<el-divider direction="vertical" class="mr-8 ml-8" />
|
||||
<AppIcon iconName="app-wordspace" style="font-size: 16px" class="color-input-placeholder"></AppIcon>
|
||||
<span class="color-input-placeholder ml-4">
|
||||
{{ current?.user_count }}
|
||||
{{ paginationConfig.total }}
|
||||
</span>
|
||||
</div>
|
||||
<el-button type="primary" @click="handleSave">
|
||||
|
|
@ -48,9 +48,9 @@
|
|||
<div class="flex-between mb-16" style="margin-top: 18px;">
|
||||
<div class="flex complex-search">
|
||||
<el-select class="complex-search__left" v-model="searchType" style="width: 120px">
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="username_or_nickname" />
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="name" />
|
||||
</el-select>
|
||||
<el-input v-if="searchType === 'username_or_nickname'" v-model="searchForm.username_or_nickname"
|
||||
<el-input v-if="searchType === 'name'" v-model="searchForm.name"
|
||||
@change="getList" :placeholder="$t('common.inputPlaceholder')" style="width: 220px" clearable />
|
||||
</div>
|
||||
<div class="flex align-center">
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
</div>
|
||||
|
||||
<app-table :data="tableData" :pagination-config="paginationConfig" @sizeChange="handleSizeChange"
|
||||
@changePage="getList" v-loading="rightLoading">
|
||||
@changePage="getList">
|
||||
<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="source" :label="$t('views.userManage.source.label')">
|
||||
|
|
@ -150,9 +150,9 @@ function clickUserGroup(item: ChatUserGroupItem) {
|
|||
|
||||
const rightLoading = ref(false)
|
||||
|
||||
const searchType = ref('username_or_nickname')
|
||||
const searchType = ref('name')
|
||||
const searchForm = ref<Record<string, any>>({
|
||||
username_or_nickname: '',
|
||||
name: '',
|
||||
})
|
||||
const automaticAuthorization = ref(false)
|
||||
const paginationConfig = reactive({
|
||||
|
|
@ -166,10 +166,7 @@ const tableData = ref<ChatUserGroupUserItem[]>([])
|
|||
async function getList() {
|
||||
if (!current.value?.id) return
|
||||
try {
|
||||
const params = {
|
||||
[searchType.value]: searchForm.value[searchType.value],
|
||||
}
|
||||
const res = await ChatUserApi.getUserGroupUserList(resource, current.value?.id, paginationConfig, params, rightLoading)
|
||||
const res = await ChatUserApi.getUserGroupUserList(resource, current.value?.id, paginationConfig, searchForm.value.name, rightLoading)
|
||||
tableData.value = res.data.records
|
||||
paginationConfig.total = res.data.total
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,122 +0,0 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:close-on-press-escape="false"
|
||||
:close-on-click-modal="false"
|
||||
:destroy-on-close="true"
|
||||
width="600"
|
||||
class="member-dialog"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<h4 :id="titleId" :class="titleClass">{{ $t('views.team.addMember') }}</h4>
|
||||
<div class="dialog-sub-title">{{ $t('views.team.addSubTitle') }}</div>
|
||||
</template>
|
||||
|
||||
<el-form
|
||||
ref="addMemberFormRef"
|
||||
:model="memberForm"
|
||||
label-position="top"
|
||||
:rules="rules"
|
||||
require-asterisk-position="right"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item :label="$t('views.team.teamForm.form.userName.label')" prop="users">
|
||||
<tags-input v-model:tags="memberForm.users" :placeholder="$t('views.team.teamForm.form.userName.placeholder')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
|
||||
<el-button type="primary" @click="submitMember(addMemberFormRef)" :loading="loading">
|
||||
{{ $t('common.add') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import GroupApi from '@/api/system/user-group'
|
||||
import { t } from '@/locales'
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
|
||||
const memberForm = ref({
|
||||
users: []
|
||||
})
|
||||
|
||||
const addMemberFormRef = ref<FormInstance>()
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
const rules = ref<FormRules>({
|
||||
users: [
|
||||
{
|
||||
type: 'array',
|
||||
required: true,
|
||||
message: t('views.team.teamForm.form.userName.requiredMessage'),
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
watch(dialogVisible, (bool) => {
|
||||
if (!bool) {
|
||||
memberForm.value = {
|
||||
users: []
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const open = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const submitMember = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
let idsArray = memberForm.value.users.map((obj: any) => obj.id)
|
||||
// GroupApi.postCreatTeamMember(idsArray)
|
||||
// .then((res) => {
|
||||
// MsgSuccess(t('common.submitSuccess'))
|
||||
// emit('refresh', idsArray)
|
||||
// dialogVisible.value = false
|
||||
// loading.value = false
|
||||
// })
|
||||
// .catch(() => {
|
||||
// loading.value = false
|
||||
// })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {})
|
||||
|
||||
defineExpose({ open, close })
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.member-dialog {
|
||||
.el-dialog__header {
|
||||
padding-bottom: 19px;
|
||||
}
|
||||
}
|
||||
.custom-select-multiple {
|
||||
width: 200%;
|
||||
.el-input {
|
||||
min-height: 100px;
|
||||
}
|
||||
.el-select__tags {
|
||||
top: 0;
|
||||
transform: none;
|
||||
padding-top: 8px;
|
||||
}
|
||||
.el-input__wrapper {
|
||||
align-items: start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<template>
|
||||
<el-dialog :title="`${!form.id ? $t('common.create') : $t('common.rename')}${$t('views.chatUser.group.title')}`"
|
||||
v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
|
||||
<el-form label-position="top" ref="formRef" :rules="rules" :model="form" require-asterisk-position="right">
|
||||
<el-form-item :label="$t('views.chatUser.group.name')" prop="name">
|
||||
<el-input v-model="form.name" maxlength="64"
|
||||
:placeholder="`${$t('common.inputPlaceholder')}${$t('views.chatUser.group.name')}`" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
|
||||
<el-button type="primary" @click="submit(formRef)" :loading="loading">
|
||||
{{ !form.id ? $t('common.create') : $t('common.save') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import { t } from '@/locales'
|
||||
import SystemGroupApi from '@/api/system/user-group'
|
||||
import type { ListItem } from '@/api/type/common'
|
||||
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'refresh', current: ListItem): void;
|
||||
}>();
|
||||
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
const defaultForm = {
|
||||
name: ''
|
||||
}
|
||||
const form = ref<ListItem>({
|
||||
...defaultForm,
|
||||
})
|
||||
function open(item?: ListItem) {
|
||||
if (item) {
|
||||
form.value = { id: item.id, name: item.name }
|
||||
} else {
|
||||
form.value = { ...defaultForm }
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const rules = reactive({
|
||||
name: [{ required: true, message: `${t('common.inputPlaceholder')}${t('views.chatUser.group.name')}`, trigger: 'blur' }],
|
||||
})
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
SystemGroupApi.postUserGroup(form.value, loading).then((res: any) => {
|
||||
MsgSuccess(!form.value.id ? t('common.createSuccess') : t('common.renameSuccess'))
|
||||
emit('refresh', res.data)
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
|
@ -1,117 +1,328 @@
|
|||
<template>
|
||||
<div class="group-manage p-16-24">
|
||||
<h4 class="mb-16">{{ $t('views.system.group.title') }}</h4>
|
||||
<ContentContainer>
|
||||
<template #header>
|
||||
<div class="shared-header">
|
||||
<span class="title">{{ t('views.system.shared_resources') }}</span>
|
||||
<el-icon size="12">
|
||||
<rightOutlined></rightOutlined>
|
||||
</el-icon>
|
||||
<span class="sub-title">{{ t('views.knowledge.title') }}</span>
|
||||
</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_title flex-between">
|
||||
<h4 class="medium">{{ $t('views.chatUser.group.title') }}</h4>
|
||||
<el-tooltip effect="dark" :content="`${$t('common.create')}${$t('views.chatUser.group.title')}`"
|
||||
placement="top">
|
||||
<el-button type="primary" text @click="createOrUpdate()">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex main-calc-height">
|
||||
<div class="group-member p-8 border-r">
|
||||
<div class="flex-between p-16">
|
||||
<h4>{{ $t('views.system.group.member') }}</h4>
|
||||
<el-button type="primary" link @click="addMember">
|
||||
<AppIcon iconName="app-add-users" class="add-user-icon" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="group-member-input">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
:placeholder="$t('views.system.group.searchBar.placeholder')"
|
||||
prefix-icon="Search"
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
<div class="list-height-left">
|
||||
<el-scrollbar>
|
||||
<common-list
|
||||
:data="filterGroup"
|
||||
class="mt-8"
|
||||
v-loading="loading"
|
||||
@click="clickMemberHandle"
|
||||
:default-active="currentUser"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<div class="flex-between">
|
||||
<div>
|
||||
<span class="mr-8">{{ row.username }}</span>
|
||||
</div>
|
||||
<div @click.stop style="margin-top: 5px">
|
||||
<el-dropdown trigger="click" v-if="!isManage(row.type)">
|
||||
<span class="cursor">
|
||||
<el-icon class="rotate-90"><MoreFilled /></el-icon>
|
||||
</span>
|
||||
<div class="p-8">
|
||||
<el-input v-model="filterText" :placeholder="$t('common.search')" prefix-icon="Search" clearable />
|
||||
</div>
|
||||
<div class="list-height-left">
|
||||
<el-scrollbar v-loading="loading">
|
||||
<common-list :data="filterList" @click="clickUserGroup" :default-active="current?.id">
|
||||
<template #default="{ row }">
|
||||
<div class="flex-between">
|
||||
<span>{{ row.name }}</span>
|
||||
<el-dropdown :teleported="false">
|
||||
<el-button text>
|
||||
<el-icon class="color-secondary">
|
||||
<MoreFilled />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<!-- <el-dropdown-item @click.prevent="deleteMember(row)">{{
|
||||
$t('views.system.group.delete.button')
|
||||
}}</el-dropdown-item> -->
|
||||
<el-dropdown-menu style="min-width: 80px">
|
||||
<el-dropdown-item @click.stop="createOrUpdate(row)" class="p-8">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
{{
|
||||
$t('common.rename')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.stop="deleteGroup(row)" class="border-t p-8">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
{{
|
||||
$t('common.delete')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #empty>
|
||||
<span></span>
|
||||
</template>
|
||||
</common-list>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右边 -->
|
||||
<div class="user-right" v-loading="rightLoading">
|
||||
<div class="flex align-center">
|
||||
<h4 class="medium">{{ current?.name }}</h4>
|
||||
<el-divider direction="vertical" class="mr-8 ml-8" />
|
||||
<AppIcon iconName="app-wordspace" style="font-size: 16px" class="color-input-placeholder"></AppIcon>
|
||||
<span class="color-input-placeholder ml-4">
|
||||
{{ paginationConfig.total }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-between mb-16" style="margin-top: 20px;">
|
||||
<div>
|
||||
<el-button type="primary" @click="createUser()">
|
||||
{{ t('views.userManage.createUser') }}
|
||||
</el-button>
|
||||
<el-button :disabled="multipleSelection.length === 0" @click="handleDeleteUser()">
|
||||
{{ $t('common.delete') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="flex-between complex-search">
|
||||
<el-select class="complex-search__left" v-model="searchType" style="width: 120px">
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="username" />
|
||||
</el-select>
|
||||
<el-input v-if="searchType === 'username'" v-model="searchForm.username" @change="getList"
|
||||
:placeholder="$t('common.searchBar.placeholder')" style="width: 220px" clearable />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-table :data="tableData" :pagination-config="paginationConfig" @sizeChange="handleSizeChange"
|
||||
@changePage="getList" @selection-change="handleSelectionChange">
|
||||
<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('views.login.loginForm.username.label')" />
|
||||
<el-table-column prop="source" :label="$t('views.userManage.source.label')">
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
row.source === 'LOCAL'
|
||||
? $t('views.userManage.source.local')
|
||||
: 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>
|
||||
</common-list>
|
||||
</el-scrollbar>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('common.operation')" width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip effect="dark" :content="`${$t('views.role.member.delete.button')}`" placement="top">
|
||||
<el-button type="primary" text @click.stop="handleDeleteUser([row.id])">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</app-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="permission-setting flex" v-loading="rLoading">
|
||||
<div class="group-manage__table">
|
||||
<h4 class="p-24 pb-0 mb-4">{{ $t('views.system.group.permissionSetting') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CreateGroupDialog ref="CreateGroupRef" @refresh="refresh" />
|
||||
</div>
|
||||
</el-card>
|
||||
</ContentContainer>
|
||||
<CreateOrUpdateGroupDialog ref="createOrUpdateGroupDialogRef" @refresh="refresh" />
|
||||
<!-- <CreateGroupUserDialog ref="createGroupUserDialogRef" @refresh="getUserGroupList" /> -->
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, reactive, watch } from 'vue'
|
||||
import GroupApi from '@/api/system/user-group'
|
||||
import CreateGroupDialog from './component/CreateGroupDialog.vue'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { onMounted, ref, watch, reactive, onBeforeMount } from 'vue'
|
||||
import SystemGroupApi from '@/api/system/user-group'
|
||||
import userManageApi from '@/api/system/chat-user'
|
||||
import { t } from '@/locales'
|
||||
const CreateGroupRef = ref<InstanceType<typeof CreateGroupDialog>>()
|
||||
const loading = ref(false)
|
||||
const rLoading = ref(false)
|
||||
const groupList = ref([]) // 全部成员
|
||||
const filterGroup = ref([]) // 搜索过滤后列表
|
||||
const currentUser = ref<String>('')
|
||||
const currentType = ref<String>('')
|
||||
import type { ChatUserGroupUserItem } from '@/api/type/systemChatUser'
|
||||
import iconMap from '@/components/app-icon/icons/common'
|
||||
import CreateOrUpdateGroupDialog from './component/CreateOrUpdateGroupDialog.vue'
|
||||
// import CreateGroupUserDialog from './component/CreateGroupUserDialog.vue'
|
||||
import type { ListItem } from '@/api/type/common'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import type { ChatUserItem } from '@/api/type/systemChatUser'
|
||||
|
||||
const filterText = ref('')
|
||||
const loading = ref(false)
|
||||
const list = ref<ListItem[]>([])
|
||||
const filterList = ref<ListItem[]>([]) // 搜索过滤后列表
|
||||
const current = ref<ListItem>()
|
||||
|
||||
const tableHeight = ref(0)
|
||||
const rightOutlined = iconMap['right-outlined'].iconReader()
|
||||
|
||||
watch(filterText, (val) => {
|
||||
if (val) {
|
||||
// filterGroup.value = groupList.value.filter((v) =>
|
||||
// v.name.toLowerCase().includes(val.toLowerCase()),
|
||||
// )
|
||||
} else {
|
||||
filterGroup.value = groupList.value
|
||||
async function getUserGroupList() {
|
||||
try {
|
||||
const res = await SystemGroupApi.getUserGroup(loading)
|
||||
list.value = res.data
|
||||
filterList.value = filter(list.value, filterText.value)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getUserGroupList()
|
||||
current.value = list.value[0]
|
||||
})
|
||||
|
||||
function isManage(type: String) {
|
||||
return type === 'manage'
|
||||
function filter(list: ListItem[], filterText: string) {
|
||||
if (!filterText.length) {
|
||||
return list
|
||||
}
|
||||
return list.filter((v: ListItem) =>
|
||||
v.name.toLowerCase().includes(filterText.toLowerCase()),
|
||||
)
|
||||
}
|
||||
|
||||
function clickMemberHandle(item: any) {
|
||||
currentUser.value = item.id
|
||||
currentType.value = item.type
|
||||
}
|
||||
function addMember() {
|
||||
CreateGroupRef.value?.open()
|
||||
watch(filterText, (val: string) => {
|
||||
filterList.value = filter(list.value, val)
|
||||
})
|
||||
|
||||
function clickUserGroup(item: ListItem) {
|
||||
current.value = item
|
||||
}
|
||||
|
||||
function getMember(id?: string) {
|
||||
loading.value = true
|
||||
const createOrUpdateGroupDialogRef = ref<InstanceType<typeof CreateOrUpdateGroupDialog>>()
|
||||
function createOrUpdate(item?: ListItem) {
|
||||
createOrUpdateGroupDialogRef.value?.open(item);
|
||||
}
|
||||
|
||||
function refresh(data?: string[]) {}
|
||||
function deleteGroup(item: ListItem) {
|
||||
MsgConfirm(
|
||||
`${t('views.chatUser.group.delete.confirmTitle')}${item.name} ?`,
|
||||
t('views.chatUser.group.delete.confirmMessage'),
|
||||
{
|
||||
confirmButtonText: t('common.confirm'),
|
||||
confirmButtonClass: 'danger',
|
||||
},
|
||||
)
|
||||
.then(() => {
|
||||
SystemGroupApi.delUserGroup(item.id as string, loading).then(async () => {
|
||||
MsgSuccess(t('common.deleteSuccess'))
|
||||
await getUserGroupList()
|
||||
current.value = item.id === current.value?.id ? list.value[0] : current.value
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {})
|
||||
async function refresh(group?: ListItem) {
|
||||
await getUserGroupList();
|
||||
// 创建角色后选中新建的角色
|
||||
current.value = group ? group : current.value
|
||||
}
|
||||
|
||||
const rightLoading = ref(false)
|
||||
|
||||
const searchType = ref('username')
|
||||
const searchForm = ref<Record<string, any>>({
|
||||
username: '',
|
||||
})
|
||||
const paginationConfig = reactive({
|
||||
current_page: 1,
|
||||
page_size: 20,
|
||||
total: 0,
|
||||
})
|
||||
|
||||
const tableData = ref<ChatUserGroupUserItem[]>([])
|
||||
|
||||
async function getList() {
|
||||
if (!current.value?.id) return
|
||||
try {
|
||||
const res = await SystemGroupApi.getUserListByGroup(current.value?.id, paginationConfig, searchForm.value.username, rightLoading)
|
||||
tableData.value = res.data.records
|
||||
paginationConfig.total = res.data.total
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
function handleSizeChange() {
|
||||
paginationConfig.current_page = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
watch(() => current.value?.id, () => {
|
||||
getList()
|
||||
})
|
||||
|
||||
const chatUserList = ref<ChatUserItem[]>([])
|
||||
async function getChatUserList() {
|
||||
try {
|
||||
const res = await userManageApi.getChatUserList()
|
||||
chatUserList.value = res.data
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
getChatUserList()
|
||||
})
|
||||
|
||||
// const createGroupUserDialogRef = ref<InstanceType<typeof CreateGroupUserDialog>>()
|
||||
function createUser() {
|
||||
// createGroupUserDialogRef.value?.open();
|
||||
}
|
||||
|
||||
const multipleSelection = ref<string[]>([])
|
||||
function handleSelectionChange(val: string[]) {
|
||||
multipleSelection.value = val
|
||||
}
|
||||
|
||||
function handleDeleteUser(ids?: string[]) {
|
||||
// TODO
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group-manage {
|
||||
.content-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.content-container__main) {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
:deep(.user-card) {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-left {
|
||||
box-sizing: border-box;
|
||||
width: var(--setting-left-width);
|
||||
min-width: var(--setting-left-width);
|
||||
|
||||
.user-left_title {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.list-height-left {
|
||||
height: calc(100vh - 271px);
|
||||
|
||||
:deep(.common-list li) {
|
||||
padding-right: 4px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-right {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue