Commit a1db4b1a authored by 田翔's avatar 田翔

fix: 将表格嵌入关联表单

parent 247753b3
{
"name": "panda-xform",
"version": "4.3.0",
"description": "4.3.0 弹出层修改",
"version": "4.3.1",
"description": "4.3.1 将表格嵌入关联表单",
"keywords": [
"panda-xform"
],
......@@ -54,7 +54,7 @@
"@babel/plugin-transform-modules-amd": "^7.14.5",
"@umijs/fabric": "^2.0.7",
"@wisdom-map/amap": "1.1.0-beta.45",
"@wisdom-map/arcgismap": "1.4.0-124",
"@wisdom-map/arcgismap": "1.4.0-158",
"@wisdom-map/basemap": "1.1.0-24",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
......@@ -131,4 +131,4 @@
"publishConfig": {
"registry": "https://g.civnet.cn:4873"
}
}
}
\ No newline at end of file
......@@ -14,9 +14,9 @@ const SearchGroup = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
getQueryInfo,
}));
}))
const { readOnly } = props
const { readOnly, btnsClick } = props
const [form] = Form.useForm()
const [showPicker, setShowPicker] = useState(true)
const [dateArray, setDateArray] = useState([])
......@@ -173,7 +173,7 @@ const SearchGroup = forwardRef((props, ref) => {
style={{ width: '100%', textAlign: 'left' }}
size='middle'
type='text'
onClick={() => btnsClick('导出模板')}
onClick={() => btnsClick({ type: '导出模板' })}
icon={<ExportOutlined />}
>
导出模板
......@@ -187,7 +187,7 @@ const SearchGroup = forwardRef((props, ref) => {
style={{ width: '100%', textAlign: 'left' }}
size='middle'
type='text'
onClick={() => btnsClick('导出全字段模板')}
onClick={() => btnsClick({ type: '导出全字段模板' })}
icon={<ExportOutlined />}
>
导出全字段模板 <QuestionCircleOutlined style={{ fontSize: 10 }} title='导出整张台账表字段' />
......@@ -201,7 +201,7 @@ const SearchGroup = forwardRef((props, ref) => {
style={{ width: '100%', textAlign: 'left' }}
size='middle'
type='text'
onClick={() => btnsClick('导出数据')}
onClick={() => btnsClick({ type: '导出数据' })}
icon={<ExportOutlined />}
>
导出数据
......@@ -215,7 +215,7 @@ const SearchGroup = forwardRef((props, ref) => {
style={{ width: '100%', textAlign: 'left' }}
size='middle'
type='text'
onClick={() => btnsClick('导出全字段数据')}
onClick={() => btnsClick({ type: '导出全字段数据' })}
icon={<ExportOutlined />}
>
导出全字段数据
......@@ -233,7 +233,7 @@ const SearchGroup = forwardRef((props, ref) => {
style={{ width: '100%', textAlign: 'left' }}
size='middle'
type='text'
onClick={() => btnsClick('批量删除')}
onClick={() => btnsClick({ type: '批量删除' })}
icon={<DeleteOutlined />}
>
批量删除
......@@ -247,7 +247,7 @@ const SearchGroup = forwardRef((props, ref) => {
style={{ width: '100%', textAlign: 'left' }}
size='middle'
type='text'
onClick={() => btnsClick('批量修改')}
onClick={() => btnsClick({ type: '批量修改' })}
icon={<EditOutlined />}
>
批量修改
......@@ -279,13 +279,9 @@ const SearchGroup = forwardRef((props, ref) => {
const reset = () => {
form.resetFields()
btnsClick('重置')
btnsClick({ type: '重置' })
}
const btnsClick = type => {
props?.btnsClick?.(type, null);
};
return (
<Row className={styles.controlRow}>
<Form layout={'inline'} form={form} onValuesChange={onValuesChange}>
......@@ -353,7 +349,7 @@ const SearchGroup = forwardRef((props, ref) => {
<Button
type="primary"
size="middle"
onClick={() => btnsClick('添加')}
onClick={() => btnsClick({ type: '添加' })}
icon={<PlusOutlined />}
style={{ marginLeft: 20 }}
>
......
......@@ -11,7 +11,8 @@
transform: scale(1.2);
}
.img {
width: 65px;
max-width: 65px;
max-height: 65px;
}
.imgSub {
position: absolute;
......
......@@ -37,7 +37,6 @@ const TablePack = (props, ref) => {
const [fieldResize, setFieldResize] = useState({})
const [filteredInfo, setFilteredInfo] = useState({})
const [sortedInfo, setSortedInfo] = useState({})
const inputRef = useRef()
const filtered = useMemo(() => {
let array = []
......@@ -51,16 +50,9 @@ const TablePack = (props, ref) => {
return array
}, [filteredInfo])
const getColumnSearchProps = (widgetInfo, dataIndex) => {
const { widget, sourceType, options } = widgetInfo
if (['CheckBox', 'ComboBox', 'RadioButton'].includes(widget)) {
if (sourceType === '手动输入') {
return {
filters: options.map(v => { return { text: v.value, value: v.value, } }),
}
}
}
return {
//台账列表、台账选择器表头
const getColumnProps = (json, v) => {
let searchProps = {
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters, close }) => {
return (
<div
......@@ -68,8 +60,7 @@ const TablePack = (props, ref) => {
onKeyDown={(e) => e.stopPropagation()}
>
<Input
ref={inputRef}
placeholder={`搜索 ${dataIndex}`}
placeholder={`搜索 ${v}`}
value={selectedKeys[0]}
onChange={e => {
setSelectedKeys(e.target.value ? [e.target.value] : [])
......@@ -117,6 +108,154 @@ const TablePack = (props, ref) => {
/>
),
}
const { widget, sourceType, options } = json?.[v]
if (['CheckBox', 'ComboBox', 'RadioButton'].includes(widget)) {
if (sourceType === '手动输入') {
searchProps = {
filters: options.map(v => { return { text: v.value, value: v.value, } }),
}
}
}
return {
title: json[v]?.title || v,
dataIndex: v,
width: fieldResize[v] || 120,
ellipsis: true,
sorter: true,
sortOrder: sortedInfo.field === v ? sortedInfo.order : null,
filteredValue: filteredInfo[v] || null,
onHeaderCell: (column) => ({
width: column.width,
onResize: (e, props) => {
setFieldResize({ ...fieldResize, [v]: props?.size?.width })
},
}),
render: (value, r) => {
let props = { ...json[v], value }
if (widget === 'FileUpload') {
return <FileView {...props} />
}
if (['Coordinate', 'Device', 'DrawPath', 'DrawArea'].includes(widget)) {
return <CoordView {...props} />
}
if (['RadioButton', 'CheckBox'].includes(widget)) {
return <SelectView {...props} />
}
if (value && value.length > 10) {
return (
<Tooltip title={value}>
<span style={{ display: 'inline-block', width: '100%' }}>{value}</span>
</Tooltip>
)
}
return (
<div>{value}</div>
)
},
}
}
//关联表单表头
const getRelevanceColumnProps = (json, v) => {
const { widget } = json?.[v] || {}
return {
title: json[v]?.title || v,
dataIndex: v,
width: fieldResize[v] || 120,
ellipsis: true,
sorter: (a, b) => a[v] - b[v],
filteredValue: filteredInfo[v] || null,
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters, close }) => (
<div
style={{ padding: 8 }}
onKeyDown={(e) => e.stopPropagation()}
>
<Input
ref={searchInput}
placeholder={`Search ${v}`}
value={selectedKeys[0]}
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => {
confirm();
}}
style={{
marginBottom: 8,
display: 'block',
}}
/>
<Space>
<Button
type="primary"
onClick={() => {
confirm();
}}
icon={<SearchOutlined />}
size="small"
style={{
width: 90,
}}
>
搜索
</Button>
<Button
onClick={() => {
clearFilters();
confirm();
}}
size="small"
style={{
width: 90,
}}
>
重置
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<SearchOutlined
style={{
color: filtered ? '#1890ff' : undefined,
}}
/>
),
onFilter: (value, record) =>
record[v].toString().toLowerCase().includes(value.toLowerCase()),
onFilterDropdownOpenChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
},
onHeaderCell: (column) => ({
width: column.width,
onResize: (e, props) => {
setFieldResize({ ...fieldResize, [v]: props?.size?.width })
},
}),
render: (value, r) => {
let props = { ...json[v], value }
if (widget === 'FileUpload') {
return <FileView {...props} />
}
if (['Coordinate', 'Device', 'DrawPath', 'DrawArea'].includes(widget)) {
return <CoordView {...props} />
}
if (['RadioButton', 'CheckBox'].includes(widget)) {
return <SelectView {...props} />
}
if (value && value.length > 10) {
return (
<Tooltip title={value}>
<span style={{ display: 'inline-block', width: '100%' }}>{value}</span>
</Tooltip>
)
}
return (
<div>{value}</div>
)
}
}
}
const btns = useMemo(() => {
......@@ -155,64 +294,30 @@ const TablePack = (props, ref) => {
let json = getFileInfo(formJson)
let array = []
showField.forEach((v, i) => {
const { widget } = json?.[v] || {}
array.push({
title: json[v]?.title || v,
dataIndex: v,
width: fieldResize[v] || 120,
ellipsis: true,
sorter: true,
sortOrder: sortedInfo.field === v ? sortedInfo.order : null,
filteredValue: filteredInfo[v] || null,
...getColumnSearchProps(json[v], v),
onHeaderCell: (column) => ({
width: column.width,
onResize: (e, props) => {
setFieldResize({ ...fieldResize, [v]: props?.size?.width })
},
}),
render: (value, r) => {
let props = { ...json[v], value }
if (widget === 'FileUpload') {
return <FileView {...props} />
}
if (['Coordinate', 'Device', 'DrawPath', 'DrawArea'].includes(widget)) {
return <CoordView {...props} />
}
if (['RadioButton', 'CheckBox'].includes(widget)) {
return <SelectView {...props} />
}
if (value && value.length > 10) {
return (
<Tooltip title={value}>
<span style={{ display: 'inline-block', width: '100%' }}>{value}</span>
</Tooltip>
)
}
return (
<div>{value}</div>
)
}
})
if (parent === '关联表单') {
array.push(getRelevanceColumnProps(json, v))
} else {
array.push(getColumnProps(json, v))
}
})
return array
}, [config, fieldList, fieldResize, filteredInfo, sortedInfo])
}, [parent, config, fieldList, fieldResize, filteredInfo, sortedInfo])
const columns = useMemo(() => {
let columns = [
{
title: '序号',
dataIndex: 'r',
key: 'r',
width: 50,
align: 'center',
fixed: 'left',
filteredValue: null,
render: (_, r, i) => i + 1
},
...fileColumns,
{
title: '操作',
width: btns.length * 35 + 30,
align: 'center',
filteredValue: null,
fixed: 'right',
render: (r) => {
return (
......@@ -224,7 +329,7 @@ const TablePack = (props, ref) => {
<Popconfirm
key={v.title}
title='确定要删除数据吗?'
onConfirm={() => btnsClick(v.title, r.ID)}
onConfirm={() => btnsClick({ type: v.title, row: r })}
okText='确定'
cancelText='取消'
>
......@@ -244,7 +349,7 @@ const TablePack = (props, ref) => {
title={v.title}
icon={v.icon}
style={{ padding: '0 7px' }}
onClick={() => btnsClick(v.title, r.ID)}
onClick={() => btnsClick({ type: v.title, row: r })}
>
</Button>
)
......@@ -264,7 +369,7 @@ const TablePack = (props, ref) => {
const onChange = (page, filters, sorter) => {
setFilteredInfo(filters)
setSortedInfo(sorter)
tableChange(page, filters, sorter)
tableChange?.(page, filters, sorter)
}
const closeTag = (e, { filterName, filterValue }) => {
......@@ -278,7 +383,7 @@ const TablePack = (props, ref) => {
}
}
setFilteredInfo(filtered)
tableChange({}, filtered, sortedInfo)
tableChange?.({}, filtered, sortedInfo)
}
return (
......@@ -339,7 +444,7 @@ const TablePack = (props, ref) => {
dataSource={dataSource}
rowSelection={rowSelection}
onRow={onRow}
pagination={false}
pagination={parent === '关联表单' ? { total: dataSource.length, showTotal: (value) => `总计 ${value} 条` } : false}
scroll={{ x: '100%', y: 'calc(100% - 40px)' }}
onChange={onChange}
components={{
......
......@@ -45,11 +45,10 @@ const Account = (props) => {
const tablePackRef = useRef()
const batchEditRef = useRef()
const btnsClick = async (type, id) => {
const btnsClick = async ({ type, row }) => {
const { addFieldGroup, editFieldGroup, formJson } = config
const addField = addFieldGroup ? addFieldGroup.split(',').filter(v => v) : []
const editField = editFieldGroup ? editFieldGroup.split(',').filter(v => v) : []
setOperation({ type, id })
if (type === '添加') {
saveClick(addField, formJson, [], type)
}
......@@ -60,7 +59,8 @@ const Account = (props) => {
getDataSource(initParams)
}
if (type === '编辑' || type === '详情') {
const { code, data, msg } = await GetTableDataInfo({ accountName, id })
setOperation({ type, id: row.ID })
const { code, data, msg } = await GetTableDataInfo({ accountName, id: row.ID })
if (code === 0) {
saveClick(editField, formJson, data, type)
} else {
......@@ -68,7 +68,8 @@ const Account = (props) => {
}
}
if (type === '删除') {
const { code, data, msg } = await DeleteTableDataInfo({ accountTable: accountName, ids: id })
setOperation({ type, id: row.ID })
const { code, data, msg } = await DeleteTableDataInfo({ accountTable: accountName, ids: row.ID })
if (code === 0) {
message.success('删除成功!')
getDataSource()
......
import React, { useMemo, useState, useRef, useLayoutEffect, useEffect } from 'react'
import { Button, message, Popconfirm } from 'antd'
import styles from './index.less'
import {
GetAccountPageList,
......@@ -9,11 +10,13 @@ import {
EditTableDataInfo,
DeleteTableDataInfo
} from '../../../../apis/process'
import { Table, Button, Modal, message, Popconfirm, ConfigProvider } from 'antd'
import { SnippetsOutlined, PlusOutlined, FormOutlined, DeleteOutlined } from '@ant-design/icons'
import { GetTableJson } from '../../../../apis/process'
import BaseForm from './BaseForm'
import { isObject } from '../../../../utils'
// import BaseTable from './BaseTable'
import TablePack from '../../../Account/components/TablePack'
import { isObject, isJson } from '../../../../utils'
import Drag from '../../../components/Drag'
const icons = {
......@@ -43,7 +46,6 @@ const RelationForm = (props) => {
const { disabled, '台账名称': accountName, '默认显示': defaultShow, '控制规则': controlShow, titleShow, '映射字段': mappedField } = schema
const [config, setConfig] = useState({ webShowFieldGroup: '', fieldGroup: '' })
const [dataSource, setDataSource] = useState([])
const [groupMeta, setGroupMeta] = useState([])
const [visible, setVisible] = useState(false)
const [formState, setFormState] = useState('详情')
const [row, setRow] = useState({})
......@@ -51,6 +53,7 @@ const RelationForm = (props) => {
const [schemaValues, setSchemaValues] = useState([])
const [loading, setLoading] = useState(false)
const baseFormRef = useRef(null)
const baseTableRef = useRef(null)
const formDataObj = useMemo(() => {
let formDataObj = {}
......@@ -224,7 +227,7 @@ const RelationForm = (props) => {
const getConfig = async () => {
let { code, data, msg } = await GetAccountConfigInfo(accountName)
if (code === 0) {
setConfig(data)
setConfig({ ...data, formJson: isJson(data.formJson) ? JSON.parse(data.formJson) : {} })
getTableData(data.addFieldGroup ? data.addFieldGroup.split(',') : [])
} else {
message.error(msg)
......@@ -353,6 +356,10 @@ const RelationForm = (props) => {
}
}
const btnsClick = ({ type, row }) => {
rowClick(type, row)
}
useEffect(() => {
if (accountName) {
getData()
......@@ -373,14 +380,13 @@ const RelationForm = (props) => {
<span className='account-header-title'>{titleShow}</span>
{disabled ? null : <Button className={styles.headerBtn} type='primary' size='middle' icon={<PlusOutlined />} onClick={addClick}>添加</Button>}
</div>
<Table
<TablePack
parent='关联表单'
loading={loading}
rowKey={r => JSON.stringify(r)}
size='small'
bordered
columns={columns}
readOnly={disabled}
config={config}
dataSource={dataSource}
pagination={{ total: dataSource.length, showTotal: (value) => `总计 ${value} 条` }}
btnsClick={btnsClick}
/>
<Drag
title={accountName}
......
......@@ -7,45 +7,10 @@
line-height: 45px;
position: relative;
text-align: center;
// .account-header-title {
// width: 100%;
// text-align: center;
// font-weight: bold;
// font-size: 16px;
// }
.headerBtn {
position: absolute;
right: 0;
top: 7px;
}
}
.@{ant-prefix}-table-thead {
.@{ant-prefix}-table-cell {
background: white;
}
th {
border-bottom: 2px solid #DBE7FB;
text-align: center;
}
}
.@{ant-prefix}-table-body {
tr {
td {
border-bottom: 1px solid #DBE7FB;
border-right: 1px solid #DBE7FB;
}
}
.@{ant-prefix}-table-row {
padding: 4px !important;
}
tr:nth-child(even) {
background: #F6F9FE;
.panda-civ-workflow-table-cell-fix-right {
background-color: #F6F9FEed;
}
}
}
.@{ant-prefix}-table-content {
overflow: auto;
}
}
\ No newline at end of file
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