feat: add im kafka admin integration

This commit is contained in:
richjohnrambo
2026-09-04 11:57:38 +08:00
parent a2abaef3a6
commit f7f8cc0ef0
74 changed files with 6254 additions and 47 deletions
+111 -7
View File
@@ -9,11 +9,17 @@
:title="'群成员 ' + current.topic"
:style="{ width: dialogWidth }"
>
<n-form label-placement="left" :label-width="110" class="member-command-form">
<n-form-item label="操作IM用户ID">
<n-input-number v-model:value="actorUserId" clearable />
</n-form-item>
</n-form>
<BasicTable
ref="actionRef"
:columns="memberColumns"
:request="loadDataTable"
:row-key="(row) => row.userId"
:actionColumn="actionColumn"
:scroll-x="scrollX"
:resizeHeightOffset="-10000"
/>
@@ -27,17 +33,63 @@
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { BasicTable } from '@/components/Table';
import { MemberList } from '@/api/imGroup';
import { memberColumns, newState, State } from './model';
import { computed, h, reactive, ref } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';
import { AdminRemove, AdminSet, MemberList, MemberMute, MemberRemove, MemberUnmute } from '@/api/imGroup';
import { MemberState, memberColumns, newState, State } from './model';
import { adaModalWidth, adaTableScrollX } from '@/utils/hotgo';
const dialog = useDialog();
const message = useMessage();
const showModal = ref(false);
const current = ref<State>(newState(null));
const actorUserId = ref<number | null>(null);
const actionRef = ref();
const dialogWidth = computed(() => adaModalWidth(980));
const scrollX = computed(() => adaTableScrollX(memberColumns, 0));
const dialogWidth = computed(() => adaModalWidth(1120));
const actionColumn = reactive({
width: 300,
title: '操作',
key: 'action',
fixed: 'right',
render(record: MemberState) {
return h(TableAction as any, {
style: 'button',
actions: [
{
label: '设管理员',
onClick: () => submitMemberCommand('setAdmin', record),
auth: ['/imGroup/adminSet'],
ifShow: record.role !== 'admin' && record.role !== 'owner',
},
{
label: '删管理员',
onClick: () => submitMemberCommand('removeAdmin', record),
auth: ['/imGroup/adminRemove'],
ifShow: record.role === 'admin',
},
{
label: '禁言',
onClick: () => submitMemberCommand('mute', record),
auth: ['/imGroup/memberMute'],
},
{
label: '解禁',
onClick: () => submitMemberCommand('unmute', record),
auth: ['/imGroup/memberUnmute'],
},
{
label: '移出',
onClick: () => submitMemberCommand('remove', record),
auth: ['/imGroup/memberRemove'],
},
],
});
},
});
const scrollX = computed(() => adaTableScrollX(memberColumns, actionColumn.width));
// 加载表格数据
const loadDataTable = async (res) => {
@@ -56,9 +108,57 @@
showModal.value = false;
}
function baseCommand(record: MemberState) {
if (!actorUserId.value) {
message.warning('请先填写操作IM用户ID');
return null;
}
return {
tenantId: current.value.tenantId,
topic: current.value.topic,
actorUserId: String(actorUserId.value),
userId: String(record.userId),
};
}
function submitMemberCommand(type: string, record: MemberState) {
const labels = {
setAdmin: '设置管理员',
removeAdmin: '删除管理员',
mute: '禁言成员',
unmute: '解除禁言',
remove: '移出群成员',
};
dialog.warning({
title: labels[type],
content: `确认对用户 ${record.userId} 执行该操作?`,
positiveText: '确认',
negativeText: '取消',
onPositiveClick: async () => {
const params = baseCommand(record);
if (!params) return false;
let res: any;
if (type === 'setAdmin') {
res = await AdminSet({ ...params, userIds: [String(record.userId)] });
} else if (type === 'removeAdmin') {
res = await AdminRemove(params);
} else if (type === 'mute') {
res = await MemberMute(params);
} else if (type === 'unmute') {
res = await MemberUnmute(params);
} else {
res = await MemberRemove(params);
}
message.success(`命令已发送:${res?.commandId || '-'}`);
actionRef.value?.reload();
},
});
}
// 打开弹窗
function openModal(state: State) {
current.value = newState(state);
actorUserId.value = current.value.ownerId || null;
showModal.value = true;
setTimeout(() => {
actionRef.value?.reload();
@@ -70,4 +170,8 @@
});
</script>
<style lang="less"></style>
<style lang="less" scoped>
.member-command-form {
margin-bottom: 12px;
}
</style>