import { Form, Modal, Row, Col, Input, DatePicker, Icon, Button, Divider, Steps, Select, TreeSelect, InputNumber, Upload, Space, Radio, message, } from 'antd'; import ModuleTitle from '../../../components/ModuleTitle/moduleTitle'; import { useEffect, useMemo, useState } from 'react'; import { queryAuditByCode, queryCompany, queryContractCode, queryOAReCall, querySupplierList, } from '@/services/contract'; import { queryDepsV2 } from '@/services/approval'; import { useModel, useRequest } from '@umijs/max'; import { CloudUploadOutlined } from '@ant-design/icons'; import styles from '../index.less'; import dayjs from 'dayjs'; import { advanceSubmitNextNode, audit } from '@/services/boom'; import AuditSteps from './AuditSteps'; import FileViewerModal from '@/components/FileViewerNew'; export const Type = { add: 0, //新增 detail: 1, //详情 cancel: 2, //作废 save: 3, //保存草稿 }; export const StatusText = [ '', '待审核', '审核拒绝', '已存档', '作废待审核', '作废拒绝', '已作废', ]; export const Status = { ReCall: -1, None: 0, Checking: 1, CheckReject: 2, CheckSuccess: 3, CalChecking: 4, CalCheckReject: 5, CalCheckSuccess: 6, }; const ContractModal = (props) => { const [form] = Form.useForm(); const { initialState } = useModel('@@initialState'); const user = initialState?.user || {}; const { userList, run: userListRun } = useModel('userList'); const { depList, run: depListRun } = useModel('depList'); const [auditList, setAuditList] = useState([]); const [fileViewerVisible, setFileViewerVisible] = useState(false); const [fileViewerData, setFileViewerData] = useState(); const FORMAT = 'YYYY-MM-DD'; const { detail: data, type, visible, projectList = [], handleOk, handleCancel, parent_id, handlerReCall, } = props; const title = type == Type.add ? '新增' : type == Type.cancel ? '作废' : '详情'; const archivesOptions = [ { Name: '财务部', ID: '财务部', }, { Name: '行政部', ID: '行政部', }, ]; const [companyDepList, setCompanyDepList] = useState(depList || []); const [archivesDepList, setArchivesDepList] = useState(archivesOptions); const [dealDisable, setDealDisable] = useState(false); const [attachData, setAttachData] = useState({ attach: [], attach_extend: [], }); const company = Form.useWatch('company_id', form); const project_name = Form.useWatch('project_name', form); const archives_dep = Form.useWatch('archives_dep', form); // 当为审核拒绝状态时,点击编辑按钮可以时为强制修改状态 const [forceModify, setForceModify] = useState(false); //是否补充协议,是的话需要填合同编号 const is_supplement = Form.useWatch('is_supplement', form); //请求合同编号用 const dep_id = Form.useWatch('dep_id', form); const parent_code = Form.useWatch('parent_code', form); //审批流拼接 const formData = [ { name: '是否本部', id: 'DDSelectField_4ad8bda8-60ce-428b-88a3-bf1a18c24a50', type: 'DDSelectField', value: ['是'], }, { name: '合同归档部门', id: 'DDSelectField_3b661423-9fb8-4498-9eda-bcadf2d98473', type: 'DDSelectField', value: ['财务部'], }, { name: '合同编码', id: 'TextField_f73531d8-c2c0-4769-a8ef-68b2eae2dc3a', type: 'TextField', value: ['1'], }, { name: '提审类型', id: 'DDSelectField_bed77d5f-d02c-4f1d-98bf-0638245a3331', type: 'DDSelectField', value: ['1'], }, ]; //计算审批流数据 const advance = { flow_id: 47, form_list: null, formComponentValues: '', }; //旧审批流兼容 const oldAuditList = { OaAuditList: [ { id: 14, auditor: 7, AuditorUser: { UserName: 'admin', CName: '管理员', IsSuper: true, ID: 7, }, seq: 1, oa_id: 7, seq_name: '审批1', }, ], audit_status: 3, current_seq: 1, }; const { data: companyData, run: runCompany } = useRequest(queryCompany); // 新建合同时,选择本部时,需要用另一个接口请求部门数据 const { data: companyDeps, run: runCompanyDeps } = useRequest(queryDepsV2, { manual: true, formatResult: (response) => { console.log(response.data); return response.data; }, }); //填写表单时计算审批流接口 const { run: runAuditList } = useRequest( (data) => advanceSubmitNextNode(data), { debounceInterval: 500, manual: true, formatResult(res) { const list = res.data[0]?.map((item) => { const name = userList?.find( (user) => user.ID == item[0].value, )?.CName; return { ...item[0], name }; }); setAuditList( res.data[0]?.map((item) => { const name = userList?.find( (user) => user.ID == item[0].value, )?.CName; return { ...item[0], name }; }), ); }, }, ); //计算合同编号接口 const { run: runCode } = useRequest((data) => queryContractCode(data), { manual: true, onSuccess: (data) => { form.setFieldsValue({ code: data?.code, }); }, }); //供应商列表 const { data: supplierList = [], loading } = useRequest(querySupplierList, { defaultParams: [ { project_id: 1, is_super: user?.IsSuper, created_by: user?.CName, page_size: 99999, }, ], formatResult: (res) => { return res?.data?.list ? res?.data.list.map((item) => { return { ...item, Name: item.name }; }) : []; }, }); //获取OA 归档审批列表 const { data: auditData, run: runAudit } = useRequest( (data) => queryAuditByCode({ ...data, extend_type: 0 }), { manual: true, formatResult: (res) => { if (res?.data) { return res.data; } else { if (data?.status == Status.CheckReject) { return { ...oldAuditList, audit_status: 2 }; } return oldAuditList; } }, }, ); //获取OA 作废审批列表 const { data: auditCelData, run: runCalAudit } = useRequest( (data) => queryAuditByCode({ ...data, extend_type: 1 }), { manual: true, formatResult: (res) => { if (res?.data) { return res.data; } else { if (data?.status == Status.CalCheckReject) { return { ...oldAuditList, audit_status: 2 }; } return oldAuditList; } }, }, ); useEffect(() => { if (!visible) { setDealDisable(false); setAuditList([]); setCompanyDepList([]); setArchivesDepList([]); } else { userListRun(); depListRun(); runCompany(); runCompanyDeps(); } }, [visible]); useEffect(() => { //兼容之前选择的所属部门,用的现在的接口匹配不到部门显示数字的问题 if (data?.company_id) { const deps = getDepItemById(data?.company_id)?.children; setCompanyDepList(deps); } }, [data, depList]); useEffect(() => { form.resetFields(); if (data?.status >= Status.Checking) runAudit({ extend_code: data.code }); if (data?.status >= Status.CalChecking) runCalAudit({ extend_code: data.code }); let result = { attach: [], attach_extend: [] }; if (data?.attach) { let att = JSON.parse(data.attach); result.attach = att.map((item, idx) => { return { ...item, uid: idx, status: 'done' }; }); } if (data?.attach_extend) { let att = JSON.parse(data.attach_extend); result.attach_extend = att.map((item, idx) => { return { ...item, uid: idx, status: 'done' }; }); } setAttachData(result); }, [data]); const isSuper = useMemo(() => { if ( type == Type.add || type == Type.cancel || data?.status == Status.ReCall || (data?.status == Status.CheckReject && forceModify) ) return true; }, [data, type, forceModify]); useEffect(() => { if ( type !== Type.add && data?.status !== Status.ReCall && data?.status !== Status.CheckReject ) return; const newCompony = company || data?.company_id; //recall状态时compony是空, 需要用data?.company_id if (!newCompony) { setCompanyDepList([]); setArchivesDepList([]); return; } const deps = getDepItemById(newCompony)?.children; deps ? setCompanyDepList(deps) : setCompanyDepList([]); const item = companyData?.find((item) => item.ID == newCompony); if (item?.Flag == 1) { //公司为本部 经办人为自己并不可编辑 合同存档部门从财务和行政部选 setDealDisable(false); setArchivesDepList(archivesOptions); form.setFieldsValue({ deal_by: user?.CName }); // 公司为本部时,使用另一个接口获取部门数据 companyDeps ? setCompanyDepList(companyDeps) : setCompanyDepList([]); } else { //公司为分子公司 经办人为手动输入 合同存档部门从所选分子公司的子部门选择 setDealDisable(true); setArchivesDepList(deps); form.setFieldsValue({ deal_by: '' }); } }, [company, data, forceModify]); //获取合同编号逻辑 只有新增才请求 useEffect(() => { if (type !== Type.add || !company || !dep_id) return; const item = companyData?.find((item) => item.ID == company); const dep_code = getDepItemById(dep_id)?.Code; if (item) { let params = { company_id: item.ID, company_code: item.Code, dep_code, parent_code, }; runCode(params); } }, [dep_id, parent_code]); //获取审批流逻辑 useEffect(() => { if ( type !== Type.add && data?.status !== Status.ReCall && data?.status !== Status.CheckReject ) return; const param = { ...advance }; let formValues = []; const item = companyData?.find((item) => item.ID == company); formValues.push({ ...formData[0], value: item?.Flag == 1 ? ['是'] : ['否'], }); if (archives_dep) formValues.push({ ...formData[1], value: [archives_dep] }); param.formComponentValues = formValues; runAuditList(param); }, [company, archives_dep]); //根据项目名称填充项目编号逻辑 useEffect(() => { if ( type !== Type.add && data?.status !== Status.ReCall && data?.status !== Status.CheckReject ) return; const project_code = projectList?.find( (item) => item.project_name == project_name, )?.project_full_code; if (project_code) { form.setFieldsValue({ project_code }); } else { form.setFieldsValue({ project_code: '' }); } }, [project_name]); const supplyList = useMemo(() => { return companyData ? [...companyData, ...supplierList] : supplierList; }, [companyData, supplierList]); const disableds = useMemo(() => { // 当合同处于审核拒绝状态时,通过修改按钮可强制修改合同并重新进入审核 if (forceModify && data?.status == Status.CheckReject) { return { contract: false, recall: false }; } // if (data?.status == Status.ReCall) { // return { contract: false, recall: true }; // } if (data?.status > Status.None) { return { contract: true, recall: true }; } return { contract: false, recall: false }; }, [visible, forceModify]); const UploadProps = { action: `/api/contract/v1/attach`, headers: { 'JWT-TOKEN': localStorage.getItem('JWT-TOKEN'), }, defaultFileList: attachData?.attach, onChange({ file, fileList }) { if (file.status !== 'uploading') { const list = fileList.map((item) => item.response?.data?.attach); form.setFieldsValue({ attach: list }); } }, }; const UploadPropsExtend = { action: `/api/contract/v1/attach`, headers: { 'JWT-TOKEN': localStorage.getItem('JWT-TOKEN'), }, defaultFileList: attachData?.attach_extend, onChange({ file, fileList }) { if (file.status !== 'uploading') { const list = fileList.map((item) => item.response?.data?.attach); form.setFieldsValue({ attach_extend: list }); } }, }; //获取提交审批流所需form字段 const getAuditData = (values, type) => { // 合同类型type "1" 归档 “2”作废 const flag = companyData?.find((item) => item.ID == values.company)?.Flag == 1 ? '是' : '否'; const newValues = [[flag], [values.archives_dep], [values.code], [type]]; const form = formData.map((item, index) => { return { ...item, value: newValues[index] }; }); return form; }; const handleSubmit = () => { form.validateFields().then((values) => { if (type == Type.add) { const form = getAuditData(values, '1'); const audit_list = auditList.map((item) => item.value); values.effect_on = dayjs(values.effect_on).format(FORMAT); values.created_on = values.created_on || dayjs().format(FORMAT); if (parent_id) values.parent_id = parent_id; if (values.amount || values.amount == 0) values.amount = values.amount + ''; if (values.attach) values.attach = JSON.stringify(values.attach); if (values.attach_extend) values.attach_extend = JSON.stringify(values.attach_extend); values.party_c = values.party_c?.join(','); const companyItem = companyData?.find( (item) => item.ID == values.company_id, ); values.company_name = companyItem.Name; values.company_code = companyItem.Code; const depItem = getDepItemById(values.dep_id); values.dep_name = depItem?.Name; values.dep_code = depItem?.Code; values.created_by = user?.ID; handleOk(values, Type.add, form, audit_list); } else if (type == Type.cancel) { const form = getAuditData(values, '2'); const audit_list = auditData?.OaAuditList?.map((item) => item?.auditor); let result = { id: data?.id, cancel_desc: values.cancel_desc, code: data?.code, }; handleOk(result, Type.cancel, form, audit_list); } else if ( data?.status == Status.ReCall || data?.status == Status.CheckReject ) { const form = getAuditData(values, '1'); const audit_list = auditList.map((item) => item.value); values.effect_on = dayjs(values.effect_on).format(FORMAT); values.created_on = values.created_on || dayjs().format(FORMAT); if (values.amount || values.amount == 0) values.amount = values.amount + ''; if (values.attach) values.attach = JSON.stringify(values.attach); if (values.attach_extend) values.attach_extend = JSON.stringify(values.attach_extend); values.party_c = values.party_c?.join(','); const companyItem = companyData?.find( (item) => item.ID == values.company_id, ); values.company_name = companyItem.Name; values.company_code = companyItem.Code; const depItem = getDepItemById(values.dep_id); values.dep_name = depItem?.Name; values.dep_code = depItem?.Code; values.created_by = user?.ID; values.id = data?.id; handleOk(values, Type.add, form, audit_list); } }); }; const handleSaveDraft = () => { let values = form.getFieldsValue(); if (!values.name) { message.error('请填写合同名称!'); return; } Object.keys(values).forEach((key) => { if (Array.isArray(values[key])) values[key].length == 0 ? delete values[key] : (values[key] = JSON.stringify(values[key])); }); if (values.effect_on) values.effect_on = dayjs(values.effect_on).format(FORMAT); const params = { name: values.name, content: JSON.stringify(values), }; if (data?.id) params.id = data?.id; handleOk(params, Type.save); }; const getDepItemById = (id) => { const fun = (list) => { for (let i = 0; i < list.length; i++) { let item = list[i]; if (item.ID == id) { return item; } else if (item.children?.length > 0) { let res = fun(item.children); if (res) return res; } } }; return fun(depList); }; const handlePreViewSingle = (data) => { if (!data) return; const arr = data.name.split('.'); const type = arr[arr.length - 1]; const dataItem = { url: data.url, name: data.name, type }; setFileViewerData(dataItem); setFileViewerVisible(true); }; const renderFooter = () => { return ( {data?.status == Status.Checking && ( )} {data?.status == Status.CheckReject && !forceModify && ( )} {type == Type.add && ( )} ); }; return ( <>
{ return { label: item.Name, value: item.Name, }; })} disabled={disableds.contract} /> { return { label: item.Name, value: item.Name, }; })} disabled={disableds.contract} /> {type == Type.add || data?.status == Status.ReCall || forceModify ? ( ) : ( )} )} {type == Type.cancel && ( 确认作废该合同,作废提交后无法撤回 )} {data?.status >= Status.CalChecking && ( <>
)} {(type == Type.add || data?.status == Status.ReCall || forceModify) && auditList.length > 0 && ( <>
{ return { title: `审批${index + 1}`, description: `审批人:${item.name}`, }; })} />
)}
{ setFileViewerVisible(false); }} /> ); }; export default ContractModal;