From b64a0deae5b5d33f9e20671a68936b27f0b9b00b Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 21 七月 2026 18:03:03 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_pro2.0' into dev_pro2.0
---
src/views/im/manager/group/components/select-dialog.vue | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 271 insertions(+), 0 deletions(-)
diff --git a/src/views/im/manager/group/components/select-dialog.vue b/src/views/im/manager/group/components/select-dialog.vue
new file mode 100644
index 0000000..f1af583
--- /dev/null
+++ b/src/views/im/manager/group/components/select-dialog.vue
@@ -0,0 +1,271 @@
+<script lang="ts" setup>
+import type { VbenFormSchema } from '#/adapter/form';
+import type { VxeTableGridOptions } from '#/adapter/vxe-table';
+import type { ImManagerGroupApi } from '#/api/im/manager/group';
+
+import { nextTick, ref } from 'vue';
+
+import { DICT_TYPE } from '#/packages/constants/src';
+import { getDictOptions } from '#/packages/effects/hooks/src';
+
+import { Button, message, Modal } from 'ant-design-vue';
+
+import { useVbenVxeGrid } from '#/adapter/vxe-table';
+import {
+ getManagerGroup,
+ getManagerGroupPage,
+} from '#/api/im/manager/group';
+
+const emit = defineEmits<{
+ selected: [rows: ImManagerGroupApi.Group[]];
+}>();
+
+const open = ref(false); // 寮圭獥鏄惁鎵撳紑
+const multiple = ref(false); // 鏄惁澶氶��
+const selectedRows = ref<ImManagerGroupApi.Group[]>([]); // 宸查�夌兢鍒楄〃
+const preSelectedIds = ref<number[]>([]); // 棰勯�夌兢缂栧彿鍒楄〃
+
+/** 缇ら�夋嫨寮圭獥鐨勬悳绱㈣〃鍗� */
+function useGroupSelectGridFormSchema(): VbenFormSchema[] {
+ return [
+ {
+ fieldName: 'name',
+ label: '缇ゅ悕绉�',
+ component: 'Input',
+ componentProps: {
+ allowClear: true,
+ placeholder: '璇疯緭鍏ョ兢鍚嶇О',
+ },
+ },
+ {
+ fieldName: 'status',
+ label: '缇ょ姸鎬�',
+ component: 'Select',
+ componentProps: {
+ allowClear: true,
+ options: getDictOptions(DICT_TYPE.IM_GROUP_STATUS, 'number'),
+ placeholder: '璇烽�夋嫨缇ょ姸鎬�',
+ },
+ },
+ ];
+}
+
+/** 缇ら�夋嫨寮圭獥鐨勫瓧娈� */
+function useGroupSelectGridColumns(
+ isMultiple = false,
+): VxeTableGridOptions<ImManagerGroupApi.Group>['columns'] {
+ return [
+ {
+ type: isMultiple ? 'checkbox' : 'radio',
+ width: 50,
+ },
+ {
+ field: 'id',
+ title: '缂栧彿',
+ width: 100,
+ },
+ {
+ field: 'name',
+ title: '缇ゅ悕绉�',
+ minWidth: 160,
+ },
+ {
+ field: 'ownerNickname',
+ title: '缇や富',
+ minWidth: 160,
+ },
+ {
+ field: 'memberCount',
+ title: '鎴愬憳鏁�',
+ width: 90,
+ },
+ {
+ field: 'status',
+ title: '缇ょ姸鎬�',
+ width: 100,
+ cellRender: {
+ name: 'CellDict',
+ props: { type: DICT_TYPE.IM_GROUP_STATUS },
+ },
+ },
+ ];
+}
+
+/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 VXE reserve 璺ㄩ〉璁板綍 */
+function getMultipleSelectedRows() {
+ const selectedMap = new Map<number, ImManagerGroupApi.Group>();
+ const records = [
+ ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
+ ...(gridApi.grid.getCheckboxRecords?.() ?? []),
+ ] as ImManagerGroupApi.Group[];
+ records.forEach((row) => {
+ selectedMap.set(row.id, row);
+ });
+ return [...selectedMap.values()];
+}
+
+/** 澶勭悊澶氶�夊嬀閫夊彉鍖� */
+function handleCheckboxSelectChange() {
+ selectedRows.value = getMultipleSelectedRows();
+}
+
+/** 澶勭悊鍗曢�夊垏鎹� */
+function handleRadioChange(row: ImManagerGroupApi.Group) {
+ selectedRows.value = [row];
+}
+
+/** 澶氶�夋ā寮忎笅鍒囨崲琛屽嬀閫� */
+async function toggleMultipleRow(row: ImManagerGroupApi.Group) {
+ const selected = gridApi.grid.isCheckedByCheckboxRow(row);
+ await gridApi.grid.setCheckboxRow(row, !selected);
+ selectedRows.value = getMultipleSelectedRows();
+}
+
+/** 澶勭悊琛屽弻鍑伙細鍗曢�夌洿鎺ョ‘璁わ紝澶氶�夊垏鎹㈠嬀閫� */
+async function handleCellDblclick({ row }: { row: ImManagerGroupApi.Group }) {
+ if (multiple.value) {
+ await toggleMultipleRow(row);
+ return;
+ }
+ selectedRows.value = [row];
+ await gridApi.grid.setRadioRow(row);
+ handleConfirm();
+}
+
+/** 鍥炴樉棰勯�夌兢 */
+async function applyPreSelection() {
+ if (preSelectedIds.value.length === 0) {
+ return;
+ }
+ const rows = gridApi.grid.getData() as ImManagerGroupApi.Group[];
+ for (const row of rows) {
+ if (!preSelectedIds.value.includes(row.id)) {
+ continue;
+ }
+ if (multiple.value) {
+ await gridApi.grid.setCheckboxRow(row, true);
+ } else {
+ await gridApi.grid.setRadioRow(row);
+ selectedRows.value = [row];
+ return;
+ }
+ }
+ if (multiple.value) {
+ selectedRows.value = getMultipleSelectedRows();
+ return;
+ }
+ const targetId = preSelectedIds.value[0];
+ if (targetId) {
+ selectedRows.value = [await getManagerGroup(targetId)];
+ }
+}
+
+const [Grid, gridApi] = useVbenVxeGrid({
+ formOptions: {
+ schema: useGroupSelectGridFormSchema(),
+ },
+ gridOptions: {
+ columns: useGroupSelectGridColumns(false),
+ height: 520,
+ keepSource: true,
+ checkboxConfig: {
+ highlight: true,
+ range: true,
+ reserve: true,
+ },
+ radioConfig: {
+ highlight: true,
+ trigger: 'row',
+ },
+ proxyConfig: {
+ ajax: {
+ query: async ({ page }, formValues) => {
+ return await getManagerGroupPage({
+ pageNo: page.currentPage,
+ pageSize: page.pageSize,
+ ...formValues,
+ });
+ },
+ },
+ },
+ rowConfig: {
+ keyField: 'id',
+ isHover: true,
+ },
+ toolbarConfig: {
+ refresh: true,
+ search: true,
+ },
+ } as VxeTableGridOptions<ImManagerGroupApi.Group>,
+ gridEvents: {
+ cellDblclick: handleCellDblclick,
+ checkboxAll: handleCheckboxSelectChange,
+ checkboxChange: handleCheckboxSelectChange,
+ radioChange: ({ row }: { row: ImManagerGroupApi.Group }) => {
+ handleRadioChange(row);
+ },
+ },
+});
+
+/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�� */
+async function resetQueryState() {
+ selectedRows.value = [];
+ await gridApi.grid.clearCheckboxRow();
+ await gridApi.grid.clearCheckboxReserve();
+ await gridApi.grid.clearRadioRow();
+ await gridApi.formApi.resetForm();
+}
+
+/** 鎵撳紑缇ら�夋嫨寮圭獥 */
+async function openModal(
+ selectedIds?: number[],
+ options?: { multiple?: boolean },
+) {
+ open.value = true;
+ multiple.value = options?.multiple ?? false;
+ preSelectedIds.value = selectedIds || [];
+ await nextTick();
+ gridApi.setGridOptions({
+ columns: useGroupSelectGridColumns(multiple.value),
+ });
+ await resetQueryState();
+ await gridApi.query();
+ await nextTick();
+ await applyPreSelection();
+}
+
+/** 鍏抽棴缇ら�夋嫨寮圭獥 */
+function closeModal() {
+ open.value = false;
+}
+
+/** 纭閫夋嫨缇� */
+function handleConfirm() {
+ const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value;
+ if (rows.length === 0) {
+ message.warning(multiple.value ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
+ return;
+ }
+ emit('selected', multiple.value ? rows : [rows[0]!]);
+ open.value = false;
+}
+
+defineExpose({ open: openModal });
+</script>
+
+<template>
+ <Modal
+ v-model:open="open"
+ title="缇ら�夋嫨"
+ width="70%"
+ :destroy-on-close="true"
+ @ok="handleConfirm"
+ @cancel="closeModal"
+ >
+ <Grid table-title="缇ゅ垪琛�" />
+ <template #footer>
+ <Button @click="closeModal">鍙栨秷</Button>
+ <Button type="primary" @click="handleConfirm">纭畾</Button>
+ </template>
+ </Modal>
+</template>
--
Gitblit v1.9.3