import React, { useState, useEffect, useRef } from 'react'; import styles from './styles.less'; import { Button, Icon } from 'antd'; import ShowItem, { dragEventList, zipImage } from './ShowItem'; import { apiRequest } from '../../utils/request'; import { deepCopy } from '@/webPublic/one_stop_public/utils/myutils'; import { getMessage, getModal, getPopconfirm } from '@/webPublic/one_stop_public/utils/utils'; const Modal = getModal(); const message = getMessage(); const styleList = { modalParentDiv: { display: 'grid', placeItems: 'center', width: '100%', height: '100%', }, modalDiv: { display: 'grid', position: 'relative', overflow: 'auto', backgroundRepeat: 'no-repeat', backgroundPosition: 'center', backgroundSize: 'cover', }, oneSetItem: { position: 'absolute', }, oneSetItemP: { marginBottom: 0, userSelect: 'none', }, draggableIcon: { // position: 'absolute', // left: '10', // top: '10', // color: 'red', zIndex: '10000', border: '1px solid red', }, readOnlyImage: { width: '100%', display: 'grid', placeItems: 'center', }, }; const getContent = (signConfig = [], ratioX) => { let data = deepCopy(signConfig); return JSON.stringify({ objs: data.map(g => { // 1200 的 x => 1500的 x // g.x = Math.ceil(g.x * ratioX); g.y = Math.ceil(g.y * ratioX); if (g.type === 'text') { g.fontSize = Math.ceil(g.fontSize * ratioX); g.y = g.y + (g.offsetY || 0); g.x = g.x + (g.offsetX || 0); } if (g.type === 'image') { g.w = Math.ceil(g.w * ratioX); g.h = Math.ceil(g.h * ratioX); } return g; }), }); }; export default function PictureSignature({ json, disabled, basicUrl, onChangeFile, imageIndex, form, // fileInfo, ...others }) { let imageRef = useRef(); const [fileInfo, setFileInfo] = useState({}); // const [fileInfo, setFileInfo] = useState(fakeFileInfo); const [openEdit, setOpenEdit] = useState(false); const [originSignConfig, setOriginConfig] = useState([]); const [showModal, setShowModal] = useState(false); const [otherProps, setOtherProps] = useState({}); const [imageInfo, setImageInfo] = useState(null); const changeShowModal = () => { if (!showModal) { if (!imageInfo && !disabled) { zipImage(fileInfo.path, fileInfo.name, otherProps?.backgroundImageWidth).then(res => { let image = new Image(); //新建一个img标签(还没嵌入DOM节点) image.src = basicUrl + res; image.onload = () => { // alert(image.width); setImageInfo({ width: image.width, height: image.height, }); }; setFileInfo({ path: res, name: fileInfo.name, originPath: res, }); }); } } setShowModal(!showModal); }; useEffect(() => { if (otherProps?.signConfig && !imageRef?.current) { imageRef.current = true; dragEventList(setOtherProps, otherProps); } }, [otherProps]); useEffect(() => { setFileInfo({ ...others?.fileInfo, }) }, [others?.fileInfo]); useEffect(() => { if (json.otherProps) { try { let func = new Function(json.otherProps); let otherPropsX = func(); setOtherProps(otherPropsX); setOriginConfig([...otherPropsX.signConfig]); } catch (e) { console.log('签章组件 其余配置项出错,没有返回一个正确的值'); return false; } } }, [json.otherProps]); const { ModalProps = {}, signConfig, footerButtons, originButtons, backgroundImageWidth, saveSignConfigValue = '', showImageWidth = 1200, } = otherProps || {}; const deleteSignConfig = key => { let findX = signConfig.findIndex(g => g.key === key); signConfig.splice(findX, 1); setOtherProps({ ...otherProps, signConfig, }); }; const handleClickButton = clickType => { switch (clickType) { case 'startEdit': // 开始签章 if (signConfig && signConfig.length < originSignConfig.length) { setOtherProps({ ...otherProps, signConfig: originSignConfig, }); } setOpenEdit(true); break; case 'confirm': // 确定 onChangeFile({ ...fileInfo }, imageIndex); changeShowModal(); break; case 'save': // 保存签章 Modal.confirm({ title: '是否确认生成签章图片?', content: '生成后图片不能还原,请谨慎操作!', okText: '确定', cancelText: '取消', onOk: () => { let ratioX = backgroundImageWidth / showImageWidth; // 本来是 1500 的 图片 宽度变成了 1200 高度变成了 1200/1500 * imageInfo.height; let content = getContent(otherProps.signConfig, ratioX); apiRequest('/ImageLibApi/merge', { background: fileInfo?.path, content, }).then(res => { if (form && saveSignConfigValue) { form.setFieldsValue({ [saveSignConfigValue]: content, }); } if (res && res.path) { message.success('操作成功'); let newPath = res.path; fileInfo.originPath = fileInfo.path; fileInfo.path = newPath; setFileInfo({ ...fileInfo }); setOpenEdit(false); } }); } }) break; case 'restore': // 还原图片 if (fileInfo.originPath) { fileInfo.path = fileInfo.originPath; setFileInfo({ ...fileInfo }); setOpenEdit(false); } break; default: return true; } }; const Footer = () => { if (disabled) { return null; } if (openEdit) { return footerButtons.map(g => { return ( <Button type={g.type} key={g.key} onClick={() => { handleClickButton(g.clickType); }} > {g.name} </Button> ); }); } else { return originButtons.map(g => { // if (g.clickType === 'startEdit') { // return <Popconfirm // title={<div> // <p>选择签章组件</p> // <div> // {signConfig.map((g) => { // return <p key={g.key}>{g.name}</p> // })} // </div> // </div>} // onConfirm={()=>{ // handleClickButton(g.clickType); // }} // onCancel={()=>{}} // okText="确定" // key={g.key} // cancelText="取消" // > // <Button // type={g.type} // > // {g.name} // </Button> // </Popconfirm> // } return ( <Button type={g.type} key={g.key} onClick={() => { handleClickButton(g.clickType); }} > {g.name} </Button> ); }); } }; if (!fileInfo) { return null; } console.log('签章组件'); return ( <div className={styles.outSideDiv}> {fileInfo && fileInfo?.path && ( <img className={styles.onePic} src={basicUrl + fileInfo?.path} alt={fileInfo.name} onClick={changeShowModal} /> )} {showModal && ( <Modal visible={true} destroyOnClose={true} maskClosable={false} onCancel={changeShowModal} className={styles.ModalClass} footer={<Footer />} title={'图片签章'} width={showImageWidth + 50 + 'px'} bodyStyle={{ minHeight: '700px', overflow: 'auto', padding: '5px', maxWidth: '99%', maxHeight: '99%', }} {...ModalProps} > <div style={styleList.modalParentDiv}> {openEdit && ( // 开启签章功能 <div style={{ ...styleList.modalDiv, backgroundImage: `url(${basicUrl + fileInfo?.path})`, width: showImageWidth, height: (imageInfo && imageInfo.height / (imageInfo.width / showImageWidth)) || 0, }} alt={'拖拽区域'} draggable={false} id={'dropZone'} > {Array.isArray(signConfig) && signConfig.map(g => { return ( <div key={g.key} data-mes={g.key} draggable={false} style={{ ...styleList.oneSetItem, top: g.y, left: g.x, }} > <div style={styleList.draggableIcon} data-mes={g.key} draggable={true}> <div style={{ display: 'inline', }} > <Icon type="close-circle" onClick={e => { if (e && e.stopPropagation) { e.stopPropagation(); e.preventDefault(); deleteSignConfig(g.key); } }} style={{ position: 'absolute', top: 0, right: 0, cursor: 'pointer', color: 'red', }} /> </div> <ShowItem {...g} basicUrl={basicUrl} /> </div> </div> ); })} </div> )} {!openEdit && ( // 不开启签章功能 只是预览图片 <div style={styleList.readOnlyImage} draggable={false}> <img src={basicUrl + fileInfo?.path + `?v=${Math.random()}`} alt={fileInfo.name} draggable={false} style={{ width: `${showImageWidth}px`, height: 'auto', }} /> </div> )} </div> </Modal> )} </div> ); } export function SignArray(props) { const { value, onChange, basicUrl, json, form } = props; let files = value?.files || []; const onChangeFile = (newFielInfo, imageIndex) => { if (newFielInfo && newFielInfo.path) { files[imageIndex] = newFielInfo; value.files = files; onChange(value); } }; return ( <div> {files.map((g, index) => { return ( <PictureSignature json={json} basicUrl={basicUrl} fileInfo={g} form={form} imageIndex={index} onChangeFile={onChangeFile} /> ); })} </div> ); }