mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 10:02:46 +00:00
feat: applicationChatUser
This commit is contained in:
parent
a892f3075f
commit
d86ad90e31
|
|
@ -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 {get, put, post, del} from '@/request/index'
|
||||
import type {pageRequest} from '@/api/type/common'
|
||||
import type {Ref} from 'vue'
|
||||
import { Result } from '@/request/Result'
|
||||
import { get, put, post, del } from '@/request/index'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
const prefix = '/system/chat_user'
|
||||
/**
|
||||
* 用户分页列表
|
||||
* @query 参数
|
||||
email_or_username: string
|
||||
username_or_nickname: string
|
||||
*/
|
||||
const getUserManage: (
|
||||
page: pageRequest,
|
||||
email_or_username: string,
|
||||
username_or_nickname: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (page, email_or_username, loading) => {
|
||||
) => Promise<Result<any>> = (page, username_or_nickname, loading) => {
|
||||
return get(
|
||||
`${prefix}/user_manage/${page.current_page}/${page.page_size}`,
|
||||
email_or_username ? {email_or_username} : undefined,
|
||||
username_or_nickname ? { username_or_nickname } : undefined,
|
||||
loading,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export enum ChatUserResourceEnum {
|
||||
KNOWLEDGE = 'KNOWLEDGE',
|
||||
APPLICATION = 'APPLICATION',
|
||||
}
|
||||
|
|
@ -84,4 +84,5 @@ export default {
|
|||
},
|
||||
info: 'Base Information',
|
||||
otherSetting: 'Other Settings',
|
||||
username: 'username'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 problem from './problem'
|
||||
import chatLog from './chat-log'
|
||||
import chatUser from './chat-user'
|
||||
import applicationWorkflow from './application-workflow'
|
||||
import login from './login'
|
||||
import operateLog from './operate-log'
|
||||
|
|
@ -36,5 +37,6 @@ export default {
|
|||
login,
|
||||
operateLog,
|
||||
role,
|
||||
workspace
|
||||
workspace,
|
||||
chatUser
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,4 +88,5 @@ export default {
|
|||
},
|
||||
info: '基本信息',
|
||||
otherSetting: '其他设置',
|
||||
username: '用户名'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 paragraph from './paragraph'
|
||||
import chatLog from './chat-log'
|
||||
import chatUser from './chat-user'
|
||||
// import notFound from './404'
|
||||
|
||||
// import operateLog from './operate-log'
|
||||
|
|
@ -34,6 +35,7 @@ export default {
|
|||
applicationWorkflow,
|
||||
paragraph,
|
||||
chatLog,
|
||||
chatUser,
|
||||
// notFound,
|
||||
|
||||
// operateLog
|
||||
|
|
|
|||
|
|
@ -84,4 +84,5 @@ export default {
|
|||
},
|
||||
info: '使用者資訊',
|
||||
otherSetting: '其他設定',
|
||||
username: '用户名'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 problem from './problem'
|
||||
import chatLog from './chat-log'
|
||||
import chatUser from './chat-user'
|
||||
import applicationWorkflow from './application-workflow'
|
||||
import login from './login'
|
||||
import operateLog from './operate-log'
|
||||
|
|
@ -36,5 +37,6 @@ export default {
|
|||
login,
|
||||
operateLog,
|
||||
role,
|
||||
workspace
|
||||
workspace,
|
||||
chatUser
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { ChatUserResourceEnum } from '@/enums/workspaceChatUser'
|
||||
|
||||
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||
|
||||
const ApplicationDetailRouter = {
|
||||
|
|
@ -63,6 +65,20 @@ const ApplicationDetailRouter = {
|
|||
},
|
||||
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',
|
||||
name: 'ChatLog',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { ChatUserResourceEnum } from '@/enums/workspaceChatUser'
|
||||
|
||||
const DocumentRouter = {
|
||||
path: '/knowledge/:id/:folderId',
|
||||
name: 'KnowledgeDetail',
|
||||
|
|
@ -43,6 +45,20 @@ const DocumentRouter = {
|
|||
},
|
||||
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',
|
||||
name: 'KnowledgeSetting',
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ const systemRouter = {
|
|||
meta: {
|
||||
icon: 'app-folder-share',
|
||||
iconActive: 'app-folder-share-active',
|
||||
title: '对话用户',
|
||||
title: 'views.chatUser.title',
|
||||
activeMenu: '/system',
|
||||
parentPath: '/system',
|
||||
parentName: 'system',
|
||||
|
|
@ -121,7 +121,7 @@ const systemRouter = {
|
|||
path: '/system/chat/chat-user',
|
||||
name: 'ChatUser',
|
||||
meta: {
|
||||
title: '对话用户',
|
||||
title: 'views.chatUser.title',
|
||||
activeMenu: '/system',
|
||||
parentPath: '/system',
|
||||
parentName: 'system',
|
||||
|
|
@ -132,7 +132,7 @@ const systemRouter = {
|
|||
path: '/system/chat/group',
|
||||
name: 'Group',
|
||||
meta: {
|
||||
title: '用户组',
|
||||
title: 'views.chatUser.group.title',
|
||||
activeMenu: '/system',
|
||||
parentPath: '/system',
|
||||
parentName: 'system',
|
||||
|
|
@ -143,7 +143,7 @@ const systemRouter = {
|
|||
path: '/system/chat/authentication',
|
||||
name: 'Authentication',
|
||||
meta: {
|
||||
title: '登录认证',
|
||||
title: 'views.system.authentication.title',
|
||||
activeMenu: '/system',
|
||||
parentPath: '/system',
|
||||
parentName: 'system',
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
<div class="p-16-24">
|
||||
<h2 class="mb-16">{{ $t('views.userManage.title') }}</h2>
|
||||
<el-card>
|
||||
<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 class="h-full">
|
||||
<div class="flex-between mb-16">
|
||||
<el-button type="primary" @click="createUser()">{{
|
||||
$t('views.userManage.createUser')
|
||||
}}
|
||||
</el-button>
|
||||
<div>
|
||||
<el-button type="primary" @click="createUser()">
|
||||
{{ t('views.userManage.createUser') }}
|
||||
</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">
|
||||
<el-select
|
||||
class="complex-search__left"
|
||||
v-model="search_type"
|
||||
style="width: 120px"
|
||||
@change="search_type_change"
|
||||
>
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="name"/>
|
||||
<el-select class="complex-search__left" v-model="search_type" style="width: 120px"
|
||||
@change="search_type_change">
|
||||
<el-option :label="$t('views.login.loginForm.username.label')" value="name" />
|
||||
</el-select>
|
||||
<el-input
|
||||
v-if="search_type === 'name'"
|
||||
v-model="search_form.name"
|
||||
@change="getList"
|
||||
:placeholder="$t('common.searchBar.placeholder')"
|
||||
style="width: 220px"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-if="search_type === 'name'" v-model="search_form.name" @change="getList"
|
||||
:placeholder="$t('common.searchBar.placeholder')" style="width: 220px" clearable />
|
||||
</div>
|
||||
</div>
|
||||
<app-table
|
||||
class="mt-16"
|
||||
:data="userTableData"
|
||||
:pagination-config="paginationConfig"
|
||||
@sizeChange="handleSizeChange"
|
||||
@changePage="getList"
|
||||
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')"/>
|
||||
<app-table class="mt-16" :data="userTableData" :pagination-config="paginationConfig"
|
||||
@sizeChange="handleSizeChange" @changePage="getList" v-loading="loading"
|
||||
@selection-change="handleSelectionChange" @sort-change="handleSortChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')" />
|
||||
<el-table-column prop="username" :label="$t('common.username')" />
|
||||
<el-table-column prop="is_active" :label="$t('common.status.label')">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.is_active" class="flex align-center">
|
||||
<el-icon class="color-success mr-8" style="font-size: 16px"
|
||||
>
|
||||
<SuccessFilled
|
||||
/>
|
||||
<el-icon class="color-success mr-8" style="font-size: 16px">
|
||||
<SuccessFilled />
|
||||
</el-icon>
|
||||
<span class="color-secondary">
|
||||
{{ $t('common.status.enabled') }}
|
||||
|
|
@ -71,6 +73,12 @@
|
|||
{{ row.phone || '-' }}
|
||||
</template>
|
||||
</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')">
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
|
|
@ -98,57 +106,54 @@
|
|||
<el-table-column :label="$t('common.operation')" width="160" align="left" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<span @click.stop>
|
||||
<el-switch
|
||||
size="small"
|
||||
v-model="row.is_active"
|
||||
:before-change="() => changeState(row)"
|
||||
/>
|
||||
<el-switch size="small" v-model="row.is_active" :before-change="() => changeState(row)" />
|
||||
</span>
|
||||
<el-divider direction="vertical"/>
|
||||
<el-divider direction="vertical" />
|
||||
<span class="mr-8">
|
||||
<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>
|
||||
</span>
|
||||
|
||||
<span class="mr-8">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
@click.stop="editPwdUser(row)"
|
||||
:title="$t('views.userManage.setting.updatePwd')"
|
||||
>
|
||||
<el-icon><Lock/></el-icon>
|
||||
<el-button type="primary" text @click.stop="editPwdUser(row)"
|
||||
:title="$t('views.userManage.setting.updatePwd')">
|
||||
<el-icon>
|
||||
<Lock />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
<span>
|
||||
<el-button
|
||||
:disabled="row.role === 'ADMIN'"
|
||||
type="primary"
|
||||
text
|
||||
@click.stop="deleteUserManage(row)"
|
||||
:title="$t('common.delete')"
|
||||
>
|
||||
<el-icon><Delete/></el-icon>
|
||||
<el-button :disabled="row.role === 'ADMIN'" type="primary" text @click.stop="deleteUserManage(row)"
|
||||
:title="$t('common.delete')">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</app-table>
|
||||
</el-card>
|
||||
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh"/>
|
||||
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh"/>
|
||||
</div>
|
||||
</ContentContainer>
|
||||
|
||||
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh" />
|
||||
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" />
|
||||
</template>
|
||||
|
||||
<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 UserPwdDialog from './component/UserPwdDialog.vue'
|
||||
import userManageApi from '@/api/system/chat-user'
|
||||
import {datetimeFormat} from '@/utils/time'
|
||||
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
||||
import {t} from '@/locales'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
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_form = ref<{
|
||||
|
|
@ -156,11 +161,17 @@ const search_form = ref<{
|
|||
}>({
|
||||
name: '',
|
||||
})
|
||||
const search_type_change = () => {
|
||||
search_form.value = { name: '' }
|
||||
}
|
||||
|
||||
const UserDrawerRef = ref()
|
||||
const UserPwdDialogRef = ref()
|
||||
const loading = ref(false)
|
||||
|
||||
const multipleSelection = ref<string[]>([])
|
||||
function handleSelectionChange(val: string[]) {
|
||||
multipleSelection.value = val
|
||||
}
|
||||
|
||||
const paginationConfig = reactive({
|
||||
current_page: 1,
|
||||
page_size: 20,
|
||||
|
|
@ -169,15 +180,6 @@ const paginationConfig = reactive({
|
|||
|
||||
const userTableData = ref<any[]>([])
|
||||
|
||||
const search_type_change = () => {
|
||||
search_form.value = {name: ''}
|
||||
}
|
||||
|
||||
function handleSizeChange() {
|
||||
paginationConfig.current_page = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
function getList() {
|
||||
return userManageApi
|
||||
.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) {
|
||||
const obj = {
|
||||
is_active: !row.is_active,
|
||||
|
|
@ -205,7 +218,7 @@ function changeState(row: any) {
|
|||
}
|
||||
|
||||
const title = ref('')
|
||||
|
||||
const UserDrawerRef = ref()
|
||||
function editUser(row: any) {
|
||||
title.value = t('views.userManage.editUser')
|
||||
UserDrawerRef.value.open(row)
|
||||
|
|
@ -236,6 +249,7 @@ function deleteUserManage(row: any) {
|
|||
})
|
||||
}
|
||||
|
||||
const UserPwdDialogRef = ref()
|
||||
function editPwdUser(row: any) {
|
||||
UserPwdDialogRef.value.open(row)
|
||||
}
|
||||
|
|
@ -249,4 +263,14 @@ onMounted(() => {
|
|||
})
|
||||
</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