Commit d0a36583 authored by 田翔's avatar 田翔

fix: 控件优化

parent 922f8a6f
{
"name": "panda-xform",
"version": "6.9.25",
"description": "6.9.25 描述控件重新编辑报错问题",
"version": "6.10.0",
"description": "6.10.0 控件优化",
"keywords": [
"panda-xform"
],
......
@import '~antd/es/style/themes/default.less';
@imgSrc: '../../../../../../../../assets/images/accout';
.tablePack {
width: 100%;
height: 100%;
position: relative;
transition: all 0.5s ease;
.condition {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 30px;
display: flex;
align-items: center;
}
.operation {
.operationSpan {
margin-left: 10px;
display: inline-block;
&:hover {
cursor: pointer;
color: #1890ff;
}
}
}
.headerTitle {
width: 100%;
overflow: hidden;
word-spacing: normal;
text-overflow: ellipsis;
}
.@{ant-prefix}-table-wrapper {
height: 100%;
.@{ant-prefix}-spin-nested-loading {
height: 100%;
}
.@{ant-prefix}-spin-container {
height: 100%;
}
.@{ant-prefix}-table {
height: 100%;
.@{ant-prefix}-table-container {
height: 100%;
}
}
}
.@{ant-prefix}-table.@{ant-prefix}-table-bordered>.@{ant-prefix}-table-container {
border-left: 1px solid #dbe7fb;
.ant-table-header>table {
border-top: 1px solid #dbe7fb;
}
}
.@{ant-prefix}-table-thead>tr {
height: 40px;
th {
font-weight: bold;
overflow: inherit;
user-select: none;
/* Chrome and Opera */
-webkit-user-select: none;
/* Safari */
-khtml-user-select: none;
/* Konqueror HTML */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* Internet Explorer/Edge */
border-right: 1px solid #dbe7fb !important;
border-bottom: 1px solid #dbe7fb;
background: white;
}
th:last-child {
border-left: 1px solid #dbe7fb;
}
}
.@{ant-prefix}-table-tbody>tr {
&:nth-child(2n-1) {
td {
background: #f6f9fe;
}
}
td {
border-bottom: 1px solid #dbe7fb;
border-right: 1px solid #dbe7fb !important;
&:last-child {
border-left: 1px solid #dbe7fb;
}
}
&:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) {
td {
background: rgb(237, 242, 255) !important;
}
}
}
.@{ant-prefix}-table-body {
overflow-x: scroll;
&::-webkit-scrollbar {
width: 0;
height: 12px;
}
&::-webkit-scrollbar {
width: 0;
height: 6px;
}
&::-webkit-scrollbar-thumb {
background: rgb(41, 166, 255);
}
&::-webkit-scrollbar-track {
background: #f7f4f5;
padding: 0 3px;
}
}
}
.iconBtn {
width: 16px;
height: 16px;
&[type='详情'] {
background: url('@{imgSrc}/详情.svg');
background-size: 100% 100%;
}
&[type='编辑'] {
background: url('@{imgSrc}/编辑.svg');
background-size: 100% 100%;
}
&[type='删除'] {
background: url('@{imgSrc}/删除.svg');
background-size: 100% 100%;
}
}
\ No newline at end of file
import React, { useState, useEffect, useRef, useMemo } from 'react'
import { Input, message, Pagination } from 'antd'
import { SnippetsOutlined } from '@ant-design/icons'
import { GetAccountConfigInfo, GetAccountPageList, getStationListByUserID, GetTableDataInfo } from '../../../../../../../apis/process'
import styles from './index.less';
import { isJson, isObject } from '../../../../../../../utils'
import MinTablePack from './MinTablePack'
import SearchGroup from '../../../../SearchGroup'
import Drag from '../../../../../../components/Drag'
const initConfig = {
accountFieids: [],
formJson: {},
enableBatchOperation: 0, //批量操作
enableImportExport: 0, //导入导出
enablePrint: 0, //打印
enableQuickSearch: 0, //快捷搜索
enableSiteFilter: 0, //站点过滤
enableTimeFilter: 0, //时间筛选
}
let defaultParams = {
sortFields: '录入时间',
direction: 'desc',
}
const AccountSelectorCell = (props) => {
const userID = window?.globalConfig?.userInfo?.OID || 1
const codes = window?.pandaXform?.codes || { 工单编号: '', 事件编号: '', }
// const { value, onChange, schema, addons } = props
const {
value,
onChange,
disabled,
accountName,
fieldshine,
siteFilter,
sql,
isMultiple,
presetValue,
placeholder,
fieldList,
isStoreID,
} = props
const initParams = {
user: userID,
accountName,
extendQuery: {
caseNo: codes['工单编号']
},
total: 0,
pageIndex: 1,
pageSize: 100,
siteFilter,
...defaultParams,
}
const [showValue, setShowValue] = useState('')
const [params, setParams] = useState(initParams)
const [loading, setLoading] = useState(false)
const [dataSource, setDataSource] = useState([])
const [config, setConfig] = useState(initConfig)
const [visible, setVisible] = useState(false)
const [keys, setKeys] = useState([])
const tablePackRef = useRef(null)
const iconClick = () => {
if (!accountName) {
return message.info('请配置台账名称!')
}
if (!fieldshine.length) {
return message.info('请配置映射字段!')
}
setVisible(true)
getConfig()
}
const getConfig = async () => {
const { code, data } = await GetAccountConfigInfo(accountName);
if (code == 0) {
setConfig({ ...data, formJson: isJson(data.formJson) ? JSON.parse(data.formJson) : {} })
defaultParams = {
sortFields: data?.defaultSortFields || '录入时间',
direction: data?.sortOrder || 'desc',
}
let param = {
condition: data?.sqlFilter ? window.btoa(encodeURIComponent(data?.sqlFilter)) : '',
pageSize: data.pageSize || 20,
...defaultParams,
}
getDataSource(param)
}
}
const getDataSource = async (outParams = {}) => {
setLoading(true);
let param = {
...params,
user: userID,
accountName: accountName,
...outParams,
condition: sql ? window.btoa(encodeURIComponent(sql)) : (outParams.condition || params.condition || ''),
};
const { data, code, msg } = await GetAccountPageList(param);
if (code === 0) {
if (data.jsonData) {
let Data = JSON.parse(data.jsonData);
let dataKeys = dataSource.filter(v => keys.includes(v.ID))
let otherData = Data.filter(v => !keys.includes(v.ID))
setDataSource([...otherData, ...dataKeys]);
if (!keys.length) {
let valueArr = value ? value.split(',') : [];
let rows = Data.filter(v => valueArr.includes(v[fieldshine[0].fromField]));
setKeys(rows.map(v => v.ID));
}
setParams({ ...params, ...outParams, total: data.totalCount });
} else {
setDataSource([])
}
} else {
message.error(msg);
}
setLoading(false);
}
const tableChange = (page, filters, sorter) => {
let queryWheres = []
Object.keys(filters).forEach(k => {
if (filters[k]?.[0]) {
queryWheres.push({ field: k, type: '模糊查询', value: filters[k][0] })
}
})
let param = {
sortFields: sorter.order ? sorter.field : '录入时间',
direction: sorter.order !== 'ascend' ? 'desc' : 'asc',
queryWheres
}
setParams({ ...params, ...param })
getDataSource(param)
}
const rowClick = (row) => {
if (isMultiple) {
if (keys.includes(row.ID)) {
let values = keys.filter(v => v !== row.ID)
setKeys(values)
} else {
let values = [...keys, row.ID]
setKeys(values)
}
} else {
setKeys([row.ID]);
}
}
const formatterFn = ({ value, formatter, decimalDigits }) => {
if (value) {
if (formatter === '${百分比}') {
return `${value}%`
} else if (formatter === '${货币}') {
return formatMoney(Number(value), Number(decimalDigits))
} else if (formatter === '${整数}') {
return `${parseInt(value)}`
} else if (formatter === '${小数}') {
return Number(value).toFixed(Number(decimalDigits))
} else if (formatter === '${科学计数法}') {
return Number(value).toExponential()
} else if (formatter) {
return `${value}${formatter}`
}
}
return value
}
const getShowValue = (keys) => {
let array = []
if (keys.length) {
keys.forEach(v => {
array.push(GetTableDataInfo({ accountName: accountName, id: v, timeLimit: null }))
})
Promise.all(array).then(res => {
let showArray = []
res?.forEach(v => {
if (v.code === 0) {
v.data?.forEach(v => {
if (v.fieldName === fieldshine[0].fromField) {
showArray.push(v.fieldValue)
}
})
}
})
setShowValue(showArray.join(','))
})
}
}
const onOk = () => {
if (fieldshine.length > 1) {
let row = dataSource.find(v => v.ID === keys[0]) || {};
let array = []
fieldshine.forEach((v, index) => {
// if (isStoreID && index === 0) {
// array.push({ fieldName: v.toField, fieldValue: row[v.fromField] })
// getShowValue(keys)
// }
array.push({ fieldName: v.toField, fieldValue: (isStoreID && index === 0) ? (keys.join(',')) : row[v.fromField] })
})
onChange({ fields: array })
} else {
let array = dataSource.filter(v => keys.includes(v.ID))
let rowValues = array.map(v => v[fieldshine[0].fromField]).filter(v => v).join(',')
onChange({ fieldName: v[fieldshine[0].toField], fieldValue: isStoreID ? keys.join(',') : rowValues })
}
getShowValue(keys)
setVisible(false);
}
const search = (values) => {
setParams({ ...params, ...values })
getDataSource({ ...values })
}
const btnsClick = ({ type }) => {
if (type === '重置') {
tablePackRef.current.setFilteredInfo({})
setParams({ ...params, queryWheres: [] })
getDataSource({ queryWheres: [] })
}
}
useEffect(() => {
if (value && isStoreID) {
getShowValue(presetValue?.split(','))
}
}, [])
const pageChange = (pageIndex, pageSize) => {
getDataSource({ pageIndex, pageSize })
}
return (
<div className={styles.AccountSelector}>
<Input
placeholder={disabled ? (placeholder || '') : (placeholder || '点击选择台账')}
value={isStoreID ? showValue : value}
onClick={() => iconClick()}
disabled={disabled}
// allowClear
// onChange={e => {
// onChange('')
// setShowValue('')
// }}
/>
<Drag
onCancel={() => setVisible(false)}
onOk={onOk}
width='60%'
title={accountName}
visible={visible}
getContainer={false}
bodyStyle={{ height: 570, paddingBottom: 0 }}
>
<div className={styles.content}>
<div className={styles.top}>
<SearchGroup
onChange={search}
notUse={'edit,add,del'}
btnsClick={btnsClick}
config={{ ...config, parent: '台账选择器' }}
/>
</div>
<div className={styles.bottom}>
<MinTablePack
ref={tablePackRef}
loading={loading}
notUse={'edit,add,del'}
config={{ ...config, parent: '台账选择器' }}
dataSource={dataSource}
btnsClick={btnsClick}
fieldList={fieldList}
tableChange={tableChange}
rowSelection={{
type: isMultiple && fieldshine.length === 1 ? 'checkbox' : 'radio',
selectedRowKeys: keys,
fixed: 'left',
onChange: (keys) => setKeys(keys)
}}
onRow={record => ({
onClick: event => {
event.stopPropagation();
rowClick(record);
},
})}
/>
</div>
<div className={styles.footer}>
<div className={styles.total}>共计{params.total}条数据</div>
<div className={styles.pagination}>
<Pagination
size='small'
showQuickJumper
pageSize={params.pageSize}
current={params.pageIndex}
total={params.total}
onChange={pageChange}
/>
</div>
</div>
</div>
</Drag>
</div>
)
}
export default AccountSelectorCell
\ No newline at end of file
@import '~antd/es/style/themes/default.less';
.AccountSelectorCell {
.content {
width: 100%;
height: 100%;
position: relative;
padding-bottom: 40px;
.top {
width: 100%;
height: 50px;
}
.bottom {
width: 100%;
height: calc(100% - 50px);
.@{ant-prefix}-table-wrapper {
height: 100%;
.@{ant-prefix}-spin-nested-loading {
height: 100%;
}
.@{ant-prefix}-spin-container {
height: 100%;
}
.@{ant-prefix}-table {
height: 100%;
.@{ant-prefix}-table-container {
height: 100%;
}
}
}
}
.footer {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
.@{ant-prefix}-input-affix-wrapper-disabled {
background: #f8fafc;
border: none;
}
}
\ No newline at end of file
import React, { useEffect, useCallback } from 'react'
import { Input, InputNumber, DatePicker } from 'antd'
import { Input, InputNumber, DatePicker, Select } from 'antd'
import locale from 'antd/lib/date-picker/locale/zh_CN'
import moment from 'moment'
import { debounce } from '../../../../../../utils'
import { formAutomaticComputation } from '../../../../../../apis/process'
import AccountSelectorCell from './AccountSelectorCell'
const initUserInfo = {
fullName: '【本人姓名】',
......@@ -40,6 +41,9 @@ const ValueEdit = (props) => {
disabled,
placeholder,
widget,
isMultiple,
sourceType,
options,
format,
min,
max,
......@@ -69,6 +73,24 @@ const ValueEdit = (props) => {
}
}, [])
if (widget === 'AccountSelector') {
return <AccountSelectorCell {...props} />
}
if (['CheckBox', 'ComboBox', 'RadioButton'].includes(widget) && sourceType === '手动输入') {
return (
<Select
value={value}
style={{ width: '100%' }}
mode={isMultiple ? 'multiple' : ''}
onChange={(value) => onChange({ fieldName, fieldValue: value })}
placeholder={`请输入${fieldName}`}
options={options?.map(v => ({ label: v.value, value: v.value }))}
allowClear
/>
)
}
if (widget === 'DateTime') {
const isValid = value ? moment(value)._isValid : false
const timeOtions = format === 'dateTime' ?
......
......@@ -266,9 +266,20 @@ const TablePack = (props, ref) => {
return (
<ValueEdit
{...props}
onChange={({ fieldName, fieldValue }) => {
btnsClick({ type: '变化', row: { ...record, [fieldName]: fieldValue } })
onChange={({ fieldName, fieldValue, fields }) => {
if (fields?.length) {
let otherRow = {}
fields.forEach(v => {
otherRow[v.fieldName] = v.fieldValue
})
console.log('otherRow', record, otherRow)
btnsClick({ type: '变化', row: { ...record, ...otherRow } })
} else {
btnsClick({ type: '变化', row: { ...record, [fieldName]: fieldValue } })
}
}}
// batchChange=
otherChange={(otherRow) => {
btnsClick({ type: '变化', row: { ...record, ...otherRow } })
}}
......@@ -364,7 +375,6 @@ const TablePack = (props, ref) => {
let array = []
showField.forEach((v, i) => {
if (parent === '关联表单') {
// array.push(getRelevanceColumnProps(json, v, isEdit))
array.push(getRelevanceColumnProps({ json, field: v, isEdit, autoArray, accountFieids }))
} else {
array.push(getColumnProps(json, v))
......
@import '~antd/es/style/themes/default.less';
@imgSrc: '../../assets/images/accout';
.account {
width: 100%;
height: 100%;
padding: 10px;
background: white;
.tableRender {
width: 100%;
height: 100%;
.content {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
.left {
width: 236px;
height: 100%;
margin-right: 14px;
position: relative;
transition: all 0.3s ease-out;
.t-header {
overflow: hidden;
font-size: 15px;
......@@ -25,6 +32,7 @@
padding: 5px 10px;
color: #1890ff;
}
.shrink {
position: absolute;
right: -14px;
......@@ -32,33 +40,40 @@
transform: translateY(-50%);
height: 100px;
width: 14px;
&:hover {
cursor: pointer;
}
&[type='true'] {
background: url('@{imgSrc}/show_true.png');
background-size: 100% 100%;
}
&[type='false'] {
background: url('@{imgSrc}/show_false.png');
background-size: 100% 100%;
}
}
}
.right {
transition: all 0.3s ease-out;
width: calc(100% - 250px);
height: 100%;
padding-bottom: 50px;
position: relative;
.top {
width: 100%;
height: 40px;
}
.bottom {
width: 100%;
height: calc(100% - 50px);
}
.footer {
position: absolute;
bottom: 0;
......@@ -72,15 +87,18 @@
}
}
}
.tableDetail {
width: 100%;
height: 100%;
padding-bottom: 50px;
.formBox {
width: 100%;
height: 100%;
overflow: auto;
}
.formBtns {
display: flex;
align-items: center;
......
This diff is collapsed.
......@@ -157,7 +157,6 @@ const DeviceFieldshine = (props) => {
marginBottom: '5px',
justifyContent: 'center',
position: 'relative',
left: index === 0 ? '-11px' : '',
}}
align="baseline"
>
......@@ -227,7 +226,7 @@ const DeviceFieldshine = (props) => {
>
<Input />
</Form.Item>
{index !== 0 ? <MinusCircleOutlined onClick={() => remove(name)} /> : null}
<MinusCircleOutlined onClick={() => remove(name)} />
</Space>
))}
<Form.Item style={{ padding: '0 10px' }}>
......
......@@ -84,7 +84,7 @@ const OtherSource = (props) => {
</Select>
</Form.Item>
<Form.Item
label={'台账名称'}
label={'按钮名称'}
name={'btnName'}
>
<Input placeholder='请输入按钮名称' />
......
......@@ -152,8 +152,11 @@ const TextInput = (props) => {
}
}, [otherValue])
if (disabled && urlRegExp.test(showValue)) {
return <div className={styles.textUrl} onClick={() => window.open(showValue)}>{showValue}</div>
if (disabled) {
if (urlRegExp.test(showValue)) {
return <div className={styles.textUrl} onClick={() => window.open(showValue)}>{showValue}</div>
}
return <div className={styles.textInputD} style={{ color: loaclPaths.includes(presetValue) ? 'blue' : '' }}>{showValue}</div>
}
return (
......
@import '~antd/es/style/themes/default.less';
.textInput {
&[isdisabled='true'] {
.@{ant-prefix}-input-group-addon {
......@@ -7,10 +8,17 @@
}
}
.textInputD {
background: #f8fafc;
padding: 5px 10px;
border-radius: 2px;
}
.textUrl {
color: #1890ff;
padding: 4px 11px;
background: #f8fafc;
&:hover {
color: #0a7fec;
cursor: pointer;
......
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