|
|
import { PlusOutlined } from '@ant-design/icons';
|
|
|
import { Button, message, Input, Drawer, Row, Col, Space, Modal } 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({ page_size: 1000 });
|
|
|
// console.log(Items, ')))');
|
|
|
|
|
|
const sinfo = []
|
|
|
for (let i = 0; i < Items.list.length; i++) {
|
|
|
// console.log(Items.list[i], ">>>")
|
|
|
sinfo.push({ label: Items.list[i].subject_name, value: Items.list[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);
|
|
|
// const _record = JSON.parse(JSON.stringify(record))
|
|
|
// const idsArr = _record?.org_ids?.split(",")
|
|
|
// const orgName = _record.org_names != "" ? _record.org_names.split(",") : ""
|
|
|
// const idsData = []
|
|
|
// if (_record?.org_ids != false) {
|
|
|
// idsArr.map((e, i) => {
|
|
|
// idsData.push({
|
|
|
// label: orgName[i], value: Number(e)
|
|
|
// })
|
|
|
// })
|
|
|
|
|
|
// }
|
|
|
// _record.org_names = idsData
|
|
|
// _record.date_time = [_record.start_time, _record.end_time]
|
|
|
// console.log("2323", _record);
|
|
|
|
|
|
setCurrentRow(record);
|
|
|
}}
|
|
|
>
|
|
|
编辑
|
|
|
</a>,
|
|
|
<a
|
|
|
key="remove"
|
|
|
onClick={ () => {
|
|
|
handleRemove([{ key: record?.train_id }]); // 调用批量删除函数(如果接口不支持批量需要在service中处理)
|
|
|
setSelectedRows([]);
|
|
|
actionRef.current?.reloadAndRest?.();
|
|
|
}}>
|
|
|
删除
|
|
|
</a>,
|
|
|
],
|
|
|
},
|
|
|
];
|
|
|
/** 获取列数据初始值 */
|
|
|
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>{' '}
|
|
|
项
|
|
|
<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);
|
|
|
//return false;
|
|
|
// values.attachment_json.response.file.response.url
|
|
|
|
|
|
|
|
|
|
|
|
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) => {
|
|
|
console.log('1111', 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, orgTree);
|
|
|
//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, orgTree, 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) => {
|
|
|
console.log(e, 'e');
|
|
|
|
|
|
})
|
|
|
|
|
|
// tree[i].org_id = e.id
|
|
|
// tree[i].org_name = e.name
|
|
|
console.log(values.org_names, 'false values.org_names')
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|