feat: applicationChatUser
This commit is contained in:
parent
a892f3075f
commit
d86ad90e31
48
ui/src/api/chat-user/chat-user.ts
Normal file
48
ui/src/api/chat-user/chat-user.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import type { Ref } from 'vue'
|
||||||
|
import { Result } from '@/request/Result'
|
||||||
|
import { get, put } from '@/request/index'
|
||||||
|
import type { ChatUserGroupItem, ChatUserGroupUserItem, ChatUserResourceParams, putUserGroupUserParams } from '@/api/type/workspaceChatUser'
|
||||||
|
import type { pageRequest, PageList } from '@/api/type/common'
|
||||||
|
const prefix = '/workspace/' + localStorage.getItem('workspace_id')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户组列表
|
||||||
|
*/
|
||||||
|
const getUserGroupList: (resource: ChatUserResourceParams, loading?: Ref<boolean>) => Promise<Result<ChatUserGroupItem[]>> = (resource, loading) => {
|
||||||
|
return get(`${prefix}/${resource.resource_type}/${resource.resource_id}/user_group`, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户组的用户列表
|
||||||
|
*/
|
||||||
|
const getUserGroupUserList: (
|
||||||
|
resource: ChatUserResourceParams,
|
||||||
|
user_group_id: string,
|
||||||
|
page: pageRequest,
|
||||||
|
param: any,
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<PageList<ChatUserGroupUserItem[]>>> = (resource, user_group_id, page, param, loading) => {
|
||||||
|
return get(
|
||||||
|
`${prefix}/${resource.resource_type}/${resource.resource_id}/user_group_id/${user_group_id}/${page.current_page}/${page.page_size}`,
|
||||||
|
param,
|
||||||
|
loading,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户组的用户列表
|
||||||
|
*/
|
||||||
|
const putUserGroupUser: (
|
||||||
|
resource: ChatUserResourceParams,
|
||||||
|
user_group_id: string,
|
||||||
|
data: putUserGroupUserParams[],
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<boolean>> = (resource, user_group_id, data, loading) => {
|
||||||
|
return put(`${prefix}/${resource.resource_type}/${resource.resource_id}/user_group_id/${user_group_id}`, data, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getUserGroupList,
|
||||||
|
getUserGroupUserList,
|
||||||
|
putUserGroupUser
|
||||||
|
}
|
||||||
@ -1,22 +1,22 @@
|
|||||||
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 {Ref} from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
const prefix = '/system/chat_user'
|
const prefix = '/system/chat_user'
|
||||||
/**
|
/**
|
||||||
* 用户分页列表
|
* 用户分页列表
|
||||||
* @query 参数
|
* @query 参数
|
||||||
email_or_username: string
|
username_or_nickname: string
|
||||||
*/
|
*/
|
||||||
const getUserManage: (
|
const getUserManage: (
|
||||||
page: pageRequest,
|
page: pageRequest,
|
||||||
email_or_username: string,
|
username_or_nickname: string,
|
||||||
loading?: Ref<boolean>,
|
loading?: Ref<boolean>,
|
||||||
) => Promise<Result<any>> = (page, email_or_username, loading) => {
|
) => Promise<Result<any>> = (page, username_or_nickname, loading) => {
|
||||||
return get(
|
return get(
|
||||||
`${prefix}/user_manage/${page.current_page}/${page.page_size}`,
|
`${prefix}/user_manage/${page.current_page}/${page.page_size}`,
|
||||||
email_or_username ? {email_or_username} : undefined,
|
username_or_nickname ? { username_or_nickname } : undefined,
|
||||||
loading,
|
loading,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
33
ui/src/api/type/workspaceChatUser.ts
Normal file
33
ui/src/api/type/workspaceChatUser.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
import { ChatUserResourceEnum } from '@/enums/workspaceChatUser'
|
||||||
|
|
||||||
|
interface ChatUserResourceParams {
|
||||||
|
resource_id: string,
|
||||||
|
resource_type: ChatUserResourceEnum
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChatUserGroupItem {
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
is_auth: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface putUserGroupUserParams {
|
||||||
|
chat_user_id: string,
|
||||||
|
is_auth: boolean
|
||||||
|
}
|
||||||
|
export type { ChatUserGroupItem, putUserGroupUserParams, ChatUserResourceParams, ChatUserGroupUserItem }
|
||||||
4
ui/src/enums/workspaceChatUser.ts
Normal file
4
ui/src/enums/workspaceChatUser.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export enum ChatUserResourceEnum {
|
||||||
|
KNOWLEDGE = 'KNOWLEDGE',
|
||||||
|
APPLICATION = 'APPLICATION',
|
||||||
|
}
|
||||||
@ -84,4 +84,5 @@ export default {
|
|||||||
},
|
},
|
||||||
info: 'Base Information',
|
info: 'Base Information',
|
||||||
otherSetting: 'Other Settings',
|
otherSetting: 'Other Settings',
|
||||||
|
username: 'username'
|
||||||
}
|
}
|
||||||
|
|||||||
10
ui/src/locales/lang/en-US/views/chat-user.ts
Normal file
10
ui/src/locales/lang/en-US/views/chat-user.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
title: 'Chat users',
|
||||||
|
syncUsers: 'Sync users',
|
||||||
|
setUserGroups: 'Set user groups',
|
||||||
|
autoAuthorization: 'Auto authorization',
|
||||||
|
authorization: 'Authorization',
|
||||||
|
group: {
|
||||||
|
title: 'User groups',
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -14,6 +14,7 @@ import document from './document'
|
|||||||
import paragraph from './paragraph'
|
import paragraph from './paragraph'
|
||||||
import problem from './problem'
|
import problem from './problem'
|
||||||
import chatLog from './chat-log'
|
import chatLog from './chat-log'
|
||||||
|
import chatUser from './chat-user'
|
||||||
import applicationWorkflow from './application-workflow'
|
import applicationWorkflow from './application-workflow'
|
||||||
import login from './login'
|
import login from './login'
|
||||||
import operateLog from './operate-log'
|
import operateLog from './operate-log'
|
||||||
@ -36,5 +37,6 @@ export default {
|
|||||||
login,
|
login,
|
||||||
operateLog,
|
operateLog,
|
||||||
role,
|
role,
|
||||||
workspace
|
workspace,
|
||||||
|
chatUser
|
||||||
}
|
}
|
||||||
|
|||||||
@ -88,4 +88,5 @@ export default {
|
|||||||
},
|
},
|
||||||
info: '基本信息',
|
info: '基本信息',
|
||||||
otherSetting: '其他设置',
|
otherSetting: '其他设置',
|
||||||
|
username: '用户名'
|
||||||
}
|
}
|
||||||
|
|||||||
10
ui/src/locales/lang/zh-CN/views/chat-user.ts
Normal file
10
ui/src/locales/lang/zh-CN/views/chat-user.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
title: '对话用户',
|
||||||
|
syncUsers: '同步用户',
|
||||||
|
setUserGroups: '设置用户组',
|
||||||
|
autoAuthorization: '自动授权',
|
||||||
|
authorization: '授权',
|
||||||
|
group: {
|
||||||
|
title: '用户组',
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,7 @@ import applicationOverview from './application-overview'
|
|||||||
import applicationWorkflow from './application-workflow'
|
import applicationWorkflow from './application-workflow'
|
||||||
import paragraph from './paragraph'
|
import paragraph from './paragraph'
|
||||||
import chatLog from './chat-log'
|
import chatLog from './chat-log'
|
||||||
|
import chatUser from './chat-user'
|
||||||
// import notFound from './404'
|
// import notFound from './404'
|
||||||
|
|
||||||
// import operateLog from './operate-log'
|
// import operateLog from './operate-log'
|
||||||
@ -34,6 +35,7 @@ export default {
|
|||||||
applicationWorkflow,
|
applicationWorkflow,
|
||||||
paragraph,
|
paragraph,
|
||||||
chatLog,
|
chatLog,
|
||||||
|
chatUser,
|
||||||
// notFound,
|
// notFound,
|
||||||
|
|
||||||
// operateLog
|
// operateLog
|
||||||
|
|||||||
@ -84,4 +84,5 @@ export default {
|
|||||||
},
|
},
|
||||||
info: '使用者資訊',
|
info: '使用者資訊',
|
||||||
otherSetting: '其他設定',
|
otherSetting: '其他設定',
|
||||||
|
username: '用户名'
|
||||||
}
|
}
|
||||||
|
|||||||
10
ui/src/locales/lang/zh-Hant/views/chat-user.ts
Normal file
10
ui/src/locales/lang/zh-Hant/views/chat-user.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
title: '對話用戶',
|
||||||
|
syncUsers: '同步用戶',
|
||||||
|
setUserGroups: '設定用戶組',
|
||||||
|
autoAuthorization: '自動授權',
|
||||||
|
authorization: '授權',
|
||||||
|
group: {
|
||||||
|
title: '用戶組',
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -14,6 +14,7 @@ import document from './document'
|
|||||||
import paragraph from './paragraph'
|
import paragraph from './paragraph'
|
||||||
import problem from './problem'
|
import problem from './problem'
|
||||||
import chatLog from './chat-log'
|
import chatLog from './chat-log'
|
||||||
|
import chatUser from './chat-user'
|
||||||
import applicationWorkflow from './application-workflow'
|
import applicationWorkflow from './application-workflow'
|
||||||
import login from './login'
|
import login from './login'
|
||||||
import operateLog from './operate-log'
|
import operateLog from './operate-log'
|
||||||
@ -36,5 +37,6 @@ export default {
|
|||||||
login,
|
login,
|
||||||
operateLog,
|
operateLog,
|
||||||
role,
|
role,
|
||||||
workspace
|
workspace,
|
||||||
|
chatUser
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { ChatUserResourceEnum } from '@/enums/workspaceChatUser'
|
||||||
|
|
||||||
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||||
|
|
||||||
const ApplicationDetailRouter = {
|
const ApplicationDetailRouter = {
|
||||||
@ -63,6 +65,20 @@ const ApplicationDetailRouter = {
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/hit-test/index.vue'),
|
component: () => import('@/views/hit-test/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'chat-user',
|
||||||
|
name: 'applicationChatUser',
|
||||||
|
meta: {
|
||||||
|
icon: 'app-document',
|
||||||
|
iconActive: 'app-document-active',
|
||||||
|
title: 'views.chatUser.title',
|
||||||
|
active: 'chat-log',
|
||||||
|
parentPath: '/application/:id/:type',
|
||||||
|
parentName: 'ApplicationDetail',
|
||||||
|
resourceType: ChatUserResourceEnum.APPLICATION
|
||||||
|
},
|
||||||
|
component: () => import('@/views/chat-user/index.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'chat-log',
|
path: 'chat-log',
|
||||||
name: 'ChatLog',
|
name: 'ChatLog',
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { ChatUserResourceEnum } from '@/enums/workspaceChatUser'
|
||||||
|
|
||||||
const DocumentRouter = {
|
const DocumentRouter = {
|
||||||
path: '/knowledge/:id/:folderId',
|
path: '/knowledge/:id/:folderId',
|
||||||
name: 'KnowledgeDetail',
|
name: 'KnowledgeDetail',
|
||||||
@ -43,6 +45,20 @@ const DocumentRouter = {
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/hit-test/index.vue'),
|
component: () => import('@/views/hit-test/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'chat-user',
|
||||||
|
name: 'KnowledgeChatUser',
|
||||||
|
meta: {
|
||||||
|
icon: 'app-document',
|
||||||
|
iconActive: 'app-document-active',
|
||||||
|
title: 'views.chatUser.title',
|
||||||
|
active: 'chat-log',
|
||||||
|
parentPath: '/knowledge/:id/:folderId',
|
||||||
|
parentName: 'KnowledgeDetail',
|
||||||
|
resourceType: ChatUserResourceEnum.APPLICATION
|
||||||
|
},
|
||||||
|
component: () => import('@/views/chat-user/index.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'setting',
|
path: 'setting',
|
||||||
name: 'KnowledgeSetting',
|
name: 'KnowledgeSetting',
|
||||||
|
|||||||
@ -111,7 +111,7 @@ const systemRouter = {
|
|||||||
meta: {
|
meta: {
|
||||||
icon: 'app-folder-share',
|
icon: 'app-folder-share',
|
||||||
iconActive: 'app-folder-share-active',
|
iconActive: 'app-folder-share-active',
|
||||||
title: '对话用户',
|
title: 'views.chatUser.title',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
@ -121,7 +121,7 @@ const systemRouter = {
|
|||||||
path: '/system/chat/chat-user',
|
path: '/system/chat/chat-user',
|
||||||
name: 'ChatUser',
|
name: 'ChatUser',
|
||||||
meta: {
|
meta: {
|
||||||
title: '对话用户',
|
title: 'views.chatUser.title',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
@ -132,7 +132,7 @@ const systemRouter = {
|
|||||||
path: '/system/chat/group',
|
path: '/system/chat/group',
|
||||||
name: 'Group',
|
name: 'Group',
|
||||||
meta: {
|
meta: {
|
||||||
title: '用户组',
|
title: 'views.chatUser.group.title',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
@ -143,7 +143,7 @@ const systemRouter = {
|
|||||||
path: '/system/chat/authentication',
|
path: '/system/chat/authentication',
|
||||||
name: 'Authentication',
|
name: 'Authentication',
|
||||||
meta: {
|
meta: {
|
||||||
title: '登录认证',
|
title: 'views.system.authentication.title',
|
||||||
activeMenu: '/system',
|
activeMenu: '/system',
|
||||||
parentPath: '/system',
|
parentPath: '/system',
|
||||||
parentName: 'system',
|
parentName: 'system',
|
||||||
|
|||||||
260
ui/src/views/chat-user/index.vue
Normal file
260
ui/src/views/chat-user/index.vue
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<ContentContainer>
|
||||||
|
<template #header>
|
||||||
|
<div>
|
||||||
|
<h2>{{ $t('views.chatUser.title') }}</h2>
|
||||||
|
<div class="color-secondary">{{ $t('views.user.title') }}</div>
|
||||||
|
</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">
|
||||||
|
<h4 class="medium">{{ $t('views.chatUser.group.title') }}</h4>
|
||||||
|
</div>
|
||||||
|
<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 }">
|
||||||
|
<span>{{ row.name }}</span>
|
||||||
|
</template>
|
||||||
|
<template #empty>
|
||||||
|
<span></span>
|
||||||
|
</template>
|
||||||
|
</common-list>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右边 -->
|
||||||
|
<div class="user-right" v-loading="rightLoading">
|
||||||
|
<div class="flex-between">
|
||||||
|
<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">
|
||||||
|
{{ current?.user_count }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="handleSave">
|
||||||
|
{{ t('common.save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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-select>
|
||||||
|
<el-input v-if="searchType === 'username_or_nickname'" v-model="searchForm.username_or_nickname"
|
||||||
|
@change="getList" :placeholder="$t('common.inputPlaceholder')" style="width: 220px" clearable />
|
||||||
|
</div>
|
||||||
|
<div class="flex align-center">
|
||||||
|
<div class="color-secondary mr-8">{{ $t('views.chatUser.autoAuthorization') }}</div>
|
||||||
|
<el-switch size="small" v-model="automaticAuthorization"></el-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-table :data="tableData" :pagination-config="paginationConfig" @sizeChange="handleSizeChange"
|
||||||
|
@changePage="getList" v-loading="rightLoading">
|
||||||
|
<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>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :width="140" align="center">
|
||||||
|
<template #header>
|
||||||
|
<el-checkbox :model-value="allChecked" :indeterminate="allIndeterminate" :disabled="disabled"
|
||||||
|
@change="handleCheckAll">{{ $t('views.chatUser.authorization') }}</el-checkbox>
|
||||||
|
</template>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-checkbox v-model="row.enable" :indeterminate="row.indeterminate" :disabled="disabled"
|
||||||
|
@change="(value: boolean) => handleRowChange(value, row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</app-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</ContentContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref, watch, reactive, computed } from 'vue'
|
||||||
|
import ChatUserApi from '@/api/chat-user/chat-user'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
import type { ChatUserGroupItem, ChatUserResourceParams, ChatUserGroupUserItem } from '@/api/type/workspaceChatUser'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { ChatUserResourceEnum } from '@/enums/workspaceChatUser'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const resource: ChatUserResourceParams = { resource_id: route.params.id as string, resource_type: route.meta.resourceType as ChatUserResourceEnum }
|
||||||
|
|
||||||
|
const disabled = computed(() => false) // TODO
|
||||||
|
|
||||||
|
const filterText = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
const list = ref<ChatUserGroupItem[]>([])
|
||||||
|
const filterList = ref<ChatUserGroupItem[]>([]) // 搜索过滤后列表
|
||||||
|
const current = ref<ChatUserGroupItem>()
|
||||||
|
|
||||||
|
async function getUserGroupList() {
|
||||||
|
try {
|
||||||
|
const res = await ChatUserApi.getUserGroupList(resource, 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 filter(list: ChatUserGroupItem[], filterText: string) {
|
||||||
|
if (!filterText.length) {
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
return list.filter((v: ChatUserGroupItem) =>
|
||||||
|
v.name.toLowerCase().includes(filterText.toLowerCase()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(filterText, (val: string) => {
|
||||||
|
filterList.value = filter(list.value, val)
|
||||||
|
})
|
||||||
|
|
||||||
|
function clickUserGroup(item: ChatUserGroupItem) {
|
||||||
|
current.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
const rightLoading = ref(false)
|
||||||
|
|
||||||
|
const searchType = ref('username_or_nickname')
|
||||||
|
const searchForm = ref<Record<string, any>>({
|
||||||
|
username_or_nickname: '',
|
||||||
|
})
|
||||||
|
const automaticAuthorization = ref(false)
|
||||||
|
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 params = {
|
||||||
|
[searchType.value]: searchForm.value[searchType.value],
|
||||||
|
}
|
||||||
|
const res = await ChatUserApi.getUserGroupUserList(resource, current.value?.id, paginationConfig, params, 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 allChecked = computed(() =>
|
||||||
|
tableData.value.length > 0 && tableData.value.every((item: ChatUserGroupUserItem) => item.is_auth)
|
||||||
|
);
|
||||||
|
|
||||||
|
const allIndeterminate = computed(() =>
|
||||||
|
!allChecked.value && tableData.value.some((item: ChatUserGroupUserItem) => item.is_auth)
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleCheckAll = (checked: boolean) => {
|
||||||
|
tableData.value.forEach((item: ChatUserGroupUserItem) => {
|
||||||
|
item.is_auth = checked;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRowChange = (value: boolean, row: ChatUserGroupUserItem) => {
|
||||||
|
row.is_auth = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handleSave() {
|
||||||
|
try {
|
||||||
|
const params = tableData.value.map(item => ({ chat_user_id: item.id, is_auth: item.is_auth }))
|
||||||
|
await ChatUserApi.putUserGroupUser(resource, current.value?.id as string, params, rightLoading)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.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 {
|
||||||
|
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>
|
||||||
@ -1,48 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-16-24">
|
<ContentContainer>
|
||||||
<h2 class="mb-16">{{ $t('views.userManage.title') }}</h2>
|
<template #header>
|
||||||
<el-card>
|
<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 class="h-full">
|
||||||
<div class="flex-between mb-16">
|
<div class="flex-between mb-16">
|
||||||
<el-button type="primary" @click="createUser()">{{
|
<div>
|
||||||
$t('views.userManage.createUser')
|
<el-button type="primary" @click="createUser()">
|
||||||
}}
|
{{ t('views.userManage.createUser') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button :disabled="multipleSelection.length === 0">
|
||||||
|
{{ $t('views.chatUser.syncUsers') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button :disabled="multipleSelection.length === 0">
|
||||||
|
{{ $t('views.chatUser.setUserGroups') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button :disabled="multipleSelection.length === 0">
|
||||||
|
{{ $t('common.delete') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
<div class="flex-between complex-search">
|
<div class="flex-between complex-search">
|
||||||
<el-select
|
<el-select class="complex-search__left" v-model="search_type" style="width: 120px"
|
||||||
class="complex-search__left"
|
@change="search_type_change">
|
||||||
v-model="search_type"
|
<el-option :label="$t('views.login.loginForm.username.label')" value="name" />
|
||||||
style="width: 120px"
|
|
||||||
@change="search_type_change"
|
|
||||||
>
|
|
||||||
<el-option :label="$t('views.login.loginForm.username.label')" value="name"/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input
|
<el-input v-if="search_type === 'name'" v-model="search_form.name" @change="getList"
|
||||||
v-if="search_type === 'name'"
|
:placeholder="$t('common.searchBar.placeholder')" style="width: 220px" clearable />
|
||||||
v-model="search_form.name"
|
|
||||||
@change="getList"
|
|
||||||
:placeholder="$t('common.searchBar.placeholder')"
|
|
||||||
style="width: 220px"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<app-table
|
<app-table class="mt-16" :data="userTableData" :pagination-config="paginationConfig"
|
||||||
class="mt-16"
|
@sizeChange="handleSizeChange" @changePage="getList" v-loading="loading"
|
||||||
:data="userTableData"
|
@selection-change="handleSelectionChange" @sort-change="handleSortChange">
|
||||||
:pagination-config="paginationConfig"
|
<el-table-column type="selection" width="55" />
|
||||||
@sizeChange="handleSizeChange"
|
<el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')" />
|
||||||
@changePage="getList"
|
<el-table-column prop="username" :label="$t('common.username')" />
|
||||||
v-loading="loading"
|
|
||||||
>
|
|
||||||
<el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')"/>
|
|
||||||
<el-table-column prop="username" :label="$t('views.userManage.userForm.username.label')"/>
|
|
||||||
<el-table-column prop="is_active" :label="$t('common.status.label')">
|
<el-table-column prop="is_active" :label="$t('common.status.label')">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div v-if="row.is_active" class="flex align-center">
|
<div v-if="row.is_active" class="flex align-center">
|
||||||
<el-icon class="color-success mr-8" style="font-size: 16px"
|
<el-icon class="color-success mr-8" style="font-size: 16px">
|
||||||
>
|
<SuccessFilled />
|
||||||
<SuccessFilled
|
|
||||||
/>
|
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span class="color-secondary">
|
<span class="color-secondary">
|
||||||
{{ $t('common.status.enabled') }}
|
{{ $t('common.status.enabled') }}
|
||||||
@ -71,6 +73,12 @@
|
|||||||
{{ row.phone || '-' }}
|
{{ row.phone || '-' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<!-- TODO -->
|
||||||
|
<el-table-column prop="user_group_names" :label="$t('views.chatUser.group.title')">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.user_group_names || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<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 }">
|
||||||
{{
|
{{
|
||||||
@ -98,57 +106,54 @@
|
|||||||
<el-table-column :label="$t('common.operation')" width="160" align="left" fixed="right">
|
<el-table-column :label="$t('common.operation')" width="160" align="left" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span @click.stop>
|
<span @click.stop>
|
||||||
<el-switch
|
<el-switch size="small" v-model="row.is_active" :before-change="() => changeState(row)" />
|
||||||
size="small"
|
|
||||||
v-model="row.is_active"
|
|
||||||
:before-change="() => changeState(row)"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<el-divider direction="vertical"/>
|
<el-divider direction="vertical" />
|
||||||
<span class="mr-8">
|
<span class="mr-8">
|
||||||
<el-button type="primary" text @click.stop="editUser(row)" :title="$t('common.edit')">
|
<el-button type="primary" text @click.stop="editUser(row)" :title="$t('common.edit')">
|
||||||
<el-icon><EditPen/></el-icon>
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="mr-8">
|
<span class="mr-8">
|
||||||
<el-button
|
<el-button type="primary" text @click.stop="editPwdUser(row)"
|
||||||
type="primary"
|
:title="$t('views.userManage.setting.updatePwd')">
|
||||||
text
|
<el-icon>
|
||||||
@click.stop="editPwdUser(row)"
|
<Lock />
|
||||||
:title="$t('views.userManage.setting.updatePwd')"
|
</el-icon>
|
||||||
>
|
|
||||||
<el-icon><Lock/></el-icon>
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<el-button
|
<el-button :disabled="row.role === 'ADMIN'" type="primary" text @click.stop="deleteUserManage(row)"
|
||||||
:disabled="row.role === 'ADMIN'"
|
:title="$t('common.delete')">
|
||||||
type="primary"
|
<el-icon>
|
||||||
text
|
<Delete />
|
||||||
@click.stop="deleteUserManage(row)"
|
</el-icon>
|
||||||
:title="$t('common.delete')"
|
|
||||||
>
|
|
||||||
<el-icon><Delete/></el-icon>
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</app-table>
|
</app-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh"/>
|
</ContentContainer>
|
||||||
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh"/>
|
|
||||||
</div>
|
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh" />
|
||||||
|
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {onMounted, ref, reactive, watch} from 'vue'
|
import { onMounted, ref, reactive, watch } from 'vue'
|
||||||
import UserDrawer from './component/UserDrawer.vue'
|
import UserDrawer from './component/UserDrawer.vue'
|
||||||
import UserPwdDialog from './component/UserPwdDialog.vue'
|
import UserPwdDialog from './component/UserPwdDialog.vue'
|
||||||
import userManageApi from '@/api/system/chat-user'
|
import userManageApi from '@/api/system/chat-user'
|
||||||
import {datetimeFormat} from '@/utils/time'
|
import { datetimeFormat } from '@/utils/time'
|
||||||
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
import {t} from '@/locales'
|
import { t } from '@/locales'
|
||||||
|
import iconMap from '@/components/app-icon/icons/common'
|
||||||
|
|
||||||
|
const rightOutlined = iconMap['right-outlined'].iconReader()
|
||||||
|
|
||||||
const search_type = ref('name')
|
const search_type = ref('name')
|
||||||
const search_form = ref<{
|
const search_form = ref<{
|
||||||
@ -156,11 +161,17 @@ const search_form = ref<{
|
|||||||
}>({
|
}>({
|
||||||
name: '',
|
name: '',
|
||||||
})
|
})
|
||||||
|
const search_type_change = () => {
|
||||||
|
search_form.value = { name: '' }
|
||||||
|
}
|
||||||
|
|
||||||
const UserDrawerRef = ref()
|
|
||||||
const UserPwdDialogRef = ref()
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const multipleSelection = ref<string[]>([])
|
||||||
|
function handleSelectionChange(val: string[]) {
|
||||||
|
multipleSelection.value = val
|
||||||
|
}
|
||||||
|
|
||||||
const paginationConfig = reactive({
|
const paginationConfig = reactive({
|
||||||
current_page: 1,
|
current_page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
@ -169,15 +180,6 @@ const paginationConfig = reactive({
|
|||||||
|
|
||||||
const userTableData = ref<any[]>([])
|
const userTableData = ref<any[]>([])
|
||||||
|
|
||||||
const search_type_change = () => {
|
|
||||||
search_form.value = {name: ''}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSizeChange() {
|
|
||||||
paginationConfig.current_page = 1
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getList() {
|
function getList() {
|
||||||
return userManageApi
|
return userManageApi
|
||||||
.getUserManage(paginationConfig, search_form.value.name, loading)
|
.getUserManage(paginationConfig, search_form.value.name, loading)
|
||||||
@ -187,6 +189,17 @@ function getList() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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: any) {
|
function changeState(row: any) {
|
||||||
const obj = {
|
const obj = {
|
||||||
is_active: !row.is_active,
|
is_active: !row.is_active,
|
||||||
@ -205,7 +218,7 @@ function changeState(row: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const title = ref('')
|
const title = ref('')
|
||||||
|
const UserDrawerRef = ref()
|
||||||
function editUser(row: any) {
|
function editUser(row: any) {
|
||||||
title.value = t('views.userManage.editUser')
|
title.value = t('views.userManage.editUser')
|
||||||
UserDrawerRef.value.open(row)
|
UserDrawerRef.value.open(row)
|
||||||
@ -236,6 +249,7 @@ function deleteUserManage(row: any) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UserPwdDialogRef = ref()
|
||||||
function editPwdUser(row: any) {
|
function editPwdUser(row: any) {
|
||||||
UserPwdDialogRef.value.open(row)
|
UserPwdDialogRef.value.open(row)
|
||||||
}
|
}
|
||||||
@ -249,4 +263,14 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.content-container {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
:deep(.content-container__main) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user