feat: add IM governance admin enhancements
This commit is contained in:
@@ -15,21 +15,84 @@
|
||||
<n-descriptions label-placement="left" bordered :column="settingStore.isMobile ? 1 : 2">
|
||||
<n-descriptions-item label="群名称">{{ governance.name || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="业务状态">{{ groupStatusLabel }}</n-descriptions-item>
|
||||
<n-descriptions-item label="群主ID">{{ governance.ownerUserId || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="成员数">{{ governance.memberCount || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="入群审批">{{ governance.joinApproval ? '开启' : '关闭' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="全员禁言">{{ governance.muteAll ? '开启' : '关闭' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="成员上传文件">{{ governance.memberUploadFiles ? '允许' : '禁止' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="成员私聊">{{ governance.memberPrivateChat ? '允许' : '禁止' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="成员邀请">{{ governance.memberInvite ? '允许' : '禁止' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="最大成员数">{{ governance.maxMemberCount || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="最大管理员数">{{ governance.maxAdminCount || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="版本">{{ governance.version || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="创建人">{{ governance.createdBy || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="创建时间">{{ governance.createdAt || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="解散人">{{ governance.dissolvedBy || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="解散时间">{{ governance.dissolvedAt || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="简介" :span="2">{{ governance.description || '-' }}</n-descriptions-item>
|
||||
<n-descriptions-item label="群主ID">{{
|
||||
governance.ownerUserId || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="成员数">{{
|
||||
governance.memberCount || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="入群审批">
|
||||
<n-switch
|
||||
v-model:value="governance.joinApproval"
|
||||
:checked-value="1"
|
||||
:unchecked-value="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="全员禁言">
|
||||
<n-switch
|
||||
v-model:value="governance.muteAll"
|
||||
:checked-value="1"
|
||||
:unchecked-value="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="成员上传文件">
|
||||
<n-switch
|
||||
v-model:value="governance.memberUploadFiles"
|
||||
:checked-value="1"
|
||||
:unchecked-value="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="成员私聊">
|
||||
<n-switch
|
||||
v-model:value="governance.memberPrivateChat"
|
||||
:checked-value="1"
|
||||
:unchecked-value="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="成员邀请">
|
||||
<n-switch
|
||||
v-model:value="governance.memberInvite"
|
||||
:checked-value="1"
|
||||
:unchecked-value="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="最大成员数">
|
||||
<n-input-number
|
||||
v-model:value="governance.maxMemberCount"
|
||||
:min="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="最大管理员数">
|
||||
<n-input-number
|
||||
v-model:value="governance.maxAdminCount"
|
||||
:min="0"
|
||||
:disabled="!canUpdateGovernance"
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="版本">{{
|
||||
governance.version || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="创建人">{{
|
||||
governance.createdBy || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="创建时间">{{
|
||||
governance.createdAt || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="解散人">{{
|
||||
governance.dissolvedBy || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="解散时间">{{
|
||||
governance.dissolvedAt || '-'
|
||||
}}</n-descriptions-item>
|
||||
<n-descriptions-item label="简介" :span="2">{{
|
||||
governance.description || '-'
|
||||
}}</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-tab-pane>
|
||||
@@ -69,6 +132,7 @@
|
||||
:columns="muteColumns"
|
||||
:request="muteData"
|
||||
:row-key="(row) => row.topic + '-' + row.userId"
|
||||
:actionColumn="muteActionColumn"
|
||||
:scroll-x="muteScrollX"
|
||||
:resizeHeightOffset="-10000"
|
||||
/>
|
||||
@@ -86,6 +150,22 @@
|
||||
</n-tabs>
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button
|
||||
v-if="activeTab === 'settings' && canUpdateGovernance"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="handleSaveGovernance"
|
||||
>
|
||||
保存治理配置
|
||||
</n-button>
|
||||
<n-button
|
||||
v-if="activeTab === 'settings' && canDissolve && governance.groupStatus !== 'dissolved'"
|
||||
type="error"
|
||||
:loading="submitLoading"
|
||||
@click="handleDissolve"
|
||||
>
|
||||
解散群
|
||||
</n-button>
|
||||
<n-button @click="closeForm">关闭</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
@@ -94,16 +174,21 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { computed, h, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { BasicTable } from '@/components/Table';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import {
|
||||
AdminLogList,
|
||||
AnnouncementList,
|
||||
Dissolve,
|
||||
Governance,
|
||||
GovernanceUpdate,
|
||||
InvitationList,
|
||||
JoinRequestList,
|
||||
MuteList,
|
||||
Unmute,
|
||||
} from '@/api/imGroup';
|
||||
import {
|
||||
adminLogColumns,
|
||||
@@ -120,24 +205,52 @@
|
||||
|
||||
const settingStore = useProjectSettingStore();
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const { hasPermission } = usePermission();
|
||||
const showModal = ref(false);
|
||||
const loading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const activeTab = ref('settings');
|
||||
const current = ref<State>(newState(null));
|
||||
const governance = ref<GovernanceState>(new GovernanceState());
|
||||
const dialogWidth = computed(() => adaModalWidth(1120));
|
||||
const groupStatusLabel = computed(() => dict.getLabel('ImGroupStatusOptions', governance.value.groupStatus) || '-');
|
||||
const canUpdateGovernance = computed(() => hasPermission(['/imGroup/governanceUpdate']));
|
||||
const canDissolve = computed(() => hasPermission(['/imGroup/dissolve']));
|
||||
const groupStatusLabel = computed(
|
||||
() => dict.getLabel('ImGroupStatusOptions', governance.value.groupStatus) || '-'
|
||||
);
|
||||
|
||||
const joinRequestRef = ref();
|
||||
const invitationRef = ref();
|
||||
const announcementRef = ref();
|
||||
const muteRef = ref();
|
||||
const adminLogRef = ref();
|
||||
const muteActionColumn = reactive({
|
||||
width: 110,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
actions: [
|
||||
{
|
||||
label: '解除',
|
||||
type: 'warning',
|
||||
ifShow: () => record.status === 'active',
|
||||
auth: ['/imGroup/unmute'],
|
||||
onClick: () => handleUnmute(record),
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const joinRequestScrollX = computed(() => adaTableScrollX(joinRequestColumns, 0));
|
||||
const invitationScrollX = computed(() => adaTableScrollX(invitationColumns, 0));
|
||||
const announcementScrollX = computed(() => adaTableScrollX(announcementColumns, 0));
|
||||
const muteScrollX = computed(() => adaTableScrollX(muteColumns, 0));
|
||||
const muteScrollX = computed(() => adaTableScrollX(muteColumns, muteActionColumn.width));
|
||||
const adminLogScrollX = computed(() => adaTableScrollX(adminLogColumns, 0));
|
||||
|
||||
function baseParams(res) {
|
||||
@@ -176,13 +289,78 @@
|
||||
async function loadGovernance() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await Governance({ tenantId: current.value.tenantId, topic: current.value.topic });
|
||||
const res = await Governance({
|
||||
tenantId: current.value.tenantId,
|
||||
topic: current.value.topic,
|
||||
});
|
||||
governance.value = Object.assign(new GovernanceState(), res || {});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveGovernance() {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
await GovernanceUpdate({
|
||||
tenantId: current.value.tenantId,
|
||||
topic: current.value.topic,
|
||||
joinApproval: governance.value.joinApproval,
|
||||
muteAll: governance.value.muteAll,
|
||||
memberUploadFiles: governance.value.memberUploadFiles,
|
||||
memberPrivateChat: governance.value.memberPrivateChat,
|
||||
memberInvite: governance.value.memberInvite,
|
||||
maxMemberCount: governance.value.maxMemberCount,
|
||||
maxAdminCount: governance.value.maxAdminCount,
|
||||
});
|
||||
message.success('操作成功');
|
||||
await loadGovernance();
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDissolve() {
|
||||
dialog.error({
|
||||
title: '解散群',
|
||||
content: '解散后该群将进入不可用状态,并写入群事件等待 IM 服务端同步,是否确认?',
|
||||
positiveText: '确认',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
await Dissolve({
|
||||
tenantId: current.value.tenantId,
|
||||
topic: current.value.topic,
|
||||
reason: '后台管理员解散',
|
||||
});
|
||||
message.success('操作成功');
|
||||
await loadGovernance();
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function handleUnmute(record) {
|
||||
dialog.warning({
|
||||
title: '解除禁言',
|
||||
content: '确定解除该成员禁言?',
|
||||
positiveText: '确认',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
await Unmute({
|
||||
tenantId: current.value.tenantId,
|
||||
topic: current.value.topic,
|
||||
userId: record.userId,
|
||||
});
|
||||
message.success('操作成功');
|
||||
muteRef.value?.reload();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function reloadActiveTable() {
|
||||
const refs = {
|
||||
joinRequests: joinRequestRef,
|
||||
|
||||
Reference in New Issue
Block a user