康来智慧冷链系统 - 前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

204 lines
6.1 KiB

<script setup lang="ts">
/**
* 提供模板规范代码参考,请尽量保证编写代码风格跟模板规范代码一致
* 采用vben-动态表格表单封装组件编写,采用 setup 写法
* Copyright © 2023-2023 <a href="https://godolphinx.org">海豚生态开源社区</a> All rights reserved.
* author wangxiang4
*/
import { reactive, ref, toRaw, watch } from 'vue';
import { BasicTable, useTable } from '/@/components/Table';
import DeptTree from '/@/views/system/user/DeptTree.vue';
import { listUser } from '/@/api/platform/system/controller/user';
import { columns, searchFormSchema } from './userPicker.data';
import { BasicModal, ModalProps, useModalInner } from '/@/components/Modal';
import { useDesign } from '/@/hooks/web/useDesign';
import { ScrollContainer } from '/@/components/Container';
import { useAppStore } from '/@/store/modules/app';
import { isArray } from '/@/utils/is';
import { useMessage } from '/@/hooks/web/useMessage';
import { propTypes } from '/@/utils/propTypes';
const props = defineProps({
limit: propTypes.number.def(0),
title: propTypes.string.def('用户选择'),
emitEventNameClosable: propTypes.bool.def(false)
});
/** 类型规范统一声明定义区域 */
interface TableState {
ids: string[];
single: boolean;
multiple: boolean;
searchInfo: Recordable;
tag: string;
emitEventName: string;
}
/** 通用变量统一声明区域 */
const appStore = useAppStore();
const darkMode = appStore.getDarkMode;
const { prefixCls } = useDesign('user-picker');
const { createMessage } = useMessage();
const state = reactive<TableState>({
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 搜索信息
searchInfo: {},
// 操作标签
tag: '',
// 组件触发的自定义名称
emitEventName: ''
});
const [registerTable, { reload, clearSelectedRowKeys, getSelectRows, setSelectedRowKeys, setProps }] = useTable({
title: '用户列表',
api: listUser,
rowKey: 'id',
columns,
formConfig: {
compact: true,
labelWidth: 100,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
autoAdvancedLine: 3,
fieldMapToTime: [['dateRange', ['beginTime', 'endTime'], 'YYYY-MM-DD']]
},
maxHeight: 450,
rowSelection: { type: 'checkbox' },
useSearchForm: true,
showTableSetting: true,
bordered: true,
clickToRowSelect: false,
showIndexColumn: false,
searchInfo: state.searchInfo,
handleSearchInfoFn: () => clearSelectedRowKeys()
});
watch(() => props.limit, limit => {
const rowSelectType = limit === 1 ? 'radio' : 'checkbox';
setProps({
rowSelection: { type: rowSelectType },
});
});
const modal = ref();
/** https://v3.cn.vuejs.org/api/options-data.html#emits */
const emit = defineEmits(['success', 'register'] as Recordable);
const [registerModal, { setModalProps, closeModal, changeLoading }] = useModalInner(async (data: BoxPayload = { _tag: '' }) => {
changeLoading(true);
// 处理清除脏数据
await handleRefreshTable();
// 处理设置数据
state.tag = data._tag;
const { ids, emitEventName } = data.record as Recordable;
isArray(ids) && setSelectedRowKeys(ids);
const modalProps: Partial<ModalProps> = { title: props.title };
state.emitEventName = emitEventName || 'success';
// 为后续扩展做准备,采用tag标签区分操作(预留)
switch (state.tag) {
case 'single':
break;
case 'multiple':
break;
}
// 尾部:设置处理后的最终配置数据
setModalProps(modalProps);
changeLoading(false);
});
/** 处理多选框选中数据 */
function handleSelectionChange(selection?: Recordable) {
const rowSelection = toRaw(selection?.keys) || [];
state.ids = rowSelection;
state.single = rowSelection.length != 1;
state.multiple = !rowSelection.length;
}
/** 处理表格刷新 */
async function handleRefreshTable() {
clearSelectedRowKeys();
await reload();
}
/** 处理部门管理点击 */
function handleSelect(departId: string) {
state.searchInfo.deptId = departId;
handleRefreshTable();
}
/** 处理弹出框提交 */
async function handleSubmit() {
try {
if (getSelectRows().length === 0) {
return createMessage.error('请选择一个用户!');
} else if (props.limit !== 0 && props.limit < getSelectRows().length) {
return createMessage.error(`最多只能选择${props.limit}个用户!`);
}
closeModal();
if (props.emitEventNameClosable) {
emit('success', state.emitEventName ,(getSelectRows()));
} else {
emit(state.emitEventName, toRaw(getSelectRows()));
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<template>
<div ref="modal" :class="prefixCls">
<BasicModal
v-bind="$attrs"
width="1600px"
:minHeight="600"
:getContainer="modal"
@ok="handleSubmit"
@register="registerModal"
>
<a-layout>
<a-layout-sider :width="250" :theme="darkMode">
<DeptTree class="sidebar" @select="handleSelect"/>
</a-layout-sider>
<a-layout-content>
<BasicTable @register="registerTable" @selection-change="handleSelectionChange"/>
</a-layout-content>
<a-layout-sider :theme="darkMode">
<a-divider>选择记录</a-divider>
<ScrollContainer class="pl-2">
<a-tag v-for="row in getSelectRows()"
:key="row.id"
color="processing"
>
{{ row.username }}
</a-tag>
</ScrollContainer>
</a-layout-sider>
</a-layout>
</BasicModal>
</div>
</template>
<style scoped lang="less">
@prefix-cls: ~'@{namespace}-user-picker';
.@{prefix-cls} {
.sidebar {
max-height: 700px;
}
:deep(.ant-modal) {
top: 20px;
}
.scroll-container {
max-height: 660px;
.ant-tag {
margin: 0 0 5px 8px;
}
}
}
</style>