Commit 86030319 authored by 田翔's avatar 田翔

fix: 增加手写签名

parent d569240d
{
"name": "panda-xform",
"version": "4.7.8",
"description": "4.7.8 坐标写死问题",
"version": "4.7.9",
"description": "4.7.9 增加手写签名控件",
"keywords": [
"panda-xform"
],
......@@ -41,7 +41,7 @@
"react-dnd-html5-backend": "^16.0.1",
"react-file-viewer": "^1.2.1",
"react-resizable": "^3.0.5",
"react-sign2": "^0.0.3",
"react-signature-canvas": "^1.0.6",
"react-svg": "15.1.9",
"viewerjs": "^1.11.3",
"viewerjs-react": "^1.0.2",
......@@ -54,7 +54,7 @@
"@babel/plugin-transform-modules-amd": "^7.14.5",
"@umijs/fabric": "^2.0.7",
"@wisdom-map/amap": "1.1.0-beta.56",
"@wisdom-map/arcgismap": "1.4.0-177",
"@wisdom-map/arcgismap": "1.4.0-178",
"@wisdom-map/basemap": "1.1.0-27",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
......
......@@ -181,6 +181,10 @@ const widgetData = {
name: '自动计算',
type: '高级控件',
},
'Signature': {
name: '手写签名',
type: '高级控件',
},
}
const getStyles = (type) => {
......
......@@ -2599,6 +2599,75 @@ const advancedWidgets = [
},
},
},
{
text: '手写签名',
name: '手写签名',
icon: <IconPack.RelationForm />,
schema: {
title: '手写签名',
type: 'string',
widget: 'Signature',
},
setting: {
widget: {
title: '控件类型',
type: 'string',
widget: 'WidgetType',
displayType: 'row',
labelWidth: 80,
},
$id: {
title: '数据源',
type: 'string',
widget: 'FieldNames',
required: true,
},
title: {
title: '展示名称',
type: 'string',
widget: 'htmlInput',
default: '关联表单',
},
hiddenCondition: {
title: '隐藏条件',
type: 'string',
description: '所有形态默认显示',
widget: 'HiddenCondition'
},
description: {
title: '字段说明',
type: 'string',
widget: 'htmlInput',
},
disabled: {
title: '只读',
type: 'boolean',
widget: 'checkbox',
default: false,
width: '33%',
},
groupStyle: {
title: '控件样式',
type: 'object',
properties: {}
},
width: {
title: '元素宽度',
type: 'string',
widget: 'percentSlider',
},
labelWidth: {
title: '标签宽度',
default: 120,
type: 'number',
widget: 'slider',
max: 400,
props: {
hideNumber: true,
},
},
},
},
]
const settings = [
......
import React from 'react'
import Sign from 'react-sign2'
import React, { useRef, useState } from 'react'
import ReactSignatureCanvas from 'react-signature-canvas'
import Drag from '../../../components/Drag'
import { UploadFileReturnUrl } from '../../../../apis/process'
import styles from './index.less'
const Signature = (props) => {
const { value } = props
const { addons, value, onChange, schema } = props
const { disabled } = schema
const [visible, setVisible] = useState(false)
const canvasRef = useRef(null)
const open = () => {
if (addons && !disabled) {
setVisible(true)
}
}
const onOk = async () => {
if (addons) {
const dataUrl = canvasRef.current.toDataURL(); // 获取 Base64 编码的字符串
const byteString = atob(dataUrl.split(',')[1]); // 将 Base64 编码的字符串转换为字节数组
const mimeString = dataUrl.split(',')[0].split(':')[1].split(';')[0]; // 获取 MIME 类型
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
const file = new Blob([ab], { type: mimeString }); // 将字节数组转换为文件流
const formData = new FormData(); // 创建表单数据对象
formData.append('file', file, 'signature.png'); // 添加文件流到表
const { code, data } = await UploadFileReturnUrl(formData)
if (code === 0) {
onChange(data)
setVisible(false)
} else {
message.error('生成图片失败!')
}
}
}
return (
<div>
<Sign />
<div className={styles.signature}>
<div className={styles.content} onClick={open}>
{
value ? <img src={`${window.origin}/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles?filePath=${value}`}></img> : <div className={styles.text}>点击签名</div>
}
</div>
<Drag
title={'手写签名'}
visible={visible}
onOk={onOk}
onCancel={() => setVisible(false)}
destroyOnClose
>
<div style={{ background: '#aaa', borderRadius: '5px' }}>
<ReactSignatureCanvas
ref={canvasRef}
canvasProps={{ width: 500, height: 300 }}
/>
</div>
</Drag>
</div>
)
......
.signature {
width: 100%;
.content {
&:hover {
cursor: pointer;
}
img {
width: 100px;
height: 60px;
}
.text {
width: 100px;
height: 60px;
text-align: center;
line-height: 60px;
border-radius: 5px;
background: #efefef;
color: #a8a8a8;
&:hover {
font-weight: bold;
}
}
}
}
\ No newline at end of file
......@@ -163,6 +163,19 @@ const Coordinate = (props) => {
return cityName;
}
if (screenShot && disabled) {
return (
<div style={{ width: '100%', height: '150px' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
)
}
return (
<div>
{
......@@ -176,59 +189,44 @@ const Coordinate = (props) => {
onClick={showMap}
/>
:
!screenShot ? (
<Button
icon={<CompassOutlined style={{ color: value ? '#0092fe' : 'rgba(0, 0, 0, 0.25)' }} />}
onClick={() => {
if (value) {
showMap()
}
}}
>
{value ? '查看位置' : '无位置信息'}
</Button>
) : null
}
{
screenShot && disabled ? (
<div style={{ width: '100%', height: '150px' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
) : (
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
>
<div style={{ height: '90%' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
{
view ? <div style={{ width: '400px', position: 'absolute', right: '0', top: '25px' }}>
<AutoCompleteSearch areaName={getCityName()} view={view} />
</div> : ''
<Button
icon={<CompassOutlined style={{ color: value ? '#0092fe' : 'rgba(0, 0, 0, 0.25)' }} />}
onClick={() => {
if (value) {
showMap()
}
</div>
</Drag>
)
}}
>
{value ? '查看位置' : '无位置信息'}
</Button>
}
</div>
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
>
<div style={{ height: '90%' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
{
view ? <div style={{ width: '400px', position: 'absolute', right: '0', top: '25px' }}>
<AutoCompleteSearch areaName={getCityName()} view={view} />
</div> : ''
}
</div>
</Drag>
</div >
)
}
......
......@@ -25,7 +25,8 @@ const Device = (props) => {
let clickref = useRef(null)
let view = useRef(null)
const getMapInfo = (mapObj, Map) => {
const getMapInfo = (mapObj, Map, disabled) => {
console.log('disabled', disabled)
setTimeout(() => {
if (mapObj) {
view.current = mapObj
......@@ -122,6 +123,19 @@ const Device = (props) => {
}
}, [presetValue])
if (screenShot && disabled) {
return (
<div style={{ width: '100%', height: '120px' }}>
<ArcGISSceneMap
getMapInfo={(mapObj, Map) => getMapInfo(mapObj, Map, true)}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
)
}
return (
<div>
{
......@@ -134,7 +148,7 @@ const Device = (props) => {
addonAfter={disabled ? null : <CompassOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} onClick={iconClick} />}
style={{ width: '100%' }}
/> :
!screenShot ? <Button
<Button
icon={<CompassOutlined style={{ color: value ? '#0092fe' : 'rgba(0, 0, 0, 0.25)' }} />}
onClick={() => {
if (value) {
......@@ -143,40 +157,27 @@ const Device = (props) => {
}}
>
{value ? '查看设备' : '无设备信息'}
</Button> : null
}
{
screenShot && disabled ? (
<div style={{ width: '100%', height: '120px' }}>
<ArcGISSceneMap
getMapInfo={getMapInfo}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
) : (
<Drag
visible={visible}
title='设备选择'
width={'80%'}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: 'auto', position: 'relative' }}
getContainer={true}
{...disabled ? { footer: null } : {}}
>
<ArcGISSceneMap
getMapInfo={getMapInfo}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</Drag>
)
</Button>
}
<Drag
visible={visible}
title='设备选择'
width={'80%'}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: 'auto', position: 'relative' }}
getContainer={true}
{...disabled ? { footer: null } : {}}
>
<ArcGISSceneMap
getMapInfo={(mapObj, Map) => getMapInfo(mapObj, Map, disabled)}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</Drag>
</div >
)
}
......
......@@ -99,6 +99,19 @@ const DrawArea = (props) => {
}
}, [presetValue])
if (screenShot && disabled) {
return (
<div style={{ width: '100%', height: '150px' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
)
}
return (
<div>
{
......@@ -112,7 +125,7 @@ const DrawArea = (props) => {
onClick={showMap}
/>
:
!screenShot ? <Button
<Button
icon={<CompassOutlined style={{ color: value ? '#0092fe' : 'rgba(0, 0, 0, 0.25)' }} />}
onClick={() => {
if (value) {
......@@ -121,49 +134,36 @@ const DrawArea = (props) => {
}}
>
{value ? '查看位置' : '无位置信息'}
</Button> : null
</Button>
}
{
screenShot && disabled ? (
<div style={{ width: '100%', height: '150px' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
) : (
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
>
<div style={{ height: '90%' }}>
<Button
style={{ position: 'absolute', zIndex: '99', right: '10px', top: '10px' }}
type='primary'
onClick={start}
>
<div style={{ height: '90%' }}>
<Button
style={{ position: 'absolute', zIndex: '99', right: '10px', top: '10px' }}
type='primary'
onClick={start}
>
开始绘制
</Button>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
</Drag >
)
}
开始绘制
</Button>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
</Drag>
</div >
)
......
......@@ -98,6 +98,19 @@ const DrawPath = (props) => {
}
}, [presetValue])
if (screenShot && disabled) {
return (
<div style={{ width: '100%', height: '150px' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
)
}
return (
<div>
{
......@@ -111,7 +124,7 @@ const DrawPath = (props) => {
onClick={showMap}
/>
:
!screenShot ? <Button
<Button
icon={<CompassOutlined style={{ color: value ? '#0092fe' : 'rgba(0, 0, 0, 0.25)' }} />}
onClick={() => {
if (value) {
......@@ -120,49 +133,36 @@ const DrawPath = (props) => {
}}
>
{value ? '查看位置' : '无位置信息'}
</Button> : null
</Button>
}
{
screenShot && disabled ? (
<div style={{ width: '100%', height: '150px' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
) : (
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
<Drag
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
{...disabled ? { footer: null } : {}}
>
<div style={{ height: '90%' }}>
<Button
style={{ position: 'absolute', zIndex: '99', right: '10px', top: '10px' }}
type='primary'
onClick={start}
>
<div style={{ height: '90%' }}>
<Button
style={{ position: 'absolute', zIndex: '99', right: '10px', top: '10px' }}
type='primary'
onClick={start}
>
开始绘制
</Button>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
</Drag >
)
}
开始绘制
</Button>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
token={token}
client={token ? client : 'sandbox'}
/>
</div>
</Drag>
</div >
)
......
......@@ -6,10 +6,6 @@ const WidgetType = (props) => {
const { value, onChange } = props
// const options = useMemo(() => {
// }, [])
return (
<span
style={{
......@@ -21,19 +17,6 @@ const WidgetType = (props) => {
{widgetData[value]?.name}
</span>
)
// return (
// <Select
// showArrow
// tagRender={tagRender}
// defaultValue={['gold', 'cyan']}
// style={{
// width: '100%',
// }}
// options={options}
// >
// </Select>
// )
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment