Commit 3b85970e authored by 田翔's avatar 田翔

增加表单渲染组件

parent d91680b2
import React, { useState, useEffect, useRef } from 'react';
import { FormRender, FormDesigner } from '../../src/index';
import { options1, options2 } from './data';
import { Button } from 'antd';
import { Button, Tabs } from 'antd';
window.globalConfig = {
"env": "daily",
......@@ -3506,36 +3506,27 @@ window.globalConfig = {
"apiGatewayDomain": "http://127.0.0.1:8080"
}
export default (props) => {
const [editState, setEditState] = useState('edit');
const [trigger, setTrigger] = useState(false);
const [readOnly, setReadOnly] = useState(false)
const testRef = useRef();
const Test = (props) => {
const [schema, setSchema] = useState({})
const changeSchema = (value) => {
setSchema(value)
}
return (
<div>
<FormDesigner
style={{ margin: '0' }}
loading={props.loading}
key={editState}
handleType={editState}
// isReadOnly={1}
tablesSchema={options1}
onSubmit={(formData, formInstance) => {
console.log('formData', formData)
// setEditState('scan')
// setReadOnly(true)
}}
// codes={{ '工单编号': 'RYWX00000269', '事件编号': 'RYWXTB220000320' }}
// ref={testRef}
customerSubmitTrigger={{
trigger: trigger,
}}
onBack={() => {
// setEditState('edit')
// setReadOnly(false)
}}
/>
<div style={{ width: '100%' }}>
<Tabs>
<Tabs.TabPane tab="编辑" key="item-1">
<FormDesigner setSchema={changeSchema} />
</Tabs.TabPane>
<Tabs.TabPane tab="渲染" key="item-2">
<FormRender schema={schema} />
</Tabs.TabPane>
</Tabs>
</div>
);
};
)
}
export default Test
......@@ -29,7 +29,7 @@ app.use(webpackHotMiddleware(compiler));
app.use(express.static(__dirname));
// app.use('/', createProxyMiddleware('/', { target: 'http://127.0.0.1:8880', changeOrigin: true }));
app.use('/', createProxyMiddleware('/', { target: 'http://192.168.10.167:8088', changeOrigin: true }));
const port = process.env.PORT || 8383;
const port = process.env.PORT || 8888;
module.exports = app.listen(port, () => {
console.log(`Server listening on http://localhost:${port}, Ctrl+C to stop`);
});
......@@ -64,13 +64,37 @@ module.exports = {
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: {
getLocalIdent: (context, _, localName) => {
if (
context.resourcePath.includes('node_modules') ||
context.resourcePath.includes('ant.design.pro.less') ||
context.resourcePath.includes('main.less')
) {
return localName;
}
const match = context.resourcePath.match(/src(.*)/);
const matchAntd = /^ant/.test(localName);
if (match && match[1] && !matchAntd) {
const antdProPath = match[1].replace('.less', '');
const arr = slash(antdProPath)
.split('/')
.map(a => a.replace(/([A-Z])/g, '-$1'))
.map(a => a.toLowerCase());
return `parse-form-${arr.join('-')}-${localName}`.replace(/--/g, '-');
}
return localName;
},
},
},
},
{
loader: 'less-loader',
......
{
"name": "panda-xform",
"version": "1.1.0",
"description": "1.1.0: 项目初始化",
"version": "1.2.0",
"description": "1.2.0: 增加渲染表单组件",
"keywords": [
"panda-xform"
],
......@@ -37,6 +37,7 @@
"moment": "^2.29.1",
"qrcode.react": "^1.0.1",
"react": "17.0.2",
"react-file-viewer": "^1.2.1",
"react-svg": "15.1.9",
"yarn": "^1.22.17"
},
......@@ -124,4 +125,4 @@
"publishConfig": {
"registry": "https://g.civnet.cn:4873"
}
}
\ No newline at end of file
}
import settings from './settings'
import {
baseSettings,
commonSettings,
switchSettings,
elementSettings,
globalSettings,
} from './otherSettings'
export {
settings,
baseSettings,
commonSettings,
switchSettings,
elementSettings,
globalSettings,
}
\ No newline at end of file
const baseSettings = {
title: {
title: '标题',
type: 'string',
// widget: 'htmlInput',
displayType: 'row',
labelWidth: 80,
},
}
const commonSettings = {
$id: {
title: '字段名称',
type: 'string',
widget: 'FieldNames',
required: true,
displayType: 'row',
labelWidth: 80,
// width: '70%',
},
title: {
title: '标题',
required: true,
type: 'string',
widget: 'htmlInput',
displayType: 'row',
labelWidth: 80,
},
placeholder: {
title: '提示语',
type: 'string',
displayType: 'row',
labelWidth: 80,
},
// description: {
// title: '说明',
// type: 'string',
// },
presetValue: {
title: '默认值',
type: 'string',
displayType: 'row',
labelWidth: 80,
// default: ''
},
}
const switchSettings = {
disabled: {
title: '只读',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
default: false
},
required: {
title: '必填',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
default: false
},
hidden: {
title: '隐藏',
type: 'boolean',
widget: 'BooleanSwitch',
default: false,
displayType: 'row',
labelWidth: 80,
},
}
const elementSettings = {
width: {
title: '元素宽度',
type: 'string',
widget: 'percentSlider',
// default: '33%',
},
labelWidth: {
title: '标签宽度',
description: '默认值110',
default: 110,
type: 'number',
widget: 'slider',
max: 400,
props: {
hideNumber: true,
},
},
}
const globalSettings = {
type: 'object',
properties: {
column: {
title: '整体布局',
type: 'number',
enum: [1],
default: 1,
enumNames: ['一行一列'],
widget: 'select',
props: {
placeholder: '默认一行一列',
},
displayType: 'row',
labelWidth: 100,
},
displayType: {
title: '标签展示模式',
type: 'string',
default: 'row',
enum: ['row', 'column'],
enumNames: ['同行', '单独一行'],
widget: 'select',
displayType: 'row',
labelWidth: 100,
},
labelWidth: {
title: '标签宽度',
type: 'number',
widget: 'slider',
max: 300,
default: 120,
props: {
hideNumber: true,
},
},
},
}
export {
baseSettings,
commonSettings,
switchSettings,
elementSettings,
globalSettings
}
\ No newline at end of file
const baseSettings = {
title: {
title: '标题',
type: 'string',
// widget: 'htmlInput',
displayType: 'row',
labelWidth: 80,
},
}
const commonSettings = {
$id: {
title: '字段名称',
type: 'string',
widget: 'FieldNames',
required: true,
displayType: 'row',
labelWidth: 80,
// width: '70%',
},
title: {
title: '标题',
required: true,
type: 'string',
widget: 'htmlInput',
displayType: 'row',
labelWidth: 80,
},
placeholder: {
title: '提示语',
type: 'string',
displayType: 'row',
labelWidth: 80,
},
// description: {
// title: '说明',
// type: 'string',
// },
presetValue: {
title: '默认值',
type: 'string',
displayType: 'row',
labelWidth: 80,
// default: ''
},
}
const switchSettings = {
disabled: {
title: '只读',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
default: false
},
required: {
title: '必填',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
default: false
},
hidden: {
title: '隐藏',
type: 'boolean',
widget: 'BooleanSwitch',
default: false,
displayType: 'row',
labelWidth: 80,
},
}
const elementSettings = {
width: {
title: '元素宽度',
type: 'string',
widget: 'percentSlider',
// default: '33%',
},
labelWidth: {
title: '标签宽度',
description: '默认值110',
default: 110,
type: 'number',
widget: 'slider',
max: 400,
props: {
hideNumber: true,
},
},
}
import { commonSettings, switchSettings, elementSettings } from './otherSettings'
const allSetting = {
...commonSettings,
......@@ -110,16 +18,7 @@ const settings = [
type: 'object',
properties: {}
},
setting: {
hidden: {
title: '隐藏',
type: 'boolean',
widget: 'BooleanSwitch',
default: false,
displayType: 'row',
labelWidth: 80,
},
},
setting: {},
},
],
},
......@@ -132,7 +31,6 @@ const settings = [
schema: {
title: '文本',
type: 'string',
widget: 'TextInput',
},
setting: {
...allSetting
......@@ -168,7 +66,7 @@ const settings = [
schema: {
title: '数值',
type: 'number',
widget: 'NumberInput'
widget: 'number'
},
setting: {
...allSetting
......@@ -243,10 +141,10 @@ const settings = [
},
setting: {
...commonSettings,
options: {
title: '可选值',
dataSource: {
title: '数据来源',
type: 'string',
widget: 'EnumOptions',
widget: 'DataSource',
displayType: 'row',
labelWidth: 80,
},
......@@ -365,32 +263,20 @@ const settings = [
},
setting: {
...commonSettings,
interaction: {
title: '交互方式',
type: 'string',
enum: ['下拉框', '分组模态', '树形模态'],
default: '下拉框',
enumNames: ['下拉框', '分组模态', '树形模态'],
displayType: 'row',
labelWidth: 80,
},
role: {
title: '机构角色',
type: 'string',
required: true,
// enum: ['下拉框', '分组模态', '树形模态'],
// default: '下拉框',
// enumNames: ['下拉框', '分组模态', '树形模态'],
displayType: 'row',
labelWidth: 80,
},
isMultiple: {
title: '是否多选',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
},
// dependencies: {
// title: '关联字段',
// type: 'array',
// widget: 'CascadeField',
// displayType: 'row',
// labelWidth: 80,
// },
// isMultiple: {
// title: '是否多选',
// type: 'boolean',
// widget: 'BooleanSwitch',
// displayType: 'row',
// labelWidth: 80,
// },
...switchSettings,
...elementSettings,
}
......@@ -417,14 +303,16 @@ const settings = [
type: 'string',
displayType: 'row',
labelWidth: 80,
widget: 'date',
widget: 'DateSelect',
dependencies: ['format']
},
format: {
title: '日期格式',
type: 'string',
enum: ['date', 'dateTime', 'year', 'month', 'quarter', 'week'],
// enum: ['date', 'dateTime', 'year', 'month', 'quarter', 'week'],
enum: ['date', 'dateTime', 'year', 'month'],
default: 'date',
enumNames: ['日期', '日期时间', '日期年份', '日期月份', '日期季度', '日期周'],
enumNames: ['日期', '日期时间', '日期年份', '日期月份'],
displayType: 'row',
labelWidth: 80,
},
......@@ -470,32 +358,31 @@ const settings = [
type: 'string',
widget: 'FileUpload',
},
},
{
text: '图片',
name: '图片',
schema: {
title: '图片',
type: 'string',
widget: 'FileUpload',
},
},
{
text: '录音',
name: '录音',
schema: {
title: '录音',
type: 'string',
widget: 'FileUpload',
},
},
{
text: '视频',
name: '视频',
schema: {
title: '视频',
type: 'string',
widget: 'FileUpload',
setting: {
...commonSettings,
presetValue: {},
fileType: {
title: '文件类型',
type: 'string',
required: true,
widget: 'select',
enum: ['图片', '文档', '音频', '视频'],
enumNames: ['图片', '文档', '音频', '视频'],
default: '图片',
displayType: 'row',
labelWidth: 80,
},
listType: {
title: '显示样式',
type: 'string',
default: 'picture',
enum: ['picture', 'text', 'picture-card'],
enumNames: ['列表', '文本', '卡片'],
displayType: 'row',
labelWidth: 80,
},
...switchSettings,
...elementSettings,
},
},
],
......@@ -511,55 +398,11 @@ const settings = [
schema: {
title: '坐标控件',
type: 'string',
widget: 'DateSelect',
widget: 'Coordinate',
},
},
],
},
]
const globalSettings = {
type: 'object',
properties: {
column: {
title: '整体布局',
type: 'number',
enum: [1],
default: 1,
enumNames: ['一行一列'],
widget: 'select',
props: {
placeholder: '默认一行一列',
},
displayType: 'row',
labelWidth: 100,
},
displayType: {
title: '标签展示模式',
type: 'string',
default: 'row',
enum: ['row', 'column'],
enumNames: ['同行', '单独一行'],
widget: 'select',
displayType: 'row',
labelWidth: 100,
},
labelWidth: {
title: '标签宽度',
type: 'number',
widget: 'slider',
max: 300,
default: 120,
props: {
hideNumber: true,
},
},
},
}
export {
settings,
baseSettings,
commonSettings,
globalSettings
}
\ No newline at end of file
export default settings
\ No newline at end of file
......@@ -19,6 +19,7 @@ const FormDesigner = (props) => {
if (errors.length) {
return message.error('请按照提示完善表单内容')
}
props.setSchema && props.setSchema(ref.current.getValue())
}
}
]
......@@ -46,7 +47,6 @@ const FormDesigner = (props) => {
<div className={prefixCls}>
<Generator
configProvider={{ prefixCls: prefixClsWithoutParseForm }}
// getId={name => name ? `${name}_${count++}` : null}
mapping={{
object: 'Header',
}}
......
const schema = {
"type": "object",
"properties": {
"formGroup_1": {
"type": "object",
"title": "文本类",
"properties": {
"多行文本": {
"title": "多行文本",
"type": "string",
"format": "textarea",
"default": "",
"min": 0,
"max": 254,
"className": "",
"showDescIcon": true,
"column": 1,
"required": false,
"widget": "textArea",
"rules": [
{
"patterns": false,
"message": ""
}
],
"disabled": false,
"placeholder": "请输入多行文本",
"width": "100%",
"pathKey": "formGroup_1"
},
"富文本": {
"title": "富文本",
"widget": "RichText",
"type": "string",
"config": "",
"format": "text",
"className": "",
"default": "富文本默认值",
"content": "富文本默认值",
"min": 0,
"max": 254,
"disabled": false,
"showDescIcon": true,
"required": false,
"widget": "RichText",
"rules": [
{},
{
"pattern": false,
"message": ""
}
],
"width": "100%",
"pathKey": "formGroup_1"
},
},
"required": [],
"className": "ant-parse-form-group"
},
},
"required": [],
"column": 4,
"displayType": "row",
"showDescIcon": true,
"labelWidth": 120
}
export default schema
\ No newline at end of file
import React, { useState, useEffect, useRef, useContext, createContext, forwardRef, useImperativeHandle, useMemo } from 'react'
import FormRender, { useForm } from 'form-render'
import { ConfigProvider } from 'antd'
import widgets from '../widgets'
// import schema from './data'
// console.log('FormRender', widgets)
export const GlobalStore = createContext(null)
const XRender = (props, ref) => {
// useImperativeHandle(ref, () => ({
// form,
// getFormValues,
// setListData
// }))
const { schema } = props
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext)
const prefixCls = getPrefixCls('parse-form')
const prefixClsWithoutParseForm = getPrefixCls()
const [extraData, setExtraData] = useState({})
const form = useForm()
return (
<GlobalStore.Provider
value={{
extraData,
setExtraData
}}>
<div className={prefixCls}>
<FormRender
configProvider={{ prefixCls: prefixClsWithoutParseForm }}
form={form}
schema={schema}
// onChange={form.setValues}
mapping={{
object: 'Header',
}}
widgets={widgets}
/>
</div>
</GlobalStore.Provider>
);
}
export default forwardRef(XRender)
/*
* 地图中,显示的是墨卡托坐标,使用在地图上来做交互是用的经纬度坐标
* */
import React, { useState, useEffect, useContext, useRef } from 'react';
import { Input, Modal, Spin, Button } from 'antd';
import { CompassOutlined } from '@ant-design/icons';
import { AMapScene, AMapDrawTool, VectorLayer, PointLayer } from '@wisdom-map/amap';
import {
ArcGISSceneMap,
AutoCompleteSearch,
Drawtool as drawTool,
Graphic,
GraphicsLayer,
Point
} from '@wisdom-map/arcgismap';
import { mktlng } from '@wisdom-map/basemap/es/utils/coordTransformation';
import { GlobalStore } from '../../../../FormRender'
import React, { useState, useEffect, useContext, useRef } from 'react'
import { Input, Modal, Spin, Button } from 'antd'
import { CompassOutlined } from '@ant-design/icons'
import { AMapScene, AMapDrawTool, VectorLayer, PointLayer } from '@wisdom-map/amap'
import { ArcGISSceneMap, AutoCompleteSearch, Drawtool as drawTool, Graphic, GraphicsLayer, Point } from '@wisdom-map/arcgismap'
import { mktlng } from '@wisdom-map/basemap/es/utils/coordTransformation'
import { GlobalStore } from '../../../FormRender'
const CoordinatePicker = ({ value, onChange, name, schema }) => {
......
/*
* 地图中,显示的是墨卡托坐标,使用在地图上来做交互是用的经纬度坐标
* */
import React, {useState, useEffect, useContext} from 'react';
const CoordinatePicker = ({value}) => {
return <div>{value || '地图组件暂不可用'}</div>
};
export default CoordinatePicker;
import React, { useState, useEffect, useContext } from 'react'
import { Input, message } from 'antd';
import { GlobalStore } from '../../../../FormRender'
import { GlobalStore } from '../../../FormRender'
import { AMap } from '@wisdom-map/amap'
const SearchLocation = ({ value, onChange, name, schema }) => {
......
// 自定义时间组件
import React, { useState, useEffect, useMemo } from 'react';
import { DatePicker, Input } from 'antd';
import { dateType, dateFormat } from '../../../../constant/constant';
import moment from 'moment';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import React, { useState, useEffect, useMemo } from 'react'
import { DatePicker, Input } from 'antd'
import style from '../../style'
import moment from 'moment'
import locale from 'antd/lib/date-picker/locale/zh_CN'
const DateTime = ({ value, onChange, schema }) => {
const DateTime = (props) => {
console.log('schema', schema)
const { value, onChange, schema } = props
const { disabled, format, presetValue, placeholder } = schema
// console.log('schema', schema)
// const dateTime = value || schema.default;
// const format = schema.shape != '日期周' ? dateFormat[schema.shape] : 'YYYY-wo';
const valueShow = useMemo(() => {
return moment(value || presetValue)
console.log('value+presetValue', value, presetValue)
return (value || presetValue) ? moment(value || presetValue) : null
}, [presetValue, value])
const disabledDate = (current) => {
......@@ -24,45 +22,30 @@ const DateTime = ({ value, onChange, schema }) => {
} else {
return false
}
};
// 不超过当前时间这个配置没有意义,在moment的工具中,已经囊括了未到时间这步
const disabledTime = (current) => {
if (schema.config === '不超过当前时间') {
return {
disabledHours: () => [],
disabledMinutes: () => [],
disabledSeconds: () => [55, 56],
};
} else {
return {}
}
};
}
const dateChange = (date, dateStr) => {
// console.log(val, dateVal)
// onChange(schema.shape != '日期周' ? dateVal : (val ? moment(val).format('YYYY-MM-DD') : null))
// onChange(moment(date._d).format('YYYY-MM-DD HH:mm:ss'))
console.log(date, dateStr)
onChange(date)
onChange(dateStr)
}
const onOk = (value) => {
console.log('value', value)
}
// useEffect(() => {
// onChange(dateTime);
// }, []);
// console.log('valueShow', valueShow)
return (
<DatePicker
mode={format}
picker={format}
disabled={disabled}
placeholder={placeholder}
value={valueShow}
onChange={dateChange}
picker={dateType[schema.shape]}
showNow
showTime={format === 'dateTime'}
style={{ width: '100%' }}
style={style}
locale={locale}
disabledDate={disabledDate}
onOk={onOk}
/>
);
......
import React, { useMemo } from 'react'
import { TimePicker } from 'antd'
import moment from 'moment'
const format = 'HH:mm:ss'
import style from '../../style'
const Time = ({ value, onChange, schema }) => {
// console.log(value, onChange, schema)
const { presetValue } = schema
const valueShow = useMemo(() => {
// console.log('时间改变', moment(value || presetValue))
// return (value || presetValue) ? moment(value || presetValue) : null
return (value || presetValue) ? moment(value || presetValue) : null
return (value || presetValue) ? moment(value || presetValue, 'HH:mm:ss') : null
}, [presetValue, value])
const timeChange = (time, timeStr) => {
console.log(time, timeStr)
onChange(timeStr)
}
console.log('valueShow', valueShow)
return (
<TimePicker value={valueShow} onChange={timeChange} format={format} />
<TimePicker style={style} value={valueShow} onChange={timeChange} />
)
}
......
import React, { useEffect, useMemo, useState } from 'react'
import styles from './index.less'
import { Upload, Button, message, Modal } from 'antd'
import { UploadOutlined, FileOutlined } from '@ant-design/icons'
import FileViewer from 'react-file-viewer'
import { uploadFileUrl, downloadFileUrl, downloadFile } from '../../../../apis/process'
import { downloadFunc, filenameVerification } from '../../../../utils/utils'
const accepts = {
'图片': ['.bmp', '.gif', '.jpeg', 'tiff', '.png', '.svg', '.jpg'],
'文档': ['.docx', '.xlsx', '.pdf'],
'视频': ['.mp4'],
'音频': ['.mp3'],
}
const FileUpload = (props) => {
const { value, schema, onChange } = props
const { disabled, fileType, listType, presetValue, placeholder } = schema
const [showList, setShowList] = useState('')
const [visible, setVisible] = useState(false)
const [showFile, setShowFile] = useState({ fileType: '', filePath: '' })
const option = {
name: 'file',
action: `${window.location.origin}${uploadFileUrl}`,
listType: listType,
withCredentials: true,
beforeUpload(file, fileList) {
/** @Tips: 解决提交文件中存在特殊字符的问题 */
let _continueUpload = true;
let _msg = {
type: 'success',
content: '上传成功!',
};
fileList.forEach(item => {
let _msgObject = filenameVerification(item);
if (_msgObject.type === 'error') {
_continueUpload = false;
_msg = {
type: 'error',
content: '上传失败!文件名不符合规则!',
};
}
});
_msg.type === 'error' ? message[_msg.type](_msg.content) : ''
return _continueUpload;
},
onChange: ({ file, fileList, event }) => {
// 检验名字,名字不通过不允许显示
if (filenameVerification(file).type === 'error') return false;
// 返回的链接在file.response内;不设置url,预览图表不可点击
if (file.status === 'done' && file.response.code === 0) {
file.url = `${downloadFileUrl}?filePath=${file.response.data}`
file.sourcePath = file.response.data;
message.success('上传成功!')
} else if (file.status === 'done' && file.response.code !== 0) {
file.status = 'error';
message.error('上传失败!')
}
if (Array.isArray(fileList)) {
let list = fileList.map(v => v.sourcePath || v.value)
onChange(list.join(','))
setShowList(JSON.stringify(fileList))
} else {
onChange('')
setShowList()
}
},
onPreview: (file) => {
let fileType = null
if (file.name.includes('docx')) {
fileType = 'docx'
} else if (file.name.includes('xlsx')) {
fileType = 'xlsx'
} else if (file.name.includes('jpg')) {
fileType = 'jpg'
}
if (fileType) {
setShowFile({ name: file.name, fileType: fileType, filePath: file.url })
setVisible(true)
}
}
}
const iconRender = (file, listType) => {
if (listType !== 'text') {
if (file.name.includes('docx')) {
return <div className={styles.iconImg} type='docx'></div>
} else if (file.name.includes('xlsx')) {
return <div className={styles.iconImg} type='xlsx'></div>
}
}
return <FileOutlined />
}
useEffect(() => {
if (value || presetValue) {
let fileList = [];
let list = (value || presetValue) && !(value || presetValue).includes('拍照相册') ? (value || presetValue).split(',') : []
list.forEach((item, index) => {
if (item) { // @Tips: 直接过滤掉名字中有异常字符的文件
let uid = index + '_' + Math.random()
let _obj = {
uid: uid,
value: item,
name: item.split('\\').reverse()[0],
type: fileType === '图片' ? 'image/jpeg' : 'file',
status: 'done',
url: `${downloadFileUrl}?filePath=${item}`,
sourcePath: item.url,
originFileObj: { "uid": uid },
"response": { "code": 0, "msg": "Ok", "data": item, "stackTrace": null },
"xhr": {},
};
if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
fileList.push(_obj);
}
})
setShowList(JSON.stringify(fileList))
}
}, [value, presetValue])
return (
<div className={styles.uploadBox}>
<Upload
disabled={disabled}
accept={accepts[fileType]}
fileList={showList ? JSON.parse(showList) : []}
className="upload-list-inline"
iconRender={iconRender}
{...option}
>
{listType !== 'picture-card' ? <Button icon={<UploadOutlined />}>{placeholder || '上传'}</Button> : (disabled ? null : (placeholder || '+ 上传'))}
</Upload>
<Modal
width={'80%'}
title={showFile.name}
visible={visible}
onCancel={() => setVisible(false)}
bodyStyle={{ height: 650, overflowY: showFile.fileType.includes('xlsx') ? 'none' : "auto" }}
>
<FileViewer
title='123'
fileType={showFile.fileType}
filePath={window.location.origin + showFile.filePath}
/>
</Modal>
</div>
)
}
export default FileUpload
\ No newline at end of file
@imgSrc: '../../../../assets/images';
.uploadBox {
.iconImg {
width:45px;
height: 45px;
margin: 0 auto;
&[type='docx'] {
background: url('@{imgSrc}/Word.png');
background-size: 100% 100%;
}
&[type='xlsx'] {
background: url('@{imgSrc}/Excel.png');
background-size: 100% 100%;
}
}
}
\ No newline at end of file
import FileUpload from './FileUpload'
const file = {
FileUpload,
}
export default file
\ No newline at end of file
......@@ -3,15 +3,17 @@ import setting from './settings'
import text from './text'
import date from './date'
import select from './select'
// import file from './file'
// import coord from './coord'
import file from './file'
import coord from './coord'
export default {
const widgets = {
Header,
...setting,
...text,
...date,
...select,
// ...file,
// ...coord,
}
\ No newline at end of file
...file,
...coord,
}
export default widgets
\ No newline at end of file
// 选择器,值选择器
import React, { useState, useMemo } from 'react'
import { Select } from 'antd'
import style from '../../style'
const { Option } = Select
......@@ -33,7 +34,7 @@ const ValueSelect = ({ value, onChange, schema }) => {
return (
<Select
style={{ minWidth: 150 }}
style={style}
mode={mode}
disabled={disabled}
showArrow={!disabled}
......
import React, { useState } from 'react'
import { Button, Form, Input, Select, Space, Modal } from 'antd'
import style from '../../style'
const options = [
{ label: '手动输入', value: '手动输入' },
{ label: '数据字典', value: '数据字典' },
]
const DataSource = (props) => {
console.log('props', props)
const { formData } = props.addons
const [visible, setVisible] = useState(false)
const [form] = Form.useForm()
const onFocus = () => {
setVisible(true)
}
const inputChange = (e) => {
console.log('e', e)
}
return (
<>
<Modal
title={`【${formData.$id}】数据来源`}
width='500px'
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
>
<Form
form={form}
>
<Form.Item
name="area"
label="数据来源"
rules={[
{
required: true,
message: 'Missing area',
},
]}
>
<Select options={options} />
</Form.Item>
</Form>
</Modal>
<Input value={valueShow} onChange={inputChange} style={style} onClick={onFocus} />
</>
)
}
export default DataSource
\ No newline at end of file
import React, { useState, useEffect, useMemo } from 'react'
import { DatePicker, Input } from 'antd'
import { DatePicker, TimePicker, Input } from 'antd'
import moment from 'moment'
import locale from 'antd/lib/date-picker/locale/zh_CN'
......@@ -13,12 +13,33 @@ const DateSelect = (props) => {
onChange(dateStr)
}
const onOk = (value) => {
console.log('value', value)
}
console.log('format', format)
if (format === 'dateTime') {
return (
<DatePicker
picker={format}
// value={valueShow}
onChange={dateChange}
onOk={onOk}
showNow
showTime
style={{ width: '100%' }}
locale={locale}
/>
)
}
return (
<DatePicker
picker={format}
// value={valueShow}
onChange={dateChange}
showTime={format === 'dateTime'}
onOk={onOk}
style={{ width: '100%' }}
locale={locale}
/>
......
import React, { useMemo } from 'react'
import { Input, Select } from 'antd'
import style from '../../style'
const field = [
"处理站点",
......@@ -90,7 +91,7 @@ const FieldNames = (props) => {
}
return (
<Select onChange={change} style={{ minWidth: '143px' }} value={valueShow}>
<Select onChange={change} style={style} value={valueShow}>
{
field.map(v => <Select.Option key={v} value={v}>{v}</Select.Option>)
}
......
......@@ -3,6 +3,7 @@ import EnumOptions from './EnumOptions'
import FieldNames from './FieldNames'
import CascadeField from './CascadeField'
import DateSelect from './DateSelect'
import DataSource from './DataSource'
const settings = {
BooleanSwitch,
......@@ -10,6 +11,7 @@ const settings = {
FieldNames,
CascadeField,
DateSelect,
DataSource,
}
export default settings
\ No newline at end of file
const style = {
width: '100%'
}
export default style
\ No newline at end of file
import React, { useMemo } from 'react'
import { InputNumber } from 'antd'
const style = {
width: '100%'
}
import style from '../../style'
const NumberInput = ({ value, onChange, schema }) => {
console.log('数字输入框', schema)
const { disabled, presetValue } = schema
const valueShow = useMemo(() => {
return presetValue || value
}, [presetValue, value])
return (
<InputNumber
disabled={disabled}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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