feat: add im kafka admin integration

This commit is contained in:
richjohnrambo
2026-08-28 00:05:54 +08:00
parent d53b0c1b62
commit 4779214591
75 changed files with 9053 additions and 185 deletions
+142
View File
@@ -0,0 +1,142 @@
<template>
<n-modal
v-model:show="showModal"
:mask-closable="false"
:show-icon="false"
preset="dialog"
transform-origin="center"
:title="'用户治理 #' + formValue.userId"
:style="{ width: dialogWidth }"
>
<n-spin :show="loading" description="请稍候...">
<n-descriptions label-placement="left" bordered :column="settingStore.isMobile ? 1 : 2">
<n-descriptions-item label="租户">{{ formValue.tenantName || '-' }}</n-descriptions-item>
<n-descriptions-item label="用户ID">{{ formValue.userId }}</n-descriptions-item>
<n-descriptions-item label="昵称">{{ formValue.nickname || '-' }}</n-descriptions-item>
<n-descriptions-item label="状态">{{ stateLabel }}</n-descriptions-item>
</n-descriptions>
<n-form class="mt-4" label-placement="left" :label-width="110">
<n-form-item label="治理动作">
<n-select v-model:value="actionForm.action" :options="actionOptions" />
</n-form-item>
<n-form-item label="操作IM用户ID">
<n-input-number v-model:value="actionForm.actorUserId" clearable class="w-full" />
</n-form-item>
<n-form-item v-if="actionForm.action === 'deviceKick'" label="设备ID">
<n-input v-model:value="actionForm.deviceId" clearable placeholder="请输入 device_id" />
</n-form-item>
<n-form-item v-if="actionForm.action === 'accountCancel'" label="硬删除">
<n-switch v-model:value="actionForm.hard" />
</n-form-item>
<n-form-item label="原因">
<n-input v-model:value="actionForm.reason" type="textarea" clearable placeholder="请输入操作原因" />
</n-form-item>
</n-form>
</n-spin>
<template #action>
<n-space>
<n-button @click="closeForm">关闭</n-button>
<n-button type="primary" :loading="loading" @click="submitAction">提交命令</n-button>
</n-space>
</template>
</n-modal>
</template>
<script lang="ts" setup>
import { computed, reactive, ref } from 'vue';
import { useDictStore } from '@/store/modules/dict';
import {
AccountCancel,
AccountDelete,
Ban,
DeviceKick,
Freeze,
LogoutAll,
Unban,
Unfreeze,
} from '@/api/imUser';
import { newState, State } from './model';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { adaModalWidth } from '@/utils/hotgo';
import { useMessage } from 'naive-ui';
const emit = defineEmits(['reload']);
const settingStore = useProjectSettingStore();
const dict = useDictStore();
const message = useMessage();
const loading = ref(false);
const showModal = ref(false);
const formValue = ref<State>(newState(null));
const dialogWidth = computed(() => adaModalWidth(720));
const stateLabel = computed(() => dict.getLabel('ImUserStateOptions', formValue.value.state) || '-');
const actionOptions = [
{ label: '封禁用户', value: 'ban' },
{ label: '解封用户', value: 'unban' },
{ label: '冻结用户', value: 'freeze' },
{ label: '解冻用户', value: 'unfreeze' },
{ label: '踢出指定设备', value: 'deviceKick' },
{ label: '踢出全部会话', value: 'logoutAll' },
{ label: '注销账号', value: 'accountCancel' },
{ label: '删除账号', value: 'accountDelete' },
];
const actionForm = reactive({
action: 'ban',
actorUserId: null as number | null,
deviceId: '',
reason: '',
hard: false,
});
function closeForm() {
showModal.value = false;
loading.value = false;
}
function openModal(state: State) {
formValue.value = newState(state);
actionForm.action = 'ban';
actionForm.actorUserId = state.userId || null;
actionForm.deviceId = '';
actionForm.reason = '';
actionForm.hard = false;
showModal.value = true;
}
async function submitAction() {
const params = {
tenantId: formValue.value.tenantId,
userId: formValue.value.userId,
actorUserId: actionForm.actorUserId,
deviceId: actionForm.deviceId,
reason: actionForm.reason,
hard: actionForm.hard,
};
const apiMap = {
ban: Ban,
unban: Unban,
freeze: Freeze,
unfreeze: Unfreeze,
deviceKick: DeviceKick,
logoutAll: LogoutAll,
accountCancel: AccountCancel,
accountDelete: AccountDelete,
};
loading.value = true;
try {
const res = await apiMap[actionForm.action](params);
message.success(`命令已提交:${res?.commandId || '-'}`);
emit('reload');
closeForm();
} finally {
loading.value = false;
}
}
defineExpose({
openModal,
});
</script>
<style lang="less"></style>