<script lang="ts" setup>
|
import type { FormInstance } from 'ant-design-vue';
|
|
import { computed, nextTick, reactive, ref, toRefs, unref } from 'vue';
|
|
import { DrawerFooter } from '@jnpf/ui/drawer';
|
import { ModalClose } from '@jnpf/ui/modal';
|
|
import { useUserStore } from '@vben/stores';
|
|
import { RedoOutlined } from '@ant-design/icons-vue';
|
import { Drawer as ADrawer, Modal as AModal } from 'ant-design-vue';
|
|
import { getFieldDataSelect } from '#/api/onlineDev/visualDev';
|
import { getDataInterfaceDataSelect } from '#/api/systemData/dataInterface';
|
import { $t } from '#/locales';
|
|
interface State {
|
list: any[];
|
listQuery: any;
|
loading: boolean;
|
total: number;
|
selectedRowKeys: any[];
|
selectedRows: any[];
|
}
|
|
defineOptions({ inheritAttrs: false, name: 'SelectModal' });
|
const props = defineProps({
|
config: {
|
type: Object,
|
default: () => {},
|
},
|
formData: Object,
|
});
|
const emit = defineEmits(['select']);
|
|
const selectRow = ref<any>(null);
|
const visible = ref(false);
|
const userStore = useUserStore();
|
const formElRef = ref<FormInstance>();
|
const tableElRef = ref<any>(null);
|
const indexColumn = { width: 50, title: '序号', dataIndex: 'index', key: 'index', align: 'center', customRender: ({ index }) => index + 1 };
|
const state = reactive<State>({
|
list: [],
|
listQuery: {
|
keyword: '',
|
currentPage: 1,
|
pageSize: 20,
|
},
|
loading: false,
|
total: 0,
|
selectedRowKeys: [],
|
selectedRows: [],
|
});
|
const { listQuery, list } = toRefs(state);
|
|
const getUserInfo: any = computed(() => userStore.getUserInfo || {});
|
const getIsDynamic = computed(() => props.config.dataSource == 'dynamic');
|
const getColumns = computed<any[]>(() => {
|
const columns = (props.config.columnOptions as any)
|
.filter((o) => o.ifShow || o.ifShow === undefined)
|
.map((o) => ({
|
title: o.label,
|
dataIndex: o.value,
|
sorter: unref(getIsDynamic) || o.value.includes('jnpf_') ? false : { multiple: 1 },
|
ellipsis: true,
|
width: o.width || 100,
|
}));
|
return [indexColumn, ...columns];
|
});
|
const searchInfo = computed(() => {
|
const paramList = getParamList();
|
const columnOptions = (props.config.columnOptions as any).map((o) => o.value).join(',');
|
const info: any = {
|
interfaceId: props.config.interfaceId,
|
columnOptions,
|
paramList,
|
};
|
const data = {
|
modelId: props.config.modelId,
|
relationField: props.config.relationField,
|
columnOptions,
|
};
|
return unref(getIsDynamic) ? info : data;
|
});
|
const getPagination = computed<any>(() => {
|
return {
|
current: state.listQuery.currentPage,
|
pageSize: state.listQuery.pageSize,
|
size: 'small',
|
defaultPageSize: 20,
|
showTotal: (total) => $t('component.table.total', { total }),
|
showSizeChanger: true,
|
pageSizeOptions: ['20', '50', '80', '100'],
|
showQuickJumper: true,
|
total: state.total,
|
};
|
});
|
const getRowSelection = computed<any>(() => ({
|
type: 'checkbox',
|
onChange: setSelectedRowKeys,
|
selectedRowKeys: state.selectedRowKeys,
|
}));
|
const getScrollY = computed(() => {
|
let height = props.config.popupType === 'drawer' ? window.innerHeight - 120 - 52 - 38 : window.innerHeight * 0.7 - 52 - 38;
|
height -= 44;
|
return height;
|
});
|
const getTableBindValues = computed(() => {
|
return {
|
columns: unref(getColumns),
|
pagination: unref(getPagination),
|
rowSelection: unref(getRowSelection),
|
customRow,
|
size: 'small',
|
loading: state.loading,
|
rowKey: (record) => record,
|
scroll: {
|
y: unref(getScrollY),
|
},
|
class: 'jnpf-basic-table',
|
};
|
});
|
|
defineExpose({ openSelectModal });
|
|
function customRow(record: Recordable) {
|
return {
|
onClick: (e: Event) => {
|
e?.stopPropagation();
|
const tr: HTMLElement = (e as MouseEvent).composedPath?.().find((dom: any) => dom.tagName === 'TR') as HTMLElement;
|
if (!tr) return;
|
const key = record;
|
// 找到Checkbox,检查是否为disabled
|
const checkBox = tr.querySelector('input[type=checkbox]');
|
if (!checkBox || checkBox.hasAttribute('disabled')) return;
|
if (state.selectedRowKeys.includes(key)) {
|
const keyIndex = state.selectedRowKeys.indexOf(key);
|
state.selectedRowKeys.splice(keyIndex, 1);
|
state.selectedRows = state.selectedRows.filter((o) => o !== key);
|
} else {
|
state.selectedRowKeys.push(key);
|
state.selectedRows.push(record);
|
}
|
},
|
};
|
}
|
function getForm() {
|
const form = unref(formElRef);
|
if (!form) {
|
throw new Error('form is null!');
|
}
|
return form;
|
}
|
function openSelectModal() {
|
visible.value = true;
|
setTimeout(() => {
|
nextTick(() => {
|
handleReset();
|
state.selectedRowKeys = [];
|
state.selectedRows = [];
|
state.list = [];
|
state.total = 0;
|
const tableEl = tableElRef.value?.$el;
|
const bodyEl = tableEl.querySelector('.ant-table-body');
|
bodyEl!.style.height = `${unref(getScrollY)}px`;
|
});
|
}, 50);
|
}
|
function handleCancel() {
|
visible.value = false;
|
}
|
function handleSubmit() {
|
if (!state.selectedRowKeys.length && !state.selectedRows.length) return;
|
selectRow.value = state.selectedRows;
|
const checked: any[] = [];
|
for (let i = 0; i < unref(selectRow).length; i++) {
|
const e = unref(selectRow)[i];
|
const item = {};
|
for (let j = 0; j < props.config.relationOptions.length; j++) {
|
const row = props.config.relationOptions[j];
|
item[row.field] = row.type === 1 ? e[unref(getIsDynamic) ? row.value : `${row.value}_jnpfId`] : row.value;
|
}
|
checked.push(item);
|
}
|
emit('select', checked);
|
handleCancel();
|
}
|
function getParamList() {
|
const templateJson: any[] = props.config.templateJson;
|
if (!props.formData) return templateJson;
|
for (const e of templateJson) {
|
const data = props.formData;
|
if (e.sourceType == 1) {
|
e.defaultValue = data[e.relationField] || data[e.relationField] == 0 || data[e.relationField] == false ? data[e.relationField] : '';
|
}
|
if (e.jnpfKey === 'createUser') e.defaultValue = unref(getUserInfo).userId;
|
if (e.jnpfKey === 'createTime') e.defaultValue = Date.now();
|
if (e.jnpfKey === 'currOrganize') e.defaultValue = unref(getUserInfo).organizeId;
|
if (e.jnpfKey === 'currPosition') e.defaultValue = unref(getUserInfo).positionId;
|
}
|
return templateJson;
|
}
|
function handleSearch() {
|
state.listQuery.currentPage = 1;
|
state.listQuery.pageSize = 20;
|
initData();
|
}
|
function handleReset() {
|
getForm().resetFields();
|
state.listQuery.keyword = '';
|
handleSearch();
|
}
|
function initData() {
|
if (unref(getIsDynamic) && !props.config.interfaceId) return;
|
if (!unref(getIsDynamic) && !props.config.modelId) return;
|
state.loading = true;
|
const query = {
|
...state.listQuery,
|
...unref(searchInfo),
|
};
|
const method = unref(getIsDynamic) ? getDataInterfaceDataSelect : getFieldDataSelect;
|
method(query)
|
.then((res) => {
|
state.list = res.data.list;
|
state.total = res.data.pagination.total;
|
state.loading = false;
|
})
|
.catch(() => {
|
state.loading = false;
|
});
|
}
|
function handleTableChange(pagination, _f, sorter, type) {
|
if (!unref(getIsDynamic) && type?.action === 'sort' && sorter) {
|
if (Array.isArray(sorter)) {
|
const sortList = sorter.map((o) => (o.order === 'descend' ? '-' : '') + o.field);
|
state.listQuery.sidx = sortList.join(',');
|
} else {
|
const { field, order } = sorter;
|
state.listQuery.sidx = field && order ? (order === 'descend' ? '-' : '') + field : undefined;
|
}
|
}
|
if (type?.action === 'paginate') {
|
state.listQuery.currentPage = pagination.current;
|
state.listQuery.pageSize = pagination.pageSize;
|
}
|
initData();
|
}
|
function setSelectedRowKeys(selectedRowKeys, selectedRows) {
|
state.selectedRowKeys = selectedRowKeys;
|
state.selectedRows = selectedRows;
|
}
|
</script>
|
|
<template>
|
<div class="common-container">
|
<template v-if="config.popupType === 'dialog'">
|
<AModal
|
v-model:open="visible"
|
:title="config.popupTitle"
|
:width="config.popupWidth"
|
class="common-container-modal"
|
@ok="handleSubmit"
|
@cancel="handleCancel"
|
:mask-closable="false">
|
<template #closeIcon>
|
<ModalClose :can-fullscreen="false" @cancel="handleCancel" />
|
</template>
|
<div class="jnpf-common-search-box jnpf-common-search-box-modal">
|
<a-form :colon="false" label-align="right" :model="listQuery" ref="formElRef" class="jnpf-basic-form jnpf-basic-form--compact search-form">
|
<a-row :gutter="10">
|
<a-col :span="8">
|
<a-form-item :label="$t('common.keyword')" name="keyword">
|
<a-input v-model:value="listQuery.keyword" :placeholder="$t('common.enterKeyword')" allow-clear @press-enter="handleSearch" />
|
</a-form-item>
|
</a-col>
|
<a-col :span="8">
|
<a-form-item label=" ">
|
<a-button type="primary" class="mr-2" @click="handleSearch">{{ $t('common.queryText') }}</a-button>
|
<a-button @click="handleReset">{{ $t('common.resetText') }}</a-button>
|
</a-form-item>
|
</a-col>
|
</a-row>
|
</a-form>
|
<div class="jnpf-common-search-box-right">
|
<a-tooltip placement="top">
|
<template #title>
|
<span>{{ $t('common.redo') }}</span>
|
</template>
|
<RedoOutlined class="jnpf-common-search-box-right-icon" @click="initData" />
|
</a-tooltip>
|
</div>
|
</div>
|
<a-table :data-source="list" v-bind="getTableBindValues" @change="handleTableChange" ref="tableElRef">
|
<template #bodyCell="{ column, record }">
|
<template v-if="column.dataIndex !== 'index'">{{ record[column.dataIndex] }}</template>
|
</template>
|
</a-table>
|
</AModal>
|
</template>
|
<template v-if="config.popupType === 'drawer'">
|
<ADrawer :title="config.popupTitle" :width="config.popupWidth" v-model:open="visible" class="jnpf-basic-drawer common-container-drawer">
|
<div class="common-container-drawer-body">
|
<div class="jnpf-common-search-box jnpf-common-search-box-modal">
|
<a-form :colon="false" label-align="right" :model="listQuery" ref="formElRef" class="jnpf-basic-form jnpf-basic-form--compact search-form">
|
<a-row :gutter="10">
|
<a-col :span="8">
|
<a-form-item :label="$t('common.keyword')" name="keyword">
|
<a-input v-model:value="listQuery.keyword" :placeholder="$t('common.enterKeyword')" allow-clear @press-enter="handleSearch" />
|
</a-form-item>
|
</a-col>
|
<a-col :span="8">
|
<a-form-item label=" ">
|
<a-button type="primary" class="mr-2" @click="handleSearch">{{ $t('common.queryText') }}</a-button>
|
<a-button @click="handleReset">{{ $t('common.resetText') }}</a-button>
|
</a-form-item>
|
</a-col>
|
</a-row>
|
</a-form>
|
<div class="jnpf-common-search-box-right">
|
<a-tooltip placement="top">
|
<template #title>
|
<span>{{ $t('common.redo') }}</span>
|
</template>
|
<RedoOutlined class="jnpf-common-search-box-right-icon" @click="initData" />
|
</a-tooltip>
|
</div>
|
</div>
|
<a-table :data-source="list" v-bind="getTableBindValues" @change="handleTableChange" ref="tableElRef">
|
<template #bodyCell="{ column, record }">
|
<template v-if="column.dataIndex !== 'index'">{{ record[column.dataIndex] }}</template>
|
</template>
|
</a-table>
|
</div>
|
<DrawerFooter show-footer @close="handleCancel" @ok="handleSubmit" />
|
</ADrawer>
|
</template>
|
</div>
|
</template>
|