feat: chat user operation

This commit is contained in:
teukkk 2025-06-18 17:43:41 +08:00
parent 4975c4b2bf
commit 0af7da36a1
14 changed files with 347 additions and 112 deletions

View File

@ -1,6 +1,6 @@
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, PageList } from '@/api/type/common'
import type { ChatUserItem } from '@/api/type/systemChatUser' 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'
@ -22,7 +22,7 @@ const getUserManage: (
page: pageRequest, page: pageRequest,
username_or_nickname: string, username_or_nickname: string,
loading?: Ref<boolean>, loading?: Ref<boolean>,
) => Promise<Result<any>> = (page, username_or_nickname, loading) => { ) => Promise<Result<PageList<ChatUserItem[]>>> = (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}`,
username_or_nickname ? { username_or_nickname } : undefined, username_or_nickname ? { username_or_nickname } : undefined,
@ -73,12 +73,43 @@ const putUserManagePassword: (
return put(`${prefix}/${user_id}/re_password`, data, undefined, loading) return put(`${prefix}/${user_id}/re_password`, data, undefined, loading)
} }
/**
*
*/
const batchAddGroup: (data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
data,
loading,
) => {
return post(`${prefix}/batch_add_group`, data, undefined, loading)
}
/**
*
*/
const batchDelete: (data: string[], loading?: Ref<boolean>) => Promise<Result<any>> = (
data,
loading,
) => {
return post(`${prefix}/batch_delete`, data, undefined, loading)
}
/**
*
*/
const batchSync: (sync_type: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
sync_type,
loading,
) => {
return post(`${prefix}/sync/${sync_type}`, undefined, undefined, loading)
}
export default { export default {
getUserManage, getUserManage,
putUserManage, putUserManage,
delUserManage, delUserManage,
postUserManage, postUserManage,
putUserManagePassword, putUserManagePassword,
getChatUserList getChatUserList,
batchAddGroup,
batchDelete,
batchSync
} }

View File

@ -12,15 +12,12 @@ interface ChatUserItem {
user_group_names?: string[], user_group_names?: string[],
} }
// TODO
interface ChatUserGroupUserItem { interface ChatUserGroupUserItem {
id: string, id: string,
is_auth: boolean,
email: string, email: string,
phone: string, phone: string,
nick_name: string, nick_name: string,
username: string, username: string,
password: string,
source: string, source: string,
is_active: boolean, is_active: boolean,
create_time: string, create_time: string,

View File

@ -1,4 +1,5 @@
export default { export default {
syncSuccess: 'Successful',
create: 'Create', create: 'Create',
createSuccess: 'Successful', createSuccess: 'Successful',
copy: 'Copy', copy: 'Copy',

View File

@ -1,19 +1,24 @@
export default { export default {
title: 'Chat users', title: 'Chat Users',
syncUsers: 'Synchronize users', syncUsers: 'Sync Users',
setUserGroups: 'Configure user groups', syncUsersTip: 'Only sync newly added users',
knowledgeTitleTip: 'This configuration will only take effect when the associated application enables chat user login authentication', setUserGroups: 'Configure User Groups',
knowledgeTitleTip: 'This configuration will only take effect after enabling chat user login authentication in the associated application',
applicationTitleTip: 'This configuration requires login authentication to be enabled in the application', applicationTitleTip: 'This configuration requires login authentication to be enabled in the application',
autoAuthorization: 'Auto authorization', autoAuthorization: 'Auto Authorization',
authorization: 'Authorization', authorization: 'Authorization',
batchDeleteUser: 'Delete selected {count} users?',
settingMethod: 'Configuration Method',
append: 'Append',
replace: 'Replace',
group: { group: {
title: 'User groups', title: 'User Groups',
name: 'User group name', name: 'User Group Name',
usernameOrName: 'Username/Name', usernameOrName: 'Username/Name',
delete: { delete: {
confirmTitle: 'Confirm to delete user group:', confirmTitle: 'Confirm to delete user group:',
confirmMessage: 'After deletion, all members in this user group will be removed. Please proceed with caution!', confirmMessage: 'All members in this group will be removed after deletion. Proceed with caution!',
}, },
batchDeleteMember: 'Remove selected {count} members?', batchDeleteMember: 'Remove selected {count} members?',
} }
}; }

View File

@ -1,4 +1,5 @@
export default { export default {
syncSuccess: '同步成功',
create: '创建', create: '创建',
createSuccess: '创建成功', createSuccess: '创建成功',
copy: '复制', copy: '复制',

View File

@ -1,11 +1,16 @@
export default { export default {
title: '对话用户', title: '对话用户',
syncUsers: '同步用户', syncUsers: '同步用户',
syncUsersTip: '仅同步新增用户',
setUserGroups: '设置用户组', setUserGroups: '设置用户组',
knowledgeTitleTip: '该配置需要关联的应用开启对话用户登录认证后才会生效', knowledgeTitleTip: '该配置需要关联的应用开启对话用户登录认证后才会生效',
applicationTitleTip: '该配置需要应用开启登录认证后生效', applicationTitleTip: '该配置需要应用开启登录认证后生效',
autoAuthorization: '自动授权', autoAuthorization: '自动授权',
authorization: '授权', authorization: '授权',
batchDeleteUser: '是否删除选中的 {count} 个用户?',
settingMethod: '设置方式',
append: '追加',
replace: '替换',
group: { group: {
title: '用户组', title: '用户组',
name: '用户组名称', name: '用户组名称',

View File

@ -1,4 +1,5 @@
export default { export default {
syncSuccess: '同步完成',
create: '創建', create: '創建',
createSuccess: '創建成功', createSuccess: '創建成功',
copy: '複製', copy: '複製',

View File

@ -1,11 +1,16 @@
export default { export default {
title: '對話用戶', title: '對話用戶',
syncUsers: '同步用戶', syncUsers: '同步用戶',
syncUsersTip: '僅同步新增用戶',
setUserGroups: '設定用戶組', setUserGroups: '設定用戶組',
knowledgeTitleTip: '該配置需要關聯的應用開啟對話用戶登入認證後才會生效', knowledgeTitleTip: '該配置需要關聯的應用開啟對話用戶登入認證後才會生效',
applicationTitleTip: '該配置需要應用開啟登入認證後生效', applicationTitleTip: '該配置需要應用開啟登入認證後生效',
autoAuthorization: '自動授權', autoAuthorization: '自動授權',
authorization: '授權', authorization: '授權',
batchDeleteUser: '是否刪除選中的 {count} 個用戶?',
settingMethod: '設定方式',
append: '追加',
replace: '替換',
group: { group: {
title: '用戶組', title: '用戶組',
name: '用戶組名稱', name: '用戶組名稱',
@ -16,4 +21,4 @@ export default {
}, },
batchDeleteMember: '是否移除選中的 {count} 個成員?', batchDeleteMember: '是否移除選中的 {count} 個成員?',
} }
}; }

View File

@ -263,7 +263,7 @@ watch(() => current.value?.id, () => {
const createGroupUserDialogRef = ref<InstanceType<typeof CreateGroupUserDialog>>() const createGroupUserDialogRef = ref<InstanceType<typeof CreateGroupUserDialog>>()
function createUser() { function createUser() {
createGroupUserDialogRef.value?.open(current.value?.id); createGroupUserDialogRef.value?.open(current.value?.id as string);
} }
const multipleSelection = ref<any[]>([]) const multipleSelection = ref<any[]>([])

View File

@ -0,0 +1,86 @@
<template>
<el-dialog width="600" :title="$t('views.chatUser.setUserGroups')" 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.settingMethod')" prop="user_group_ids">
<el-radio-group v-model="form.is_append">
<el-radio :value="true">{{ $t('views.chatUser.append') }}</el-radio>
<el-radio :value="false">{{ $t('views.chatUser.replace') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('views.chatUser.group.title')" prop="user_group_ids">
<el-select v-model="form.user_group_ids" multiple filterable :placeholder="$t('common.selectPlaceholder')"
:loading="props.optionLoading">
<el-option v-for="item in props.chatGroupList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</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">
{{ $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 userManageApi from '@/api/system/chat-user'
import type { ListItem } from '@/api/type/common'
const props = defineProps<{
optionLoading: boolean,
chatGroupList: ListItem[],
}>()
const emit = defineEmits<{
(e: 'refresh'): void;
}>();
const dialogVisible = ref<boolean>(false)
const defaultForm = {
user_group_ids: [],
is_append: true,
ids: []
}
const form = ref<{
ids: string[], user_group_ids: string[], is_append: boolean
}>({
...defaultForm,
})
function open(ids: string[]) {
form.value = { ...defaultForm, ids }
dialogVisible.value = true
}
const formRef = ref<FormInstance>();
const rules = reactive({
user_group_ids: [{ required: true, message: t('common.selectPlaceholder'), trigger: 'blur' }],
is_append: [{ required: true, message: t('common.selectPlaceholder'), trigger: 'blur' }],
})
const loading = ref<boolean>(false)
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
userManageApi.batchAddGroup(form.value, loading).then(() => {
MsgSuccess(t('common.settingSuccess'))
emit('refresh')
dialogVisible.value = false
})
}
})
}
defineExpose({ open })
</script>

View File

@ -0,0 +1,74 @@
<template>
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="false"
:destroy-on-close="true" width="600">
<template #header>
<h4 class="mb-8 medium">{{ t('views.chatUser.syncUsers') }}</h4>
<div class="color-secondary lighter">{{ t('views.chatUser.syncUsersTip') }}</div>
</template>
<el-form label-position="top" ref="formRef" :rules="rules" :model="form" require-asterisk-position="right">
<el-form-item :label="$t('views.userManage.source.label')" prop="sync_type">
<el-select v-model="form.sync_type" :placeholder="$t('common.selectPlaceholder')">
<el-option :label="t('views.userManage.source.local')" value="LOCAL">
</el-option>
</el-select>
</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">
{{ $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 userManageApi from '@/api/system/chat-user'
const emit = defineEmits<{
(e: 'refresh'): void;
}>();
const dialogVisible = ref<boolean>(false)
const defaultForm = {
sync_type: 'LOCAL',
}
const form = ref<{
sync_type: string
}>({
...defaultForm,
})
function open() {
form.value = { ...defaultForm }
dialogVisible.value = true
}
const formRef = ref<FormInstance>();
const rules = reactive({
sync_type: [{ required: true, message: t('common.selectPlaceholder'), trigger: 'blur' }],
})
const loading = ref<boolean>(false)
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
userManageApi.batchSync(form.value.sync_type, loading).then(() => {
MsgSuccess(t('common.syncSuccess'))
emit('refresh')
dialogVisible.value = false
})
}
})
}
defineExpose({ open })
</script>

View File

@ -1,68 +1,43 @@
<template> <template>
<el-drawer v-model="visible" size="60%"> <el-drawer v-model="visible" size="60%">
<template #header> <template #header>
<h4>{{ title }}</h4> <h4>{{ props.title }}</h4>
</template> </template>
<h4 class="title-decoration-1 mb-16 mt-8">{{ $t('common.info') }}</h4> <h4 class="title-decoration-1 mb-16 mt-8">{{ $t('common.info') }}</h4>
<el-form <el-form ref="userFormRef" :model="userForm" :rules="rules" label-position="top" require-asterisk-position="right"
ref="userFormRef" @submit.prevent :close-on-click-modal="false" :close-on-press-escape="false">
:model="userForm" <el-form-item :prop="isEdit ? '' : 'username'" :label="$t('views.login.loginForm.username.label')">
:rules="rules" <el-input v-model="userForm.username" :placeholder="$t('views.login.loginForm.username.placeholder')"
label-position="top" maxlength="20" show-word-limit :disabled="isEdit">
require-asterisk-position="right"
@submit.prevent
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<el-form-item
:prop="isEdit ? '' : 'username'"
:label="$t('views.login.loginForm.username.label')"
>
<el-input
v-model="userForm.username"
:placeholder="$t('views.login.loginForm.username.placeholder')"
maxlength="20"
show-word-limit
:disabled="isEdit"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('views.userManage.userForm.nick_name.label')"> <el-form-item prop="nick_name" :label="$t('views.userManage.userForm.nick_name.label')">
<el-input <el-input v-model="userForm.nick_name" :placeholder="$t('views.userManage.userForm.nick_name.placeholder')"
v-model="userForm.nick_name" maxlength="64" show-word-limit>
:placeholder="$t('views.userManage.userForm.nick_name.placeholder')"
maxlength="64"
show-word-limit
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('views.login.loginForm.email.label')" prop="email"> <el-form-item :label="$t('views.login.loginForm.email.label')" prop="email">
<el-input <el-input type="email" v-model="userForm.email" :placeholder="$t('views.login.loginForm.email.placeholder')">
type="email"
v-model="userForm.email"
:placeholder="$t('views.login.loginForm.email.placeholder')"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('views.userManage.userForm.phone.label')"> <el-form-item :label="$t('views.userManage.userForm.phone.label')">
<el-input <el-input v-model="userForm.phone" :placeholder="$t('views.userManage.userForm.phone.placeholder')">
v-model="userForm.phone"
:placeholder="$t('views.userManage.userForm.phone.placeholder')"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item label="默认密码" v-if="!isEdit">
:label="$t('views.userManage.form.password.label')" <span class="mr-8">{{ userForm.password }}</span>
prop="password" <el-button type="primary" link @click="copyClick(userForm.password)">
v-if="!isEdit" <AppIcon iconName="app-copy"></AppIcon>
> </el-button>
<el-input </el-form-item>
type="password" <h4 class="title-decoration-1 mb-16 mt-8">{{ $t('views.chatUser.group.title') }}</h4>
v-model="userForm.password" <el-form-item :label="$t('views.chatUser.group.title')" prop="user_group_ids">
:placeholder="$t('views.userManage.form.password.placeholder')" <el-select v-model="userForm.user_group_ids" multiple filterable
show-password :placeholder="`${$t('common.selectPlaceholder')}${$t('views.chatUser.group.title')}`"
> :loading="props.optionLoading">
</el-input> <el-option v-for="item in props.chatGroupList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -74,15 +49,20 @@
</el-drawer> </el-drawer>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref, reactive, watch} from 'vue' import { ref, reactive, watch } from 'vue'
import type {FormInstance} from 'element-plus' import type { FormInstance } from 'element-plus'
import userManageApi from '@/api/system/chat-user' import chatUserApi from '@/api/system/chat-user'
import {MsgSuccess} from '@/utils/message' import userManageApi from '@/api/user/user-manage'
import {t} from '@/locales' import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales'
import type { ListItem } from '@/api/type/common'
import { copyClick } from '@/utils/clipboard'
const props = defineProps({ const props = defineProps<{
title: String, title: string,
}) optionLoading: boolean,
chatGroupList: ListItem[],
}>()
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
@ -93,6 +73,7 @@ const userForm = ref<any>({
password: '', password: '',
phone: '', phone: '',
nick_name: '', nick_name: '',
user_group_ids: []
}) })
const rules = reactive({ const rules = reactive({
@ -109,23 +90,10 @@ const rules = reactive({
trigger: 'blur', trigger: 'blur',
}, },
], ],
email: [ nick_name: [
{ {
required: true, required: true,
message: t('views.login.loginForm.email.requiredMessage'), message: t('views.userManage.userForm.nick_name.placeholder'),
trigger: 'blur',
},
],
password: [
{
required: true,
message: t('views.login.loginForm.password.requiredMessage'),
trigger: 'blur',
},
{
min: 6,
max: 20,
message: t('views.login.loginForm.password.lengthMessage'),
trigger: 'blur', trigger: 'blur',
}, },
], ],
@ -142,6 +110,7 @@ watch(visible, (bool) => {
password: '', password: '',
phone: '', phone: '',
nick_name: '', nick_name: '',
user_group_ids: []
} }
isEdit.value = false isEdit.value = false
userFormRef.value?.clearValidate() userFormRef.value?.clearValidate()
@ -153,11 +122,16 @@ const open = (data: any) => {
userForm.value['id'] = data.id userForm.value['id'] = data.id
userForm.value.username = data.username userForm.value.username = data.username
userForm.value.email = data.email userForm.value.email = data.email
userForm.value.password = data.password
userForm.value.phone = data.phone userForm.value.phone = data.phone
userForm.value.nick_name = data.nick_name userForm.value.nick_name = data.nick_name
userForm.value.user_group_ids = data.user_group_ids
isEdit.value = true isEdit.value = true
} else {
userManageApi.getSystemDefaultPassword().then((res: any) => {
userForm.value.password = res.data.password
})
} }
visible.value = true visible.value = true
} }
@ -166,13 +140,13 @@ const submit = async (formEl: FormInstance | undefined) => {
await formEl.validate((valid, fields) => { await formEl.validate((valid, fields) => {
if (valid) { if (valid) {
if (isEdit.value) { if (isEdit.value) {
userManageApi.putUserManage(userForm.value.id, userForm.value, loading).then((res) => { chatUserApi.putUserManage(userForm.value.id, userForm.value, loading).then((res) => {
emit('refresh') emit('refresh')
MsgSuccess(t('common.editSuccess')) MsgSuccess(t('common.editSuccess'))
visible.value = false visible.value = false
}) })
} else { } else {
userManageApi.postUserManage(userForm.value, loading).then((res) => { chatUserApi.postUserManage(userForm.value, loading).then((res) => {
emit('refresh') emit('refresh')
MsgSuccess(t('common.createSuccess')) MsgSuccess(t('common.createSuccess'))
visible.value = false visible.value = false
@ -182,6 +156,10 @@ const submit = async (formEl: FormInstance | undefined) => {
}) })
} }
defineExpose({open}) defineExpose({ open })
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped>
:deep(.el-form-item__content) {
font-weight: 400
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<el-dialog :title="$t('views.userManage.setting.updatePwd')" v-model="dialogVisible"> <el-dialog :title="$t('views.login.resetPassword')" v-model="dialogVisible">
<el-form <el-form
ref="userFormRef" ref="userFormRef"
:model="userForm" :model="userForm"
@ -44,7 +44,7 @@ import { ref, reactive, watch } from 'vue'
import useStore from '@/stores' import useStore from '@/stores'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import type { ResetPasswordRequest } from '@/api/type/user' import type { ResetPasswordRequest } from '@/api/type/user'
import userManageApi from '@/api/user/user-manage' import userManageApi from '@/api/system/chat-user'
import { MsgSuccess } from '@/utils/message' import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales' import { t } from '@/locales'
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])

View File

@ -15,13 +15,13 @@
<el-button type="primary" @click="createUser()"> <el-button type="primary" @click="createUser()">
{{ t('views.userManage.createUser') }} {{ t('views.userManage.createUser') }}
</el-button> </el-button>
<el-button :disabled="multipleSelection.length === 0"> <el-button @click="syncUsers">
{{ $t('views.chatUser.syncUsers') }} {{ $t('views.chatUser.syncUsers') }}
</el-button> </el-button>
<el-button :disabled="multipleSelection.length === 0"> <el-button :disabled="multipleSelection.length === 0" @click="setUserGroups">
{{ $t('views.chatUser.setUserGroups') }} {{ $t('views.chatUser.setUserGroups') }}
</el-button> </el-button>
<el-button :disabled="multipleSelection.length === 0"> <el-button :disabled="multipleSelection.length === 0" @click="handleBatchDelete">
{{ $t('common.delete') }} {{ $t('common.delete') }}
</el-button> </el-button>
</div> </div>
@ -135,19 +135,28 @@
</el-card> </el-card>
</ContentContainer> </ContentContainer>
<UserDrawer :title="title" ref="UserDrawerRef" @refresh="refresh" /> <UserDrawer :title="title" :optionLoading="optionLoading" :chatGroupList="chatGroupList" ref="UserDrawerRef"
@refresh="refresh" />
<UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" /> <UserPwdDialog ref="UserPwdDialogRef" @refresh="refresh" />
<SetUserGroupsDialog :optionLoading="optionLoading" :chatGroupList="chatGroupList" ref="setUserGroupsRef"
@refresh="refresh" />
<SyncUsersDialog ref="syncUsersDialogRef" @refresh="refresh" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref, reactive, watch } from 'vue' import { onMounted, ref, reactive } 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 SetUserGroupsDialog from './component/SetUserGroupsDialog.vue'
import SyncUsersDialog from './component/SyncUsersDialog.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' import iconMap from '@/components/app-icon/icons/common'
import type { ChatUserItem } from '@/api/type/systemChatUser'
import SystemGroupApi from '@/api/system/user-group'
import type { ListItem } from '@/api/type/common'
const rightOutlined = iconMap['right-outlined'].iconReader() const rightOutlined = iconMap['right-outlined'].iconReader()
@ -163,8 +172,8 @@ const search_type_change = () => {
const loading = ref(false) const loading = ref(false)
const multipleSelection = ref<string[]>([]) const multipleSelection = ref<any[]>([])
function handleSelectionChange(val: string[]) { function handleSelectionChange(val: any[]) {
multipleSelection.value = val multipleSelection.value = val
} }
@ -174,7 +183,7 @@ const paginationConfig = reactive({
total: 0, total: 0,
}) })
const userTableData = ref<any[]>([]) const userTableData = ref<ChatUserItem[]>([])
function getList() { function getList() {
return userManageApi return userManageApi
@ -196,14 +205,15 @@ function handleSizeChange() {
getList() getList()
} }
function changeState(row: any) { function changeState(row: ChatUserItem) {
const obj = { const obj = {
...row,
is_active: !row.is_active, is_active: !row.is_active,
} }
const str = obj.is_active ? t('common.status.enableSuccess') : t('common.status.disableSuccess') const str = obj.is_active ? t('common.status.enableSuccess') : t('common.status.disableSuccess')
userManageApi userManageApi
.putUserManage(row.id, obj, loading) .putUserManage(row.id, obj, loading)
.then((res) => { .then(() => {
getList() getList()
MsgSuccess(str) MsgSuccess(str)
return true return true
@ -215,7 +225,7 @@ function changeState(row: any) {
const title = ref('') const title = ref('')
const UserDrawerRef = ref() const UserDrawerRef = ref()
function editUser(row: any) { function editUser(row: ChatUserItem) {
title.value = t('views.userManage.editUser') title.value = t('views.userManage.editUser')
UserDrawerRef.value.open(row) UserDrawerRef.value.open(row)
} }
@ -225,10 +235,10 @@ function createUser() {
UserDrawerRef.value.open() UserDrawerRef.value.open()
} }
function deleteUserManage(row: any) { function deleteUserManage(row: ChatUserItem) {
MsgConfirm( MsgConfirm(
`${t('views.user.delete.confirmTitle')}${row.username} ?`, `${t('views.userManage.delete.confirmTitle')}${row.username} ?`,
t('views.user.delete.confirmMessage'), '',
{ {
confirmButtonText: t('common.confirm'), confirmButtonText: t('common.confirm'),
confirmButtonClass: 'danger', confirmButtonClass: 'danger',
@ -246,7 +256,7 @@ function deleteUserManage(row: any) {
} }
const UserPwdDialogRef = ref() const UserPwdDialogRef = ref()
function editPwdUser(row: any) { function editPwdUser(row: ChatUserItem) {
UserPwdDialogRef.value.open(row) UserPwdDialogRef.value.open(row)
} }
@ -255,8 +265,49 @@ function refresh() {
} }
onMounted(() => { onMounted(() => {
getChatGroupList()
getList() getList()
}) })
const optionLoading = ref(false)
const chatGroupList = ref<ListItem[]>([])
async function getChatGroupList() {
try {
const res = await SystemGroupApi.getUserGroup(optionLoading)
chatGroupList.value = res.data
} catch (e) {
console.error(e)
}
}
function handleBatchDelete() {
MsgConfirm(
t('views.chatUser.batchDeleteUser', { count: multipleSelection.value.length }),
'',
{
confirmButtonText: t('common.confirm'),
confirmButtonClass: 'danger',
},
)
.then(() => {
userManageApi.batchDelete(multipleSelection.value.map(item => (item.id)), loading).then(async () => {
MsgSuccess(t('common.deleteSuccess'))
await getList()
})
})
.catch(() => {
})
}
const setUserGroupsRef = ref<InstanceType<typeof SetUserGroupsDialog>>()
function setUserGroups() {
setUserGroupsRef.value?.open(multipleSelection.value.map(item => (item.id)))
}
const syncUsersDialogRef = ref<InstanceType<typeof SyncUsersDialog>>()
function syncUsers() {
syncUsersDialogRef.value?.open()
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>