feat: 选人组件(未完成) 加签减签
This commit is contained in:
@@ -1,45 +1,287 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import type { User } from '#/api';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { Transfer } from 'ant-design-vue';
|
||||
import { useVbenModal, type VbenFormProps } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid, type VxeGridProps } from '#/adapter/vxe-table';
|
||||
import { userList } from '#/api/system/user';
|
||||
import DeptTree from '#/views/system/user/dept-tree.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'UserSelectModal',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const [BasicModal] = useVbenModal({
|
||||
title: '选择',
|
||||
class: 'w-[800px]',
|
||||
const props = withDefaults(defineProps<{ mode?: 'multiple' | 'single' }>(), {
|
||||
mode: 'multiple',
|
||||
});
|
||||
|
||||
const targetKeys = ref<string[]>([]);
|
||||
const emit = defineEmits<{
|
||||
finish: [User[]];
|
||||
}>();
|
||||
|
||||
const dataSource = ref<Awaited<ReturnType<typeof userList>>['rows']>([]);
|
||||
onMounted(async () => {
|
||||
const resp = await userList({ pageNum: 1, pageSize: 10 });
|
||||
dataSource.value = resp.rows.map((item) => ({
|
||||
...item,
|
||||
userId: String(item.userId),
|
||||
}));
|
||||
const [BasicModal, modalApi] = useVbenModal({
|
||||
title: '选择人员',
|
||||
class: 'w-[1000px]',
|
||||
fullscreenButton: false,
|
||||
onConfirm: handleSubmit,
|
||||
});
|
||||
|
||||
// 左边部门用
|
||||
const selectDeptId = ref<string[]>([]);
|
||||
const formOptions: VbenFormProps = {
|
||||
schema: [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'userName',
|
||||
label: '用户账号',
|
||||
hideLabel: true,
|
||||
componentProps: {
|
||||
placeholder: '请输入账号',
|
||||
},
|
||||
},
|
||||
],
|
||||
commonConfig: {
|
||||
labelWidth: 80,
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
wrapperClass: 'grid-cols-2',
|
||||
handleReset: async () => {
|
||||
selectDeptId.value = [];
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
const { formApi, reload } = tableApi;
|
||||
await formApi.resetForm();
|
||||
const formValues = formApi.form.values;
|
||||
formApi.setLatestSubmissionValues(formValues);
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
await rightTableApi.grid.loadData([]);
|
||||
await reload(formValues);
|
||||
},
|
||||
};
|
||||
|
||||
const gridOptions: VxeGridProps = {
|
||||
checkboxConfig: {
|
||||
// 翻页时保留选中状态
|
||||
reserve: true,
|
||||
// 点击行选中
|
||||
trigger: 'row',
|
||||
},
|
||||
radioConfig: {
|
||||
trigger: 'row',
|
||||
strict: true,
|
||||
},
|
||||
columns: [
|
||||
{ type: props.mode === 'single' ? 'radio' : 'checkbox', width: 60 },
|
||||
{
|
||||
field: 'userName',
|
||||
title: '名称',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
field: 'nickName',
|
||||
title: '昵称',
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
field: 'deptName',
|
||||
title: '部门',
|
||||
width: 120,
|
||||
},
|
||||
],
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
pagerConfig: {},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues = {}) => {
|
||||
// 部门树选择处理
|
||||
if (selectDeptId.value.length === 1) {
|
||||
formValues.deptId = selectDeptId.value[0];
|
||||
} else {
|
||||
Reflect.deleteProperty(formValues, 'deptId');
|
||||
}
|
||||
|
||||
return await userList({
|
||||
pageNum: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
rowConfig: {
|
||||
isHover: true,
|
||||
keyField: 'userId',
|
||||
},
|
||||
toolbarConfig: {
|
||||
// 自定义列
|
||||
custom: false,
|
||||
// 最大化
|
||||
zoom: false,
|
||||
// 刷新
|
||||
refresh: false,
|
||||
},
|
||||
};
|
||||
|
||||
const [BasicTable, tableApi] = useVbenVxeGrid({
|
||||
formOptions,
|
||||
gridOptions,
|
||||
gridEvents: {
|
||||
// 需要控制不同的事件 radio也会触发checkbox事件
|
||||
checkboxChange: checkBoxEvent,
|
||||
checkboxAll: checkBoxEvent,
|
||||
radioChange: radioEvent,
|
||||
},
|
||||
});
|
||||
|
||||
function checkBoxEvent() {
|
||||
if (props.mode !== 'multiple') {
|
||||
return;
|
||||
}
|
||||
// 给右边表格赋值
|
||||
const records = tableApi.grid.getCheckboxRecords();
|
||||
console.log(records);
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
rightTableApi.grid.loadData(records);
|
||||
}
|
||||
|
||||
function radioEvent() {
|
||||
if (props.mode !== 'single') {
|
||||
return;
|
||||
}
|
||||
// 给右边表格赋值
|
||||
const records = tableApi.grid.getRadioRecord();
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
rightTableApi.grid.loadData([records]);
|
||||
}
|
||||
|
||||
const rightGridOptions: VxeGridProps = {
|
||||
checkboxConfig: {},
|
||||
columns: [
|
||||
{
|
||||
field: 'nickName',
|
||||
title: '昵称',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
slots: { default: 'action' },
|
||||
},
|
||||
],
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
pagerConfig: {
|
||||
enabled: false,
|
||||
},
|
||||
proxyConfig: {
|
||||
enabled: false,
|
||||
},
|
||||
rowConfig: {
|
||||
isHover: true,
|
||||
keyField: 'userId',
|
||||
},
|
||||
toolbarConfig: {
|
||||
// 自定义列
|
||||
custom: false,
|
||||
// 最大化
|
||||
zoom: false,
|
||||
// 刷新
|
||||
refresh: false,
|
||||
},
|
||||
};
|
||||
|
||||
const [RightBasicTable, rightTableApi] = useVbenVxeGrid({
|
||||
gridOptions: rightGridOptions,
|
||||
});
|
||||
|
||||
function handleRemoveItem(row: any) {
|
||||
if (props.mode === 'multiple') {
|
||||
tableApi.grid.setCheckboxRow(row, false);
|
||||
}
|
||||
if (props.mode === 'single') {
|
||||
tableApi.grid.clearRadioRow();
|
||||
}
|
||||
rightTableApi.grid.remove(row);
|
||||
}
|
||||
|
||||
function handleRemoveAll() {
|
||||
if (props.mode === 'multiple') {
|
||||
tableApi.grid.clearCheckboxRow();
|
||||
}
|
||||
if (props.mode === 'single') {
|
||||
tableApi.grid.clearRadioRow();
|
||||
}
|
||||
rightTableApi.grid.loadData([]);
|
||||
}
|
||||
|
||||
async function handleDeptQuery() {
|
||||
await tableApi.reload();
|
||||
// 重置后恢复 保存勾选的数据
|
||||
const records = rightTableApi.grid.getData();
|
||||
if (props.mode === 'multiple') {
|
||||
tableApi?.grid.setCheckboxRow(records, true);
|
||||
}
|
||||
if (props.mode === 'single' && records.length === 1) {
|
||||
tableApi.grid.setRadioRow(records[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
const records = rightTableApi.grid.getData();
|
||||
console.log(records);
|
||||
emit('finish', records);
|
||||
modalApi.close();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BasicModal>
|
||||
<div class="min-h-[350px]">
|
||||
<Transfer
|
||||
v-model:target-keys="targetKeys"
|
||||
:data-source="dataSource"
|
||||
:pagination="true"
|
||||
:render="(item) => item.nickName"
|
||||
:row-key="(record) => record.userId"
|
||||
class="h-full"
|
||||
<div class="flex min-h-[600px]">
|
||||
<DeptTree
|
||||
v-model:select-dept-id="selectDeptId"
|
||||
:show-search="false"
|
||||
class="w-[230px]"
|
||||
@reload="() => tableApi.reload()"
|
||||
@select="handleDeptQuery"
|
||||
/>
|
||||
<div class="h-[600px] w-[420px]">
|
||||
<BasicTable />
|
||||
</div>
|
||||
<div class="flex h-[600px] w-[360px] flex-col">
|
||||
<div class="flex w-full px-4">
|
||||
<div class="flex w-full items-center justify-between">
|
||||
<div>已选中人员</div>
|
||||
<div>
|
||||
<a-button size="small" @click="handleRemoveAll">
|
||||
清空选中
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightBasicTable>
|
||||
<template #action="{ row }">
|
||||
<a-button size="small" @click="handleRemoveItem(row)">
|
||||
移除
|
||||
</a-button>
|
||||
</template>
|
||||
</RightBasicTable>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(div.vben-link) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:deep(.vxe-body--row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user