Files
sgxt_web/src/components/Consultation/memberMangerModal/index.vue
2025-12-12 15:19:45 +08:00

837 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template lang="pug">
a-modal(
v-model:visible="visible"
title-align="start"
class="userMangeModal"
width="648px"
:title="`${$t('meeting.modal.user.title')} (${userList.length})`"
popup-container=".arco-layout-content"
:mask="false"
unmount-on-close
draggable
@close="closeFn"
@open="fetchMemberList")
a-space(direction="vertical" fill)
a-space(direction="vertical" fill)
a-button(@click="invitVisible = true") {{ $t('conference.components.media.footer.defaultBtns.invitingAttendees') }}
a-tabs(
default-active-key="1"
class="userMange_tab"
v-model:active-key="tabVal")
a-tab-pane(key="1" :title="`${$t('conference.member.present')} (${meetingMembers.length})`")
.user_list
user-item(
v-for="(item, index) in meetingMembers"
:key="`present_${item.basedata_id}`"
:userInfo="item"
:index="index"
:currentIndex="currentIndex"
:isShowType="true"
meetingType="meeting"
@reliveSelect="(params) => meetingControlSelect(params, 0)"
@controlSelect="(params) => meetingControlSelect(params, 1)"
@changeCurrentIndex="changeCurrentIndex")
div.footer_btn
a-button.btn(@click="() => setAllMemberProhibition(MICROPHONE_STATUS_OPEN)") {{ $t('conference.control.allBan') }}
a-button.btn(@click="() => setAllMemberProhibition(MICROPHONE_STATUS_CLOSE)") {{ $t('conference.control.openAllBan') }}
a-tab-pane(key="2" :title="`${$t('conference.member.absent')} (${notMeetingMembers.length})`")
.user_list
user-item(
v-for="(item, index) in notMeetingMembers"
:key="`absent_${item.basedata_id}`"
:userInfo="item"
:index="index"
:currentIndex="currentIndex"
:isShowType="true"
meetingType="noMeet"
@reliveSelect="(params) => noMeetControlSelect(params, 0)"
@controlSelect="(params) => noMeetControlSelect(params, 1)"
@changeCurrentIndex="changeCurrentIndex")
.user_footer
a-modal(
v-model:visible="invitVisible"
title-align="start"
width="648px"
:title="`${$t('conference.components.media.footer.defaultBtns.invitingAttendees')} (${tableData.length})`"
:mask="false"
popup-container=".arco-layout-content"
unmount-on-close
@close="onInvitModalClose"
@ok="addMember")
a-space(fill style="margin-bottom: 10px")
a-input-search(v-model="memberNumber")
a-button(
shape="circle"
@click="addMemberByNumber")
template(#icon)
icon-plus
a-table(
v-model:selectedKeys="selectedKeys"
row-key="rowKey"
:data="tableData"
:columns="rightColumns"
:pagination="false"
:scroll="{ y: '100%' }"
@dragover="(e) => e.preventDefault()"
@drop="handleDrop")
template(#name="{ record }") {{ record.alias || record.number }}
template(#optional="{ record }")
icon-close(class="iconClose"
@click="() => deleteSelection(record)")
a-modal(
v-model:visible="reNnameVisible"
title-align="start"
width="648px"
:title="`${$t('conference.control.reName')}`"
:mask="true"
popup-container=".arco-layout-content"
unmount-on-close
@ok="modifyMemberNickname")
<a-input v-model="nickname" :style="{width:'320px'}" allow-clear />
</template>
<script lang="ts" setup>
import {
ref,
computed,
getCurrentInstance,
h,
onMounted,
onBeforeMount,
} from 'vue';
import { Message } from '@arco-design/web-vue';
import { IconDelete } from '@arco-design/web-vue/es/icon';
import ResultModal from '@/views/webPuc/resourcesAndGroup/group/components/resultModal.vue';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import AddGroup from '@/views/webPuc/resourcesAndGroup/group/components/addGroupNew.vue';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { $t } from '@/locale';
import useCallModule from '@/sdk/call';
import useBaseDataModule from '@/components/Consultation/sdk/baseData';
import useConferenceControlModule, {
CONFERENCE_ROLE_NORMAL,
CONFERENCE_ROLE_HOST,
MICROPHONE_STATUS_NO,
MICROPHONE_STATUS_OPEN,
MICROPHONE_STATUS_CLOSE,
MUTE_STATUS_Y,
MUTE_STATUS_N,
CAMERA_STATUS_NO,
CAMERA_STATUS_OPEN,
CAMERA_STATUS_CLOSE,
} from '@/components/Consultation/sdk/conferenceControl';
import useConferencModule from '@/components/Consultation/sdk/conferenceControl';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import UserItem from './components/UserItem.vue';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import SearchList from './components/SearchList.vue';
import tableColAvatar from '@/views/webPuc/org/components/tableColAvatarByNumType.vue';
import { useGlobalStore, resourcesStore } from '@/store';
const globalStore = useGlobalStore();
const props = defineProps({
cptCurrentConference: {
type: Object,
default: () => ({}),
},
});
const Modal = getCurrentInstance().appContext.config.globalProperties.$modal;
const bus: any = getCurrentInstance().appContext.config.globalProperties.$bus;
// 新的成员昵称
const reNnameVisible = ref(false);
const currentMember = ref(null);
const nickname = ref('');
// 会议信息
const conference_info = ref<any>({});
const visible = ref(false);
const invitVisible = ref(false);
const currentIndex = ref(-1);
const searchCurrentIndex = ref(-1);
const searchBoxStatus = ref(false);
const searchContent = ref('');
const tabVal = ref('1');
const searchCollapse = ref(['1', '2']);
const tempModalVisible = ref(false);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const editData = ref<Record<string, any> | undefined>({});
/** 临时组modal编辑传入数据 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const hideData = ref(['alias', 'number', 'timeInterval', 'autoDelete']);
const userList = computed(
() => globalStore.activeMeetingConfig?.members || []
);
const storeResources = resourcesStore();
// 入会成员
const meetingMembers = computed(() => {
return userList.value.filter((v) => v.member_state === 1); // member_state 成员会议中的状态 0=未入会1=已入会2=呼叫中
});
// 未入会成员
const notMeetingMembers = computed(() => {
return userList.value.filter((v) => v.member_state !== 1);
});
const searchMeetingList = ref([]);
const searchNoMeetList = ref([]);
const CALL = useCallModule();
const useBDModule = useBaseDataModule();
const conferenceControlModule = useConferenceControlModule();
const conferenceModule = useConferencModule();
// 邀请会议成员相关
const addMember = () => {
console.log('邀请成员入会 = ', tableData.value);
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceModule
.addConferenceMember({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
members: tableData.value,
})
.then((resp) => {
if (resp.result === 0) {
Message.success($t(`public.use.success`));
} else {
Message.error($t(`errorCode.${resp.result}`));
}
});
};
const memberNumber = ref('');
// 拨号添加会议成员
const addMemberByNumber = () => {
const isError =
!memberNumber.value || Number.isNaN(Number(memberNumber.value));
if (isError) {
Message.error($t('common.number.invalid'));
return;
}
// 走通用的拖放逻辑
storeResources.setActiveResource({
number: memberNumber.value,
});
storeResources.setResourceListAuto();
// 重置数据
memberNumber.value = '';
};
const selectedKeys = ref<string[]>([]);
const tableData = computed<any[]>(() => {
const data = storeResources.getResourceList.map((item) => {
return {
...item,
rowKey: item.basedata_id || item.number,
};
});
console.info('table data ', data);
return data;
});
const rightColumns = computed<any[]>(() => {
const columns: any[] = [
{
title: `${$t(`groupList.columns.member`)}${tableData.value.length}`,
dataIndex: 'alias',
slotName: 'name',
align: 'left',
width: 250,
},
];
let extraColumns: any[] = [];
const operation: any = {
slotName: 'optional',
align: 'right',
fixed: 'right',
width: 100,
title: () => {
return h(IconDelete, {
style: { cursor: 'pointer' },
onClick: () => {
const newList = storeResources.getResourceList.filter(
(item) => item.device_guid === sessionStorage.getItem('user_guid')
);
storeResources.setResourceList(newList);
},
});
},
};
return columns.concat(extraColumns, operation);
});
const rowSelection = computed<any>(() => {
return {
// type: 'checkbox',
showCheckedAll: true,
};
});
// 穿梭框-右侧-删除选择行事件
const deleteSelection = (record: any) => {
console.info('deleteSelection', record);
// 会议主持人不允许删掉
if (record.guid === sessionStorage.getItem('user_guid')) {
Message.warning($t('meeting.tip.no_can_del'));
} else {
// dgna_guid是唯一标识符
const filterData = tableData.value.filter((item) => {
return item?.rowKey !== record.rowKey;
});
storeResources.setResourceList(filterData);
selectedKeys.value = selectedKeys.value.filter((selected) =>
tableData.value.some((data) => data.rowKey === selected)
);
}
};
// 拖拽
const beforeDropdown = (
record: Record<string, any>
// allRecords: Record<string, any>[]
) => {
const result = {
success: true,
message: 'success',
formattedData: {},
};
console.info('----sdf->>>>>', record);
// 错误的数据格式或过滤已有userlist
if (
!record.guid ||
tableData.value?.some((item) => item.guid === record.guid)
) {
result.success = false;
result.message = $t(`${$t('meeting.modal.userExit')}`);
return result;
}
result.formattedData = {
...record,
};
return result;
};
// 拖拽置入table事件 dropdown
const handleDrop = async () => {
const emitResult = beforeDropdown(storeResources.getActiveResource);
if (!emitResult) {
storeResources.setResourceListAuto();
} else if (emitResult.success) {
if (emitResult.formattedData) {
storeResources.setActiveResource(emitResult.formattedData);
}
storeResources.setResourceListAuto();
} else {
Message.error(emitResult.message);
}
};
// 弹窗关闭时
const onInvitModalClose = () => {
storeResources.setResourceList([]);
};
// 踢出会议成员
const kickoutMember = (record) => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.kickoutMember({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
members: [record],
})
.then((resp) => {
if (resp.result === 0) {
Message.success($t('meeting.deleteUser.success'));
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('meeting.deleteUser.fail'));
});
};
// 呼叫未入会成员
const inviteMember = (record) => {
const { meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.inviteMember({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
members: [record],
})
.then((resp) => {
if (resp.result === 0) {
Message.success($t(`public.use.success`));
} else {
Message.warning($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.error($t('gis.cross.delResult1'));
});
};
// 呼叫全部未入会成员
const inviteAllMember = () => {
const { meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.inviteAllMember({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
})
.then((resp) => {
if (resp.result === 0) {
Message.success($t(`public.use.success`));
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 修改成员昵称
const modifyMemberNickname = () => {
if (nickname.value === currentMember.value.nick) return;
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.modifyMemberNickname({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
member: currentMember.value,
nickname: nickname.value,
})
.then((resp) => {
if (resp.result === 0) {
nickname.value = '';
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 设置会员成员角色
const setMemberRole = (role: number) => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.setMemberRole({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
member: currentMember.value,
role,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 禁言会议成员
const setMemberProhibition = (prohibition: number) => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.setMemberProhibition({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
member: currentMember.value,
prohibition,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 禁言全部会议成员
const setAllMemberProhibition = (prohibition: number) => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.setAllMemberProhibition({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
prohibition,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 静音会议成员
const setMemberMute = (mute: number) => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.setMemberMute({
guid: meeting.guid,
basedata_id: meeting.basedata_id,
call_id: callId,
member: currentMember.value,
mute,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 开关会议成员摄像头
const setMemberCamera = (camera_status: number) => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.setMemberCamera({
guid: meeting.guid,
basedata_id: meeting.basedata_id,
call_id: callId,
member: currentMember.value,
camera_status,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 指定成员发言
const assignMemberSpeaker = () => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.assignMemberSpeaker({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
member: currentMember.value,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// 取消指定成员发言
const cancelMemberSpeak = () => {
const { members, meeting, callId } = globalStore.activeMeetingConfig;
conferenceControlModule
.cancelMemberSpeak({
guid: meeting?.guid,
basedata_id: meeting?.basedata_id,
call_id: callId,
member: currentMember.value,
})
.then((resp) => {
if (resp.result === 0) {
} else {
Message.error($t(`errorCode.${resp.result}`));
}
})
.catch((error) => {
Message.warning($t('gis.cross.delResult1'));
});
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const meetingControlSelect = ({ val, record }, type) => {
console.info('meetingControlSelect', val, record);
currentMember.value = record;
switch (val) {
case 'Remove': // 移除会议成员
kickoutMember(record);
break;
case 'AsMember': // 设置为成员
setMemberRole(CONFERENCE_ROLE_NORMAL);
break;
case 'AsHost': // 设置为主席
setMemberRole(CONFERENCE_ROLE_HOST);
break;
case 'Prohibition': // 禁言
setMemberProhibition(MICROPHONE_STATUS_OPEN);
break;
case 'ReleaseProhibition': // 解除禁言
setMemberProhibition(MICROPHONE_STATUS_CLOSE);
break;
case 'Mute': // 静音
setMemberMute(MUTE_STATUS_Y);
break;
case 'UnMute': // 解除静音
setMemberMute(MUTE_STATUS_N);
break;
case 'OpenCamera': // 打开摄像头
setMemberCamera(CAMERA_STATUS_OPEN);
break;
case 'CloseCamera': // 关闭摄像头
setMemberCamera(CAMERA_STATUS_CLOSE);
break;
case 'ReName': // 修改昵称
reNnameVisible.value = true;
nickname.value = record.nick || '';
break;
case 'Speech': // 指定成员发言
assignMemberSpeaker();
break;
case 'CancelSpeech': // 取消指定成员发言
cancelMemberSpeak();
break;
case 'AppointImage': // 指定画面
break;
case 'CancelImage': // 取消指定画面
break;
default:
console.info(val);
}
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const noMeetControlSelect = ({ val, record }, type) => {
console.info('noMeetControlSelect', record);
switch (val) {
case 'FullDuplexCall': // 全双工呼叫
inviteMember(record);
break;
case 'HalfDuplexCall': // 半双工呼叫
inviteMember(record);
break;
case 'AllCall': // 呼叫所有未入会成员
inviteAllMember();
break;
}
};
const init = () => {
currentIndex.value = -1;
searchCurrentIndex.value = -1;
searchBoxStatus.value = false;
searchContent.value = '';
tabVal.value = '1';
searchCollapse.value = ['1', '2'];
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const closeFn = () => {
init();
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const changeCurrentIndex = (index) => {
currentIndex.value = index;
};
const closeAllModal = () => {
visible.value = false;
invitVisible.value = false;
reNnameVisible.value = false;
};
defineExpose({
visible,
closeAllModal,
});
</script>
<style lang="less">
.userMangeModal {
.arco-modal-footer {
display: none;
}
.search_result_box {
.user_list {
.user_item_info {
.avatar {
width: 18px;
height: 18px;
}
}
.user_item_opration {
img {
width: 15px;
height: 15px;
}
.no_meeting_btn {
font-size: 12px;
img {
width: 10px;
height: 10px;
}
}
}
}
}
}
</style>
<style scoped lang="less">
.userMangeModal {
.search_box {
position: relative;
.search_result_box {
position: absolute;
top: 34px;
left: 0;
z-index: 2;
width: 320px;
height: 224px;
overflow-y: scroll;
background: #2d3238;
border: 1px solid #3c4046;
border-radius: 4px;
// padding: 22px 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
/deep/.arco-collapse-item {
border: none;
}
/deep/.arco-collapse-item-header {
background: transparent;
border: none;
}
/deep/.arco-collapse-item-content {
padding: 0;
background: transparent;
border: none;
}
/deep/.arco-collapse-item-content-box {
padding: 0;
}
}
}
.userMange_tab {
.arco-tabs-content {
padding: 0;
.user_list {
min-height: 367px;
max-height: 367px;
overflow-y: scroll;
}
.user_footer {
display: flex;
justify-content: flex-end;
width: 100%;
margin-top: 20px;
/deep/.arco-btn {
margin-left: 10px;
}
}
}
}
.footer_btn {
margin-top: 30px;
.btn {
margin-right: 10px;
}
}
}
</style>