Commit d91680b2 authored by 田翔's avatar 田翔

项目初始化

parents
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
\ No newline at end of file
module.exports = {
extends: [require.resolve('@umijs/fabric/dist/eslint')],
rules: {
'no-return-assign': 0,
semi: ['error', 'always'],
'no-confusing-arrow': 0,
'no-console': 0,
'max-len': ['error', { code: 120, ignoreComments: true, ignoreStrings: true }],
// see https://github.com/prettier/prettier/issues/3847
'space-before-function-paren': ['error', { anonymous: 'never', named: 'never', asyncArrow: 'always' }],
'no-underscore-dangle': 0,
'no-plusplus': 0,
},
};
const type = process.env.BUILD_TYPE;
let config = {};
if (type === 'lib') {
config = {
cjs: { type: 'babel', lazy: true },
esm: false,
runtimeHelpers: true,
extraBabelPlugins: [['babel-plugin-import', { libraryName: 'antd', libraryDirectory: 'lib', style: true }, 'antd']],
};
}
if (type === 'es') {
config = {
cjs: false,
esm: {
type: 'babel',
},
runtimeHelpers: true,
extraBabelPlugins: [['babel-plugin-import', { libraryName: 'antd', libraryDirectory: 'es', style: true }, 'antd']],
};
}
export default config;
pids
logs
node_modules
npm-debug.log
coverage/
run
dist
.DS_Store
.nyc_output
config.local.js
.umi
.umi-production
.idea/
.cache
yarn.lock
package-lock.json
.eslintcache
.history
.now
es
lib
/test/fixtures
**/*.gif
/dist
/docs
/es
/lib
\ No newline at end of file
const fabric = require('@umijs/fabric');
module.exports = {
...fabric.prettier,
printWidth: 120,
};
Copyright 2020 dengxiaofeng <1186313486@qq.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React, {useEffect, useRef, useState} from 'react';
import ReactDOM from 'react-dom';
import Test from './test';
function render() {
ReactDOM.render(<Test />, document.getElementById('root'));
}
render();
export const options1 = {
groups: [
{
"groupName": "(未分组)",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "ID",
"alias": "ID",
"uiGroup": "(未分组)",
"tableGroup": null,
"type": "数值",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "number",
"allowCorrect": 0,
"order": 1,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "录入时间",
"alias": "录入时间",
"uiGroup": "(未分组)",
"tableGroup": null,
"type": "时间",
"shape": "时间",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "",
"allowCorrect": 0,
"order": 2,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "是否删除",
"alias": "是否删除",
"uiGroup": "(未分组)",
"tableGroup": null,
"type": "数值",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "number",
"allowCorrect": 0,
"order": 3,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "所属站点",
"alias": "所属站点",
"uiGroup": "(未分组)",
"tableGroup": null,
"type": "文本",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 4,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "文本类",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "文本",
"alias": "文本",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 5,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "唯一值文本",
"alias": "唯一值文本",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "唯一值文本",
"unit": "",
"configInfo": "台账_形态测试表.唯一值文本",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:100",
"allowCorrect": 0,
"order": 6,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "多行文本",
"alias": "多行文本",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "多行文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 7,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "本人部门",
"alias": "本人部门",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "本人部门",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 8,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "本人姓名",
"alias": "本人姓名",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "本人姓名",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 9,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "数值",
"alias": "数值",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "数值",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 10,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "地址",
"alias": "地址",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "地址",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 11,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "设备二维码",
"alias": "设备二维码",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "设备二维码",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 12,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "本人ID",
"alias": "本人ID",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "本人ID",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 13,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "富文本",
"alias": "富文本",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "富文本",
"unit": "",
"configInfo": "",
"presetValue": "富文本默认值",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 14,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "编码",
"alias": "编码",
"uiGroup": "文本类",
"tableGroup": null,
"type": "文本",
"shape": "编码",
"unit": "",
"configInfo": "一般编码.EGJZ",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 1,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 15,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "选择器类",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "选择器",
"alias": "选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "选择器",
"unit": "",
"configInfo": "维修工单反映区名",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 16,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "选择器_关联选择器父",
"alias": "选择器_关联选择器父",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "选择器",
"unit": "",
"configInfo": "维修工单上报类型",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 17,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "选择器_关联选择器子",
"alias": "选择器_关联选择器子",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "选择器",
"unit": "",
"configInfo": "选择器_关联选择器父.维修工单上报内容",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 18,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "搜索选择器",
"alias": "搜索选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "搜索选择器",
"unit": "",
"configInfo": "维修工单反映区名.n",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 19,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "值选择器",
"alias": "值选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "值选择器",
"unit": "",
"configInfo": "测试1,测试2,测试3,测试4",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 20,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "值复选器",
"alias": "值复选器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "值复选器",
"unit": "",
"configInfo": "test1,test2,test3,test4,test5",
"presetValue": "test5",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 21,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "业务选择器",
"alias": "业务选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "业务选择器",
"unit": "",
"configInfo": "台账_形态测试表.唯一值文本.n",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 22,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "可编辑值选择器",
"alias": "可编辑值选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "可编辑值选择器",
"unit": "",
"configInfo": "demo1,demo2,demo3,demo4,demo5",
"presetValue": "demo3",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 23,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "平铺值选择器",
"alias": "平铺值选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "平铺值选择器",
"unit": "",
"configInfo": "事件,工单",
"presetValue": "事件,工单",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 24,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "站点选择器",
"alias": "站点选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "站点选择器",
"unit": "",
"configInfo": "全部.n",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 25,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "人员选择器_下拉框",
"alias": "人员选择器_下拉框",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "人员选择器",
"unit": "",
"configInfo": "平台管理员.n",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 26,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "人员选择器_分组模态",
"alias": "人员选择器_分组模态",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "人员选择器",
"unit": "",
"configInfo": "全部.管理员.n",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 27,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "城市选择器",
"alias": "城市选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "城市选择器",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 28,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "台账选择器",
"alias": "台账选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "台账选择器",
"unit": "",
"configInfo": "形态测试台账.唯一值文本.n",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 29,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "部门选择器",
"alias": "部门选择器",
"uiGroup": "选择器类",
"tableGroup": null,
"type": "文本",
"shape": "部门选择器",
"unit": "",
"configInfo": "",
"presetValue": "部门选择器默认",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 30,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "附件类",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "附件",
"alias": "附件",
"uiGroup": "附件类",
"tableGroup": null,
"type": "文本",
"shape": "附件",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 31,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "可预览附件",
"alias": "可预览附件",
"uiGroup": "附件类",
"tableGroup": null,
"type": "文本",
"shape": "可预览附件",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 32,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "图片",
"alias": "图片",
"uiGroup": "附件类",
"tableGroup": null,
"type": "文本",
"shape": "图片",
"unit": "",
"configInfo": "拍照相册",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 33,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "可预览图片",
"alias": "可预览图片",
"uiGroup": "附件类",
"tableGroup": null,
"type": "文本",
"shape": "可预览图片",
"unit": "",
"configInfo": "拍照相册",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 34,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "录音",
"alias": "录音",
"uiGroup": "附件类",
"tableGroup": null,
"type": "文本",
"shape": "录音",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 35,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "视频",
"alias": "视频",
"uiGroup": "附件类",
"tableGroup": null,
"type": "文本",
"shape": "视频",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 36,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "时间类",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "日期时间",
"alias": "日期时间",
"uiGroup": "时间类",
"tableGroup": null,
"type": "文本",
"shape": "日期时间",
"unit": "",
"configInfo": "默认为当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 37,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "日期",
"alias": "日期",
"uiGroup": "时间类",
"tableGroup": null,
"type": "文本",
"shape": "日期",
"unit": "",
"configInfo": "默认为当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 38,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "日期月份",
"alias": "日期月份",
"uiGroup": "时间类",
"tableGroup": null,
"type": "文本",
"shape": "日期月份",
"unit": "",
"configInfo": "不超过当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 39,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "日期年份",
"alias": "日期年份",
"uiGroup": "时间类",
"tableGroup": null,
"type": "文本",
"shape": "日期年份",
"unit": "",
"configInfo": "不超过当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 40,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "日期周",
"alias": "日期周",
"uiGroup": "时间类",
"tableGroup": null,
"type": "文本",
"shape": "日期周",
"unit": "",
"configInfo": "不超过当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 41,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "时分秒",
"alias": "时分秒",
"uiGroup": "时间类",
"tableGroup": null,
"type": "文本",
"shape": "时分秒",
"unit": "",
"configInfo": "不超过当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 42,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "地图类",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "设备选择",
"alias": "设备选择",
"uiGroup": "地图类",
"tableGroup": null,
"type": "文本",
"shape": "设备选择",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 43,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "坐标控件",
"alias": "坐标控件",
"uiGroup": "地图类",
"tableGroup": null,
"type": "文本",
"shape": "坐标控件",
"unit": "",
"configInfo": "当前坐标",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 44,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "路径控件",
"alias": "路径控件",
"uiGroup": "地图类",
"tableGroup": null,
"type": "文本",
"shape": "路径控件",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 46,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "位置坐标",
"alias": "位置坐标",
"uiGroup": "地图类",
"tableGroup": null,
"type": "文本",
"shape": "位置坐标",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 47,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "GIS编码",
"alias": "GIS编码",
"uiGroup": "地图类",
"tableGroup": null,
"type": "文本",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 1,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 48,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "台账_形态测试表",
"fieldName": "GIS图层",
"alias": "GIS图层",
"uiGroup": "地图类",
"tableGroup": null,
"type": "文本",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 1,
"validateRule": "maxlength:25",
"allowCorrect": 0,
"order": 49,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "台账专有类",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "智能抄表",
"alias": "智能抄表",
"uiGroup": "台账专有类",
"tableGroup": null,
"type": "文本",
"shape": "智能抄表",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 50,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "(无)",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "",
"schema": [
{
"tableName": "台账_形态测试表",
"fieldName": "高级表单",
"alias": "高级表单",
"uiGroup": "",
"tableGroup": null,
"type": "文本",
"shape": "关联表单",
"unit": "",
"configInfo": "{\"台账名称\":\"二供泵房\",\"默认显示\":true,\"控制规则\":\"\",\"映射字段\":[{\"fromField\":\"工单编号\",\"toField\":\"设备分类\"}]}",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:127",
"allowCorrect": 0,
"order": 51,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
}
],
values: [
{ 'fieldName': '编码', fieldValue: '213' }
]
}
export const options2 = {
groups: [
{
"groupName": "维修派单",
"schema": [
{
"tableName": "工单_维修填报",
"fieldName": "分支环节2",
"alias": "分支环节2",
"uiGroup": "维修派单",
"tableGroup": null,
"type": "文本",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "这是维修派单环节",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:255",
"allowCorrect": 0,
"order": 30,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "工单_维修填报",
"fieldName": "服务人员",
"alias": "服务人员",
"uiGroup": "维修派单",
"tableGroup": null,
"type": "文本",
"shape": "文本",
"unit": "",
"configInfo": "",
"presetValue": "张建开",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:50",
"allowCorrect": 0,
"order": 31,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "工单_维修填报",
"fieldName": "派单提交时间",
"alias": "派单提交时间",
"uiGroup": "维修派单",
"tableGroup": null,
"type": "文本",
"shape": "日期时间",
"unit": "",
"configInfo": "默认为当前时间",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:50",
"allowCorrect": 0,
"order": 32,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "维修接单",
"schema": [
{
"tableName": "工单_维修填报",
"fieldName": "是否接单",
"alias": "是否接单",
"uiGroup": "维修接单",
"tableGroup": null,
"type": "文本",
"shape": "平铺值选择器",
"unit": "",
"configInfo": "是,否",
"presetValue": "是",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "required,maxlength:50",
"allowCorrect": 0,
"order": 34,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
},
{
"tableName": "工单_维修填报",
"fieldName": "接单提交时间",
"alias": "接单提交时间",
"uiGroup": "维修接单",
"tableGroup": null,
"type": "文本",
"shape": "日期时间",
"unit": "",
"configInfo": "",
"presetValue": "",
"rowSpan": 1,
"colSpan": 1,
"readOnly": 0,
"validateRule": "maxlength:50",
"allowCorrect": 0,
"order": 35,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
},
{
"groupName": "维修处理",
"schema": [
{
"tableName": "工单_维修填报",
"fieldName": "管道资产",
"alias": "维修要素清单",
"uiGroup": "维修处理",
"tableGroup": null,
"type": "文本",
"shape": "关联表单",
"unit": "",
"configInfo": "{\"台账名称\":\"维修要素清单\",\"默认显示\":false,\"控制规则\":\" {工单_维修填报.是否收费} ='是'\",\"映射字段\":[{\"fromField\":\"工单编号\",\"toField\":\"工单编号\"}]}",
"presetValue": "",
"rowSpan": 1,
"colSpan": 6,
"readOnly": 0,
"validateRule": "maxlength:255",
"allowCorrect": 0,
"order": 38,
"visible": 1,
"isSync": 0,
"triggerProblemValue": "",
"triggerEvent": "",
"triggerEventFields": "",
"showCss": "中"
}
],
"visible": 1
}
],
values: []
}
// 返回设备类型
function returnObjectType(obj) {
return Object.prototype.toString.call(obj);
}
// 返回驼峰
function returnCamelCaseString(str) {
if (returnObjectType(str) === '[object String]') {
return str.slice(0, 1).toLowerCase() + str.slice(1);
}
return str;
}
/**
* @description: 转换key大小写,删除原来的key:value
* @params: {Object} data = {key:value}
* */
function handleObject(data) {
if (returnObjectType(data) !== '[object Object]') return null;
let _data = { ...data };
Object.keys(data).forEach(key => {
let _key = returnCamelCaseString(key);
_data[_key] = switchCamelCase(data[key]);
delete _data[key];
});
return _data;
}
/**
* @description: 处理数组的逻辑
* @params: {Array} data = []
* */
function handleArray(data) {
if (returnObjectType(data) !== '[object Array]') return null;
let _data = [...data];
return _data.map(item => {
});
}
function switchCamelCase(obj) {
let _type = returnObjectType(obj);
let _obj = null;
if (_type === '[object Object]') {
_obj = handleObject(obj);
} else if (_type === '[object Array]') {
_obj = handleArray(obj);
}
return _obj;
}
body {
padding: 10px;
}
::-webkit-scrollbar,
*::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track,
*::-webkit-scrollbar-track {
background-color: rgba(0, 0, 0, 0.02);
border-radius: 0;
}
::-webkit-scrollbar-thumb,
*::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Base example</title>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<div id="root"></div>
<script src="/__build__/base.js"></script>
</body>
</html>
This source diff could not be displayed because it is too large. You can view the blob instead.
html,
body {
color: #2c3e50;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol';
}
ul {
padding-left: 1.5em;
line-height: 1.5em;
}
a {
color: #7f8c8d;
text-decoration: none;
}
a:hover {
color: #4fc08d;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jsonToHtml examples</title>
<link rel="stylesheet" href="/global.css" />
</head>
<body style="padding: 0 20px">
<h1> examples</h1>
<ul>
<li><a href="base">base</a></li>
</ul>
</body>
</html>
\ No newline at end of file
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const WebpackConfig = require('./webpack.config');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const compiler = webpack(WebpackConfig);
app.use(
webpackDevMiddleware(compiler, {
publicPath: '/__build__/',
stats: {
colors: true,
chunks: false,
},
}),
);
const admin = express();
admin.get('/', function (req, res) {
console.dir(admin.mountpath); // [ '/adm*n', '/manager' ]
res.send('Admin Homepage');
});
app.use(['/admin', '/manager'], admin);
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;
module.exports = app.listen(port, () => {
console.log(`Server listening on http://localhost:${port}, Ctrl+C to stop`);
});
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const slash = require('slash');
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: fs.readdirSync(__dirname).reduce((entries, dir) => {
const fullDir = path.join(__dirname, dir);
const entry = path.join(fullDir, 'app.js');
if (fs.statSync(fullDir).isDirectory() && fs.existsSync(entry)) {
entries[dir] = ['webpack-hot-middleware/client', entry];
}
return entries;
}, {}),
output: {
path: path.join(__dirname, '__build__'),
filename: '[name].js',
publicPath: '/__build__/',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
sourceType: 'unambiguous',
babelrc: false,
cacheDirectory: false,
presets: [
[
'@babel/preset-env',
{
targets: { browsers: 'defaults' },
},
],
'@babel/preset-react',
],
plugins: [
'@babel/plugin-syntax-jsx',
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-modules-amd',
[
'babel-plugin-import',
{
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
},
],
['@babel/plugin-proposal-private-methods', { loose: true }],
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
['@babel/plugin-proposal-class-properties', { loose: true }],
],
},
},
},
{
test: /\.css$/,
//exclude: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
},
},
],
},
{
test: /\.(eot|otf|ttf|woff|woff2)$/,
use: 'file-loader',
},
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
// Inline files smaller than 10 kB
limit: 10 * 1024,
noquotes: true,
},
},
],
},
{
test: /\.(jpg|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10 * 1024,
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.jsx', '.js'],
},
plugins: [new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin()],
};
{
"name": "panda-xform",
"version": "1.1.0",
"description": "1.1.0: 项目初始化",
"keywords": [
"panda-xform"
],
"main": "./lib/index.js",
"module": "./es/index.js",
"scripts": {
"build": "cross-env BUILD_TYPE=lib father-build && cross-env BUILD_TYPE=es father-build",
"dev": "node examples/server.js",
"release": "np --no-cleanup --yolo --tag",
"prepublishOnly": "yarn build",
"lint": "yarn lint:js && yarn lint:prettier",
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
"lint:fix": "yarn lint:js -- --fix",
"lint:prettier": "check-prettier lint",
"prettier": "prettier -c --write **/*",
"test": "cross-env NODE_ENV=test jest"
},
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@babel/plugin-proposal-private-property-in-object": "^7.15.4",
"@babel/runtime": "^7.19.0",
"@wangeditor/editor": "^5.1.22",
"@wangeditor/editor-for-react": "^1.0.6",
"@wisdom-components/RichText": "^0.2.10",
"@wisdom-components/basictable": "^1.5.18",
"@wisdom-components/empty": "^1.4.7",
"@wisdom-utils/utils": "0.0.46",
"antd": "4.20.7",
"antd-img-crop": "^3.14.1",
"form-render": "1.6.7",
"fr-generator": "^2.8.3",
"http-proxy-middleware": "^1.0.6",
"moment": "^2.29.1",
"qrcode.react": "^1.0.1",
"react": "17.0.2",
"react-svg": "15.1.9",
"yarn": "^1.22.17"
},
"devDependencies": {
"@babel/plugin-proposal-private-methods": "^7.14.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-jsx": "^7.12.13",
"@babel/plugin-transform-modules-amd": "^7.14.5",
"@umijs/fabric": "^2.0.7",
"@wisdom-map/amap": "^1.0.49--27.11",
"@wisdom-map/arcgismap": "1.4.0-75",
"@wisdom-map/basemap": "1.1.0-14",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"check-prettier": "^1.0.3",
"colors": "^1.3.2",
"core-js": "^3.9.1",
"cross-env": "^7.0.2",
"css-loader": "^4.3.0",
"express": "^4.17.1",
"father-build": "^1.18.1",
"file-loader": "^6.2.0",
"html-loader": "^2.1.1",
"husky": "^2.3.0",
"jest": "^25.2.2",
"less": "3.9.0",
"less-loader": "5.0.0",
"lint-staged": "^9.4.2",
"np": "^5.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^1.18.2",
"prompt": "^1.0.0",
"react-dom": "^17.0.1",
"replace-in-file": "^6.2.0",
"rimraf": "^3.0.0",
"shelljs": "^0.8.4",
"slash": "^3.0.0",
"style-loader": "^2.0.0",
"svg-url-loader": "^7.1.1",
"url-loader": "^4.1.1",
"webpack": "4.46.0",
"webpack-cli": "^3.3.0",
"webpack-dev-middleware": "3.6.2",
"webpack-hot-middleware": "2.24.3"
},
"repository": {
"type": "git",
"url": ""
},
"files": [
"dist",
"es",
"lib"
],
"lint-staged": {
"**/*.{js,ts,json,css,md}": [
"yarn prettier",
"git add"
],
"**/*.{js,ts}": [
"yarn lint:fix",
"git add"
]
},
"jest": {
"moduleFileExtensions": [
"js",
"ts"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.test.js"
],
"testPathIgnorePatterns": [
"/node_modules/",
"/fixtures/"
],
"coveragePathIgnorePatterns": [
"/node_modules/",
"/__tests__/",
"/dist/"
]
},
"author": "dengxiaofeng <1186313486@qq.com>",
"license": "MIT",
"publishConfig": {
"registry": "https://g.civnet.cn:4873"
}
}
\ No newline at end of file
import { request } from '@wisdom-utils/utils/es';
const { REACT_APP_ENV } = process.env;
// 流程列表
/** @Tips: 新版接口,逐步替换老版接口 2021年12月1日 */
const BASE = '/PandaWorkFlow/WorkFlow';
const BASEURL = '/PandaWorkFlow/WorkFlow/AccountManage';
const YOURSELFER_SERVER = 'http://127.0.0.1:8181';
const url = (REACT_APP_ENV || 'dev') !== 'dev' ? `${YOURSELFER_SERVER}/${BASEURL}` : `${window.location.origin}${BASEURL}`;// 新版的链接
/** @End */
/** @Tips: 增加空值检测 */
const NOTHING = [undefined, '', null, void 0]; // void 0 === void 1
/** @End */
// 选择器选项的值查询
/** @Tips: web4版本接口 */
/*export function getSelectName(nodeName) {
return request({
url: `${requestIP}/WorkFlow`,
method: 'get',
});
}*/
// 获取字典的接口
export function getSelectName(nodeName) {
return request({
url: `${BASEURL}/GetSelectItemList?nodeName=${nodeName}`,
method: 'get',
});
}
// 选择器选项的子节点查询
/** @Tips: web4版本接口 */
/* export function getSelectChildName(nodeName) {
return request({
url: `${requestIP}/WorkChildFlow`,
method: 'get',
});
} */
export function getSelectChildName(nodeName) {
return request({
url: `${BASEURL}/WorkChildFlow`,
method: 'get',
});
}
// 站点选择器查询
/** @Tips: web4版本接口 */
/*export function getStationListByUserID(name) {
return request({
url: `${requestIP}/GetStationListByUserID`,
method: 'get',
});
}*/
export function getStationListByUserID(id, sysType, isAll) {
return request({
url: `/PandaWorkFlow/WorkFlow/WorkFlow/GetStationListByUserID?userID=${id}${!NOTHING.includes(sysType) ? '&sysType=' + sysType : ''}${!NOTHING.includes(sysType) ? '&isAll=' + isAll : ''}`,
method: 'get',
});
}
// 人员选择器查询
/** @Tips: web4版本接口 */
/* export function getUserListForRole() {
return request({
url: `${requestIP}/GetUserListForRole`,
method: 'get',
});
} */
export function getUserListForRole() {
return request({
url: `${BASEURL}/GetUserListForRole`,
method: 'get',
});
}
//人员选择器_下拉框
export const getMenTreeByRole = (paramas) => {
const { role, userID } = paramas
return request({
url: `${BASE}/WorkFlow/GetMenTreeByRole?userID=${userID}&role=${role}`,
method: 'get',
})
}
//部门选择器
export const getDeptList = (params) => {
return request({
url: `${BASEURL}/GetDeptList`,
method: 'post',
})
}
// 台账的配置查询
/*export function GetAccountConfigInfo(accountName) {
return request({
url: `${requestIP}/GetAccountConfigInfo`,
method: 'get',
});
}*/
export function GetAccountConfigInfo(accountName) {
return request({
url: `${BASEURL}/GetAccountConfigInfo?accountName=${accountName}`,
method: 'get',
});
}
// 台账的表查询
/*export function GetAccountPageList(pageIndex, pageSize, accountName, info) {
return request({
url: `${requestIP}/GetAccountPageList`,
method: 'get',
});
}*/
export function GetAccountPageList(data) {
return request({
url: `${BASEURL}/GetAccountPageList`,
method: 'post',
data,
});
}
export function GetTableGroupMeta(accountName) {
return request({
url: `${BASEURL}/GetTableGroupMeta?accountName=${accountName}`,
method: 'get'
});
}
// 业务选择器查询
/*export function GetFieldValueFromTable(pageIndex, pageSize, accountName, info) {
return request({
url: `${requestIP}/GetFieldValueFromTable`,
method: 'get',
});
}*/
// NEXT需要增加分页
export function GetFieldValueFromTable(accountName, fieldName, filter) {
return request({
url: `${BASEURL}/GetFieldValueFromTable?tableName=${accountName}&fieldName=${fieldName}${filter ? '&filter=' + filter : ''}`,
method: 'get',
});
}
// 台账表单的提交
/*export function SubmitAccountData(tableName, key, value, data) {
return request({
url: `${requestIP}/EditTableData?tableName=${tableName}&key=${key}&id=${value}`,
method: 'post',
data: data,
});
}*/
export function SubmitAccountData(tableName, key, value, data) {
return request({
url: `${BASEURL}/EditTableData?tableName=${tableName}&key=${key}&id=${value}`,
method: 'post',
data: data,
});
}
// 台账的新增
/*export function AddNewAccountData(data) {
return request({
url: `${requestIP}/`,
method: 'post',
data,
});
}*/
export function AddNewAccountData(data) {
return request({
url: `${BASEURL}/`,
method: 'post',
data,
});
}
/** @Tips: 新版接口,逐步替换老版接口 2021年12月1日 */
// 上传文件
export function UploadFileReturnUrl(data) {
return request({
url: `${url}/UploaderFiles`,
method: 'post',
data,
});
}
export function downloadFile(str) {
return request({
url: `${url}/DownloadFiles?filePath=${str}`,
method: 'get',
});
}
export const uploadFileUrl = `${BASEURL}/UploaderFiles`; // 上传文件链接
export const downloadFileUrl = `${BASEURL}/DownloadFiles`; // 下载/播放文件链接
/** @End */
/**
* @Description: 获取单条数据,使用JsonToHtml去编译
* @Date: 2021/9/29
* @Author: ChenLong
* @Params tableName: 需要查询的表名;includeFields:需要的字段名;id:记录id
* */
export function GetTableDataInfo({ accountName, id }) {
return request({
url: `${BASEURL}/GetTableDataInfo?accountName=${accountName}&id=${id}`,
method: 'GET',
});
}
/**
* @Description: 保存单条数据,使用JsonToHtml去编译
* @Date: 2021/11/1
* @Author: tianxiang
* @Params tableName,values
* */
export function SaveTableDataInfo(data) {
return request({
url: `${BASEURL}/SaveTableDataInfo`,
method: 'post',
data,
});
}
/**
* @Description: 保存单条数据,使用JsonToHtml去编译
* @Date: 2021/11/1
* @Author: tianxiang
* @Params tableName,values
* */
export function EditTableDataInfo(data) {
return request({
url: `${BASEURL}/EditTableDataInfo`,
method: 'post',
data,
});
}
export function DeleteTableDataInfo(data) {
return request({
url: `${BASEURL}/DeleteTableDataInfo`,
method: 'post',
data,
});
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
// 常量集合
/**
* @Description: 新增形态 【时间】相关内容
* @Date: 2021/11/30
* @Edit: ChenLong
* */
import moment from 'moment';
const dateDescribe = {
默认为空: {
initTime: '',
endTime: '',
readOnly: false,
},
默认为当前时间: {
initTime: moment(new Date()),
endTime: '',
readOnly: false,
},
锁定为当前时间: {
initTime: moment(new Date()),
endTime: '',
readOnly: true,
},
不超过当前时间: {
initTime: '',
endTime: moment(),
readOnly: false,
},
};
const dateType = {
日期时间: 'date',
时间: 'time',
日期: 'date',
日期年份: 'year',
日期月份: 'month',
日期周: 'week',
时分秒: 'time',
};
const dateFormat = {
日期时间: 'YYYY-MM-DD HH:mm:ss',
时间: 'YYYY-MM-DD HH:mm:ss',
日期: 'YYYY-MM-DD',
日期年份: 'YYYY',
日期月份: 'YYYY-MM',
日期周: 'YYYY-MM-DD',
时分秒: 'HH:mm:ss',
};
const RegExpObject = {
number: '^(\\-|\\+)?((0\\.\\d+)|([0-9])|([1-9]\\d+(\\.\\d+)?))$',// 数字,支持正、负、浮点数
digits: '^(\\-|\\+)?(\\d|[1-9]\\d+)$', // 整数
email: '^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$', // 邮箱
identity: '(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)',
mobile: '^1(3|4|5|6|7|8|9)\\d{9}$',
bankAccount: '^(\\d{16}|\\d{19})$',
};
const dateArray = { timeControl: ['时间', '仅时间', '日期', '日期月份', '日期年份', '时分秒'] };
const doNotDisplayInEditModelShape = ['编码'];
export { dateDescribe, dateType, dateFormat, RegExpObject, dateArray, doNotDisplayInEditModelShape };
// 公共函数
// 处理校验规则
/**
* @Description: 业务
* 1. 校验规则类型唯一,通过内置的正则来匹配;或者使用自定义输入的正则;增加RegExpString字段,来存储正则表达式;
* 2. 需要处理考虑处理 number,digits,email,identity,mobile,bankAccount;[required,emphasis,sensitive]
* 3. 需要处理时间类 timeControl = ["时间", "仅时间", "日期", "日期月份", "日期年份"];
* 4. 业务逻辑:正则类只有一个 number,digits,email,identity,mobile,bankAccount,timeControl,RegExp=....;
* 样式类可以有多个[required,emphasis,sensitive]
* 5. 特殊情况:文本类的字段,返回的validateRule内会有maxLength和maxlength两个,这时候需要使用maxlength并且乘以2(数据库使用)
* 使用replace替换掉没,然后统计长度
* */
import {RegExpObject, dateArray} from './constant';
const returnMessage = (key) => {
let obj = {
number: '请输入数字',
digits: '请输入整数',
email: '请输入符合规则的邮箱账号',
identity: '请输入正确的身份证号',
mobile: '请输入正确的手机号',
bankAccount: '请输入正确的银行卡账号',
others: '输入不符合规则,请查看'
};
return obj[key];
};
const handleSinglePattern = (pattern, obj) => {
/**
* @Description:
* 1. 首先判断是否有冒号,确定是否是maxlength的校验规则;
* 2. 分别判断是不是 required、emphasis、sensitive等样式熟悉;
* 3. 类型判断并设定正则,分别为内置的六种和按照RegExp=...规则自己输入的;
* 4. 如果不是正则类型,则最后一种是时间类型;
* */
/**
* obj可能存在的字段如下
* maxLength,minLength;
* required,emphasis,sensitive;
* number,digits,email,identity,mobile,bankAccount;
* timeControl;
* */
if (pattern.indexOf(':') > -1) {
const maxLengthArr = pattern.split(':');
if (maxLengthArr[0] === 'maxlength') {
obj.minLength = null;
obj.maxLength = parseInt(maxLengthArr[1]) * 2;
}
if (maxLengthArr[0] === 'maxLength') {
obj.minLength = null;
obj.maxLength = parseInt(maxLengthArr[1]);
}
} else if (['required', 'emphasis', 'sensitive'].includes(pattern)) {
obj[pattern] = true;
} else if (pattern.indexOf('RegExp=') > -1) {
obj.RegExp = pattern.replace('RegExp=', '');
obj.message = returnMessage('others');
} else if (['number', 'digits', 'email', 'identity', 'mobile', 'bankAccount'].includes(pattern)) {
obj.RegExp = RegExpObject[pattern];
obj.message = returnMessage(pattern);
} else if (pattern === 'timeControl') {
// obj.isDateArray = true; ??问题待解决
}
};
const handlePattern = ValidateRule => {
const obj = {};
// 如果不存在校验规则,直接返回
if (!ValidateRule) {
return {};
}
// 如果只有一条校验规则
if (ValidateRule.indexOf(',') < 0) {
handleSinglePattern(ValidateRule, obj)
} else {
const arr = ValidateRule.split(',');
// 如果存在maxLength并且存在maxlength(后端为了确保存储正常,将数据库该字段可存储长度也一并返回了:maxlength)
let _index1 = arr.indexOf('maxLength');
let _index2 = arr.indexOf('maxlength');
if (_index1 > -1 && _index2 > -1) {
arr.splice(_index1,1)
}
arr.forEach(item => {
handleSinglePattern(item, obj)
});
}
return obj;
};
export {handlePattern};
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 allSetting = {
...commonSettings,
...switchSettings,
...elementSettings
}
const settings = [
{
title: '布局类',
widgets: [
{
text: '分组名称',
name: '分组名称',
schema: {
title: '分组名称',
type: 'object',
properties: {}
},
setting: {
hidden: {
title: '隐藏',
type: 'boolean',
widget: 'BooleanSwitch',
default: false,
displayType: 'row',
labelWidth: 80,
},
},
},
],
},
{
title: '文本类',
widgets: [
{
text: '文本',
name: '文本',
schema: {
title: '文本',
type: 'string',
widget: 'TextInput',
},
setting: {
...allSetting
},
},
{
text: '唯一值文本',
name: '唯一值文本',
schema: {
title: '唯一值文本',
type: 'string',
widget: 'UniqueValue'
},
setting: {
...allSetting
},
},
{
text: '多行文本',
name: '多行文本',
schema: {
title: '多行文本',
type: 'string',
widget: 'TextArea'
},
setting: {
...allSetting
},
},
{
text: '数值',
name: '数值',
schema: {
title: '数值',
type: 'number',
widget: 'NumberInput'
},
setting: {
...allSetting
},
},
{
text: '本人部门',
name: '本人部门',
schema: {
title: '本人部门',
type: 'string',
name: '本人部门',
widget: 'SelfInfo'
},
setting: {
...allSetting
},
},
{
text: '本人姓名',
name: '本人姓名',
schema: {
title: '本人姓名',
name: '本人姓名',
type: 'string',
widget: 'SelfInfo'
},
setting: {
...allSetting
},
},
{
text: '本人ID',
name: '本人ID',
schema: {
title: '本人ID',
name: '本人ID',
type: 'string',
widget: 'SelfInfo'
},
setting: {
...allSetting
},
},
{
text: '富文本',
name: '富文本',
schema: {
title: '富文本',
name: '富文本',
type: 'string',
widget: 'RichText'
},
setting: {
...allSetting
},
},
],
},
{
title: '选择器类',
widgets: [
{
text: '值选择器',
name: '值选择器',
schema: {
title: '值选择器',
name: '值选择器',
type: 'string',
widget: 'ValueSelect',
require: true,
},
setting: {
...commonSettings,
options: {
title: '可选值',
type: 'string',
widget: 'EnumOptions',
displayType: 'row',
labelWidth: 80,
},
isMultiple: {
title: '是否多选',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
},
...switchSettings,
...elementSettings,
}
},
{
text: '平铺值选择器',
name: '平铺值选择器',
schema: {
title: '平铺值选择器',
name: '平铺值选择器',
type: 'string',
widget: 'TileSelect',
require: true,
},
setting: {
...commonSettings,
options: {
title: '可选值',
type: 'string',
widget: 'EnumOptions',
displayType: 'row',
labelWidth: 80,
},
isMultiple: {
title: '是否多选',
name: '是否多选',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
},
...switchSettings,
...elementSettings,
}
},
{
text: '搜索选择器',
name: '搜索选择器',
schema: {
title: '搜索选择器',
name: '搜索选择器',
type: 'string',
widget: 'SearchSelect',
require: true,
},
setting: {
...commonSettings,
options: {
title: '数据字典',
type: 'string',
widget: 'input',
displayType: 'row',
labelWidth: 80,
},
isMultiple: {
title: '是否多选',
name: '是否多选',
type: 'boolean',
widget: 'BooleanSwitch',
displayType: 'row',
labelWidth: 80,
},
...switchSettings,
...elementSettings,
}
},
{
text: '关联选择器',
name: '关联选择器',
schema: {
title: '关联选择器',
name: '关联选择器',
type: 'string',
widget: 'CascadeSelect',
require: true,
},
setting: {
...commonSettings,
dependencies: {
title: '关联字段',
type: 'array',
widget: 'CascadeField',
displayType: 'row',
labelWidth: 80,
},
// isMultiple: {
// title: '是否多选',
// type: 'boolean',
// widget: 'BooleanSwitch',
// displayType: 'row',
// labelWidth: 80,
// },
...switchSettings,
...elementSettings,
}
},
{
text: '人员选择器',
name: '人员选择器',
schema: {
title: '人员选择器',
name: '人员选择器',
type: 'string',
widget: 'PersonSelect',
require: true,
},
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,
},
...switchSettings,
...elementSettings,
}
},
],
},
{
title: '时间类',
show: true,
useCommon: true,
widgets: [
{
text: '日期选择',
name: '日期选择',
schema: {
title: '日期选择',
type: 'string',
widget: 'DateTime',
},
setting: {
...commonSettings,
presetValue: {
title: '默认值',
type: 'string',
displayType: 'row',
labelWidth: 80,
widget: 'date',
},
format: {
title: '日期格式',
type: 'string',
enum: ['date', 'dateTime', 'year', 'month', 'quarter', 'week'],
default: 'date',
enumNames: ['日期', '日期时间', '日期年份', '日期月份', '日期季度', '日期周'],
displayType: 'row',
labelWidth: 80,
},
...switchSettings,
...elementSettings,
},
},
{
text: '时间选择',
name: '时间选择',
schema: {
title: '时间选择',
type: 'string',
widget: 'Time',
format: 'time',
},
setting: {
...commonSettings,
presetValue: {
title: '默认值',
type: 'string',
widget: 'time',
format: 'time',
displayType: 'row',
labelWidth: 80,
},
...switchSettings,
...elementSettings,
},
},
],
},
{
title: '附件类',
show: true,
useCommon: true,
widgets: [
{
text: '附件',
name: '附件',
schema: {
title: '附件',
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',
},
},
],
},
{
title: '地图类',
show: true,
useCommon: true,
widgets: [
{
text: '坐标控件',
name: '坐标控件',
schema: {
title: '坐标控件',
type: 'string',
widget: 'DateSelect',
},
},
],
},
]
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
import React, { useRef, useMemo, useState, useContext } from 'react'
import { ConfigProvider, message } from 'antd'
import Generator from 'fr-generator'
import { settings, baseSettings, globalSettings } from './config'
import widgets from '../widgets'
const FormDesigner = (props) => {
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext)
const prefixCls = getPrefixCls('parse-form')
const prefixClsWithoutParseForm = getPrefixCls()
const ref = useRef(null)
const extraButtons = [
{
text: '提交',
onClick: (value) => {
const errors = ref.current.getErrorFields()
if (errors.length) {
return message.error('请按照提示完善表单内容')
}
}
}
]
const getId = (value) => {
// console.log('value', value)
return value
}
const onChange = (value) => {
// console.log('value', value)
}
const onSchemaChange = (value) => {
// console.log('value', value)
return value
}
const onCanvasSelect = (schema) => {
// setWidget(schema.widget)
// console.log('value', value)
}
return (
<div className={prefixCls}>
<Generator
configProvider={{ prefixCls: prefixClsWithoutParseForm }}
// getId={name => name ? `${name}_${count++}` : null}
mapping={{
object: 'Header',
}}
validation={true}
ref={ref}
extraButtons={extraButtons}
onChange={onChange}
onSchemaChange={onSchemaChange}
widgets={widgets}
onCanvasSelect={onCanvasSelect}
settings={settings}
commonSettings={baseSettings}
globalSettings={globalSettings}
/>
</div>
)
}
export default FormDesigner
\ No newline at end of file
import React, { useContext } from 'react'
import { Divider, ConfigProvider } from 'antd'
import './index.less'
const Header = (props) => {
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext)
const prefixCls = getPrefixCls('parse-form')
const { title } = props
return (
<div>
<div
className={`${prefixCls}-title`}
style={{ justifyContent: 'left' }}
>
{title ? <i className={`${prefixCls}-bg`}></i> : null}
{title}
</div>
{title ? <Divider /> : ''}
{props.children}
</div>
)
}
export default Header
\ No newline at end of file
@import '~antd/es/style/themes/default.less';
@parse-form-prefix-cls: ~'@{ant-prefix}-parse-form';
.@{parse-form-prefix-cls} {
.@{parse-form-prefix-cls}-title {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
}
.@{parse-form-prefix-cls}-bg {
width: 3px;
height: 16px;
margin-right: 10px;
background-color: #337ab7;
}
.fr-label-object {
.fr-label-title {
padding: 10px 10px 0 0;
}
.fr-label-title::after {
content: '';
}
}
.b--black-20 {
border-color: rgba(232, 240, 237, 1);
}
}
\ No newline at end of file
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1665553984169"
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2541"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<path
d="M283.083845 290.799062c0 126.207423 102.313224 228.5186 228.511437 228.5186 126.2064 0 228.514507-102.311177 228.514507-228.5186 0-126.202307-102.308107-228.51553-228.514507-228.51553C385.390929 62.283532 283.083845 164.596755 283.083845 290.799062L283.083845 290.799062zM647.796314 519.854898c-39.302121 25.200962-86.044702 39.814798-136.202055 39.814798-50.154283 0-96.894817-14.613836-136.197962-39.814798-171.106006 56.998155-294.485011 218.435964-294.485011 408.697239 0 11.157107 0.422625 22.218024 1.254573 33.164331l858.852706 0c0.831948-10.946306 1.255597-22.007223 1.255597-33.164331 0-190.261275-123.372865-351.698061-294.483988-408.697239L647.796314 519.854898zM647.796314 519.854898"
p-id="2542"></path>
</svg>
\ No newline at end of file
import React from 'react'
import { ReactSVG } from 'react-svg'
const style = {
width: '14px',
height: '18px'
}
function getAll(context) {
return context.keys().reduce((o, modulePath, i) => {
o[modulePath.replace(/.\/|.svg/g, '')] = props => {
return <ReactSVG style={style} src={context.keys().map(context)[i]} {...props} />;
};
return o;
}, {});
}
const IconPack = getAll(require.context('./icons', false, /\.svg$/))
export default IconPack
\ No newline at end of file
/*
* 地图中,显示的是墨卡托坐标,使用在地图上来做交互是用的经纬度坐标
* */
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 }) => {
const { disabled, placeholder } = schema
const { extraData, setExtraData } = useContext(GlobalStore);
const [coordinate, setCoordinate] = useState('');
const [layersConifg, setLayersConifg] = useState(() => {
const mapConfig = window.globalConfig.mapsettings?.layers || null;
return { layers: mapConfig };
});
const mapSettings = window.globalConfig.mapsettings;
const layers = window.globalConfig.mapsettings.layers;
const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false);
const [currentPointer, setCurrentPointer] = useState([]);
const [initCoordinate, setInitCoordinate] = useState([]);
const [currentPointerCoordinate, setCurrentPointerCoordinate] = useState([]);
const [view, setView] = useState(null);
const [coordGetLayers, setCoordGetLayers] = useState(null);
let _temp = [];
/* let _tempCoordinateArray = [];
let _lnglatArray = [];*/
/*
* 问题:在getAMapInfo中,react的hook函数无法生效
* */
// 这个是使用高德地图的点生成的写法
/* const
= (AMap, map) => {
if (currentPointerCoordinate && currentPointerCoordinate.length) {
var initMarker = new AMap.Marker({
content: `<div>
<p style="position: absolute;background: #ffffff;padding: 4px;top:-50px;left:20px;border-radius: 4px">经纬度坐标: [${currentPointerCoordinate[0]},${currentPointerCoordinate[1]}]</p>
<img src="https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png" alt="">
</div>`,
icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
position: currentPointerCoordinate,
anchor: 'bottom-center'
});
map.add(initMarker);
setCurrentPointer([initMarker]);
_temp.push(initMarker);
}
map.on('click', function (e) {
if (_temp.length) map.remove(_temp);
var marker = new AMap.Marker({
content: `<div>
<p style="position: absolute;background: #ffffff;padding: 4px;top:-50px;left:20px;border-radius: 4px">经纬度坐标: [${e.lnglat.getLng()},${e.lnglat.getLat()}]</p>
<img src="https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png" alt="">
</div>`,
icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
position: [e.lnglat.getLng(), e.lnglat.getLat()],
anchor: 'bottom-center'
});
setCurrentPointer([marker]);
_temp = [marker];
setCurrentPointerCoordinate([e.lnglat.getLng(), e.lnglat.getLat()]);
map.add(marker);
})
};*/
const getAMapInfo = (AMap, map) => {
let geocoder;
AMap.plugin('AMap.Geocoder', function () {
geocoder = new AMap.Geocoder({
city: "010", //城市设为北京,默认:“全国”
radius: 1000 //范围,默认:500
});
});
if (value && value.length) {
let _value = value.split(',');
const initMarker = mktlng({ x: _value[0], y: _value[1] }); // @Return: { lat: xxx,lng: xxx };
const polintLayer = new PointLayer({
Amap: AMap,
map,
markersOption: {
content: `<div>
<p style="position: absolute;background: #ffffff;padding: 4px;top:-50px;left:20px;border-radius: 4px;width: 300px;">坐标: [${_value[0]},${_value[1]}]</p>
<img src="https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png" alt="">
</div>`,
icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
position: [initMarker.lng, initMarker.lat],
anchor: 'bottom-center'
}
});
map.setCenter([initMarker.lng, initMarker.lat]);
}
map.on('click', function (e) {
let _position = [e.lnglat.getLng(), e.lnglat.getLat()];
geocoder.getAddress(_position, function (status, result) {
if (status === 'complete' && result.regeocode) {
let address = result.regeocode.formattedAddress;
let _extraData = { ...extraData };
_extraData.address = address;
setExtraData(_extraData);
} else {
log.error('根据经纬度查询地址失败');
}
});
// 暂时未能找到封装后的框架提供的remove方法
map.getAllOverlays().forEach(item => {
if (item.className === 'AMap.Marker') {
map.remove(item);
}
});
let marker = new PointLayer({
Amap: AMap,
map,
markersOption: {
content: `<div>
<p style="position: absolute;background: #ffffff;padding: 4px;top:-50px;left:20px;border-radius: 4px;width: 300px;">坐标: [${e.pos[0]},${e.pos[1]}]</p>
<img src="https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png" alt="">
</div>`,
icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
position: _position,
anchor: 'bottom-center',
}
});
setCurrentPointerCoordinate([e.pos[0], e.pos[1]]);
let _lng = e.lnglat.getLng();
let _lat = e.lnglat.getLat();
// map.setCenter([_lng, _lat]);
_temp.push(marker);
});
};
const getView = (viewObject) => {
if (viewObject) {
setView(viewObject);
let coordGetLayer = viewObject.map.layers.find(layer => layer.id == 'coordGet');
if (coordGetLayer) {
viewObject.map.remove(coordGetLayer);
} else {
coordGetLayer = new GraphicsLayer({
id: 'coordGet',
});
}
viewObject.map.add(coordGetLayer);
if (value) {
coordGetLayer.removeAll();
const newVal = value.split(",");
const defalutGraphic = createGraphic(new Point({
x: newVal[0],
y: newVal[1],
spatialReference: {
wkid: 3857
}
}));
coordGetLayer.add(defalutGraphic);
}
setCoordGetLayers(coordGetLayer);
getPoints(viewObject, coordGetLayer);
}
};
const createGraphic = (geometry) => {
return new Graphic({
geometry: geometry,
symbol: {
type: "picture-marker", // autocasts as new PictureMarkerSymbol()
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAhCAYAAAA2/OAtAAAACXBIWXMAAArrAAAK6wGCiw1aAAAGlmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4xLWMwMDAgNzkuZWRhMmIzZiwgMjAyMS8xMS8xNC0xMjozMDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIzLjEgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0xMC0xN1QwOTowODoxNSswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTAtMTdUMDk6MTU6MzMrMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMTAtMTdUMDk6MTU6MzMrMDg6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1OTQyNjQzLWNlYzgtNjU0NS05YmY0LTYyZmYxYjdiYmY1OSIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjE3M2JmMDVmLWVmZGUtMzY0YS1hY2UxLTkwMGExYmZhZDU1NCIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjc0ZmE3MTM1LTljYTItZTM0OC04MjY1LTRjYTlhYjMzNDRmMyI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NzRmYTcxMzUtOWNhMi1lMzQ4LTgyNjUtNGNhOWFiMzM0NGYzIiBzdEV2dDp3aGVuPSIyMDIyLTEwLTE3VDA5OjA4OjE1KzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjMuMSAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmJmNjg5ZTI3LWJkMDYtMjk0YS1hYWMyLWU2MjY3ODg2Nzg2MiIgc3RFdnQ6d2hlbj0iMjAyMi0xMC0xN1QwOToxNTozMyswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIzLjEgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NTk0MjY0My1jZWM4LTY1NDUtOWJmNC02MmZmMWI3YmJmNTkiIHN0RXZ0OndoZW49IjIwMjItMTAtMTdUMDk6MTU6MzMrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMy4xIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5EbHqSAAADjklEQVRIia2W32scVRTHP+fOZM2P3RpDmhobEpBY0qBo5kGEDYsUC+qrUNG2/4AvBaEPvvnWBxXbKqjPPghK6Zt0Nb98qYK6RUUtRce4tARiGuNOlmw2e+/xYXbT3exkk1S/cJiZM/d+7jkzZ84dYRcVMt4kcBaYBkaAAWAVKALXgY+DyP6SNFcSYCPAW8CpYc+ZtEAXiidgFaoIZYUlaxzwKXA+iOztXaGFjPc88Mmw5/qHjO6WxLaWnbBkzRrwchDZL9qghYz3InB1zHOpQ3Wgq98zHcAlJ/xpTRV4IYjs3Da0kPFGgR/GfNefkRiogAX8PeONwcU44ieDyBYbQVwaMq6/D8UpOIWagqmfb5vnx8fedIs/LcqQcf3AJQApZLzHgZ8mfJccRrOMAeegLw3l9bbbN2sG4AkfOD1olH0g70naigaAQaOsODntA8/1yH6hMUz8LpJqo1sUkBM+MOEJnaEioArOxpfWJkL9eM0JH0ije0C1jvA8sBbZ2tp2JeiQD9Ts9iL7kxhJjLTuq/rAYhXGO9ZjI/36C5J7gBbV4sOiD1zfVBk3nUJVQAyIB1hEPLS9bbAZr/SNAa5sqLQWeZI5RY2pn7vEMRsqAFekkPEM8Osh0WOpgzzYHaoqlFRuAcdNEFkHnCup4OC+zAKlOMpzQWSdAQgiew24XFbB1gcdxMox8O06p6X1pYCvHhB9JnWAtDdVqMIccLKedVuTHgVudAsD3j6ANWBTuQ1MBZFdafhb+m8Q2SJwtqJ7p1wHVoGXmoFtkTZF/I4Hr3sdqqGmUDXm/JvZk5eb3A5widO+PJxJDVQ2vvbQIGkrcUDVmGsXnn72lYrf9i26xEf3V+5E38Dmxo0j5ehVAV+JP6qGWWR1ZnT8zG/9A1tA1w7zE/c0VTWfjU8ur/T0XUyqyzvpzIWFo2MVVU3vsG5VXUuE5vP5Nedc5aPJqatbxhSbgVvGFD+cnFpwzqWbrNc5V3LOLebz+cqulROG4T9Hxx/rGVsvyeHKRs4hCPD7gw998N3g8B9N6d4Fbs3MzJTCMFSAjuUYhuFq7ang7+nlO6dQekRk7f3jU+9WxXiqWlbVn2dnZ5fCMGzp8Xtu65Hn/7jc3fv5kXL5zFJv38K65xtUi/Pz8zf3mttRFx8dmf4+4+kbk8dey+VyI/8J1lA2m03NDfR8m81mH/lfgA29N/pwbr9j77ctd/pn419SR9UArKBoRwAAAABJRU5ErkJggg==",
width: "20px",
height: "30px"
}
,
});
};
const getPoints = (view, coordGetLayer) => {
drawTool.activate({
view,
action: 'point',
target: 'erroSendUpWidget',// 随便写
toolTip: '左键选择位置',
drawEnd: geometry => {
setCurrentPointerCoordinate([geometry.x, geometry.y]);
coordGetLayer && coordGetLayer.removeAll();
const coordGraphic = createGraphic(geometry);
coordGetLayer.add(coordGraphic);
getPoints(view, coordGetLayer);
},
rightClick: () => { getPoints(view, coordGetLayer); }
});
};
const showMap = () => {
if (!schema.disabled) {
setVisible(true);
}
};
const onCancel = () => {
setCurrentPointerCoordinate(initCoordinate);
setVisible(false);
};
const onOk = () => {
setVisible(false);
onChange(currentPointerCoordinate.join(','));
};
useEffect(() => {
if (value) {
let _temp = value && value.split(',') || [];
setCurrentPointerCoordinate(_temp);
setInitCoordinate(_temp);
}
}, [value]);
const getCityName = () => {
let cityName = '中华人民共和国';
if (layersConifg && layersConifg.layers) {
let pipeNetLayer = layersConifg.layers.find(item => {
return item.layerType == 'PipenetLayer';
});
if (!pipeNetLayer) {
pipeNetLayer = layersConifg.layers[0];
}
cityName = pipeNetLayer.areaName;
}
return cityName;
};
return (
<div>
<Input
disabled={disabled}
placeholder={placeholder}
value={value}
addonAfter={disabled ? null : <CompassOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} onClick={showMap} />}
style={{ width: '100%' }}
/>
<Modal
width={'80%'}
title="选取坐标"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: "auto", position: 'relative' }}
destroyOnClose={true}
>
<div style={{ height: '90%' }}>
<ArcGISSceneMap
getMapInfo={getView}
widgets={[]}
config={layersConifg}
/>
{view ? <div style={{ width: '400px', position: 'absolute', right: '0', top: '25px' }}><AutoCompleteSearch
areaName={getCityName()} view={view} /></div> : ''}
</div>
</Modal>
</div>
);
};
export default CoordinatePicker;
/*
* 地图中,显示的是墨卡托坐标,使用在地图上来做交互是用的经纬度坐标
* */
import React, {useState, useEffect, useContext} from 'react';
const CoordinatePicker = ({value}) => {
return <div>{value || '地图组件暂不可用'}</div>
};
export default CoordinatePicker;
import React, { useState, useRef, useEffect } from 'react'
import { Input, Modal } from 'antd'
import { CompassOutlined, CloseOutlined } from '@ant-design/icons'
import { ArcGISSceneMap, ClickQuery, geomUtils } from '@wisdom-map/arcgismap'
import './index.less'
let geometrystr = ''
const Device = ({ value, onChange, schema }) => {
const mapConfig = window.globalConfig.mapsettings?.layers || null
const { placeholder, disabled } = schema
const [visible, setVisible] = useState(false)
const layersConifg = { layers: mapConfig }
let clickref = useRef(null)
let view = useRef(null)
const close = () => {
clickref.current.closetip()
}
const confirm = (geometry) => {
const { x, y } = geometry
if (x && y) {
onChange(`${x},${y}`)
setVisible(false)
}
}
const tip = (data) => {
if (!Array.isArray(data)) return null
const { displayFieldName, fields, attributes, geometry } = data[0]
if (geometry) {
geometrystr = `${geometry.x},${geometry.y}`
}
useEffect(() => {
if (clickref.current) {
view.current.goTo({
center: geomUtils.toGeometry({ x: geometry.x, y: geometry.y + 400 }),
zoom: 15
})
}
}, [data])
return (
<div className='tip'>
<div className='tip-header'>
<div>{displayFieldName}</div>
<span className='tip-close' onClick={() => close()}><CloseOutlined /></span>
</div>
<div className='tip-content'>
{
fields?.map(v => {
if (v.editTypeMobile !== '隐藏') {
return (
<div className='tip-list'>
<div className='tip-list-left'>{v.name || v.alias}</div>
<div className='tip-list-right'>{attributes[v.name]}</div>
</div>
)
}
return null
})
}
</div>
<div className='tip-footer'>
<span className='confirm' onClick={() => confirm(geometry)}>确定</span>
<div className='triangle'></div>
<div className='angle'></div>
</div>
</div>
);
};
const getMapInfo = (mapObj, Map) => {
setTimeout(() => {
if (mapObj) {
view.current = mapObj
}
let arr = value && value.split(',')
let obj = (arr.length === 2) ? { point: { x: Number(arr[0]), y: Number(arr[1]) } } : {}
clickref.current = new ClickQuery({
view: view.current,
tipcontent: tip,
offsetX: -150,
offsetY: -310,
continuous: true,
...obj
})
}, 500)
}
const iconClick = () => {
if (!schema.disabled) {
setVisible(true)
}
}
const onOk = () => {
onChange(geometrystr)
setVisible(false)
}
const onCancel = () => {
setVisible(false)
}
return (
<div>
<Input
disabled={disabled}
value={value}
placeholder={placeholder}
addonAfter={disabled ? null : <CompassOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} onClick={iconClick} />}
style={{ width: '100%' }}
/>
<Modal
visible={visible}
title='设备选择'
width={'80%'}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
bodyStyle={{ height: 600, overflowY: 'auto', position: 'relative' }}
destroyOnClose={true}
>
<ArcGISSceneMap
getMapInfo={getMapInfo}
widgets={[]}
config={layersConifg}
/>
</Modal>
</div>
)
}
export default Device
\ No newline at end of file
.tip {
width: 300px;
background: white;
padding: 0;
.tip-header {
background: #637cf7;
height: 30px;
line-height: 30px;
color: white;
padding-left: 20px;
position: relative;
.tip-close {
position: absolute;
right: 20px;
top: 0;
font-size: 16px;
&:hover {
cursor: pointer;
}
}
}
.tip-content {
height: 240px;
overflow-y: auto;
.tip-list {
display: flex;
height: 25px;
line-height: 25px;
&:nth-child(odd) {
background: rgba(76, 76, 76, .1);
}
.tip-list-left {
width: 50%;
text-align: center;
font-weight: bold;
}
.tip-list-right {
width: 50%;
}
}
}
.tip-footer {
height: 40px;
position: relative;
.confirm {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 2px 7px;
border-radius: 3px;
background: #637cf7;
color: white;
&:hover {
cursor: pointer;
}
}
.triangle {
position: absolute;
bottom: -15px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 15px solid white;
z-index: 16;
}
.angle {
position: absolute;
bottom: -20px;
left: 50%;
transform: translateX(-50%);
border-radius: 50%;
width: 10px;
height: 10px;
background: red;
z-index: 15;
}
}
}
\ No newline at end of file
import React, { useState, useEffect, useRef } from 'react';
import { Input, Modal, Spin, Button } from 'antd';
import { CompassOutlined, SearchOutlined } from '@ant-design/icons';
import { AMapScene, AMapDrawTool, VectorLayer } from '@wisdom-map/amap';
let amapDrawTool = null; // 存储绘制工具实例
let currentMapInstance = null; // 存储地图的实例
let AMapFunction = null; // 存储地图的构造函数
let coverLayer = {}; // 存储分区的地图对象
const DrawPartition = ({ value, onChange, name, schema }) => {
const mapSettings = window.globalConfig.mapsettings;
const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false);
const [partition, setPartition] = useState([]);
const [initPath, setInitPath] = useState([]);
const [finalPathArray, setFinalPathArray] = useState([]);
const [selectedPartition, setSelectedPartition] = useState([]);
const [drawDisabled, setDrawDisabled] = useState(false);
let _temp = [];
/* let _tempCoordinateArray = [];
let _lnglatArray = [];*/
/*
* 问题:在getAMapInfo中,react的hook函数无法生效
* */
const drawFn = (AMap, map) => {
amapDrawTool.draw({
drawMethod: 'repeat',
saveOverlayStatus: 'saveMore',
type: 'Polygon',
drawByUser: true,
drawEnd(e) {
let _arr = map.getLayerByClass('AMap.VectorLayer').getAllOverlays(); // 获取所有矢量图形,这个会包含省市区的边框
// let _arr = []
let _temp = _arr.filter(item => {
let _lng = item.getOptions().extData.lng // 来判断是自己绘制的还是生成的范围框;
if (_lng) {
return true
}
return false
});
_temp = _temp.map(item => {
let _path = item.getPath();
return _path.map(obj => [obj.lng, obj.lat])
})
setFinalPathArray(_temp);
}
})
};
const getAMapInfo = (AMap, map, callback) => {
currentMapInstance = map;
AMapFunction = AMap;
amapDrawTool = new AMapDrawTool({
map, Amap: AMap,
})
let _value = JSON.parse(value);
callback(AMap, map, _value && Array.isArray(_value) && Array.length ? _value : 'init'); // 此时确保实例已经渲染完毕,使用回调绘制区域
setListener();
};
const showMap = () => {
let _array = JSON.parse(value || '');
renderCover(AMapFunction, currentMapInstance, _array)
setVisible(true);
};
const onCancel = () => {
onChange(JSON.stringify(initPath))
setVisible(false);
setDrawDisabled(false);
};
const onOk = () => {
onChange(JSON.stringify(finalPathArray))
setInitPath(finalPathArray);
setVisible(false);
};
const drawStart = (type) => {
setDrawDisabled(true);
currentMapInstance.remove(coverLayer.markers);
drawFn(AMapFunction, currentMapInstance);
renderCover(AMapFunction, currentMapInstance, finalPathArray);
};
const setListener = () => {
let allMarkers = currentMapInstance.getLayerByClass("AMap.VectorLayer").getAllOverlays();
allMarkers.forEach(item => {
item.on('click', function (e) {
if (item.getOptions().isSelected) {
this.setOptions({
strokeColor: '#80d8ff',
isSelected: false
});
} else {
this.setOptions({
strokeColor: 'rgba(115,121,131,0.92)',
isSelected: true
});
}
})
})
}
const drawPause = () => {
// 更新
setDrawDisabled(false);
setInitPath(finalPathArray);
// 结束绘制时,将信息
amapDrawTool.pause();
// 监听鼠标点击
setListener();
};
const deletePartition = () => {
let allMarkers = currentMapInstance.getLayerByClass("AMap.VectorLayer").getAllOverlays();
let _initPath = []
allMarkers.forEach(item => {
if (item.getOptions().isSelected) {
currentMapInstance.remove([item])
} else {
_initPath.push(item.getPath());
}
});
setInitPath(_initPath)
};
const renderCover = (AMap, map, pathData) => {
if (pathData === 'init' || pathData && Array.isArray(pathData) && pathData.length) {
let _pathArray;
if (pathData !== 'init') {
_pathArray = pathData.map((item, index) => ({
type: 'Polygon',
options: {
path: [...item],
fillColor: '#632345',
strokeWeight: 3,
strokeStyle: 'solid',
strokeColor: '#998761',
bubble: false, // 需要做事件监听时,开启冒泡,在地图对象上监听事件,
selfIndex: `marker_${index}`
},
}));
}
coverLayer = new VectorLayer({
Amap: AMap,
map,
datas: pathData !== 'init' ? [..._pathArray] : [],
});
}
};
useEffect(() => {
let _temp = value && JSON.parse(value);
if (_temp) {
setPartition(_temp)
setInitPath(_temp);
}
}, []);
return (
<div style={{ overflow: 'hidden' }}>
<Input
disabled={schema.disabled}
value={value && JSON.stringify(value) || ''}
style={{ width: 0, position: 'absolute', visibility: 'hidden', }}
/>
<Button icon={<SearchOutlined />} onClick={showMap} />
<span style={{ marginLeft: 5 }}>{initPath.length ? `已绘制${initPath.length}块区域` : '未绘制区域'}</span>
{
mapSettings ?
<Modal
width={'80%'}
title="绘制区域"
visible={visible}
onCancel={onCancel}
bodyStyle={{ height: 600, overflowY: 'auto' }}
destroyOnClose={true}
footer={null}
>
{/*{loading && <Spin/>}*/}
<Button type={'primary'} disabled={drawDisabled} style={{ marginBottom: 10, marginRight: 10 }}
onClick={() => drawStart('Polygon')}>开始绘制</Button>
<Button type={'primary'} disabled={!drawDisabled} style={{ marginBottom: 10, marginRight: 10 }}
onClick={() => drawPause('Polygon')}>结束绘制</Button>
<Button type={'danger'} style={{ marginBottom: 10 }} onClick={() => deletePartition()}>删除</Button>
<div style={{ height: '90%' }}>
<AMapScene
getMapInfo={(AMap, map) => getAMapInfo(AMap, map, renderCover)}
mapsettings={mapSettings}
config={mapSettings}
loading
/>
</div>
</Modal> : ''
}
</div>
)
}
export default DrawPartition;
import React, { useState, useEffect, useContext } from 'react'
import { Input, message } from 'antd';
import { GlobalStore } from '../../../../FormRender'
import { AMap } from '@wisdom-map/amap'
const SearchLocation = ({ value, onChange, name, schema }) => {
const { disabled, placeholder } = schema
const { extraData, setExtraData } = useContext(GlobalStore);
const [address, setAddress] = useState('');
const [pos, setPos] = useState('');
const renderSearch = async () => {
// 封装之后的AMap,如果需要使用高德地图上的方法,则需要按照如下方法去使用
AMap.prototype.key = 'e83f64300a2a55a33fa8e4ab9a46bca6';
let map = await AMap.prototype.loadLocaScript();
map.plugin(['AMap.PlaceSearch', 'AMap.AutoComplete'], function (e) {
let auto = new map.AutoComplete({
input: 'searchInput'
});
auto.on('select', function (e) {
if (e?.poi?.location?.pos?.length) {
let _pos = e.poi.location.pos.join(',');
setPos(_pos);
setAddress(e.poi.name);
let _extraData = extraData ? { ...extraData } : {};
_extraData.pos = _pos;
setExtraData(_extraData);
onChange(e.poi.name);
} else {
setAddress('');
setPos('');
onChange('');
message.error('当前地址无坐标,请重新选取')
}
});
})
};
useEffect(() => {
renderSearch();
if (value) setAddress(value);
}, [])
return (
<>
<Input
placeholder={placeholder}
disabled={disabled}
onChange={(e) => {
setAddress(e.target.value)
onChange(e.target.value)
}}
id={'searchInput'}
value={value}
style={{ width: '100%' }}
/>
</>
)
}
export default SearchLocation;
import Coordinate from './Coordinate'
import Device from './Device'
import DrawPartition from './DrawPartition'
import SearchLocation from './SearchLocation'
const coord = {
Coordinate,
Device,
DrawPartition,
SearchLocation,
}
export default coord
\ No newline at end of file
// 自定义时间组件
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';
const DateTime = ({ value, onChange, schema }) => {
console.log('schema', schema)
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)
}, [presetValue, value])
const disabledDate = (current) => {
if (schema.config === '不超过当前时间') {
return current && current > moment();
} 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)
}
// useEffect(() => {
// onChange(dateTime);
// }, []);
return (
<DatePicker
mode={format}
disabled={disabled}
placeholder={placeholder}
value={valueShow}
onChange={dateChange}
picker={dateType[schema.shape]}
showTime={format === 'dateTime'}
style={{ width: '100%' }}
locale={locale}
disabledDate={disabledDate}
/>
);
};
export default DateTime
import React, { useMemo } from 'react'
import { TimePicker } from 'antd'
import moment from 'moment'
const format = 'HH:mm:ss'
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
}, [presetValue, value])
const timeChange = (time, timeStr) => {
console.log(time, timeStr)
}
console.log('valueShow', valueShow)
return (
<TimePicker value={valueShow} onChange={timeChange} format={format} />
)
}
export default Time
\ No newline at end of file
import DateTime from './DateTime'
import Time from './Time'
const date = {
DateTime,
Time
}
export default date
\ No newline at end of file
import Header from './Header'
import setting from './settings'
import text from './text'
import date from './date'
import select from './select'
// import file from './file'
// import coord from './coord'
export default {
Header,
...setting,
...text,
...date,
...select,
// ...file,
// ...coord,
}
\ No newline at end of file
import React, { useEffect } from 'react';
import { Cascader } from 'antd';
import city from '../../../../constant/city';
const CitySelect = ({ value, onChange, name, schema }) => {
const { disabled, placeholder } = schema
const onCascaderChange = selectedValues => {
// const { onChange, getSelectedValues } = this.props;
const result = [];
// 递归查询城市所有数据
function findCityData(city) {
city.forEach(item => {
const { id, label, value, children } = item;
if (selectedValues.includes(value)) {
result.push({ id, label, value });
if (children && children.length) {
findCityData(children);
}
}
});
}
findCityData(city);
// 分发监听
const cityValue = result.map(item => {
return item.label;
});
onChange && onChange(cityValue.join('/'));
};
const getDefaultValue = selectedValues => {
if (!selectedValues || !selectedValues.length) {
return;
}
const result = [];
// 递归查询城市名称数据
function findLabel(children) {
children.forEach(item => {
const { label, value, children } = item;
if (selectedValues.includes(label)) {
result.push(value);
}
if (children && children.length) {
findLabel(children);
}
});
}
// 卡省份解决县或市名称一样的问题
city.forEach(item => {
const { label, value, children } = item;
if (selectedValues.includes(label)) {
result.push(value);
if (children && children.length) {
findLabel(children);
}
}
});
// 设置默认值
return result;
};
useEffect(() => {
onChange(value || schema.default || '');
}, []);
return (
<Cascader
disabled={disabled}
placeholder={placeholder}
options={city}
showSearch={true}
showArrow={!disabled}
value={getDefaultValue(value ? value.split('/') : [])}
onChange={onCascaderChange}
style={{ width: '100%' }}
/>
)
}
export default CitySelect;
// 可编辑值选择器
import React, { useState, useEffect } from 'react';
import { Select } from 'antd';
const { Option } = Select;
const EditSelect = ({ value, onChange, schema }) => {
const { disabled, placeholder } = schema
const children = [];
for (let i = 0; i < schema.enum.length; i++) {
children.push(<Option key={i.toString(36) + i}>{schema.enum[i]}</Option>);
}
const val = value || schema.default;
useEffect(() => {
onChange(val);
}, []);
return (
<Select
disabled={disabled}
showArrow={!disabled}
placeholder={placeholder}
mode={'tags'}
value={value ? value.split(',') : []}
onChange={val => {
onChange(val.join(','))
}}
style={{ width: '100%' }}
>
{children}
</Select>
);
};
export default EditSelect;
// 自定义复选框
import React, { useState, useEffect } from 'react';
import { Select } from 'antd';
const { Option } = Select;
const MultiSelect = ({ value, onChange, schema }) => {
const { disabled, placeholder } = schema
const children = [];
for (let i = 0; i < schema.enum.length; i++) {
children.push(<Option key={schema.enum[i]}>{schema.enum[i]}</Option>);
}
const val = value || schema.default;
useEffect(() => {
onChange(val);
}, []);
return (
<Select
disabled={disabled}
showArrow={!disabled}
mode={'multiple'}
value={value ? value.split(',') : []}
onChange={val => onChange(val.join(','))}
style={{ width: '100%' }}
placeholder={placeholder}
tokenSeparators={[',']}
>
{children}
</Select>
);
};
export default MultiSelect;
import React from 'react'
import PullStaff from './pullStaff'
const PersonSelect = (props) => {
// console.log('schema', schema)
// const {interaction} = schema
// if (props.schema.interaction === '下拉框') {
// return (
// <PullStaff {...props} />
// )
// }
return (
<PullStaff {...props} />
)
}
export default PersonSelect
\ No newline at end of file
/*
** 人员选择器 多选
** create by ChenLong on 2021/12/21
** 功能路径:src\core\components\staffSelect\staffSelect.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
* ** 形态:【人员选择器】
** 现阶段仅支持机构
** 显示名称,存储id,多个id以英文逗分隔
** 配置:全部 [.n] 返回全部的机构及人员列表
机构名称 [.n] 返回设定的机构及人员列表
(机构名称,机构名称 ...) [.n] 返回设定的某几个机构人员列表
* Tip:未剔除原有逻辑,需要后续阅读代码,删除无效代码
** 更新日志:
** edit by ChenLong on 2021/12/21: *****修改内容*****
** edit by ChenLong on 2021/12/28: ***** 支持原有配置(存储人名,显示人名)*****
** edit by ChenLong on 2021/12/28: ***** 存储方式的更改会导致控件的表现异常 *****
** edit by ChenLong on 2022/06/09: ***** 存在使用Modal单独引入后,数据状态始终存在的问题(但是在台账组件中,暂时未发现异常;该问题与使用方式有关)。变更部分逻辑, *****
*/
import React, { useState, useMemo, useEffect } from 'react';
import { Modal, Spin, Input, Checkbox } from 'antd';
import { UserAddOutlined } from '@ant-design/icons';
import Empty from '@wisdom-components/empty';
import { getUserListForRole } from '../../../../apis/process';
import './staffSelect.less';
const { Search } = Input;
const MultipleStaffSelect = ({ value, onChange, schema }) => {
let val = value || schema.default
const [visible, setVisible] = useState(false);
const [defaultPerson, setDefaultPerson] = useState([]);
const [personArr, setPersonArr] = useState([]);
const [searchVal, setSearchVal] = useState('');
const [loading, setLoading] = useState(true);
// 将所选人员存储到一个对象中,key `person_${index}`;
const [allPersonList, setAllPersonList] = useState({});
// 全选
// const [indeterminate, setIndeterminate] = useState(false);
const [allState, setAllState] = useState(false);
const [checkAll, setCheckAll] = useState({});
// 配置清单
const ouConfigArray = schema.config.split('.');
const isAll = ['全部', '全部ID'].includes(ouConfigArray[0]);
const isMultiple = !isAll && ouConfigArray[0].includes(',') && ouConfigArray.includes('(') && ouConfigArray.includes(')'); // (机构名,机构名)
const storeType = useMemo(() => {
return isAll && ouConfigArray[0] === '全部ID' ? 'userID' : 'userName'
}, [isAll, ouConfigArray])
const userNames = useMemo(() => {
if (storeType === 'userName') return value
let userList = personArr.reduce((total, current) => total.concat(current.userList), [])
let array = []
userList?.forEach(v => {
if (value.includes(v.userID)) {
array.push(v.userName)
}
})
return array.join(',')
}, [personArr, value, storeType])
/**
* @Description: 通过判断storeType来决定返回的【已选择人员数组】是存储人名还是ID;
* @Params: 参数描述
* @Date: 2021/12/28
* @Author: ChenLong
* */
const returnCheckedUserIDArray = (values, data = personArr) => {
let _checkedArray = values.split(',');
let _allPersonList = {};
data.forEach((item, index) => {
let _tempArray = [];
item.userList.forEach((obj) => {
if (_checkedArray.includes(obj[storeType])) {
_tempArray.push(obj[storeType]);
}
});
_allPersonList[`person_${index}`] = _tempArray;
});
return _allPersonList;
};
const checkInitNames = (IDs) => {
return IDs.split(',');
};
const getData = () => {
setLoading(true)
let ouConfig = ouConfigArray[0]; // 机构名的配置
getUserListForRole().then(res => {
if (res.code === 0) {
const arr = [];
res.data.forEach(item => {
// 全部机构
if (isAll) {
arr.push(item);
} else if (isMultiple) {
// 多机构
let _ouConfigArray = ouConfig.replace(/\(|\)/g, '').split(',');
if (_ouConfigArray.includes(item.ouName)) arr.push(item);
} else {
// 单机构
let _ouConfigArray = ouConfig.replace(/\(|\)/g, '');
if (_ouConfigArray.includes(item.ouName)) arr.push(item);
}
});
setDefaultPerson(arr);
setPersonArr(arr);
let _allPersonList = returnCheckedUserIDArray(value, res.data);
setAllPersonList(_allPersonList);
// 初始化时,先创建checkAll对象,避免后续第一次打开人员选择器,
let _checkAll = { ...checkAll };
arr.forEach((item, index) => {
_checkAll[`person_${index}`] = false;
})
setCheckAll(_checkAll);
} else {
onChange('请求错误');
}
setLoading(false);
});
};
const setDataStatus = () => {
setCheckAll({});
setAllPersonList({});
setAllState(false);
};
const onFocus = () => {
setVisible(true)
onChange(val)
if (!personArr.length) {
getData()
}
};
const onOk = () => {
setVisible(false);
setSearchVal('');
// 合并allPersonList内的所有id为字符串
let str = Object.values(allPersonList).flat().join(',');
onChange(str);
// setDataStatus()
};
const onCancel = () => {
setVisible(false);
setSearchVal('');
// setDataStatus()
};
const onInput = e => {
onSearch(e.target.value);
};
const onSearch = e => {
const arr = [];
setSearchVal(e);
defaultPerson.map(item => {
const list = {
ouid: item.ouid,
ouName: item.ouName,
userList: [],
};
item.userList.map(user => {
if (user.userName.indexOf(e) > -1) {
list.userList.push(user);
}
});
if (list.userList.length) {
arr.push(list);
}
});
setPersonArr(arr);
};
// 全选
const all = (e) => {
let _value = e.target.checked;
setAllState(_value);
let _allPerson = { ...allPersonList };
let _checkAll = { ...checkAll };
let _personArr = [...personArr];
_personArr.forEach((item, index) => {
_checkAll[`person_${index}`] = _value;
_allPerson[`person_${index}`] = _value ? item.userList.map(obj => obj[storeType]) : []
});
setCheckAll(_checkAll);
setAllPersonList(_allPerson);
};
// 复选框的函数
const onCheckChange = (list, key) => {
let _allPersonList = { ...allPersonList };
_allPersonList[key] = list;
setAllPersonList(_allPersonList);
};
const onCheckAllChange = (e, index) => {
// 1. 设定选中状态
let _value = e.target.checked;
let _checkAll = { ...checkAll };
_checkAll[`person_${index}`] = _value;
setCheckAll(_checkAll);
if (!_value) {
let _allPersonList = { ...allPersonList };
_allPersonList[`person_${index}`] = [];
setAllPersonList(_allPersonList);
setAllState(false)
return false
}
// 2. 要把底下所有的值全部选中
let _personArr = [...personArr];
let _currentArray = _personArr[index];
let _selectedValue = _currentArray.userList.map(item => item[storeType]);
// 3. 赋值到allPersonList
let _allPersonList = { ...allPersonList };
_allPersonList[`person_${index}`] = _selectedValue;
setAllPersonList(_allPersonList);
let _isAll = true;
Object.values(_checkAll).find(item => {
if (!item) {
_isAll = false;
}
return !item
})
if (_isAll) setAllState(true)
};
const checkSingleUser = (e, index) => {
let _value = e.target.checked;
let _checkAll = { ...checkAll };
let _allPersonList = { ...allPersonList };
let _personArr = [...personArr];
if (!_value) {
_checkAll[`person_${index}`] = false;
setCheckAll(_checkAll);
setAllState(false);
} else {
let _temp = Array.from(new Set(_allPersonList[`person_${index}`].concat(e.target.value)));
if (_temp.length === _personArr[index].userList.length) {
_checkAll[`person_${index}`] = true;
}
setCheckAll(_checkAll);
let _isAll = true;
Object.values(_checkAll).find(item => {
if (!item) {
_isAll = false;
}
return !item
})
if (_isAll) setAllState(true)
}
}
let indeterminate = (Object.values(checkAll).some(v => v === false) && !Object.values(checkAll).every(v => v === false)) ||
(Object.values(allPersonList).some(v => v.length) && Object.values(allPersonList).every(v => !v.length))
return (
<div className="personselect-wrapper" style={{ width: '100%' }}>
<Input
disabled={schema.disabled}
value={userNames || null}
placeholder={schema.disabled ? null : '点击选择人员'}
addonAfter={!schema.disabled ? <UserAddOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} onClick={onFocus} /> : ''}
style={{ width: '100%' }}
/>
<Modal
title="人员选择器"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
wrapClassName="personModalClass"
bodyStyle={{ height: 450, overflowY: 'auto' }}
>
<Spin spinning={loading}>
<Search
placeholder="请输入姓名"
value={searchVal}
allowClear
onSearch={onSearch}
onChange={onInput}
enterButton
/>
<Checkbox
style={{ marginTop: 18 }}
onChange={(e) => all(e)}
indeterminate={indeterminate}
checked={allState}>
全选
</Checkbox>
{personArr.length
? personArr.map((item, index) => {
return (
<form key={index} className="fieldset-class">
<fieldset className="person-select">
<legend className="personheader">
<Checkbox
style={{ marginRight: 8 }}
onChange={(e) => onCheckAllChange(e, index)}
indeterminate={Boolean(allPersonList[`person_${index}`] && allPersonList[`person_${index}`].length) && allPersonList[`person_${index}`].length !== item.userList.length}
checked={Boolean(allPersonList[`person_${index}`] && allPersonList[`person_${index}`].length)} />
{item.ouName}
</legend>
<Checkbox.Group className="person-radio" name="person"
onChange={(list) => onCheckChange(list, `person_${index}`)}
value={allPersonList[`person_${index}`]}>
{item.userList.map((child, childIndex) => {
return (
<Checkbox style={{ minWidth: 100 }}
value={child[storeType]} key={childIndex}
onChange={(e) => checkSingleUser(e, index)}>
{child.userName}
</Checkbox>
);
})}
</Checkbox.Group>
</fieldset>
</form>
);
})
:
<div className={'staffSelectEmpty'}>
<Empty />
</div>
}
</Spin>
</Modal>
</div>
);
};
export default MultipleStaffSelect;
import React, { useEffect, useMemo, useState } from 'react'
import { Select } from 'antd'
import { getMenTreeByRole } from '../../../../apis/process'
const pullStaff = ({ value, onChange, schema }) => {
const { disabled, role, isMultiple, presetValue } = schema
const [data, setData] = useState([])
const valueShow = useMemo(() => {
if (isMultiple) {
return (value || presetValue) ? (value || presetValue).split(',') : []
} else {
return value || presetValue
}
}, [presetValue, value, isMultiple])
const handleChange = (value) => {
if (isMultiple) {
onChange(value.join(','))
} else {
onChange(value)
}
}
const onFocus = async () => {
const { code, data, msg } = await getMenTreeByRole({ userID: 1, role })
if (code === 0) {
if (data && data.childNodes) {
setData(data.childNodes)
}
} else {
onChange(`请求错误,${msg}`)
}
}
return (
<Select
style={{ minWidth: 150 }}
mode={isMultiple ? 'multiple' : ''}
disabled={disabled}
value={valueShow}
optionFilterProp="children"
placeholder={disabled ? null : '点击选择人员'}
onChange={handleChange}
onFocus={onFocus}
showSearch
showArrow={!disabled}
>
{data.map(v => <Select.Option key={v.value} value={v.value}>{v.text}</Select.Option>)}
</Select>
)
}
export default pullStaff;
/*
** 人员选择器 单选
** create by ChenLong on 2021/12/21
** 功能路径:src\core\components\staffSelect\staffSelect.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
** 更新日志:
** edit by ChenLong on 2021/12/21: *****修改内容*****
** 形态:【人员选择器】
** 现阶段仅支持机构
** 显示名称,存储id,多个id以英文逗分隔
**配置:全部 [.n] 返回全部的机构及人员列表
机构名称 [.n] 返回设定的机构及人员列表
(机构名称,机构名称 ...) [.n] 返回设定的某几个机构人员列表
*/
import React, { useEffect, useState } from 'react';
import { Input, Modal, Radio, Spin } from 'antd';
import { UserAddOutlined } from '@ant-design/icons';
import Empty from '@wisdom-components/empty';
import { getUserListForRole } from '../../../../apis/process';
import './staffSelect.less';
const { Search } = Input;
const StaffSelect = ({ value, onChange, name, schema }) => {
const { disabled } = schema
const [visible, setVisible] = useState(false);
const [defaultPerson, setDefaultPerson] = useState([]);
const [personArr, setPersonArr] = useState([]);
const [person, setPerson] = useState(value);
const [searchVal, setSearchVal] = useState('');
const [loading, setLoading] = useState(true);
// [全部][.n] [全部.机构名][.n]
// [全部ID][.n] [全部ID.机构名][.n]
// [机构名][.n] [(机构名,机构名,机构名)][.n]
const ouConfig = schema.config;
// [全部][,n] [全部,机构名][,n]
// [全部ID][,n] [全部ID,机构名][,n]
// [机构名][,n] [(机构名,机构名,机构名)][,n]
let ouConfigArray = schema.config.split('.');
const isAll = ['全部', '全部ID'].includes(ouConfigArray[0]);
const storeType = isAll && ouConfigArray[0] === '全部ID' ? 'storeID' : 'storeName';
const isMultiple = !isAll && ouConfigArray[0].includes(',') && ouConfigArray[0].includes('(') && ouConfigArray[0].includes(')'); // (机构名,机构名)
/**
* @Description: 根据配置来返回ID或者名字
* @Params: value当前控件传入的值;
* @Date: 2021/12/28
* @Author: ChenLong
* */
const returnUserName = (value) => {
if (isNaN(Number(value))) return value;
let _list = returnUserList(personArr);
return _list.reduce((finalStr, current) => {
return finalStr += Number(current.userID) === Number(value) ? current.userName : '';
}, '');
};
const returnUserList = (data) => {
return data.reduce((finalArray, current) => {
return finalArray.concat(current.userList);
}, []);
};
const getData = () => {
getUserListForRole().then(res => {
if (res.code === 0) {
const arr = [];
setLoading(false);
res.data.forEach(item => {
// 全部 / 非全部
if (isAll) {
arr.push(item);
} else if (isMultiple) {
// 多选
let _ouConfigArray = ouConfigArray[0].replace(/\(|\)/g, '').split(',');
if (_ouConfigArray.includes(item.ouName)) arr.push(item);
} else {
// 单选
let _ouConfigArray = ouConfigArray[0].replace(/\(|\)/g, '');
if (_ouConfigArray.includes(item.ouName)) arr.push(item);
}
});
setDefaultPerson(arr);
setPersonArr(arr);
} else {
onChange('请求错误');
}
});
};
const onFocus = () => {
setVisible(true);
};
const onOk = () => {
setVisible(false);
setSearchVal('');
onChange(person);
};
const onCancel = () => {
setVisible(false);
setSearchVal('');
getData();
};
const onInput = e => {
onSearch(e.target.value);
};
const handleChange = e => {
setPerson(e.target.value);
};
const onSearch = e => {
const arr = [];
setSearchVal(e);
defaultPerson.map(item => {
const list = {
ouid: item.ouid,
ouName: item.ouName,
userList: [],
};
item.userList.map(user => {
if (user.userName.indexOf(e) > -1) {
list.userList.push(user);
}
});
if (list.userList.length) {
arr.push(list);
}
});
setPersonArr(arr);
};
useEffect(() => {
async function _getData() {
await getData();
}
_getData().catch(err => {
console.log(err);
});
}, []);
return (
<div className="personselect-wrapper" style={{ width: '100%' }}>
<Input
disabled={disabled}
placeholder={disabled ? null : '点击选择人员'}
value={returnUserName(value) || null}
addonAfter={disabled ? null : <UserAddOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} onClick={onFocus} />}
style={{ width: '100%' }}
/>
<Modal
title="人员选择器"
visible={visible}
onOk={onOk}
onCancel={onCancel}
cancelText={'取消'}
okText={'确定'}
wrapClassName="personModalClass"
bodyStyle={{ width: '80%', height: 450, overflowY: 'auto' }}
>
{loading && <Spin />}
<Search
placeholder="请输入姓名"
value={searchVal}
allowClear
onSearch={onSearch}
onChange={onInput}
enterButton
/>
{!personArr.length && (
<div className={'staffSelectEmpty'}>
<Empty />
</div>
)}
{personArr.length
? personArr.map((item, index) => {
return (
<form key={index} className="fieldset-class">
<fieldset className="person-select">
<legend className="personheader">{item.ouName}</legend>
<Radio.Group className="person-radio" name="person" onChange={handleChange} value={person}>
{item.userList.map((child, childIndex) => {
return (
<Radio value={storeType === 'storeID' ? child.userID : child.userName} key={childIndex}>
{child.userName}
</Radio>
);
})}
</Radio.Group>
</fieldset>
</form>
);
})
: ''}
</Modal>
</div>
);
};
export default StaffSelect;
@import '~antd/es/style/themes/default.less';
.personModalClass {
.@{ant-prefix}-modal-body {
display: flex;
flex-direction: column;
padding: 15px 24px 5px 24px;
.person-select {
padding: 10px 0;
.personheader {
margin-left: 10px;
font-size: 13px;
}
.person-radio {
//display: flex;
//flex-wrap: wrap;
margin: 3px 0 3px 10px;
}
.@{ant-prefix}-radio-wrapper {
width: 120px;
}
.@{ant-prefix}-checkbox-wrapper + .@{ant-prefix}-checkbox-wrapper {
margin-left: 0px;
}
}
.selectvalue {
flex: none;
margin-right: 10px;
}
.staffSelectEmpty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.fieldset-class {
padding: 10px 0;
fieldset {
border: 1px solid #f6f6f6;
}
legend {
width: auto;
}
}
}
}
// 搜索选择器,配置字典
import React, { useState, useMemo } from 'react'
import { Select } from 'antd'
import { getSelectName } from '../../../../apis/process'
const { Option } = Select
const SearchSelect = ({ value, onChange, schema }) => {
const { disabled, placeholder } = schema
const [selectList, setSelectList] = useState([]);
const mode = useMemo(() => {
if (schema.config.includes('n')) {
return 'multiple'
}
return null
}, [schema])
const valueShow = useMemo(() => {
if (mode) {
return (schema.default || value) ? (schema.default || value).split(',') : []
} else {
return schema.default || value
}
}, [schema, value])
const handleChange = value => {
if (mode) {
onChange(value.join(','))
} else {
onChange(value)
}
}
const getData = () => {
const arr = schema.config.split('.')
if (!arr.length) return false
const str = arr[0];
getSelectName(str).then(res => {
if (res.code === 0) {
setSelectList(res.data)
} else {
onChange('请求错误')
}
})
}
return (
<Select
mode={mode}
disabled={disabled}
showArrow={!disabled}
optionFilterProp="children"
value={valueShow || null}
placeholder={placeholder}
onChange={handleChange}
onFocus={() => getData()}
style={{ width: '100%' }}
showSearch
>
{selectList.map(v => <Option value={v.nodeValue} key={v.nodeId}>{v.nodeValue}</Option>)}
</Select>
)
}
export default SearchSelect
import React, { useState, useEffect, useMemo } from 'react'
import './index.less'
import { TreeSelect } from 'antd'
import { DownOutlined } from '@ant-design/icons'
import { getDeptList } from '../../../../apis/process'
const selectDept = ({ value, onChange, schema }) => {
const { isMultiple, disabled, placeholder } = schema
const [data, setData] = useState([])
const valueShow = useMemo(() => {
let valueShow = value || schema.default
if (valueShow.includes('请求错误')) {
return isMultiple ? '' : []
}
if (isMultiple) {
return Array.isArray(valueShow) ? valueShow : (valueShow ? valueShow.split(',') : [])
} else {
return valueShow || null
}
}, [schema, value])
const iconClick = async () => {
let { code, data } = await getDeptList()
if (code === 0) {
setData(data)
} else {
onChange('请求错误')
}
}
const onSelect = (value) => {
if (isMultiple) {
onChange(value.join(','));
} else {
onChange(value)
}
}
const filterTreeNode = (inputValue, treeNode) => {
if (treeNode.deptName.includes(inputValue)) {
return true
}
return false
}
useEffect(() => {
onChange(value || schema.default)
}, [])
return (
<TreeSelect
disabled={disabled}
multiple={isMultiple}
switcherIcon={<DownOutlined />}
fieldNames={{ label: 'deptName', value: 'deptName', children: 'childDepts' }}
treeData={data}
onChange={onSelect}
onFocus={iconClick}
value={valueShow}
filterTreeNode={filterTreeNode}
showSearch
showArrow={!disabled}
allowClear
treeDefaultExpandAll={true}
placeholder={placeholder}
>
</TreeSelect>
)
}
export default selectDept
@import '~antd/es/style/themes/default.less';
.select-dept-body {
width: 100%;
height: 100%;
display: flex;
.dept-body-left,
.dept-body-right {
flex: 1;
border-radius: 5px;
border: 1px solid #DDDDDD;
margin: 0 5px;
.dept-body-header {
height: 40px;
line-height: 40px;
border-bottom: 1px solid #DDDDDD;
padding-left: 5%;
position: relative;
.dept-body-header-del {
position: absolute;
right: 10px;
&:hover {
cursor: pointer;
}
}
}
.dept-body-box {
height: 400px;
overflow-y: auto;
padding: 0 5% 10px 5%;
.dept-body-box-li {
height: 35px;
line-height: 35px;
}
}
}
}
\ No newline at end of file
// 搜索选择器,配置字典
/*
** 选择器
** create by ChenLong on 2021/12/15
** 功能路径:src\core\components\selectTree\selectTree.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
** 更新日志:
* 使用搜索选择器,重写选择器的里的逻辑,并且通过新增FormRender的watch属性,来实现关联选择器的联动
** edit by ChenLong on 2021/12/15: *****修改内容*****
*/
/**
* @Description: 1. 单选情况下,传值时字符窜;2. 多选情况下,传值时数组;
* @Date: 2021/12/15
* */
import React, { useState, useEffect } from 'react';
import { Select } from 'antd';
import { getSelectName } from '../../../../apis/process';
const { Option } = Select;
const SelectTree = ({ value, onChange, schema }) => {
const { disabled, placeholder } = schema
const [selectList, setSelectList] = useState([]);
const [mode, setMode] = useState('');
// 判断当前时单选还是多选
const _configArray = schema.config.split('.');
const isMultiple = !!(_configArray[2] && _configArray[2] === 'n');
const val = value || schema.default;
const handleChange = value => {
onChange(value);
};
const getData = () => {
const arr = schema.config.split('.');
if (!arr.length) return false;
// 区别于搜索选择器
const dictionaryName = arr[1] || arr[0];
if (isMultiple) {
setMode('multiple');
} else {
setMode('');
}
getSelectName(dictionaryName).then(res => {
if (res.code === 0) {
let _list = res.data;
if (schema.filterKey) _list = _list.filter(item => item.nodeName === schema.filterKey);
setSelectList(_list);
} else {
onChange('请求错误');
}
});
};
useEffect(() => {
// 初始化的时候,处理单选/多选问题
const handleInitData = Object.prototype.toString.call(val) === '[object String]' && val ? val.split(',') : val;
let _val = isMultiple ? handleInitData : val;
onChange(_val);
// getData();
}, []);
return (
<Select
disabled={disabled}
mode={mode}
showSearch
optionFilterProp="children"
value={null}
onChange={handleChange}
onFocus={() => getData()}
placeholder={placeholder}
style={{ width: '100%' }}
>
{selectList.map((item, index) => {
return (
<Option value={item.nodeValue} key={index}>
{item.nodeValue}
</Option>
);
})}
</Select>
);
};
export default SelectTree;
/*
** 选择器,多级联动;BUT: 【当前不使用、不开发此形态控件】。
** create by ChenLong on 2021/12/7
** 功能路径:src\core\components\selectTree\selectTree.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
** 更新日志:
* 1. 业务梳理:【选择器】被匹配到时,实际是匹配了【台账字段.字典字段】这种类型的config;
* 2. 需要先取【台账字段】的值,这个值,是字典的key;再之后做相应的数据逻辑即可
* 3. 当【选择器】是多选时,选择器需要是多选,需要列出所有值
*
** edit by ChenLong on 2021/12/7: *****修改内容*****
* TIP: 当匹配到该控件时,即为联动;单独的选择器会匹配到搜索选择器
*/
// 选择器 多级联动
import React, { useState, useEffect } from 'react';
import { getSelectName, getSelectChildName } from '../../../../apis/process';
import { TreeSelect } from 'antd';
const SelectTree = ({ value, onChange, schema }) => {
const [treeData, setTreeData] = useState([]);
const val = value || schema.default;
const routeParams = schema.config;
const genTreeNode = (parentId, id, title, isLeaf) => {
return {
id,
pId: parentId,
title,
isLeaf,
};
};
const onLoadData = treeNode => {
return new Promise(resolve => {
const routeArr = routeParams.split('.');
const { id } = treeNode;
const len = treeNode.pos.split('-');
const clickIndex = len.length - 1;
const treeDataList = [];
getSelectChildName(routeArr[clickIndex]).then(res => {
if (res.code === 0) {
res.forEach(item => {
if (item.PARENTID === treeNode.nodeId)
setTreeData(treeData.concat([genTreeNode(id, item.NODEVALUE, item.NODENAME, item.ORDERID == 0)]));
});
resolve();
} else {
onChange('请求错误');
}
});
});
};
const getFirstNode = () => {
const arr = routeParams.split('.');
getSelectName(arr[0]).then(res => {
if (res.code === 0) {
const firArr = [];
res.forEach(item => {
firArr.push({
id: item.NODEVALUE,
pId: 0,
value: item.NODEVALUE,
title: item.NODENAME,
nodeId: item.NODEID,
isLeaf: item.ORDERID == 0,
});
});
setTreeData(firArr);
} else {
onChange('请求错误');
}
});
};
useEffect(() => {
onChange(val);
getFirstNode();
}, []);
return (
<TreeSelect
treeDataSimpleMode
style={{ width: '100%' }}
value={value || ''}
placeholder="点击进行选择"
onChange={val => {
onChange(val);
}}
loadData={onLoadData}
treeData={treeData}
/>
);
};
export default SelectTree;
// 业务选择器
import React, { useState, useEffect, useMemo } from 'react';
import { Select } from 'antd';
import { GetFieldValueFromTable } from '../../../../apis/process';
const { Option } = Select;
const ServiceSelect = ({ value, onChange, name, schema }) => {
const { disabled, placeholder } = schema
const [selectList, setSelectList] = useState([]);
const mode = useMemo(() => {
if (schema.config.includes('n')) {
return 'multiple'
}
return null
}, [schema])
const valueShow = useMemo(() => {
let valueShow = value || schema.default
if (valueShow.includes('请求错误')) {
return mode ? '' : []
}
if (mode) {
return Array.isArray(valueShow) ? valueShow : (valueShow ? valueShow.split(',') : [])
} else {
return valueShow
}
}, [schema, value])
const handleChange = value => {
if (mode) {
onChange(value.join(','));
} else {
onChange(value)
}
};
const getData = () => {
const arr = schema.config.split('.');
if (!arr.length) return false;
const accountName = arr[0];
const filedName = arr[1];
GetFieldValueFromTable(accountName, filedName).then(res => {
if (res.code === 0) {
setSelectList(res.data || []);
} else {
onChange(`请求错误,${res.msg}`)
}
});
};
useEffect(() => {
onChange(value || schema.default);
getData()
}, []);
return (
<Select
mode={mode}
disabled={disabled}
showSearch
showArrow={!disabled}
optionFilterProp="children"
value={valueShow || null}
onChange={handleChange}
placeholder={placeholder}>
{selectList.map((item, index) => <Option value={item} key={index}>{item}</Option>)}
</Select>
);
};
export default ServiceSelect;
// 站点选择器
import React, { useState, useEffect, useMemo } from 'react';
import { Select } from 'antd';
import { getStationListByUserID } from '../../../../apis/process';
const { Option } = Select;
const SiteSelect = ({ value, onChange, schema }) => {
const { disabled, placeholder, config } = schema
const [selectList, setSelectList] = useState([])
const isMultiple = config && config.includes('.') && config.split('.')[1] === 'n'
const userID = window?.globalConfig?.userInfo?.OID
const valueShow = useMemo(() => {
let val = value || schema.default
if (isMultiple) {
return val ? val.split(',') : []
}
return val ? val : null
}, [value, schema])
const handleChange = value => {
if (isMultiple) {
onChange(value.join(','))
} else {
onChange(value)
}
};
const getData = () => {
// 全部、全部.n,本人、本人.n,’‘
// [id,sysType,isAll]
let _params = [];
if (!config || config.includes('全部')) {
// 未配置,则默认全部
_params = [userID];
} else {
_params = [userID, '', false];
}
getStationListByUserID(..._params).then(res => {
if (res.code === 0) {
setSelectList(res.data || []);
} else {
onChange('请求错误');
}
});
};
useEffect(() => {
getData()
}, [])
return (
<Select
disabled={disabled}
showSearch
showArrow={!disabled}
mode={isMultiple ? 'multiple' : ''}
optionFilterProp="children"
value={valueShow}
onChange={handleChange}
placeholder={placeholder}
>
{selectList.map((item, index) => <Option value={item} key={index}>{item}</Option>)}
</Select>
)
}
export default SiteSelect
// 台账选择器
/*
** 台账选择器
** 功能路径:src\core\components\tableAccount\tableAccount.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
** 更新日志:
** edit by ChenLong on 2021/12/23: ***** 1.修改无法点击选择的bug;2.现在初始化状态下,不显示其他台账;3.文件类字段不显示 *****
** edit by ChenLong on 2022/02/28: ***** 1.使用btoa来给condition转码;转码 window.btoa(encodeURIComponent('aaa'));恢复 decodeURIComponent(window.atob('bbb')) *****
** edit by ChenLong on 2022/08/02: ***** 1.台账接口需要sortFields才能开启排序 *****
*/
import React, { useState } from 'react';
import { Modal, Button, Radio, Input, Table, Space, ConfigProvider, message } from 'antd';
import BasicTable from '@wisdom-components/basictable';
import { SnippetsOutlined } from '@ant-design/icons';
import zhCN from 'antd/es/locale/zh_CN';
import Empty from '@wisdom-components/empty/lib';
import { GetAccountConfigInfo, GetAccountPageList } from '../../../../apis/process';
import './index.less';
const { Column } = Table;
const { Search } = Input;
const FILE_TYPE = ['文件', '可预览文件', '图片', '可预览图片', '录音', '视频'];
class TableAccount extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
columns: [],
tableData: [],
tableAccountValue: '',
searchVal: '',
loading: true,
pagination: {
current: 1,
pageSize: 20,
total: 0,
size: 'default',
},
isInit: true,
selectionType: 'radio',
selectedRowKeys: [...props.value.split(',')],
rowSelection: {
onChange: (selectedRowKeys, record) => {
console.log('selectedRowKeys', selectedRowKeys)
this.setState({
tableAccountValue: selectedRowKeys.join(','),
showString: record.map(item => item[this.state.showKey]).join(','),
selectedRowKeys,
});
},
},
showString: props.value, //edit by Chenlong 2022年10月28日 修复初始加载无法填充值的问题
accountName: '',
condition: '',
// 新增rowKey、showKey
rowKey: '',
showKey: '',
// 用showKey来显示
};
}
componentDidMount() {
this.handleConfig(
() => {
this.getAccountConfig(
() => this.getAccountPageListFn(this.state.info, this.state.info ? '' : this.state.condition),
);
},
);
}
returnSelectType(selectionTypeStr) {
const typeObj = {
'台账选择器': 'radio',
'多选台账选择器': 'checkbox',
};
return typeObj[selectionTypeStr];
}
/**
* @Description: 获取配置
* @Params: 传递callback,看情况是否需要调用
* @Date: 2021/12/27
* */
getAccountConfig(callback) {
GetAccountConfigInfo(this.state.accountName).then(res => {
if (res.code === 0) {
const colArr = [];
const arr = res.data.webShowFieldGroup.split(',');
arr.forEach(item => {
if (!item) {
return;
}
colArr.push({
key: new Date().getTime(),
title: item,
dataIndex: item,
});
});
this.setState(
{
columns: colArr,
total: res.data.totalCount,
}, () => {
if (callback) {
callback();
}
});
} else {
this.props.onChange(`出错了!${res.msg}`);
}
});
}
async getAccountPageListFn(info, condition) {
this.setState({
loading: true,
});
const arrWrap = [];
let showStringArray = [];
let getAllData = async () => {
let _infoList = info.split(',');
await Promise.all(_infoList.map(async currentInfo => {
await GetAccountPageList({
pageIndex: this.state.pagination.current,
pageSize: this.state.pagination.pageSize,
accountName: this.state.accountName,
sortFields: '录入时间',
info: currentInfo,
condition: condition ? window.btoa(encodeURIComponent(condition)) : ''
}).then(
response => {
if (response.code === 0) {
response.data.list.forEach(item => {
const obj = this.handleItem(item);
obj.key = obj[this.state.rowKey];
if (this.state.isInit && this.state.info) {
if (currentInfo === obj[this.state.rowKey]) {
arrWrap.push(obj);
showStringArray.push(obj[this.state.showKey]);
}
} else {
arrWrap.push(obj);
}
});
} else {
this.props.onChange(`出错了!${response.msg}`);
}
},
).catch(err => {
this.setState({
loading: false,
});
});
}));
};
await getAllData();
this.setState({
loading: false,
tableData: arrWrap,
showString: showStringArray.join(','),
});
}
handleConfig(callback) {
// 判断是否有 ?
const _configArray = this.props.schema.config.split('?');
const condition = _configArray[1];
// 台账名称.台账字段|显示字段.n
const _accountInfo = _configArray[0].split('.');
// 是否多选
this.setState({
selectionType: _accountInfo.includes('n') ? 'checkbox' : 'radio',
});
// 台账名称
const accountName = _accountInfo[0];
let rowKey = '';
let showKey = '';
if (_accountInfo[1] && _accountInfo[1].indexOf('|') > -1) {
const keyArr = _accountInfo[1].split('|');
rowKey = keyArr[0];
showKey = keyArr[1];
} else {
rowKey = _accountInfo[1];
showKey = _accountInfo[1];
}
// this.state.searchVal || 初始化时候的值
const info = this.props.value || this.state.searchVal || '';
this.setState({
accountName,
rowKey,
showKey,
condition,
info,
}, () => {
if (callback) callback();
});
}
handleItem(obj) {
const dataObj = obj;
const objarr = [];
const objobj = {};
let fieldValue = [];
dataObj.webRow.forEach((item, index) => {
if (FILE_TYPE.includes(item.shape)) {
fieldValue.push(item.fieldName);
} else {
objarr.push(item.fieldValue);
}
});
let _columns = [...this.state.columns];
_columns = _columns.filter(item => !fieldValue.includes(item.dataIndex));
for (let i = 0; i < _columns.length; i++) {
for (let j = 0; j < objarr.length; j++) {
if (i === j) {
objobj[_columns[i].dataIndex] = objarr[j];
}
}
}
this.setState({
columns: _columns,
});
return objobj;
}
handleInputClick(e) {
this.setState({
visible: true,
}, () => {
if (this.state.tableData.length === 0) {
}
});
}
onOk() {
this.setState(
{
visible: false,
searchVal: '',
},
() => {
this.props.onChange(this.state.tableAccountValue);
},
);
}
onCancel() {
this.setState({
visible: false,
searchVal: '',
isInit: true,
});
}
onSearch(val) {
this.setState(
{
searchVal: val,
},
() => {
this.getAccountPageListFn(val, this.state.condition);
},
);
}
handleInputChange(e) {
console.log(e);
}
tableChange(pagination) {
this.setState(
{
pagination,
},
() => {
this.getAccountPageListFn(this.state.searchVal, this.state.condition);
},
);
}
render() {
return (
<div className="tableAccount-wrapper" style={{ width: '100%' }} ref={'modal'}>
<Input
disabled={this.props.schema.disabled}
value={this.state.showString}
placeholder={this.props.schema.disabled ? null : '点击选择台账'}
addonAfter={
!this.props.schema.disabled ? <SnippetsOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }}
onClick={this.handleInputClick.bind(this)} /> : ''
}
/>
<Modal
title="台账信息"
visible={this.state.visible}
onCancel={this.onCancel.bind(this)}
onOk={this.onOk.bind(this)}
cancelText={'取消'}
okText={'确定'}
width={'60%'}
bodyStyle={{ height: 505, overflowY: 'auto' }}
wrapClassName="tableAccountClass"
destroyOnClose
>
{
this.state.isInit ?
<Button style={{ width: 120, marginBottom: 20 }} type={'primary'}
onClick={() => this.setState(({ isInit: false }))}>点击搜索、更换</Button> :
<Search
placeholder="请输入检索内容"
allowClear
onSearch={this.onSearch.bind(this)}
enterButton
size={'middle'}
style={{ width: '400px', marginBottom: '10px' }}
/>
}
{!this.state.columns.length && (
<div className={'tableAccountEmpty'}>
<Empty />
</div>
) || <ConfigProvider locale={zhCN}>
{/* <BasicTable
rowSelection={{
type: this.state.selectionType,
...this.state.rowSelection,
selectedRowKeys: this.state.selectedRowKeys,
fixed: 'left',
}}
bordered
size="small"
columns={this.state.columns}
dataSource={this.state.tableData}
rowClassName="rowClassName"
style={{ width: '100%' }}
sticky
loading={this.state.loading}
scroll={{ x: 1500, y: 340 }}
pagination={this.state.pagination}
onChange={this.tableChange.bind(this)}
/> */}
<Table
rowSelection={{
type: this.state.selectionType,
...this.state.rowSelection,
selectedRowKeys: this.state.selectedRowKeys,
fixed: 'left',
}}
bordered
size="small"
columns={this.state.columns}
dataSource={this.state.tableData}
rowClassName="rowClassName"
style={{ width: '100%' }}
sticky
loading={this.state.loading}
scroll={{ x: 1500, y: 340 }}
pagination={this.state.pagination}
onChange={this.tableChange.bind(this)}
/>
</ConfigProvider>}
</Modal>
</div>
);
}
}
export default TableAccount;
@import '~antd/es/style/themes/default.less';
.tableAccountClass {
.@{ant-prefix}-modal-body {
display: flex;
flex-direction: column;
padding: 15px 24px 0 24px;
.tableAccountEmpty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
}
}
import React, { useEffect, useMemo } from 'react'
import { Radio, Checkbox } from 'antd'
import './index.less'
const TileSelect = ({ value, onChange, schema }) => {
const { presetValue, isMultiple, options, isDisable } = schema
console.log('isDisable', schema)
const enums = useMemo(() => {
return options ? options.split(',') : []
}, [options])
const showValue = useMemo(() => {
if (value) {
if (isMultiple) {
return value.split(',')
}
return value
}
return presetValue
}, [value, presetValue, isMultiple])
return (
<div className='tileSelect' disabled={isDisable}>
{
isMultiple ?
<Checkbox.Group
disabled={isDisable}
onChange={value => onChange(value.join(','))}
value={showValue}
>
{enums.map(v => <Checkbox key={v} value={v}>{v}</Checkbox>)}
</Checkbox.Group>
:
<Radio.Group onChange={e => onChange(e.target.value)} value={showValue} disabled={isDisable}>
{enums.map(v => <Radio key={v} value={v}>{v}</Radio>)}
</Radio.Group>
}
</div>
)
}
export default TileSelect
\ No newline at end of file
@import '~antd/es/style/themes/default.less';
.tileSelect {
width: 100%;
min-height: 30px;
&[disabled='true'] {
background: #f8fafc;
}
padding: 0 5px;
.@{ant-prefix}-checkbox-wrapper {
margin-left: 8px;
}
.@{ant-prefix}-radio-wrapper {
margin-top: 5px;
}
}
\ No newline at end of file
// 选择器,值选择器
import React, { useState, useMemo } from 'react'
import { Select } from 'antd'
const { Option } = Select
const ValueSelect = ({ value, onChange, schema }) => {
const { config, placeholder, disabled, options, presetValue } = schema
const mode = useMemo(() => {
if (config && config.includes('n')) {
return 'multiple'
}
return null
}, [config])
const valueShow = useMemo(() => {
if (mode) {
return (value || presetValue) ? (value || presetValue).split(',') : null
} else {
return value || presetValue || null
}
}, [presetValue, value])
const handleChange = value => {
if (mode) {
onChange(value.join(','))
} else {
onChange(value)
}
}
return (
<Select
style={{ minWidth: 150 }}
mode={mode}
disabled={disabled}
showArrow={!disabled}
optionFilterProp="children"
value={valueShow}
placeholder={placeholder}
onChange={handleChange}
>
{options && options.split(',').map(v => <Option value={v} key={v}>{v}</Option>)}
</Select>
)
}
export default ValueSelect
import CitySelect from './CitySelect'
import EditSelect from './EditSelect'
import MultiSelect from './MultiSelect'
import SearchSelect from './SearchSelect'
import SelectDept from './SelectDept'
import SelectTree from './SelectTree'
import ServiceSelect from './ServiceSelect'
import SiteSelect from './SiteSelect'
import PersonSelect from './PersonSelect'
import MultipleStaffSelect from './PersonSelect/multipleStaffSelect'
import PullStaff from './PersonSelect/pullStaff'
import StaffSelect from './PersonSelect/staffSelect'
import TableAccount from './TableAccount'
import TileSelect from './TileSelect'
import ValueSelect from './ValueSelect'
const select = {
CitySelect,
EditSelect,
MultiSelect,
SearchSelect,
SelectDept,
SelectTree,
ServiceSelect,
SiteSelect,
PersonSelect,
MultipleStaffSelect,
PullStaff,
StaffSelect,
TableAccount,
TileSelect,
ValueSelect,
}
export default select
\ No newline at end of file
import React from 'react'
import { Switch } from 'antd'
const BooleanSwitch = (props) => {
const { value, onChange, schema, disabled } = props
return (
<Switch
checked={value}
onChange={(checked) => onChange(checked)}
/>
)
}
export default BooleanSwitch
\ No newline at end of file
import React from 'react'
import { Input } from 'antd'
const CascadeField = (props) => {
const { value, onChange } = props
// console.log('关联字段', props)
return (
<Input value={value ? value[0] : ''} onChange={(e) => onChange([e.target.value])} />
)
}
export default CascadeField
\ No newline at end of file
import React, { useState, useEffect, useMemo } from 'react'
import { DatePicker, Input } from 'antd'
import moment from 'moment'
import locale from 'antd/lib/date-picker/locale/zh_CN'
const DateSelect = (props) => {
const { onChange } = props
const { format } = props.addons.formData
const dateChange = (date, dateStr) => {
onChange(dateStr)
}
return (
<DatePicker
picker={format}
// value={valueShow}
onChange={dateChange}
showTime={format === 'dateTime'}
style={{ width: '100%' }}
locale={locale}
/>
)
}
export default DateSelect
import React from 'react'
import { Input } from 'antd'
const EnumOptions = (props) => {
const { value, onChange } = props
return (
<div className=''>
<Input value={value} onChange={e => onChange(e.target.value)} />
</div>
)
}
export default EnumOptions
\ No newline at end of file
import React, { useMemo } from 'react'
import { Input, Select } from 'antd'
const field = [
"处理站点",
"上报人名称",
"上报人部门",
"上报时间",
"现场图片",
"现场录音",
"来源",
"微信探漏是否维修",
"表具服务流水号",
"维修状态",
"维修费用状态",
"用户编号",
"联系人",
"联系电话",
"故障类型",
"是否探到漏点",
"具体位置_门牌号",
"情况描述",
"图片",
"要求处理时间",
"附件_图片",
"探漏人员",
"配合人员",
"创建星期数",
"创建小时数",
"创建分钟数",
"工单编号",
"是否为工作日",
"分支环节1",
"分支环节2",
"服务人员",
"派单提交时间",
"派单状态数字",
"是否接单",
"接单提交时间",
"现场是否需要恢复",
"是否收费",
"管道资产",
"现场情况",
"无需维修原因",
"处理前图片",
"确认当前位置",
"经度",
"纬度",
"是否关阀",
"关闭阀门位置及大小",
"维修管径_DN",
"处理后照片",
"打开阀门位置及大小",
"实收费用",
"维修材料清单",
"缴费照片留存",
"备注",
"维修提交时间",
"维修状态数字",
"恢复前照片",
"恢复提交时间",
"是否已恢复",
"恢复后照片",
"恢复费用要素",
"恢复使用材料拍照",
"恢复费用",
"恢复状态数字",
"维修费用要素",
"计算费用",
"派单耗时",
"接单耗时",
"维修耗时",
"恢复耗时",
"派单耗时_分",
"接单耗时_分",
"维修耗时_分",
"恢复耗时_分"
]
const FieldNames = (props) => {
const { value, onChange } = props
const valueShow = useMemo(() => {
return value
}, [value])
const change = (value) => {
onChange(value)
}
return (
<Select onChange={change} style={{ minWidth: '143px' }} value={valueShow}>
{
field.map(v => <Select.Option key={v} value={v}>{v}</Select.Option>)
}
</Select>
)
}
export default FieldNames
\ No newline at end of file
import React from 'react'
import { Select } from 'antd'
const MultiSelect = (props) => {
return (
<Select />
)
}
export default MultiSelect
\ No newline at end of file
import React, { useState, useEffect, useMemo } from 'react'
import { TimePicker } from 'antd'
import locale from 'antd/lib/date-picker/locale/zh_CN'
const TimeSelect = (props) => {
const { onChange } = props
const { format } = props.addons.formData
const dateChange = (date, dateStr) => {
onChange(dateStr)
}
return (
<TimePicker
picker={format}
onChange={dateChange}
showTime={format === 'dateTime'}
style={{ width: '100%' }}
locale={locale}
/>
)
}
export default TimeSelect
import BooleanSwitch from './BooleanSwitch'
import EnumOptions from './EnumOptions'
import FieldNames from './FieldNames'
import CascadeField from './CascadeField'
import DateSelect from './DateSelect'
const settings = {
BooleanSwitch,
EnumOptions,
FieldNames,
CascadeField,
DateSelect,
}
export default settings
\ No newline at end of file
import React, { useMemo } from 'react'
import { InputNumber } from 'antd'
const style = {
width: '100%'
}
const NumberInput = ({ value, onChange, schema }) => {
console.log('数字输入框', schema)
const { disabled, presetValue } = schema
const valueShow = useMemo(() => {
return presetValue || value
}, [presetValue, value])
return (
<InputNumber
disabled={disabled}
value={valueShow}
onChange={value => onChange(value)}
style={style}
/>
)
}
export default NumberInput
\ No newline at end of file
/**
* @Description: QRCode 使用传入的值生成二维码
* @Params: 参数描述
* @Date: 2021/12/3
* @Author: ChenLong
* */
import React, { useState } from 'react';
import { Input } from 'antd';
import QR from 'qrcode.react';
import './index.less'
const QRCode = ({ schema }) => {
const [show, setShow] = useState(false)
return (
<div className='QRCode'>
<Input
disabled={schema.disabled}
value={schema.default}
onFocus={() => setShow(true)}
onBlur={() => setShow(false)}
/>
<div className='QRCode-img' style={{ display: show ? 'block' : 'none' }}>
{
schema.default ? <QR value={schema.default} /> : null
}
</div>
</div>
);
};
export default QRCode;
.QRCode {
position: relative;
.QRCode-img {
position: absolute;
z-index: 99;
}
}
\ No newline at end of file
import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef, useMemo } from 'react'
import './index.less'
import { request } from '@wisdom-utils/utils'
import { Editor, Toolbar } from '@wangeditor/editor-for-react'
import { DomEditor } from '@wangeditor/editor'
import '@wangeditor/editor/dist/css/style.css'
const uploadFileAPI = `/PandaWorkFlow/WorkFlow/AccountManage/UploaderFiles`;
const downFileAPI = `/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles`;
const RichText = forwardRef(({ schema, onChange, value }, ref) => {
const { presetValue, disabled, placeholder } = schema
useImperativeHandle(ref, () => ({
setHtml,
onClear: () => editor.onClear(),
getHtml: () => editor.txt.html(),
getText: () => editor.txt.text(),
}))
const [editor, setEditor] = useState(null)
const valueShow = useMemo(() => {
return value || presetValue
}, [presetValue, value])
// 图片上传
const uploadImg = file => {
const formData = new FormData();
formData.append('file', file);
setLoading(true);
request({
url: uploadFileAPI,
method: 'POST',
data: formData,
})
.then(res => {
if (!res.data) return;
// eslint-disable-next-line no-useless-escape
const img = res.data.replace(/[\\ \/=]/g, '/');
const imgHtml = `
<img contenteditable="false" style="display: block;" width="50%" src="${downFileAPI}?filePath=${img}" >
`;
editor.cmd.do('insertHTML', imgHtml);
setLoading(false);
})
.catch(err => {
setLoading(false);
});
}
const editorChange = (editor) => {
onChange(editor.getHtml())
}
useEffect(() => {
onChange(presetValue)
}, [presetValue])
useEffect(() => {
return () => {
if (editor == null) return
editor.destroy()
setEditor(null)
}
}, [editor])
return (
<div className='richText' disabled={disabled}>
{
!disabled ?
<Toolbar
editor={editor}
defaultConfig={{
excludeKeys: ['insertLink', 'group-image', 'group-video', 'codeBlock', 'undo', 'redo', 'fullScreen']
}}
mode="default"
style={{ borderBottom: '1px solid #ccc' }}
/> : null
}
<Editor
defaultConfig={{
readOnly: disabled,
placeholder: placeholder || '',
focus: false,
pasteFilterStyle: true, // 忽略粘贴样式
pasteIgnoreImg: true, // 忽略粘贴的图片
styleWithCSS: false,
zIndex: 500,
// customUploadImg: async (resultFiles, insertImgFn) => {
// console.log('resultFiles', resultFiles)
// // const result = await request({ url: uploadFileAPI, method: 'POST', data: formData })
// }
MENU_CONF: {
uploadImage: {
customInsert(res, inserFn) {
console.log('res', res)
const formData = new FormData();
formData.append('file', file);
},
// onBeforeUpload: (e) => {
// console.log(e)
// const file = e?.clipboardData?.items[0]?.getAsFile() || null;
// if (!file) return;
// const formData = new FormData();
// formData.append('file', file);
// request({
// url: uploadFileAPI,
// method: 'POST',
// data: formData,
// }).then(res => {
// console.log(res)
// })
// },
server: uploadFileAPI,
}
}
}}
value={valueShow}
onCreated={setEditor}
onChange={editorChange}
mode="default"
style={{ minHeight: '300px', overflowY: 'hidden' }}
/>
</div>
)
})
export default RichText;
@import '~antd/es/style/themes/default.less';
@parse-form-prefix-cls: ~'@{ant-prefix}-parse-form';
.richText {
border: 1px solid #ccc;
z-index: 100;
&[disabled] {
border: none;
background: #f8fafc;
.w-e-text-container {
background: none;
}
}
}
.RichText {
width: 100%;
height: auto;
min-height: 300px;
position: relative;
display: flex;
flex-direction: column;
border: 1px solid #d9d9d9;
border-radius: 2px;
&[disabled] {
.w-e-text-container {
background: none;
}
border: none;
background: #f8fafc;
.RichTextToolbar {
display: none;
}
}
.loadingWrap {
width: 100%;
height: 100%;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.8);
}
ol li {
list-style: decimal !important;
}
ul li {
list-style: disc !important;
}
}
.RichTextContainer {
background-color: #fff;
color: #000000d9;
position: relative;
overflow-y: scroll;
flex: 1;
}
.RichTextToolbar {
border-bottom: 1px solid #d9d9d9; // height: 0;
// overflow: hidden;
.w-e-toolbar .w-e-menu i {
background-color: transparent!important;
}
}
:global {
#RichTextContainer span[data-type='person'] {
font-weight: bold;
color: #44acb6 !important;
} // .w-e-menu[data-title="图片"] {
// display: none;
// }
.RichText-image {
position: relative;
display: inline-block;
}
#RichTextContainer .RichText-image-img {
max-width: calc(100% - 20px);
display: inline-block;
width: auto;
height: auto;
}
.RichText-image-mask {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background: rgba(0, 0, 0, 0.5);
cursor: pointer;
opacity: 0;
transition: opacity 0.3s;
padding: 0;
margin: 0;
box-sizing: border-box;
}
.RichText-image-mask-info {
padding: 0;
margin: 0;
box-sizing: border-box;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
color: #fff;
font-size: 20px;
}
.RichText-image-mask-info .anticon {
margin-inline-end: 4px;
}
.anticon svg {
display: inline-block;
}
.RichText-image-mask:hover {
opacity: 1;
}
.r-t-add-file {
color: #999;
font-family: 'w-e-icon' !important;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
padding: 0;
margin: 0;
box-sizing: border-box;
}
.r-t-add-file:before {
content: "\e9cb";
}
.@{ant-prefix}-image-error {
display: block;
}
}
\ No newline at end of file
No preview for this file type
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