PictureSignature.js 11.5 KB
Newer Older
1
import React, { useState, useEffect, useRef } from 'react';
钟是志's avatar
钟是志 committed
2
import styles from './styles.less';
3
import { Button, Icon } from 'antd';
4 5 6
import ShowItem, { dragEventList, zipImage } from './ShowItem';
import { apiRequest } from '../../utils/request';
import { deepCopy } from '@/webPublic/one_stop_public/utils/myutils';
7
import { getMessage, getModal, getPopconfirm } from '@/webPublic/one_stop_public/utils/utils';
钟是志's avatar
钟是志 committed
8

钟是志's avatar
钟是志 committed
9
const Modal = getModal();
10
const message = getMessage();
钟是志's avatar
钟是志 committed
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
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',
  },
33 34 35 36 37
  draggableIcon: {
    // position: 'absolute',
    // left: '10',
    // top: '10',
    // color: 'red',
钟是志's avatar
钟是志 committed
38
    zIndex: '10000',
39
    border: '1px solid red',
钟是志's avatar
钟是志 committed
40 41 42 43 44 45
  },
  readOnlyImage: {
    width: '100%',
    display: 'grid',
    placeItems: 'center',
  },
钟是志's avatar
钟是志 committed
46 47
};

48 49
const getContent = (signConfig = [], ratioX) => {
  let data = deepCopy(signConfig);
50 51
  return JSON.stringify({
    objs: data.map(g => {
52 53
      // 1200 的 x => 1500的 x
      //
钟是志's avatar
钟是志 committed
54 55
      g.x = Math.ceil(g.x * ratioX);
      g.y = Math.ceil(g.y * ratioX);
56 57 58

      if (g.type === 'text') {
        g.fontSize = Math.ceil(g.fontSize * ratioX);
59 60
        g.y = g.y + (g.offsetY || 0);
        g.x = g.x + (g.offsetX || 0);
61
      }
62
      if (g.type === 'image') {
63 64 65 66 67 68 69 70
        g.w = Math.ceil(g.w * ratioX);
        g.h = Math.ceil(g.h * ratioX);
      }
      return g;
    }),
  });
};

钟是志's avatar
钟是志 committed
71
export default function PictureSignature({
72 73 74 75 76 77 78 79 80
  json,
  disabled,
  basicUrl,
  onChangeFile,
  imageIndex,
  form,
  // fileInfo,
  ...others
}) {
钟是志's avatar
钟是志 committed
81
  let imageRef = useRef();
钟是志's avatar
钟是志 committed
82
  const [fileInfo, setFileInfo] = useState({});
钟是志's avatar
钟是志 committed
83
  // const [fileInfo, setFileInfo] = useState(fakeFileInfo);
钟是志's avatar
钟是志 committed
84
  const [openEdit, setOpenEdit] = useState(false);
85
  const [originSignConfig, setOriginConfig] = useState([]);
钟是志's avatar
钟是志 committed
86 87
  const [showModal, setShowModal] = useState(false);
  const [otherProps, setOtherProps] = useState({});
钟是志's avatar
钟是志 committed
88
  const [imageInfo, setImageInfo] = useState(null);
钟是志's avatar
钟是志 committed
89
  const changeShowModal = () => {
90
    if (!showModal) {
钟是志's avatar
钟是志 committed
91
      if (!imageInfo && !disabled) {
92 93 94 95 96 97 98 99
        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,
钟是志's avatar
钟是志 committed
100
            });
101 102 103 104 105
          };
          setFileInfo({
            path: res,
            name: fileInfo.name,
            originPath: res,
钟是志's avatar
钟是志 committed
106
          });
107
        });
钟是志's avatar
钟是志 committed
108 109
      }
    }
钟是志's avatar
钟是志 committed
110 111 112
    setShowModal(!showModal);
  };

钟是志's avatar
钟是志 committed
113 114


钟是志's avatar
钟是志 committed
115 116 117 118 119 120 121
  useEffect(() => {
    if (otherProps?.signConfig && !imageRef?.current) {
      imageRef.current = true;
      dragEventList(setOtherProps, otherProps);
    }
  }, [otherProps]);

