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.

617 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { PlusOutlined } from '@ant-design/icons';
import { Button, message, Input, Drawer, Row, Col, Space, Modal, Popconfirm } from 'antd';
import React, { useState, useRef } from 'react';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import type { ProColumns, ActionType } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import { BetaSchemaForm, ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
import type { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import ProDescriptions from '@ant-design/pro-descriptions';
import type { FormValueType } from './components/UpdateForm';
import UpdateForm from './components/UpdateForm';
import { queryTrainList, saveTrain, removeTrain, queryOrgTree, queryValueByKey, querySubjectList, querySubjectView } from './service';
import type { TableListItem, TableListPagination } from './data';
import { useRequest } from 'umi';
/**
* 添加培训
*
* @param fields
*/
const handleAdd = async (fields: TableListItem) => {
const hide = message.loading('正在添加');
try {
await saveTrain({ ...fields });
hide();
message.success('添加成功');
return true;
} catch (error) {
hide();
message.error('添加失败请重试!');
return false;
}
};
/**
* 更新培训
*
* @param fields
*/
const handleUpdate = async (fields: FormValueType, currentRow?: TableListItem) => {
const hide = message.loading('正在配置');
try {
await saveTrain({
...currentRow,
...fields,
});
hide();
message.success('配置成功');
return true;
} catch (error) {
hide();
message.error('配置失败请重试!');
return false;
}
};
/**
* 删除培训(接口不支持批量)
* 参数为记录数组
* @param selectedRows
*/
const handleRemove = async (selectedRows: TableListItem[]) => {
const hide = message.loading('正在删除');
if (!selectedRows) return true;
console.log('key', selectedRows);
try {
const { code, msg } = await removeTrain({
key: selectedRows.map((row) => row.key),
});
hide();
if (code === 2000) {
message.success('删除成功,即将刷新');
} else {
message.warning(msg);
}
return true;
} catch (error) {
console.log('error', error)
hide();
message.error('删除失败,请重试');
return false;
}
};
interface OrgTreeForOaItem {
id?: number;
pId?: number;
name?: string;
}
interface children {
title?: string;
value?: number;
children?: children[];
}
// 递归方法 生成 json tree 数据
const getJsonTree = (data: [], pId: number) => {
//console.log('getJsonTree..', data)
const itemArr = [];
for (let i = 0; i < data.length; i++) {
const node: OrgTreeForOaItem = data[i];
//console.log('f')
//console.log('node?.pId',node?.pId)
//console.log('pId',pId)
if (node?.pId === Number(pId)) {
console.log('if')
const treeNode: children = {};
treeNode.value = node?.id;
treeNode.label = node?.name;
//treeNode.url = node.url;
//treeNode.icon = node.icon;
//eslint-disable-next-line @typescript-eslint/no-unused-vars
treeNode.children = getJsonTree(data, node?.id || 0);
itemArr.push(treeNode);
}
}
return itemArr;
};
const TableList: React.FC = () => {
const { data, loading } = useRequest(() => {
return queryValueByKey({});
});
/** 新建窗口的弹窗 */
const [createModalVisible, handleModalVisible] = useState<boolean>(false);
const [updateModalVisible, handleUpdateModalVisible] = useState<boolean>(false);
const [showDetail, setShowDetail] = useState<boolean>(false);
const actionRef = useRef<ActionType>();
const [currentRow, setCurrentRow] = useState<TableListItem>();
const [selectedRowsState, setSelectedRows] = useState<TableListItem[]>([]);
const [orgTree, setOrgTree] = useState([]);
const columns: ProColumns<TableListItem>[] = [
{
title: '序号',
key: 'index',
valueType: 'indexBorder',
render: (text: React.ReactNode, _: any, index: number) => {
if (actionRef && actionRef?.current && actionRef?.current?.pageInfo) {
return `${(actionRef?.current?.pageInfo?.current - 1) * (actionRef.current.pageInfo?.pageSize) + (index + 1)}`;
} else {
return '';
}
},
width: 48,
},
{
title: '培训名称',
dataIndex: 'train_name',
valueType: 'text',
hideInSearch: true,
formItemProps: {
rules: [
{
required: true,
message: '请输入培训名称',
},
]
},
},
{
title: '培训对象',
valueType: 'select',
hideInSearch: true,
fieldProps: {
mode: "multiple"
},
formItemProps: {
rules: [
{
required: true,
message: '请选择培训对象',
},
]
},
dataIndex: 'org_names',
request: async () => {
const Value = await queryValueByKey({});
const orgId = Value['common.org.id'] ? Value['common.org.id'] : 0; // 平台全局设置
const tree = await queryOrgTree({
org_id: Number(orgId),
org_type: 2,
//school_type: 1,
})
setOrgTree(tree.table_List)
console.log('orgId', orgId)
console.log('tree.table_List', tree.table_List)
return getJsonTree(tree.table_List, orgId)
},
sorter: false,
hideInForm: false,
//renderText: (val: string) => `${val}`,
},
{
title: '关联主题',
dataIndex: 'subject_id',
valueType: 'text',
hideInTable: true,
hideInForm: false,
hideInSearch: false,
formItemProps: {
rules: [
{
required: true,
message: '请选择主题',
},
]
},
request: async () => {
const { data: Items } = await querySubjectList();
console.log('Items:::', Items);
const sinfo = []
for (let i = 0; i < Items.length; i++) {
console.log(Items[i], ">>>")
sinfo.push({ label: Items[i].subject_name, value: Items[i].subject_id })
}
console.log(sinfo, 'sinfo');
return sinfo;
},
},
{
title: '开始时间',
dataIndex: 'start_time',
sorter: false,
hideInForm: true,
hideInSearch: true,
renderText: (val: string) => `${val}`,
},
{
title: '结束时间',
dataIndex: 'end_time',
sorter: false,
hideInSearch: true,
hideInForm: true,
renderText: (val: string) => `${val}`,
},
{
title: '培训时间',
valueType: 'dateTimeRange',
dataIndex: 'date_time',
sorter: false,
hideInForm: false,
hideInTable: true,
hideInSearch: false,
renderText: (val: string) => `${val}`,
formItemProps: {
rules: [
{
required: true,
message: '请选择培训时间',
},
]
},
},
{
title: '学时安排',
sorter: false,
dataIndex: 'total_course_hours',
valueType: 'text',
hideInForm: true,
hideInSearch: true,
renderText: (val: string) => `${val}小时`,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="update"
onClick={() => {
handleUpdateModalVisible(true);
setCurrentRow(record);
}}
>
</a>,
<Popconfirm key="popconfirm" title={`确认删除当前项吗?`} okText="是" cancelText="否"
onConfirm={async () => {
handleRemove([{ key: record?.train_id }]); // 调用批量删除函数如果接口不支持批量需要在service中处理
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}}
>
<a key="remove"></a>
</Popconfirm>
],
},
];
/** 获取列数据初始值 */
const getInitialValues = (cols: any[], vals: any) => {
console.log('getInitialValues-columns', columns);
console.log('getInitialValues-values', vals);
const initialValues: any[] = [];
cols.forEach((column: { dataIndex: string }) => {
const key: any = column?.dataIndex || '';
initialValues.push({ ...column, initialValue: key ? vals[key] : '' });
});
console.log('initialValues::', initialValues);
return initialValues || [];
};
return (
<PageContainer>
<ProTable<TableListItem, TableListPagination>
headerTitle={false}
actionRef={actionRef}
rowKey="train_id"
options={false}
search={{
labelWidth: 120,
}}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
handleModalVisible(true);
}}
>
<PlusOutlined />
</Button>,
]}
request={async (value) => {
if (value.date_time) {
value.begin_time = value.date_time[0]
value.end_time = value.date_time[1]
}
// delete value.date_time
console.log('search', value);
const _data = await queryTrainList(value);
return {
current: _data?.page_number,
data: _data?.data?.list,
pageSize: _data?.page_size,
total: _data?.total_row || 0,
};
}}
columns={columns}
rowSelection={false}
/>
{selectedRowsState?.length > 0 && (
<FooterToolbar
extra={
<div>
{' '}
<a
style={{
fontWeight: 600,
}}
>
{selectedRowsState.length}
</a>{' '}
&nbsp;&nbsp;
<span>
{selectedRowsState.reduce((pre, item) => pre + item.callNo!, 0)}
</span>
</div>
}
>
<Button
onClick={async () => {
await handleRemove(selectedRowsState);
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
}}
>
</Button>
<Button type="primary"></Button>
</FooterToolbar>
)}
<Modal
title="新建培训"
//
width="60%"
visible={createModalVisible}
destroyOnClose
onCancel={() => {
handleModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm
layout="horizontal"
layoutType="Form"
labelCol={{ span: 8 }}
wrapperCol={{ span: 12 }}
onFinish={async (values: any) => {
// 表单处理
//console.log('columns:', columns);
console.log('values1:', values, orgTree);
const tree = orgTree.filter((item, idx, self) => {
return (values.org_names.indexOf(item.id) !== -1)
});
tree.map((e, i) => {
tree[i].org_id = e.id
tree[i].org_name = e.name
delete tree[i].id
delete tree[i].name
delete tree[i].pId
})
console.log(321);
console.log(tree, 'tree');
const _data = {
...values,
end_time: values.date_time[1],
start_time: values.date_time[0],
target_list_json: JSON.stringify(tree)
}
delete _data.date_time
delete _data.org_names
// delete params.course_time
// delete params.examination_time
console.log(_data, '_data');
const res = await saveTrain(_data);
// console.log(res, 'ressss');
if (res.code === 2000) {
handleModalVisible(false);
actionRef.current?.reloadAndRest?.();
} else {
message.error(res.msg);
}
}}
submitter={{
render: (props, doms) => (
<Row>
<Col span={12} offset={8}>
<Space>{doms}</Space>
</Col>
</Row>
),
}}
// action = ''
title="新建"
columns={columns}
/>
</Modal>
<Modal
title="编辑"
width="60%"
visible={updateModalVisible}
destroyOnClose
onCancel={() => {
handleUpdateModalVisible(false);
}}
footer={null}
>
{currentRow?.train_id && (
<BetaSchemaForm<DataItem>
layout="horizontal"
layoutType="Form"
labelCol={{ span: 8 }}
wrapperCol={{ span: 12 }}
request={async () => {
const { data } = await querySubjectView({ train_id: currentRow?.train_id });
data.date_time = [currentRow.start_time, currentRow.end_time]
data.org_names = []
data.target_list.map((e) => {
data.org_names.push({
value: e.org_id,
label: e.org_name
})
console.log("222", data);
})
console.log("edit", data);
return data
}}
onFinish={async (values: any) => {
// 表单处理
//console.log('columns:', columns);
console.log('values1:', values, values.org_names.value);
//return false;
// values.attachment_json.response.file.response.url
// 处理机构数据。直接编辑与回显结构不够
let tree = []
if (typeof values.org_names[0] === 'number') {
// tree = values.org_names
console.log('true values.org_names', tree, values)
tree = orgTree?.filter((item, idx, self) => {
return (values?.org_names?.indexOf(item?.id) !== -1)
});
console.log("tree,1111", tree);
tree.map((e, i) => {
tree[i].org_id = e.id
tree[i].org_name = e.name
delete tree[i].id
delete tree[i].name
delete tree[i].pId
})
} else {
values.org_names.map((e) => {
tree.push({
org_type: 2,
org_id: e.value,
org_name: e.label
})
})
}
console.log(321);
console.log(tree, 'tree');
const _data = {
...values,
end_time: values.date_time[1],
start_time: values.date_time[0],
target_list_json: JSON.stringify(tree),
train_id: currentRow.train_id
}
delete _data.date_time
delete _data.org_names
// delete params.course_time
// delete params.examination_time
console.log('_data', _data);
const res = await saveTrain(_data);
// console.log(res, 'ressss');
if (res.code === 2000) {
handleUpdateModalVisible(false);
actionRef.current?.reloadAndRest?.();
} else {
message.error(res.msg);
}
}}
submitter={{
render: (props, doms) => (
<Row>
<Col span={12} offset={8}>
<Space>{doms}</Space>
</Col>
</Row>
),
}}
// action = ''
title="编辑"
columns={columns}
/>
)}
</Modal>
<Drawer
width={600}
visible={showDetail}
onClose={() => {
setCurrentRow(undefined);
setShowDetail(false);
}}
closable={false}
>
{currentRow?.name && (
<ProDescriptions<TableListItem>
column={2}
title={currentRow?.name}
request={async () => ({
data: currentRow || {},
})}
params={{
id: currentRow?.name,
}}
columns={columns as ProDescriptionsItemProps<TableListItem>[]}
/>
)}
</Drawer>
</PageContainer>
);
};
export default TableList;