feat: systemChatUserGroup
This commit is contained in:
parent
e4a8f371ab
commit
63b783c8f5
@ -19,12 +19,12 @@ const getUserGroupUserList: (
|
|||||||
resource: ChatUserResourceParams,
|
resource: ChatUserResourceParams,
|
||||||
user_group_id: string,
|
user_group_id: string,
|
||||||
page: pageRequest,
|
page: pageRequest,
|
||||||
param: any,
|
username_or_nickname: string,
|
||||||
loading?: Ref<boolean>,
|
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(
|
return get(
|
||||||
`${prefix}/${resource.resource_type}/${resource.resource_id}/user_group_id/${user_group_id}/${page.current_page}/${page.page_size}`,
|
`${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,
|
loading,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,18 @@
|
|||||||
import { Result } from '@/request/Result'
|
import { Result } from '@/request/Result'
|
||||||
import { get, put, post, del } from '@/request/index'
|
import { get, put, post, del } from '@/request/index'
|
||||||
import type { pageRequest } from '@/api/type/common'
|
import type { pageRequest } from '@/api/type/common'
|
||||||
|
import type { ChatUserItem } from '@/api/type/systemChatUser'
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
const prefix = '/system/chat_user'
|
const prefix = '/system/chat_user'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户列表
|
||||||
|
*/
|
||||||
|
const getChatUserList: (loading?: Ref<boolean>) => Promise<Result<ChatUserItem[]>> = (loading) => {
|
||||||
|
return get(`${prefix}/list`, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户分页列表
|
* 用户分页列表
|
||||||
* @query 参数
|
* @query 参数
|
||||||
@ -71,4 +80,5 @@ export default {
|
|||||||
delUserManage,
|
delUserManage,
|
||||||
postUserManage,
|
postUserManage,
|
||||||
putUserManagePassword,
|
putUserManagePassword,
|
||||||
|
getChatUserList
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
import {Result} from '@/request/Result'
|
import { Result } from '@/request/Result'
|
||||||
import {get, post, del, put} from '@/request/index'
|
import { get, post, del } from '@/request/index'
|
||||||
import type {Ref} from 'vue'
|
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 prefix = '/system/group'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户组列表
|
* 获取用户组列表
|
||||||
*/
|
*/
|
||||||
const getUserGroup: (loading?: Ref<boolean>) => Promise<Result<any[]>> = () => {
|
const getUserGroup: (loading?: Ref<boolean>) => Promise<Result<ListItem[]>> = () => {
|
||||||
return get(`${prefix}`)
|
return get(`${prefix}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +21,7 @@ const getUserGroup: (loading?: Ref<boolean>) => Promise<Result<any[]>> = () => {
|
|||||||
"name": "string"
|
"name": "string"
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const postUserGroup: (data: any, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
const postUserGroup: (data: ListItem, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||||
data,
|
data,
|
||||||
loading,
|
loading,
|
||||||
) => {
|
) => {
|
||||||
@ -30,7 +32,7 @@ const postUserGroup: (data: any, loading?: Ref<boolean>) => Promise<Result<boole
|
|||||||
* 删除用户组
|
* 删除用户组
|
||||||
* @param 参数 user_group_id
|
* @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,
|
user_group_id,
|
||||||
loading,
|
loading,
|
||||||
) => {
|
) => {
|
||||||
@ -48,7 +50,7 @@ const delUserGroup: (user_group_id: String, loading?: Ref<boolean>) => Promise<R
|
|||||||
*/
|
*/
|
||||||
const postAddMember: (
|
const postAddMember: (
|
||||||
user_group_id: string,
|
user_group_id: string,
|
||||||
body: any,
|
body: Record<string, any>,
|
||||||
loading?: Ref<boolean>,
|
loading?: Ref<boolean>,
|
||||||
) => Promise<Result<any>> = (user_group_id, body, loading) => {
|
) => Promise<Result<any>> = (user_group_id, body, loading) => {
|
||||||
return post(`${prefix}/${user_group_id}/add_member`, body, {}, loading)
|
return post(`${prefix}/${user_group_id}/add_member`, body, {}, loading)
|
||||||
@ -64,16 +66,32 @@ const postAddMember: (
|
|||||||
*/
|
*/
|
||||||
const postRemoveMember: (
|
const postRemoveMember: (
|
||||||
user_group_id: string,
|
user_group_id: string,
|
||||||
body: any,
|
body: Record<string, any>,
|
||||||
loading?: Ref<boolean>,
|
loading?: Ref<boolean>,
|
||||||
) => Promise<Result<any>> = (user_group_id, body, loading) => {
|
) => 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 {
|
export default {
|
||||||
getUserGroup,
|
getUserGroup,
|
||||||
postUserGroup,
|
postUserGroup,
|
||||||
delUserGroup,
|
delUserGroup,
|
||||||
postAddMember,
|
postAddMember,
|
||||||
postRemoveMember,
|
postRemoveMember,
|
||||||
|
getUserListByGroup
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,4 +18,8 @@ interface PageList<T> {
|
|||||||
records: T
|
records: T
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { KeyValue, Dict, pageRequest, PageList }
|
interface ListItem {
|
||||||
|
name: string,
|
||||||
|
id?: string,
|
||||||
|
}
|
||||||
|
export type { KeyValue, Dict, pageRequest, PageList, ListItem }
|
||||||
|
|||||||
29
ui/src/api/type/systemChatUser.ts
Normal file
29
ui/src/api/type/systemChatUser.ts
Normal file
@ -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: '授权',
|
authorization: '授权',
|
||||||
group: {
|
group: {
|
||||||
title: '用户组',
|
title: '用户组',
|
||||||
|
name: '用户组名称',
|
||||||
|
delete: {
|
||||||
|
confirmTitle: '是否删除用户组:',
|
||||||
|
confirmMessage: '删除后,该用户组下的成员将全部移除,请谨慎操作!',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
<el-divider direction="vertical" class="mr-8 ml-8" />
|
<el-divider direction="vertical" class="mr-8 ml-8" />
|
||||||
<AppIcon iconName="app-wordspace" style="font-size: 16px" class="color-input-placeholder"></AppIcon>
|
<AppIcon iconName="app-wordspace" style="font-size: 16px" class="color-input-placeholder"></AppIcon>
|
||||||
<span class="color-input-placeholder ml-4">
|
<span class="color-input-placeholder ml-4">
|
||||||
{{ current?.user_count }}
|
{{ paginationConfig.total }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="primary" @click="handleSave">
|
<el-button type="primary" @click="handleSave">
|
||||||
@ -48,9 +48,9 @@
|
|||||||
<div class="flex-between mb-16" style="margin-top: 18px;">
|
<div class="flex-between mb-16" style="margin-top: 18px;">
|
||||||
<div class="flex complex-search">
|
<div class="flex complex-search">
|
||||||
<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_or_nickname" />
|
<el-option :label="$t('views.login.loginForm.username.label')" value="name" />
|
||||||
</el-select>
|
</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 />
|
@change="getList" :placeholder="$t('common.inputPlaceholder')" style="width: 220px" clearable />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
@ -60,7 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<app-table :data="tableData" :pagination-config="paginationConfig" @sizeChange="handleSizeChange"
|
<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="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')">
|
||||||
@ -150,9 +150,9 @@ function clickUserGroup(item: ChatUserGroupItem) {
|
|||||||
|
|
||||||
const rightLoading = ref(false)
|
const rightLoading = ref(false)
|
||||||
|
|
||||||
const searchType = ref('username_or_nickname')
|
const searchType = ref('name')
|
||||||
const searchForm = ref<Record<string, any>>({
|
const searchForm = ref<Record<string, any>>({
|
||||||
username_or_nickname: '',
|
name: '',
|
||||||
})
|
})
|
||||||
const automaticAuthorization = ref(false)
|
const automaticAuthorization = ref(false)
|
||||||
const paginationConfig = reactive({
|
const paginationConfig = reactive({
|
||||||
@ -166,10 +166,7 @@ const tableData = ref<ChatUserGroupUserItem[]>([])
|
|||||||
async function getList() {
|
async function getList() {
|
||||||
if (!current.value?.id) return
|
if (!current.value?.id) return
|
||||||
try {
|
try {
|
||||||
const params = {
|
const res = await ChatUserApi.getUserGroupUserList(resource, current.value?.id, paginationConfig, searchForm.value.name, rightLoading)
|
||||||
[searchType.value]: searchForm.value[searchType.value],
|
|
||||||
}
|
|
||||||
const res = await ChatUserApi.getUserGroupUserList(resource, current.value?.id, paginationConfig, params, 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) {
|
||||||
|
|||||||
@ -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>
|
<template>
|
||||||
<div class="group-manage p-16-24">
|
<ContentContainer>
|
||||||
<h4 class="mb-16">{{ $t('views.system.group.title') }}</h4>
|
<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="p-8">
|
||||||
<div class="group-member p-8 border-r">
|
<el-input v-model="filterText" :placeholder="$t('common.search')" prefix-icon="Search" clearable />
|
||||||
<div class="flex-between p-16">
|
</div>
|
||||||
<h4>{{ $t('views.system.group.member') }}</h4>
|
<div class="list-height-left">
|
||||||
<el-button type="primary" link @click="addMember">
|
<el-scrollbar v-loading="loading">
|
||||||
<AppIcon iconName="app-add-users" class="add-user-icon" />
|
<common-list :data="filterList" @click="clickUserGroup" :default-active="current?.id">
|
||||||
</el-button>
|
<template #default="{ row }">
|
||||||
</div>
|
<div class="flex-between">
|
||||||
<div class="group-member-input">
|
<span>{{ row.name }}</span>
|
||||||
<el-input
|
<el-dropdown :teleported="false">
|
||||||
v-model="filterText"
|
<el-button text>
|
||||||
:placeholder="$t('views.system.group.searchBar.placeholder')"
|
<el-icon class="color-secondary">
|
||||||
prefix-icon="Search"
|
<MoreFilled />
|
||||||
clearable
|
</el-icon>
|
||||||
/>
|
</el-button>
|
||||||
</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>
|
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu style="min-width: 80px">
|
||||||
<!-- <el-dropdown-item @click.prevent="deleteMember(row)">{{
|
<el-dropdown-item @click.stop="createOrUpdate(row)" class="p-8">
|
||||||
$t('views.system.group.delete.button')
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
}}</el-dropdown-item> -->
|
{{
|
||||||
|
$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>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</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>
|
</template>
|
||||||
</common-list>
|
</el-table-column>
|
||||||
</el-scrollbar>
|
<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>
|
</div>
|
||||||
<div class="permission-setting flex" v-loading="rLoading">
|
</el-card>
|
||||||
<div class="group-manage__table">
|
</ContentContainer>
|
||||||
<h4 class="p-24 pb-0 mb-4">{{ $t('views.system.group.permissionSetting') }}</h4>
|
<CreateOrUpdateGroupDialog ref="createOrUpdateGroupDialogRef" @refresh="refresh" />
|
||||||
</div>
|
<!-- <CreateGroupUserDialog ref="createGroupUserDialogRef" @refresh="getUserGroupList" /> -->
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<CreateGroupDialog ref="CreateGroupRef" @refresh="refresh" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, reactive, watch } from 'vue'
|
import { onMounted, ref, watch, reactive, onBeforeMount } from 'vue'
|
||||||
import GroupApi from '@/api/system/user-group'
|
import SystemGroupApi from '@/api/system/user-group'
|
||||||
import CreateGroupDialog from './component/CreateGroupDialog.vue'
|
import userManageApi from '@/api/system/chat-user'
|
||||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
const CreateGroupRef = ref<InstanceType<typeof CreateGroupDialog>>()
|
import type { ChatUserGroupUserItem } from '@/api/type/systemChatUser'
|
||||||
const loading = ref(false)
|
import iconMap from '@/components/app-icon/icons/common'
|
||||||
const rLoading = ref(false)
|
import CreateOrUpdateGroupDialog from './component/CreateOrUpdateGroupDialog.vue'
|
||||||
const groupList = ref([]) // 全部成员
|
// import CreateGroupUserDialog from './component/CreateGroupUserDialog.vue'
|
||||||
const filterGroup = ref([]) // 搜索过滤后列表
|
import type { ListItem } from '@/api/type/common'
|
||||||
const currentUser = ref<String>('')
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
const currentType = ref<String>('')
|
import type { ChatUserItem } from '@/api/type/systemChatUser'
|
||||||
|
|
||||||
const filterText = ref('')
|
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) => {
|
async function getUserGroupList() {
|
||||||
if (val) {
|
try {
|
||||||
// filterGroup.value = groupList.value.filter((v) =>
|
const res = await SystemGroupApi.getUserGroup(loading)
|
||||||
// v.name.toLowerCase().includes(val.toLowerCase()),
|
list.value = res.data
|
||||||
// )
|
filterList.value = filter(list.value, filterText.value)
|
||||||
} else {
|
} catch (error) {
|
||||||
filterGroup.value = groupList.value
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getUserGroupList()
|
||||||
|
current.value = list.value[0]
|
||||||
})
|
})
|
||||||
|
|
||||||
function isManage(type: String) {
|
function filter(list: ListItem[], filterText: string) {
|
||||||
return type === 'manage'
|
if (!filterText.length) {
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
return list.filter((v: ListItem) =>
|
||||||
|
v.name.toLowerCase().includes(filterText.toLowerCase()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickMemberHandle(item: any) {
|
watch(filterText, (val: string) => {
|
||||||
currentUser.value = item.id
|
filterList.value = filter(list.value, val)
|
||||||
currentType.value = item.type
|
})
|
||||||
}
|
|
||||||
function addMember() {
|
function clickUserGroup(item: ListItem) {
|
||||||
CreateGroupRef.value?.open()
|
current.value = item
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMember(id?: string) {
|
const createOrUpdateGroupDialogRef = ref<InstanceType<typeof CreateOrUpdateGroupDialog>>()
|
||||||
loading.value = true
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<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
Block a user