2025-12-19 16:40:40 +08:00

599 lines
24 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 供应商分类
import React, { useRef, useState, Suspense } from 'react';
import moment from 'moment'; // 时间相关引用,没有使用可以删除
import { connect } from 'umi';
import Draggable from 'react-draggable';
import ProTable from '@ant-design/pro-table';
import ProForm, { ProFormDatePicker, ProFormDateTimePicker, ProFormDateTimeRangePicker, ProFormDigit, ProFormMoney, ProFormSelect, ProFormText, ProFormTextArea, ProFormTreeSelect, ProFormUploadButton } from '@ant-design/pro-form';
import { MenuFoldOutlined, PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-layout';
import { Button, Col, Drawer, message, Row, Popconfirm, Space, Image, Modal, Form, Switch, Upload, Tooltip, Descriptions, TreeSelect } from 'antd';
import type { CurrentUser } from "umi";
import type { ConnectState } from '@/models/connect';
import type { ActionType, ProColumns } from '@ant-design/pro-table';
import type { FormInstance } from 'antd';
import { handlDeleteAUTOTYPE, handlDeleteUSERDEFINEDTYPE, handlGetNestingAUTOTYPEList, handlGetUSERDEFINEDTYPEList, handlSynchroAUTOTYPE, handlSynchroUSERDEFINEDTYPE } from '../service';
import PageTitleBox from '@/components/PageTitleBox';
import ModalFooter from '../scenicSpotConfig/component/modalFooter';
import { handleSetlogSave } from '@/utils/format';
const beforeUpload = (file: any) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('请上传JPEG、jpg、png格式的图片文件!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片大小不超过 2MB!');
}
return isJpgOrPng && isLt2M;
}
const SupplierClassification: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => {
const { currentUser } = props
const { confirm } = Modal;
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const [currentRow, setCurrentRow] = useState<any>();
const [modalVisible, handleModalVisible] = useState<boolean>();
const [confirmLoading, handleConfirmLoading] = useState<boolean>(false) // 弹出框的内容表单是否在提交
// 分类的树形结构数据
const [typeTreeData, setTypeTreeData] = useState<any>()
// 表单里面的是否预售
const [formPRESALE_TYPE, setFormPRESALE_TYPE] = useState<boolean>(false)
// 弹出框拖动效果
const [bounds, setBounds] = useState<{ left: number, right: number, top: number, bottom: number }>() // 移动的位置
const [disabled, setDraggleDisabled] = useState<boolean>() // 是否拖动
const draggleRef = React.createRef<any>()
// 文件列表
const [fileList, setFileList] = useState<any>([])
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false) // 预览图片
const onDraggaleStart = (event, uiData) => {
const { clientWidth, clientHeight } = window.document.documentElement;
const targetRect = draggleRef.current?.getBoundingClientRect();
if (!targetRect) {
return;
}
setBounds({
left: -targetRect.left + uiData.x,
right: clientWidth - (targetRect.right - uiData.x),
top: -targetRect.top + uiData.y,
bottom: clientHeight - (targetRect.bottom - uiData.y),
});
};
// 定义列表字段内容
const columns: any = [
// {
// title: '上级类别',
// align: 'center',
// width: 150,
// ellipsis: true,
// dataIndex: 'USERDEFINEDTYPE_PID',
// hideInSearch: true,
// hideInDescriptions: true,
// },
{
dataIndex: 'AUTOTYPE_NAME',
title: '供应商名称',
align: 'center',
width: 300,
ellipsis: true,
hideInSearch: true,
hideInDescriptions: true,
render: (_, record) => {
return record?.AUTOTYPE_NAME ? <a onClick={() => {
setCurrentRow({ ...record });
handleModalVisible(true);
}}>
{record?.AUTOTYPE_NAME}
</a> : "-"
}
},
{
dataIndex: 'AUTOTYPE_CODE',
title: '类别代码',
align: 'center',
width: 120,
ellipsis: true,
hideInSearch: true,
},
{
dataIndex: 'AUTOTYPE_INDEX',
title: '类别索引',
align: 'center',
width: 120,
ellipsis: true,
hideInSearch: true,
},
// {
// dataIndex: 'AUTOTYPE_VALID',
// title: '有效状态',
// align: 'center',
// width: 120,
// ellipsis: true,
// valueType: "select",
// // valueEnum: {
// // "1": "有效",
// // "0": "无效"
// // },
// fieldProps: {
// options: [
// { label: '有效', value: "1" },
// { label: '无效', value: "0" }
// ]
// },
// initialValue: "1"
// },
{
dataIndex: 'OWNERUNIT_NAME',
title: '业主单位',
align: 'center',
width: 180,
ellipsis: true,
hideInSearch: true,
},
{
dataIndex: 'OPERATE_DATE',
title: '配置时间',
align: 'center',
width: 180,
ellipsis: true,
hideInSearch: true,
render: (_, record) => {
return record?.OPERATE_DATE ? moment(record?.OPERATE_DATE).format('YYYY-MM-DD HH:mm:ss') : ""
}
},
// {
// dataIndex: 'option',
// title: '操作',
// width: 100,
// ellipsis: true,
// valueType: 'option',
// align: 'center',
// hideInSearch: true,
// render: (_, record) => {
// return (
// <Space>
// <a
// onClick={() => {
// setCurrentRow({ ...record });
// handleModalVisible(true);
// }}
// >
// 编辑
// </a>
// <Popconfirm
// title="确认删除该商品自定义类别列表信息吗?"
// onConfirm={async () => {
// handelDelete(record.AUTOTYPE_ID);
// }}
// >
// <a>删除</a>
// </Popconfirm>
// </Space>
// );
// },
// },
];
// 预览上传后的图片
const handlePreview = async () => {
setFileList(fileList)
setImagePreviewVisible(true)
};
const handleChangePreview = (val: any) => {
setImagePreviewVisible(val)
}
// 删除商品类别
const handelDelete = async (id: any) => {
const req: any = {
AUTOTYPEId: id
}
const result = await handlDeleteAUTOTYPE(req)
if (result.Result_Code !== 100) {
message.error(`${result.Result_Desc}` || `${result.Result_Code}:删除失败`);
} else {
message.success('删除成功!');
actionRef.current?.reload()
handleSetlogSave(`删除【${currentRow?.AUTOTYPE_NAME}`)
handleConfirmLoading(false)
handleModalVisible(false)
setFormPRESALE_TYPE(false)
setFileList([])
}
}
// 同步商品列表
const handleAddUpdate = async (res: any) => {
let req: any = {}
if (currentRow?.AUTOTYPE_ID) {
req = {
...currentRow,
...res,
AUTOTYPE_TYPEID: 4000,
// PRESALE_STARTTIME: res.PRESALE_TIME && res.PRESALE_TIME.length > 0 ? res.PRESALE_TIME[0] : "",
// PRESALE_ENDTIME: res.PRESALE_TIME && res.PRESALE_TIME.length > 0 ? res.PRESALE_TIME[1] : "",
// PROVINCE_CODE: currentUser?.ProvinceCode,
AUTOTYPE_VALID: 1,
STAFF_ID: currentUser?.ID,
STAFF_NAME: currentUser?.Name,
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
}
} else {
req = {
...res,
AUTOTYPE_TYPEID: 4000,
// PRESALE_STARTTIME: res.PRESALE_TIME && res.PRESALE_TIME.length > 0 ? res.PRESALE_TIME[0] : "",
// PRESALE_ENDTIME: res.PRESALE_TIME && res.PRESALE_TIME.length > 0 ? res.PRESALE_TIME[1] : "",
AUTOTYPE_VALID: 1,
PROVINCE_CODE: currentUser?.ProvinceCode,
STAFF_ID: currentUser?.ID,
STAFF_NAME: currentUser?.Name,
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
// USERDEFINEDTYPE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
}
}
const data = await handlSynchroAUTOTYPE(req)
handleConfirmLoading(false)
if (data.Result_Code === 100) {
message.success("新增成功!")
handleSetlogSave(`${currentRow?.AUTOTYPE_ID ? '同步' : '新增'}${data.Result_Data?.AUTOTYPE_NAME}`)
setCurrentRow(undefined)
formRef?.current?.resetFields()
handleModalVisible(false)
setFormPRESALE_TYPE(false)
setFileList([])
actionRef.current?.reload()
} else {
message.error(data.Result_Desc)
}
}
// 找出对应的id 在第几层的方法
const findLevelById = (tree: any, targetId: any, level = 0) => {
for (const node of tree) {
// 找到当前节点
if (node.AUTOTYPE_ID === targetId) {
return level;
}
// 递归查找子节点
if (node.children && node.children.length > 0) {
const childLevel: any = findLevelById(node.children, targetId, level + 1);
if (childLevel !== -1) {
return childLevel;
}
}
}
if (targetId === -1) {
return -1
}
return 0; // 暂时返回 -1用来区分未找到
}
return (
<PageContainer header={{
title: '',
breadcrumb: {}
}}>
<ProTable
style={{ height: 'calc(100vh - 135px)', background: '#fff' }}
scroll={{ y: 'calc(100vh - 410px)' }}
rowKey={(record) => {
return `${record?.USERDEFINEDTYPE_PID}-${record?.AUTOTYPE_ID}`
}}
formRef={formRef}
headerTitle={<PageTitleBox props={props} />} // 列表表头
actionRef={actionRef}
search={{ span: 6, labelWidth: 'auto' }}
bordered
// 请求数据
request={async (params, sorter) => {
const req = {
OWNERUNIT_ID: currentUser?.OwnerUnitId,
PROVINCE_CODE: "",
AUTOTYPE_TYPEID: 4000,
AUTOTYPE_VALID: 1
// SearchKey: ""
}
console.log('reqreq', req);
const data = await handlGetNestingAUTOTYPEList(req);
console.log('datadatadatadatadata', data);
if (data && data.length > 0) {
handleSetlogSave(`点击查询按钮`)
setTypeTreeData(data)
return { data: data, success: true, total: data.length }
}
return { data: [], success: true }
}}
columns={columns}
toolbar={{
actions: [
// 新增按钮
<Button
key="new"
icon={<PlusOutlined />}
type="primary"
onClick={() => {
handleModalVisible(true);
}}
>
</Button>,
],
}}
/>
{/* 图片预览组件 */}
{fileList && fileList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
handleChangePreview(vis)
}
}}>
{
fileList.map((n) => <Image src={n.url} key={n.url} />)
}
</Image.PreviewGroup>
</div>}
<Modal
title={
<div
className='supplierClassBox'
style={{
width: '100%',
cursor: 'move',
}}
onMouseOver={() => {
if (disabled) {
setDraggleDisabled(false)
}
}}
onMouseOut={() => {
setDraggleDisabled(true)
}}
onFocus={() => { }}
onBlur={() => { }}
>
{currentRow ? '更新供应商类别' : '新建供应商类别'}
</div>
}
destroyOnClose={true}
width={900}
bodyStyle={{
height: '700px', // 你可以根据需要调整高度
overflowY: 'auto',
}}
visible={modalVisible}
confirmLoading={confirmLoading}
afterClose={() => {
formRef.current?.resetFields();
setCurrentRow(undefined);
}}
onCancel={() => {
handleConfirmLoading(false)
handleModalVisible(false)
setFormPRESALE_TYPE(false)
setFileList([])
}}
onOk={async () => { // 提交框内的数据
formRef?.current?.validateFields().then(() => {
handleConfirmLoading(true)
formRef?.current?.submit()
})
}}
footer={<ModalFooter
confirmLoading={confirmLoading}
hideDelete={!currentRow?.AUTOTYPE_ID}
handleDelete={async () => {
handleConfirmLoading(true)
await handelDelete(currentRow?.AUTOTYPE_ID)
}}
handleCancel={() => {
handleConfirmLoading(false)
handleModalVisible(false)
setFormPRESALE_TYPE(false)
setFileList([])
}}
handleOK={() => {
formRef?.current?.validateFields().then(() => {
handleConfirmLoading(true)
formRef?.current?.submit()
})
}}
/>}
modalRender={(modal) => {
return <Draggable
disabled={disabled}
bounds={bounds}
onStart={(event, uiData) => onDraggaleStart(event, uiData)}
handle={'.supplierClassBox'}
>
<div ref={draggleRef}>{modal}</div>
</Draggable>
}}
>
<ProForm
layout={'horizontal'}
formRef={formRef}
autoFocusFirstInput
submitter={false}
labelCol={{ style: { width: 80 } }}
preserve={false}
initialValues={currentRow ? {
...currentRow,
OPERATE_DATE: moment(currentRow?.OPERATE_DATE).format('YYYY-MM-DD HH:mm:ss'),
} : {
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
OWNERUNIT_NAME: currentUser?.OwnerUnitName,
AUTOTYPE_VALID: 1
}}
onFinish={async (values) => {
let newValue = { ...values };
// 领导叫你别加 他自己加 2025-12-02
// const level = findLevelById(typeTreeData, newValue.AUTOTYPE_PID)
// console.log('typeTreeDatatypeTreeDatatypeTreeData', typeTreeData);
if (currentRow) {
// 编辑数据
newValue = { ...values, AUTOTYPE_ID: currentRow.AUTOTYPE_ID };
//, AUTOTYPE_LEVEL: level + 1
}
// else {
// newValue = { ...values, AUTOTYPE_LEVEL: level + 1 };
// }
// 如果有开关,要把开关的代码写进去
await handleAddUpdate(newValue);
handleConfirmLoading(false)
setFormPRESALE_TYPE(false)
}}
>
<Row gutter={8}>
<Col span={12}>
<ProFormTreeSelect
name="AUTOTYPE_PID"
label="上级类别"
request={async () => {
// 获取数据
let list: any[] = [];
if (typeTreeData && typeTreeData.length > 0) {
list = [{ AUTOTYPE_NAME: "默认类别", AUTOTYPE_ID: -1 }, ...typeTreeData];
} else {
const req = {
OWNERUNIT_ID: currentUser?.OwnerUnitId,
PROVINCE_CODE: "",
GOODSTYPE: 1000,
};
let data = await handlGetUSERDEFINEDTYPEList(req);
if (data.List && data.List.length > 0) {
data.List.unshift({ AUTOTYPE_NAME: "默认类别", AUTOTYPE_ID: -1 });
setTypeTreeData(data.List);
list = data.List;
} else {
list = [{ AUTOTYPE_NAME: "默认类别", AUTOTYPE_ID: -1 }];
}
}
// 递归禁用当前节点
const disableCurrent = (nodes: any[]): any[] =>
nodes.map(node => {
const disabled = node.AUTOTYPE_ID === currentRow?.AUTOTYPE_ID;
return {
...node,
disabled,
children: node.children ? disableCurrent(node.children) : undefined,
};
});
return disableCurrent(list);
}}
fieldProps={{
fieldNames: {
label: 'AUTOTYPE_NAME',
value: 'AUTOTYPE_ID',
children: 'children'
},
showSearch: true,
filterTreeNode: (input, node) =>
(node.AUTOTYPE_NAME || '').toLowerCase().includes(input.toLowerCase())
}}
rules={[
{
required: true,
message: "请选择上级类别"
}
]}
/>
</Col>
<Col span={12}>
<ProFormText
name="AUTOTYPE_NAME"
label="类别名称"
rules={[
{
required: true,
message: "请输入类别名称"
}
]}
/>
</Col>
<Col span={12}>
<ProFormDigit
name="AUTOTYPE_INDEX"
label="类别索引"
rules={[
{
required: true,
message: "请输入类别索引"
}
]}
/>
</Col>
{/* <Col span={12}>
<ProFormSelect
name="AUTOTYPE_VALID"
label="有效状态"
options={[{ label: "有效", value: 1 }, { label: "无效", value: 0 }]}
rules={[
{
required: true,
message: "请选择有效状态"
}
]}
/>
</Col> */}
<Col span={12}>
<ProFormText
name="OPERATE_DATE"
label="添加时间"
disabled
/>
</Col>
<Col span={12}>
<ProFormText
name="OWNERUNIT_NAME"
label="业主单位"
disabled
/>
</Col>
<Col span={24}>
<ProFormTextArea
name="AUTOTYPE_DESC"
label="备注"
/>
</Col>
</Row>
</ProForm>
</Modal>
</PageContainer>
);
};
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(SupplierClassification);