import React, { useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react' import styles from './index.less' import { message, Button, Pagination, Modal, Input, Tree } from 'antd' import { DownOutlined } from '@ant-design/icons' import { ExclamationCircleOutlined } from '@ant-design/icons' import SearchGroup from './components/SearchGroup' import TablePack from './components/TablePack' import BatchEdit from './components/BatchEdit' import { GetAccountConfigInfo, GetAccountTree, GetAccountPageList, GetTableDataInfo, EditTableDataInfo, SaveTableDataInfo, DeleteTableDataInfo, ExportAccountData, ExportAccountModel, } from '../../apis/process' import { isJson, isObject } from '../../utils/index' import FormRender from '../FormRender' const initConfig = { accountFieids: [], formJson: {}, enableBatchOperation: 0, //批量操作 enableImportExport: 0, //导入导出 enablePrint: 0, //打印 enableQuickSearch: 0, //快捷搜索 enableSiteFilter: 0, //站点过滤 enableTimeFilter: 0, //时间筛选 } const Account = (props, ref) => { useImperativeHandle(ref, () => ( { getTableColumns } )) const { accountName, parentConfig, notUse, superAccount } = props const isTreeAccount = Boolean(superAccount === 'true') const userID = window?.globalConfig?.userInfo?.OID || 1 const initParams = { user: userID, accountName, sortFields: '录入时间', direction: 'desc', total: 0, pageIndex: 1, pageSize: 100, timeFrom: '', timeTo: '', queryWheres: [], } const [treeShow, setTreeShow] = useState(true) const [treeData, setTreeData] = useState([]) const [expandedKeys, setExpandedKeys] = useState([]) const [treeValue, setTreeValue] = useState([accountName]) const [detailShow, setDetailShow] = useState(false) const [params, setParams] = useState(initParams) const [loading, setLoading] = useState(false) const [dataSource, setDataSource] = useState([]) const [config, setConfig] = useState(initConfig) const [configLoading, setConfigLoading] = useState(true) const [schemaValues, setSchemaValues] = useState({ formJson: {}, values: [] }) const [submitLoading, setSubmitLoading] = useState(false) const [operation, setOperation] = useState({ id: null, state: '添加' }) const [keys, setKeys] = useState([]) const formRenderRef = useRef(null) const tablePackRef = useRef(null) const batchEditRef = useRef(null) const getTableColumns = () => { return tablePackRef?.current?.fileColumns || [] } const btnsClick = async ({ type, row }) => { const { accountFieids, formJson } = config const addField = accountFieids.filter(v => v.isAdd).map(v => v.fieldName) const editField = accountFieids.filter(v => v.isEdit).map(v => v.fieldName) if (type === '添加') { setOperation({ type, id: null }) saveClick(addField, formJson, [], type) } if (type === '重置') { tablePackRef.current.setFilteredInfo({}) tablePackRef.current.setSortedInfo({}) setParams(initParams) getDataSource(initParams) } if (type === '编辑' || type === '详情') { setOperation({ type, id: row.ID }) const { code, data, msg } = await GetTableDataInfo({ accountName, id: row.ID }) if (code === 0) { saveClick(editField, formJson, data, type) } else { message.error(msg) } } if (type === '删除') { setOperation({ type, id: row.ID }) const { code, data, msg } = await DeleteTableDataInfo({ accountTable: accountName, ids: row.ID }) if (code === 0) { message.success('删除成功!') getDataSource() } else { message.error(msg) } } if (type === '批量删除') { if (!keys.length) { return message.info('请勾选要删除的数据!') } Modal.confirm({ icon: <ExclamationCircleOutlined />, content: '确定要批量删除数据吗?', okText: '确认', cancelText: '取消', onOk: async () => { return await new Promise(async (resolve, reject) => { const { code, data, msg } = await DeleteTableDataInfo({ accountTable: accountName, ids: keys.join(',') }) if (code === 0) { message.success('批量删除成功!') getDataSource() resolve() } else { message.error(msg) reject() } }) }, }) } if (type === '批量修改') { if (!keys.length) { return message.info('请勾选要修改的数据!') } batchEditRef.current.open({ accountTable: accountName, id: keys.join(','), }) } if (['导出数据', '导出全字段数据'].includes(type)) { exportData({ exportAll: type === '导出全字段数据' }) } if (['导出模板', '导出全字段模板'].includes(type)) { exportTemplate({ exportAll: type === '导出全字段模板' }) } } const exportData = ({ exportAll }) => { Modal.confirm({ icon: <ExclamationCircleOutlined />, content: keys.length > 0 ? `共选择${keys.length}条数据,确定要导出吗` : '确定要导出全部数据吗?', onOk: async () => { return await new Promise(async (resolve, reject) => { let res = await ExportAccountData({ accountName: accountName, ids: keys.join(','), exportAll }) if (res && res.code === -1) { message.error(res.msg) reject() } else { const url = window.URL.createObjectURL(new Blob([res])) const a = document.createElement('a') a.href = url a.target = '_blank' a.download = '数据文件.xls' a.click() a.remove() resolve() } }) }, okText: '确定', cancelText: '取消', }) } const exportTemplate = async ({ exportAll }) => { let res = await ExportAccountModel({ accountName: accountName, exportAll }) if (res && res.code === -1) { message.error(res.msg) reject() } else { const url = window.URL.createObjectURL(new Blob([res])) const a = document.createElement('a') a.href = url a.target = '_blank' a.download = '模板文件.xls' a.click() a.remove() resolve() } } const saveClick = (field, formJson, values, type) => { let json = JSON.parse(JSON.stringify(formJson)) let parent = json?.properties if (isObject(parent)) { for (let v in parent) { let hidden = true let child = parent[v]?.properties if (isObject(child)) { for (let s in child) { if (type === '详情') { child[s].disabled = true } if (field.includes(s)) { child[s].hidden = false hidden = false } else { child[s].hidden = true } } } parent[v].hidden = hidden } } setSchemaValues({ formJson: json, values }) setDetailShow(true) } const back = () => { setDetailShow(false) getDataSource() } const submit = async () => { const { formValue, relationForm, errors } = await formRenderRef.current.getValues() if (errors.length) { return message.error('请完善表单内容') } const { type, id } = operation setSubmitLoading(true) if (type === '添加') { let params = { userID, accountTable: accountName, id: operation.id, values: formValue, relationForm } const { code, data, msg } = await SaveTableDataInfo(params) if (code === 0) { message.success('保存成功!') setDetailShow(false) getDataSource() } else { message.error(msg) } } if (type === '编辑') { let params = { userID, accountTable: accountName, id: operation.id, values: formValue, relationForm } const { code, data, msg } = await EditTableDataInfo(params) if (code === 0) { message.success('修改成功!') setSubmitLoading(false) setDetailShow(false) getDataSource() } else { message.error(msg) } } setSubmitLoading(false) } const search = (values) => { getDataSource({ ...values }) } const getConfig = async ({ accountName }) => { setConfigLoading(true) const { code, data, msg } = await GetAccountConfigInfo(accountName) if (code === 0) { setConfig({ ...data, formJson: isJson(data.formJson) ? JSON.parse(data.formJson) : {} }) getDataSource({ siteFilter: Boolean(data.enableSiteFilter), accountName }) } else { message.error(msg) } setConfigLoading(false) } const getDataSource = async (param = {}) => { setLoading(true) const { code, data, msg } = await GetAccountPageList({ ...params, ...param }) if (code === 0) { setDataSource(isJson(data.jsonData) ? JSON.parse(data.jsonData) : []) setParams({ ...params, ...param, total: data.totalCount, pageIndex: data.pageIndex, pageSize: data.pageSize }) } else { setDataSource([]) message.error(msg) } setLoading(false) } const pageChange = (pageIndex, pageSize) => { getDataSource({ pageIndex, pageSize }) } const tableChange = (page, filters, sorter) => { let queryWheres = [] Object.keys(filters).forEach(k => { if (filters[k]?.[0]) { queryWheres.push({ field: k, type: '模糊查询', value: filters[k].join(',') }) } }) let param = { sortFields: sorter.order ? sorter.field : '录入时间', direction: sorter.order !== 'ascend' ? 'desc' : 'asc', queryWheres } setParams({ ...params, ...param }) getDataSource(param) } const batchEditOk = () => { setKeys([]) getDataSource() } const treeChange = (value) => { if (value.length) { setTreeValue(value) getConfig({ accountName: value[0] }) } } const getTree = async () => { const { code, data, msg } = await GetAccountTree(accountName) if (code === 0) { setExpandedKeys([data.accountName]) setTreeData([data]) } else { message.error(msg) } } useEffect(() => { if (parentConfig) { setConfig(parentConfig) getDataSource({ siteFilter: Boolean(parentConfig.enableSiteFilter) }) } else { getConfig({ accountName }) } getTree() }, []) return ( <div className={styles.account}> <div className={styles.tableRender} style={{ display: !detailShow ? 'block' : 'none' }}> <div className={styles.content}> { isTreeAccount ? ( <div style={{ width: treeShow ? '236px' : '0', }} className={styles.left} > <div className={styles['t-header']} style={{ padding: treeShow ? '5px 10px' : '0' }}>台账列表</div> <Tree style={{ overflow: 'hidden' }} checkable checkStrictly showIcon blockNode expandedKeys={expandedKeys} onExpand={(expandedKeys) => setExpandedKeys(expandedKeys)} fieldNames={{ title: 'accountName', key: 'accountName', children: 'children' }} switcherIcon={<DownOutlined />} checkedKeys={treeValue} treeData={treeData} onSelect={treeChange} /> <div className={styles.shrink} type={`${treeShow}`} onClick={() => setTreeShow(!treeShow)}></div> </div> ) : null } <div className={styles.right} style={{ width: isTreeAccount && treeShow ? 'calc(100% - 250px)' : '100%' }}> <div className={styles.top}> <SearchGroup onChange={search} btnsClick={btnsClick} keys={keys} accountName={accountName} config={config} notUse={notUse} /> </div> <div className={styles.bottom}> { !configLoading ? ( <TablePack loading={loading} notUse={notUse} config={config} dataSource={dataSource} rowSelection={{ type: 'checkbox', selectedRowKeys: keys, fixed: 'left', onChange: (keys) => setKeys(keys) }} btnsClick={btnsClick} tableChange={tableChange} ref={tablePackRef} /> ) : null } </div> <div className={styles.footer}> <div className={styles.total}>共计{params.total}条数据</div> <div className={styles.pagination}> <Pagination showQuickJumper pageSize={params.pageSize} current={params.pageIndex} total={params.total} onChange={pageChange} /> </div> </div> </div> </div> <BatchEdit config={config} ref={batchEditRef} onOk={batchEditOk} /> </div> { detailShow ? ( <div className={styles.tableDetail}> <div className={styles.formBox}> <FormRender ref={formRenderRef} schemaValues={schemaValues} /> </div> <div className={styles.formBtns}> <Button onClick={back} > 返回 </Button> <Button style={{ marginLeft: '10px', display: ['添加', '编辑'].includes(operation.type) ? 'block' : 'none' }} type='primary' loading={submitLoading} onClick={submit} > 提交 </Button> </div> </div> ) : null } </div> ) } export default forwardRef(Account)