钟是志's avatar
钟是志 committed
122 123 124 125 126 127
  useEffect(() => {
    setFileInfo({
      ...others?.fileInfo,
    })
  }, [others?.fileInfo]);

钟是志's avatar
钟是志 committed
128 129 130 131 132 133
  useEffect(() => {
    if (json.otherProps) {
      try {
        let func = new Function(json.otherProps);
        let otherPropsX = func();
        setOtherProps(otherPropsX);
134
        setOriginConfig([...otherPropsX.signConfig]);
钟是志's avatar
钟是志 committed
135 136 137 138 139 140
      } catch (e) {
        console.log('签章组件 其余配置项出错,没有返回一个正确的值');
        return false;
      }
    }
  }, [json.otherProps]);
141
  const {
钟是志's avatar
钟是志 committed
142
    ModalProps = {},
143 144 145 146 147 148
    signConfig,
    footerButtons,
    originButtons,
    backgroundImageWidth,
    saveSignConfigValue = '',
    showImageWidth = 1200,
钟是志's avatar
钟是志 committed
149
  } = otherProps || {};
150 151 152 153 154 155 156 157
  const deleteSignConfig = key => {
    let findX = signConfig.findIndex(g => g.key === key);
    signConfig.splice(findX, 1);
    setOtherProps({
      ...otherProps,
      signConfig,
    });
  };
158
  const handleClickButton = clickType => {
钟是志's avatar
钟是志 committed
159
    switch (clickType) {
钟是志's avatar
钟是志 committed
160
      case 'startEdit': // 开始签章
161 162 163 164 165 166
        if (signConfig && signConfig.length < originSignConfig.length) {
          setOtherProps({
            ...otherProps,
            signConfig: originSignConfig,
          });
        }
钟是志's avatar
钟是志 committed
167 168
        setOpenEdit(true);
        break;
钟是志's avatar
钟是志 committed
169
      case 'confirm': // 确定
170
        onChangeFile({ ...fileInfo }, imageIndex);
钟是志's avatar
钟是志 committed
171 172
        changeShowModal();
        break;
钟是志's avatar
钟是志 committed
173
      case 'save': // 保存签章
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
        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);
              }
            });
          }
钟是志's avatar
钟是志 committed
201
        })
202 203


钟是志's avatar
钟是志 committed
204
        break;
钟是志's avatar
钟是志 committed
205
      case 'restore': // 还原图片
钟是志's avatar
钟是志 committed
206 207
        if (fileInfo.originPath) {
          fileInfo.path = fileInfo.originPath;
208
          setFileInfo({ ...fileInfo });
钟是志's avatar
钟是志 committed
209 210
          setOpenEdit(false);
        }
钟是志's avatar
钟是志 committed
211 212 213 214
        break;
      default:
        return true;
    }
215
  };
钟是志's avatar
钟是志 committed
216 217

  const Footer = () => {
钟是志's avatar
钟是志 committed
218 219 220
    if (disabled) {
      return null;
    }
钟是志's avatar
钟是志 committed
221 222 223
    if (openEdit) {
      return footerButtons.map(g => {
        return (
224 225 226 227 228 229
          <Button
            type={g.type}
            key={g.key}
            onClick={() => {
              handleClickButton(g.clickType);
            }}
钟是志's avatar
钟是志 committed
230 231 232 233 234 235 236
          >
            {g.name}
          </Button>
        );
      });
    } else {
      return originButtons.map(g => {
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
        // 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>
        // }
钟是志's avatar
钟是志 committed
262
        return (
263 264 265 266 267 268
          <Button
            type={g.type}
            key={g.key}
            onClick={() => {
              handleClickButton(g.clickType);
            }}
钟是志's avatar
钟是志 committed
269 270 271 272 273 274 275
          >
            {g.name}
          </Button>
        );
      });
    }
  };
钟是志's avatar
钟是志 committed
276 277 278
  if (!fileInfo) {
    return null;
  }
279
  console.log('签章组件');
