From f7305712322e5fea16085ef4d07f8f78cc0b5b75 Mon Sep 17 00:00:00 2001 From: xingyy Date: Thu, 28 Aug 2025 11:03:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(ContactModal):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=BE=A4=E8=81=8A=E9=80=89=E6=8B=A9=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=81=94=E7=B3=BB=E4=BA=BA=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增群聊选择表格列和状态管理 - 优化联系人选择逻辑,支持单选和多选模式 - 调整弹窗高度和按钮样式 - 分离员工通讯录和群聊列表的提交处理 --- src/components/user/ContactModal.vue | 94 +++++++++++++++++++--------- src/utils/auth.js | 2 +- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/src/components/user/ContactModal.vue b/src/components/user/ContactModal.vue index fced95a..c10cc56 100644 --- a/src/components/user/ContactModal.vue +++ b/src/components/user/ContactModal.vue @@ -34,6 +34,7 @@ const forwardMode = defineProps(['forwardMode']) // 通讯录弹窗相关状态 const state = reactive({ + selectedGroupRowKeys: [], isShowAddressBookModal: false, customModalStyle: { width: '1288px', @@ -94,6 +95,9 @@ const state = reactive({ } ], groupChatListColumns: [ + { + type: 'selection' + }, { title: '群聊名称', field: 'groupName', @@ -127,7 +131,7 @@ const state = reactive({ addressBookData: [], company_name: '', groupChatListData: [], - addressBookTableHeight: 524, + addressBookTableHeight: 500, addressBookTableWidth: 800, addressBookPage: 1, addressBookPageSize: 10, @@ -189,16 +193,29 @@ const onMaskClick = () => { const selectType = ref(2) const onTriggerContact = (item) => { + const clicked = items.value.find((val) => val.id === item.id) + if (!clicked) return + if (selectType.value === 1) { + // 单选:清空后仅选中当前 items.value.forEach(contact => { contact.checked = false }) + clicked.checked = true + return } - - let data = items.value.find((val) => val.id === item.id) - if (data) { - data.checked = !data.checked + // 多选:限制同一类型选择 + if (!clicked.checked) { + const checked = items.value.filter(c => c.checked) + const currentType = checked.length ? checked[0].talk_type : null + if (currentType && currentType !== clicked.talk_type) { + // 切换类型时清空已选,保持单一类型 + items.value.forEach(c => { if (c.checked) c.checked = false }) + } + clicked.checked = true + } else { + clicked.checked = false } } @@ -353,6 +370,12 @@ const changeAddressBookSearch = (value) => { const handleAddressBookTabChange = (value) => { state.addressBookCurrentTab = value + // 切换时清空另一类选项 + if (value === 'employeeAddressBook') { + state.selectedGroupRowKeys = [] + } else if (value === 'groupChatList') { + state.selectedRowKeys = [] + } } const changeGroupChatListSearch = (value) => { @@ -379,29 +402,40 @@ const onAddressBookCancel = () => { } const onAddressBookSubmit = async () => { - if (!Array.isArray(state.selectedRowKeys) || state.selectedRowKeys.length === 0) { - processError('请选择联系人') - return - } - - try { - const results = await Promise.all( - state.selectedRowKeys.map((erpId) => getUserInfoByERPUserId({ erp_user_id: erpId })) - ) - - const data = results - .filter((res) => res && res.code === 200 && res.data && res.data.sys_id) - .map((res) => ({ receiver_id: res.data.sys_id, talk_type: 1 })) - - if (data.length === 0) { - processError('未获取到有效联系人') + if (state.addressBookCurrentTab === 'employeeAddressBook') { + if (!Array.isArray(state.selectedRowKeys) || state.selectedRowKeys.length === 0) { + processError('请选择联系人') return } + try { + const results = await Promise.all( + state.selectedRowKeys.map((erpId) => getUserInfoByERPUserId({ erp_user_id: erpId })) + ) + + const data = results + .filter((res) => res && res.code === 200 && res.data && res.data.sys_id) + .map((res) => ({ receiver_id: res.data.sys_id, talk_type: 1 })) + + if (data.length === 0) { + processError('未获取到有效联系人') + return + } + + emit('on-submit', data) + state.isShowAddressBookModal = false + } catch (e) { + processError('发送失败,请稍后重试') + } + } else if (state.addressBookCurrentTab === 'groupChatList') { + if (!Array.isArray(state.selectedGroupRowKeys) || state.selectedGroupRowKeys.length === 0) { + processError('请选择群聊') + return + } + + const data = state.selectedGroupRowKeys.map((gid) => ({ receiver_id: gid, talk_type: 2 })) emit('on-submit', data) state.isShowAddressBookModal = false - } catch (e) { - processError('发送失败,请稍后重试') } } @@ -540,7 +574,7 @@ watch(() => state.groupChatListSearchGroupName, (newValue, oldValue) => { 请选择联系人 -
+
取消 发送 @@ -633,9 +667,11 @@ watch(() => state.groupChatListSearchGroupName, (newValue, oldValue) => { :columns="state.groupChatListColumns" :data="state.groupChatListData" :style="{ - height: '523px', + height: '500px', width: '1148px' }" + :row-key="row => row.id" + v-model:checked-row-keys="state.selectedGroupRowKeys" flex-height >
@@ -656,9 +692,9 @@ watch(() => state.groupChatListSearchGroupName, (newValue, oldValue) => {
-
- 取消 - 发送 +
+ 取消 + 发送
@@ -675,7 +711,7 @@ watch(() => state.groupChatListSearchGroupName, (newValue, oldValue) => { .addressBook-tree { width: 328px; - height: 524px; + height: 500px; overflow: auto; border: 1px solid #efeff5; border-radius: 4px; diff --git a/src/utils/auth.js b/src/utils/auth.js index b71b0e4..0d58b82 100644 --- a/src/utils/auth.js +++ b/src/utils/auth.js @@ -18,7 +18,7 @@ export function isLoggedIn() { */ export function getAccessToken() { // return storage.get(AccessToken) || '' - return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22184be97f604c74931ddd023225ae1a2ab29c0eb046e9a20174f1110532e4af8498ab46f4375f2e210bae827a6146183f385fdee154fd7bee38deb6ac4c00ae82c77150d5663288f78d678db028bfb7db' + return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d2255563bc58403f27383b042a2a3b70cfd7a005ba858457a5f0ae0c6ebfc51cbe9b95318d19d4c01987709638e27778193a0e3ecc0a31b940529ef07f5b054d55af57770cad3d97738f3e9fbd7f6a2805b' } /**