Files
im_manager/web/src/views/imGroup/governance.vue
T

217 lines
7.8 KiB
Vue

<template>
<div>
<n-modal
v-model:show="showModal"
:mask-closable="false"
:show-icon="false"
preset="dialog"
transform-origin="center"
:title="'群治理 ' + current.topic"
:style="{ width: dialogWidth }"
>
<n-tabs v-model:value="activeTab" type="line" animated>
<n-tab-pane name="settings" tab="治理配置">
<n-spin :show="loading" description="请稍候...">
<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>
</n-spin>
</n-tab-pane>
<n-tab-pane name="joinRequests" tab="入群申请">
<BasicTable
ref="joinRequestRef"
:columns="joinRequestColumns"
:request="joinRequestData"
:row-key="(row) => row.requestId"
:scroll-x="joinRequestScrollX"
:resizeHeightOffset="-10000"
/>
</n-tab-pane>
<n-tab-pane name="invitations" tab="群邀请">
<BasicTable
ref="invitationRef"
:columns="invitationColumns"
:request="invitationData"
:row-key="(row) => row.invitationId"
:scroll-x="invitationScrollX"
:resizeHeightOffset="-10000"
/>
</n-tab-pane>
<n-tab-pane name="announcements" tab="群公告">
<BasicTable
ref="announcementRef"
:columns="announcementColumns"
:request="announcementData"
:row-key="(row) => row.announcementId"
:scroll-x="announcementScrollX"
:resizeHeightOffset="-10000"
/>
</n-tab-pane>
<n-tab-pane name="mutes" tab="成员禁言">
<BasicTable
ref="muteRef"
:columns="muteColumns"
:request="muteData"
:row-key="(row) => row.topic + '-' + row.userId"
:scroll-x="muteScrollX"
:resizeHeightOffset="-10000"
/>
</n-tab-pane>
<n-tab-pane name="logs" tab="管理日志">
<BasicTable
ref="adminLogRef"
:columns="adminLogColumns"
:request="adminLogData"
:row-key="(row) => row.logId"
:scroll-x="adminLogScrollX"
:resizeHeightOffset="-10000"
/>
</n-tab-pane>
</n-tabs>
<template #action>
<n-space>
<n-button @click="closeForm">关闭</n-button>
</n-space>
</template>
</n-modal>
</div>
</template>
<script lang="ts" setup>
import { computed, nextTick, ref, watch } from 'vue';
import { useDictStore } from '@/store/modules/dict';
import { BasicTable } from '@/components/Table';
import {
AdminLogList,
AnnouncementList,
Governance,
InvitationList,
JoinRequestList,
MuteList,
} from '@/api/imGroup';
import {
adminLogColumns,
announcementColumns,
GovernanceState,
invitationColumns,
joinRequestColumns,
muteColumns,
newState,
State,
} from './model';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { adaModalWidth, adaTableScrollX } from '@/utils/hotgo';
const settingStore = useProjectSettingStore();
const dict = useDictStore();
const showModal = ref(false);
const loading = 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 joinRequestRef = ref();
const invitationRef = ref();
const announcementRef = ref();
const muteRef = ref();
const adminLogRef = ref();
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 adminLogScrollX = computed(() => adaTableScrollX(adminLogColumns, 0));
function baseParams(res) {
return {
tenantId: current.value.tenantId,
topic: current.value.topic,
...res,
};
}
async function joinRequestData(res) {
return await JoinRequestList(baseParams(res));
}
async function invitationData(res) {
return await InvitationList(baseParams(res));
}
async function announcementData(res) {
return await AnnouncementList(baseParams(res));
}
async function muteData(res) {
return await MuteList(baseParams(res));
}
async function adminLogData(res) {
return await AdminLogList(baseParams(res));
}
function closeForm() {
showModal.value = false;
loading.value = false;
}
async function loadGovernance() {
loading.value = true;
try {
const res = await Governance({ tenantId: current.value.tenantId, topic: current.value.topic });
governance.value = Object.assign(new GovernanceState(), res || {});
} finally {
loading.value = false;
}
}
function reloadActiveTable() {
const refs = {
joinRequests: joinRequestRef,
invitations: invitationRef,
announcements: announcementRef,
mutes: muteRef,
logs: adminLogRef,
};
refs[activeTab.value]?.value?.reload();
}
function openModal(state: State) {
current.value = newState(state);
governance.value = new GovernanceState();
activeTab.value = 'settings';
showModal.value = true;
loadGovernance();
}
watch(activeTab, async (value) => {
if (!showModal.value || value === 'settings') return;
await nextTick();
reloadActiveTable();
});
defineExpose({
openModal,
});
</script>
<style lang="less"></style>