钟是志's avatar
钟是志 committed
280
  return (
281
    <div className={styles.outSideDiv}>
钟是志's avatar
钟是志 committed
282 283 284 285 286 287 288 289
      {fileInfo && fileInfo?.path && (
        <img
          className={styles.onePic}
          src={basicUrl + fileInfo?.path}
          alt={fileInfo.name}
          onClick={changeShowModal}
        />
      )}
钟是志's avatar
钟是志 committed
290
      {showModal && (
钟是志's avatar
钟是志 committed
291 292 293 294 295 296
        <Modal
          visible={true}
          destroyOnClose={true}
          maskClosable={false}
          onCancel={changeShowModal}
          className={styles.ModalClass}
297
          footer={<Footer />}
钟是志's avatar
钟是志 committed
298
          title={'图片签章'}
299
          width={showImageWidth + 50 + 'px'}
钟是志's avatar
钟是志 committed
300
          bodyStyle={{
钟是志's avatar
钟是志 committed
301
            minHeight: '700px',
钟是志's avatar
钟是志 committed
302
            overflow: 'auto',
钟是志's avatar
钟是志 committed
303
            padding: '5px',
钟是志's avatar
钟是志 committed
304 305
            maxWidth: '99%',
            maxHeight: '99%',
钟是志's avatar
钟是志 committed
306 307 308
          }}
          {...ModalProps}
        >
钟是志's avatar
钟是志 committed
309
          <div style={styleList.modalParentDiv}>
钟是志's avatar
钟是志 committed
310 311 312
            {openEdit && ( // 开启签章功能
              <div
                style={{
钟是志's avatar
钟是志 committed
313
                  ...styleList.modalDiv,
钟是志's avatar
钟是志 committed
314
                  backgroundImage: `url(${basicUrl + fileInfo?.path})`,
315
                  width: showImageWidth,
316
                  height: (imageInfo && imageInfo.height / (imageInfo.width / showImageWidth)) || 0,
钟是志's avatar
钟是志 committed
317 318 319 320 321
                }}
                alt={'拖拽区域'}
                draggable={false}
                id={'dropZone'}
              >
钟是志's avatar
钟是志 committed
322
                {Array.isArray(signConfig) &&
323 324 325 326 327 328 329 330 331 332 333
                  signConfig.map(g => {
                    return (
                      <div
                        key={g.key}
                        data-mes={g.key}
                        draggable={false}
                        style={{
                          ...styleList.oneSetItem,
                          top: g.y,
                          left: g.x,
                        }}
334
                      >
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
                        <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>
钟是志's avatar
钟是志 committed
361
                      </div>
362 363
                    );
                  })}
钟是志's avatar
钟是志 committed
364 365 366
              </div>
            )}
            {!openEdit && ( // 不开启签章功能 只是预览图片
367
              <div style={styleList.readOnlyImage} draggable={false}>
钟是志's avatar
钟是志 committed
368
                <img
369
                  src={basicUrl + fileInfo?.path + `?v=${Math.random()}`}
钟是志's avatar
钟是志 committed
370
                  alt={fileInfo.name}
371
                  draggable={false}
372 373
                  style={{
                    width: `${showImageWidth}px`,
钟是志's avatar
钟是志 committed
374
                    height: 'auto',
375
                  }}
钟是志's avatar
钟是志 committed
376 377 378 379 380 381 382 383 384
                />
              </div>
            )}
          </div>
        </Modal>
      )}
    </div>
  );
}
钟是志's avatar
钟是志 committed
385

钟是志's avatar
钟是志 committed
386
export function SignArray(props) {
387
  const { value, onChange, basicUrl, json, form } = props;
钟是志's avatar
钟是志 committed
388
  let files = value?.files || [];
389
  const onChangeFile = (newFielInfo, imageIndex) => {
390
    if (newFielInfo && newFielInfo.path) {
391 392 393
      files[imageIndex] = newFielInfo;
      value.files = files;
      onChange(value);
钟是志's avatar
钟是志 committed
394
    }
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
  };
  return (
    <div>
      {files.map((g, index) => {
        return (
          <PictureSignature
            json={json}
            basicUrl={basicUrl}
            fileInfo={g}
            form={form}
            imageIndex={index}
            onChangeFile={onChangeFile}
          />
        );
      })}
    </div>
  );
钟是志's avatar
钟是志 committed
412
}