diff --git a/config/theme.config.ts b/config/theme.config.ts new file mode 100644 index 0000000000000000000000000000000000000000..0ff0fd1622e35b1da7129311fa7d10f46e8e4387 --- /dev/null +++ b/config/theme.config.ts @@ -0,0 +1,6 @@ +import defaultSettings from './defaultSettings'; +const { primaryColor } = defaultSettings; +export default { + 'primary-color': primaryColor, + 'layout-header-height': '40px', +}; diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/pages/system/parameter/components/business/action/index.js b/src/pages/system/parameter/components/business/action/index.js new file mode 100644 index 0000000000000000000000000000000000000000..2ca304c7776913e9f9ec02ab561d9c747bcfc2bb --- /dev/null +++ b/src/pages/system/parameter/components/business/action/index.js @@ -0,0 +1,78 @@ +import React from 'react'; +import { Row, Col, Button, message, Upload } from 'antd'; +import styles from './index.less'; + +import { uploadParams } from '@/pages/system/parameter/services/business'; + +const beforeUpload = file => { + // 检查文件类型 + const reg = /\.(xlsx|xls)$/; + const isXls = reg.test(file.name); + if (!isXls) { + message.error('只能上传Excel文件'); + return false; + } + + // 进行文件大小检查 + const isLt100M = file.size / 1024 / 1024 < 100; + if (!isLt100M) { + message.error('文件大小不能超过100M'); + } + return isXls && isLt100M; +}; + +const customRequest = ({ file, onSuccess }) => { + uploadParams({ + file, + onSuccess: ({ code, data }) => { + if (code === 'sys.success') { + message.success('导入成功'); + onSuccess(data); + } + }, + }); +}; +const props = { + name: 'file', + headers: { + authorization: 'authorization-text', + }, + accept: '.xlsx, .xls', + beforeUpload, + customRequest, +}; + +const Action = ({ + onClickQuery, + onClickReset, + onSuccessUpload, + onClickExport, + onClickAdd, + loading, +}) => ( + + + + +
+ + + +
+ + + + + +
+); + +export default Action; diff --git a/src/pages/system/parameter/components/business/action/index.less b/src/pages/system/parameter/components/business/action/index.less new file mode 100644 index 0000000000000000000000000000000000000000..3ddc2bc8c23581f26f4c399ac61c2e9c7ecdee88 --- /dev/null +++ b/src/pages/system/parameter/components/business/action/index.less @@ -0,0 +1,24 @@ +@import "~@/themes/vars.less"; + +.root { + margin-left: -@space-lg; + margin-right: -@space-lg; + margin-bottom: @space-lg; + // padding: 0 @space-lg; + .left { + padding: 0 @space-lg; + .uploadBtn { + float: left; + } + :global { + .ant-btn { + margin-right: @space-lg / 2; + } + } + } + .right { + padding: 0 @space-lg; + display: flex; + justify-content: flex-end; + } +} diff --git a/src/pages/system/parameter/components/business/index.js b/src/pages/system/parameter/components/business/index.js new file mode 100644 index 0000000000000000000000000000000000000000..7fa7d20a15329c7a9520b61bc1042a2cad3da13c --- /dev/null +++ b/src/pages/system/parameter/components/business/index.js @@ -0,0 +1,376 @@ +import React from 'react'; +import { connect } from 'dva'; +import { message, Form, Select, InputNumber } from 'antd'; +import Search from './search'; +import Action from './action'; +import Table from '../table'; +import { generateUUID } from '@/utils'; +import Ellipsis from '@/components/Ellipsis'; + +import styles from './index.less'; + +const FormItem = Form.Item; +@connect(({ paramBusiness, loading: { effects } }) => { + const { list, pageData } = paramBusiness; + return { + list, + pageData, + loading: + effects['paramBusiness/getList'] || + effects['paramBusiness/add'] || + effects['paramBusiness/update'] || + effects['paramBusiness/remove'], + }; +}) +class Index extends React.Component { + constructor(props) { + super(props); + this.search = null; + this.table = null; + this.queryParm = { pageNum: 1, pageSize: 10 }; + this.columns = [ + { + title: '语言', + dataIndex: 'paramLocale', + width: '9%', + editable: true, + rules: [ + { + required: true, + message: '请输入参数模块', + }, + { + max: 50, + message: '最大长度50', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '参数模块', + dataIndex: 'paramModule', + width: '14%', + editable: true, + sorter: true, + rules: [ + { + required: true, + message: '请输入值', + }, + { + max: 100, + message: '最大长度100', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '参数编码', + dataIndex: 'paramCode', + width: '12%', + editable: true, + sorter: true, + rules: [ + { + required: true, + message: '请输入参数编码', + }, + { + max: 200, + message: '最大长度200', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '参数值', + dataIndex: 'paramValue', + width: '10%', + editable: true, + rules: [ + { + required: true, + message: '请输入参数值', + }, + { + max: 500, + message: '最大长度500', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '显示名称', + dataIndex: 'paramName', + width: '10%', + editable: true, + rules: [ + { + required: true, + message: '请输入显示名称', + }, + { + max: 200, + message: '最大长度200', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '说明', + dataIndex: 'remark', + // width: 100, + editable: true, + rules: [ + { + max: 200, + message: '最大长度200', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '显示顺序', + dataIndex: 'paramIndex', + width: '9%', + editable: true, + renderEditing: ({ form, record, dataIndex }) => { + const { getFieldDecorator } = form; + return ( + + {getFieldDecorator('paramIndex', { + rules: [ + { + required: true, + message: '请输入值', + }, + { + type: 'number', + min: 1, + max: 1000, + message: '长度为1-1000', + }, + ], + initialValue: record[dataIndex], + })()} + + ); + }, + }, + { + title: '状态', + dataIndex: 'paramState', + width: '8%', + editable: true, + render: (text, record) => (String(record.paramState) === '1' ? '有效' : '无效'), + renderEditing: ({ form, record }) => { + const { getFieldDecorator } = form; + return ( + + {getFieldDecorator('paramState', { + rules: [ + { + required: true, + message: '请输入参数值', + }, + ], + initialValue: String(record.paramState) || '1', + })( + , + )} + + ); + }, + }, + ]; + } + + componentDidMount() { + this.refreshList(); + } + + /** + * 表格改变 + */ + onChangeTable = (pagination, filters, sorter) => { + this.queryParm = { + ...this.queryParm, + pageNum: pagination.current, + pageSize: pagination.pageSize, + sortOrder: sorter.order, + sortField: sorter.field, + }; + + this.refreshList(); + }; + + /** + * 查询 + */ + onClickQuery = () => { + this.search.onSubmitForm(values => { + this.queryParm = { ...this.queryParm, ...values, pageNum: 1 }; + this.refreshList(); + }); + }; + + /** + * 重置 + */ + onClickReset = () => { + this.search.onResetForm(); + const { dispatch } = this.props; + this.queryParm = { pageNum: 1 }; + dispatch({ + type: 'paramBusiness/getList', + payload: this.queryParm, + }); + }; + + onSuccessUpload = () => { + this.refreshList(); + }; + + onClickExport = () => { + const { dispatch } = this.props; + this.search.onSubmitForm(values => { + const params = { ...this.queryParm, ...values }; + dispatch({ type: 'paramBusiness/exportParam', params }); + }); + }; + + // 添加行 + onClickAdd = () => { + const row = { + action: 'add', + key: generateUUID(), + paramSeq: '', + paramModule: '', + paramCode: '', + paramValue: '', + paramIndex: 1, + remark: '', + paramState: '1', + }; + this.table.addRow(row); + }; + + handleSearch = n => { + this.search = n; + }; + + handleTable = n => { + this.table = n; + }; + + // 刷新列表 + refreshList = () => { + const { dispatch } = this.props; + dispatch({ + type: 'paramBusiness/getList', + payload: this.queryParm, + }); + }; + + // 添加 + onAdd = async record => { + const { dispatch } = this.props; + const result = await dispatch({ + type: 'paramBusiness/add', + payload: { ...record }, + }); + + if (result) { + message.success('添加成功'); + this.refreshList(); + } + return result; + }; + + // 编辑 + onEdit = async record => { + const { dispatch } = this.props; + const result = await dispatch({ + type: 'paramBusiness/update', + payload: { ...record }, + }); + if (result) { + message.success('修改成功'); + } + return result; + }; + + // 删除 + onDelete = async ({ paramId, goPrePage }) => { + const { dispatch } = this.props; + if (goPrePage) { + this.queryParm.pageNum = this.queryParm.pageNum - 1; + } + const result = await dispatch({ + type: 'paramBusiness/remove', + payload: { paramId }, + }); + if (result) { + message.success('删除成功'); + this.refreshList(); + } + return result; + }; + + render() { + const { list, pageData, loading } = this.props; + const tableProps = { + dataSource: list, + pageData, + loading, + onAdd: this.onAdd, + onEdit: this.onEdit, + onDelete: this.onDelete, + onChangeTable: this.onChangeTable, + columns: this.columns, + }; + const actionProps = { + onClickQuery: this.onClickQuery, + onClickReset: this.onClickReset, + onClickExport: this.onClickExport, + onSuccessUpload: this.onSuccessUpload, + onClickAdd: this.onClickAdd, + }; + return ( +
+ + + + + ); + } +} + +export default Index; diff --git a/src/pages/system/parameter/components/business/index.less b/src/pages/system/parameter/components/business/index.less new file mode 100644 index 0000000000000000000000000000000000000000..c2026e3204dcac95b6786d4826fdb4755166ef77 --- /dev/null +++ b/src/pages/system/parameter/components/business/index.less @@ -0,0 +1,4 @@ +@import "~@/themes/vars.less"; + +.root { +} diff --git a/src/pages/system/parameter/components/business/search/index.js b/src/pages/system/parameter/components/business/search/index.js new file mode 100644 index 0000000000000000000000000000000000000000..aee20d14755800160af3e354c464fe91eb6d537b --- /dev/null +++ b/src/pages/system/parameter/components/business/search/index.js @@ -0,0 +1,74 @@ +import React from 'react'; +import { Form, Input, Row, Col, Select } from 'antd'; +import styles from './index.less'; + +const FormItem = Form.Item; + +@Form.create() +class Search extends React.Component { + componentDidMount() {} + + /** + * 提交表单 + */ + onSubmitForm = onCallback => { + const { form } = this.props; + form.validateFields((err, values) => { + if (!err && onCallback instanceof Function) { + onCallback(values); + } + }); + }; + + /** + * 重置表单 + */ + onResetForm = () => { + const { form } = this.props; + form.resetFields(); + }; + + render() { + const { form } = this.props; + const { getFieldDecorator } = form; + return ( + + + + + {getFieldDecorator('paramLocale')()} + + + + + {getFieldDecorator('paramModule')()} + + + + + {getFieldDecorator('paramCode')()} + + + + + {getFieldDecorator('paramName')()} + + + + + {getFieldDecorator('paramState', { initialValue: '' })( + , + )} + + + + + ); + } +} + +export default Search; diff --git a/src/pages/system/parameter/components/business/search/index.less b/src/pages/system/parameter/components/business/search/index.less new file mode 100644 index 0000000000000000000000000000000000000000..ea04e8037e6214c3fbfc8e3619f42dc75a45add3 --- /dev/null +++ b/src/pages/system/parameter/components/business/search/index.less @@ -0,0 +1,24 @@ +@import "~@/themes/vars.less"; + +.root { + margin-left: -@space-lg; + margin-right: -@space-lg; + :global { + .ant-form-item { + display: flex; + padding: 0 @space-lg; + margin: 0 0 @space-lg / 3 0; + .ant-form-item-label { + width: auto; + min-width: 80px; + padding-right: @space-sm / 2; + } + .ant-form-item-control-wrapper { + flex: 1 1; + } + .ant-calendar-picker { + width: 100%; + } + } + } +} diff --git a/src/pages/system/parameter/components/operation/action/index.js b/src/pages/system/parameter/components/operation/action/index.js new file mode 100644 index 0000000000000000000000000000000000000000..1846540490d6b7b43ab2b458e8945a1999ae18ba --- /dev/null +++ b/src/pages/system/parameter/components/operation/action/index.js @@ -0,0 +1,78 @@ +import React from 'react'; +import { Row, Col, Button, message, Upload } from 'antd'; +import styles from './index.less'; + +import { uploadParams } from '@/pages//system/parameter/services/operation'; + +const beforeUpload = file => { + // 检查文件类型 + const reg = /\.(xlsx|xls)$/; + const isXls = reg.test(file.name); + if (!isXls) { + message.error('只能上传Excel文件'); + return false; + } + + // 进行文件大小检查 + const isLt100M = file.size / 1024 / 1024 < 100; + if (!isLt100M) { + message.error('文件大小不能超过100M'); + } + return isXls && isLt100M; +}; + +const customRequest = ({ file, onSuccess }) => { + uploadParams({ + file, + onSuccess: ({ code, data }) => { + if (code === 'sys.success') { + message.success('导入成功'); + onSuccess(data); + } + }, + }); +}; +const props = { + name: 'file', + headers: { + authorization: 'authorization-text', + }, + accept: '.xlsx, .xls', + beforeUpload, + customRequest, +}; + +const Action = ({ + onClickQuery, + onClickReset, + onClickExport, + onClickAdd, + onSuccessUpload, + loading, +}) => ( + + + + +
+ + + +
+ + + + + + +); + +export default Action; diff --git a/src/pages/system/parameter/components/operation/action/index.less b/src/pages/system/parameter/components/operation/action/index.less new file mode 100644 index 0000000000000000000000000000000000000000..3ddc2bc8c23581f26f4c399ac61c2e9c7ecdee88 --- /dev/null +++ b/src/pages/system/parameter/components/operation/action/index.less @@ -0,0 +1,24 @@ +@import "~@/themes/vars.less"; + +.root { + margin-left: -@space-lg; + margin-right: -@space-lg; + margin-bottom: @space-lg; + // padding: 0 @space-lg; + .left { + padding: 0 @space-lg; + .uploadBtn { + float: left; + } + :global { + .ant-btn { + margin-right: @space-lg / 2; + } + } + } + .right { + padding: 0 @space-lg; + display: flex; + justify-content: flex-end; + } +} diff --git a/src/pages/system/parameter/components/operation/index.js b/src/pages/system/parameter/components/operation/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c7745c0eacea5303287c5141587d97347881e0eb --- /dev/null +++ b/src/pages/system/parameter/components/operation/index.js @@ -0,0 +1,303 @@ +import React from 'react'; +import { connect } from 'dva'; +import { message, Select, Form } from 'antd'; +import Search from './search'; +import Action from './action'; +import Table from '../table'; +import { generateUUID } from '@/utils'; +import Ellipsis from '@/components/Ellipsis'; + +import styles from './index.less'; + +const FormItem = Form.Item; + +@connect(({ paramOperation, loading: { effects } }) => { + const { list, pageData } = paramOperation; + return { + list, + pageData, + loading: + effects['paramOperation/getList'] || + effects['paramOperation/add'] || + effects['paramOperation/update'] || + effects['paramOperation/remove'], + }; +}) +class Index extends React.Component { + constructor(props) { + super(props); + this.search = null; + this.table = null; + this.queryParm = { pageNum: 1, pageSize: 10 }; + this.columns = [ + { + title: '参数模块', + dataIndex: 'paramModule', + width: '15%', + editable: true, + sorter: true, + rules: [ + { + required: true, + message: '请输入参数模块', + }, + { + max: 100, + message: '最大长度100', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '参数编码', + dataIndex: 'paramCode', + width: '20%', + editable: true, + sorter: true, + rules: [ + { + required: true, + message: '请输入参数编码', + }, + { + max: 200, + message: '最大长度200', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '参数值', + dataIndex: 'paramValue', + width: '20%', + editable: true, + rules: [ + { + required: true, + message: '请输入参数值', + }, + { + max: 500, + message: '最大长度500', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '说明', + dataIndex: 'remark', + width: '20%', + editable: true, + rules: [ + { + max: 200, + message: '最大长度200', + }, + ], + render: text => ( + + {text} + + ), + }, + { + title: '状态', + dataIndex: 'paramState', + width: '15%', + editable: true, + render: (text, record) => (String(record.paramState) === '1' ? '有效' : '无效'), + renderEditing: ({ form, record }) => { + const { getFieldDecorator } = form; + return ( + + {getFieldDecorator('paramState', { + rules: [ + { + required: true, + message: '请输入参数值', + }, + ], + initialValue: String(record.paramState) || '1', + })( + , + )} + + ); + }, + }, + ]; + } + + componentDidMount() { + this.refreshList(); + } + + /** + * 表格改变 + */ + onChangeTable = (pagination, filters, sorter) => { + this.queryParm = { + ...this.queryParm, + pageNum: pagination.current, + pageSize: pagination.pageSize, + sortOrder: sorter.order, + sortField: sorter.field, + }; + + this.refreshList(); + }; + + /** + * 查询 + */ + onClickQuery = () => { + this.search.onSubmitForm(values => { + this.queryParm = { ...this.queryParm, ...values, pageNum: 1 }; + this.refreshList(); + }); + }; + + /** + * 重置 + */ + onClickReset = () => { + this.search.onResetForm(); + const { dispatch } = this.props; + this.queryParm = { pageNum: 1 }; + dispatch({ + type: 'paramOperation/getList', + payload: this.queryParm, + }); + }; + + onSuccessUpload = () => { + this.refreshList(); + }; + + onClickExport = () => { + const { dispatch } = this.props; + this.search.onSubmitForm(values => { + const params = { ...this.queryParm, ...values }; + dispatch({ type: 'paramOperation/exportParam', params }); + }); + }; + + // 添加行 + onClickAdd = () => { + const row = { + action: 'add', + key: generateUUID(), + paramSeq: '', + paramModule: '', + paramCode: '', + paramValue: '', + remark: '', + paramState: '1', + }; + this.table.addRow(row); + }; + + handleSearch = n => { + this.search = n; + }; + + handleTable = n => { + this.table = n; + }; + + // 刷新列表 + refreshList = () => { + const { dispatch } = this.props; + dispatch({ + type: 'paramOperation/getList', + payload: { ...this.queryParm }, + }); + }; + + onAdd = async record => { + const { dispatch } = this.props; + const result = await dispatch({ + type: 'paramOperation/add', + payload: { ...record }, + }); + + if (result) { + message.success('添加成功'); + this.refreshList(); + } + return result; + }; + + onEdit = async record => { + const { dispatch } = this.props; + const result = await dispatch({ + type: 'paramOperation/update', + payload: { ...record }, + }); + if (result) { + message.success('修改成功'); + } + return result; + }; + + onDelete = async ({ paramId, goPrePage }) => { + if (goPrePage) { + this.queryParm.pageNum = this.queryParm.pageNum - 1; + } + const { dispatch } = this.props; + const result = await dispatch({ + type: 'paramOperation/remove', + payload: { paramId }, + }); + if (result) { + message.success('删除成功'); + this.refreshList(); + } + return result; + }; + + render() { + const { list, pageData, loading } = this.props; + const tableProps = { + dataSource: list, + pageData, + loading, + onAdd: this.onAdd, + onEdit: this.onEdit, + onDelete: this.onDelete, + onChangeTable: this.onChangeTable, + columns: this.columns, + }; + const actionProps = { + onClickQuery: this.onClickQuery, + onClickReset: this.onClickReset, + onClickExport: this.onClickExport, + onSuccessUpload: this.onSuccessUpload, + onClickAdd: this.onClickAdd, + }; + return ( +
+ + +
+ + ); + } +} + +export default Index; diff --git a/src/pages/system/parameter/components/operation/index.less b/src/pages/system/parameter/components/operation/index.less new file mode 100644 index 0000000000000000000000000000000000000000..c2026e3204dcac95b6786d4826fdb4755166ef77 --- /dev/null +++ b/src/pages/system/parameter/components/operation/index.less @@ -0,0 +1,4 @@ +@import "~@/themes/vars.less"; + +.root { +} diff --git a/src/pages/system/parameter/components/operation/search/index.js b/src/pages/system/parameter/components/operation/search/index.js new file mode 100644 index 0000000000000000000000000000000000000000..138a73df499d3fcb24677df510a10d75c0d304fa --- /dev/null +++ b/src/pages/system/parameter/components/operation/search/index.js @@ -0,0 +1,69 @@ +import React from 'react'; +import { Form, Input, Row, Col, Select } from 'antd'; +import styles from './index.less'; + +const FormItem = Form.Item; + +@Form.create() +class Search extends React.Component { + componentDidMount() {} + + /** + * 提交表单 + */ + onSubmitForm = onCallback => { + const { form } = this.props; + form.validateFields((err, values) => { + if (!err && onCallback instanceof Function) { + onCallback(values); + } + }); + }; + + /** + * 重置表单 + */ + onResetForm = () => { + const { form } = this.props; + form.resetFields(); + }; + + render() { + const { form } = this.props; + const { getFieldDecorator } = form; + return ( + + + + + {getFieldDecorator('paramModule')()} + + + + + {getFieldDecorator('paramCode')()} + + + + + {getFieldDecorator('paramValue')()} + + + + + {getFieldDecorator('paramState', { initialValue: '' })( + , + )} + + + + + ); + } +} + +export default Search; diff --git a/src/pages/system/parameter/components/operation/search/index.less b/src/pages/system/parameter/components/operation/search/index.less new file mode 100644 index 0000000000000000000000000000000000000000..ea04e8037e6214c3fbfc8e3619f42dc75a45add3 --- /dev/null +++ b/src/pages/system/parameter/components/operation/search/index.less @@ -0,0 +1,24 @@ +@import "~@/themes/vars.less"; + +.root { + margin-left: -@space-lg; + margin-right: -@space-lg; + :global { + .ant-form-item { + display: flex; + padding: 0 @space-lg; + margin: 0 0 @space-lg / 3 0; + .ant-form-item-label { + width: auto; + min-width: 80px; + padding-right: @space-sm / 2; + } + .ant-form-item-control-wrapper { + flex: 1 1; + } + .ant-calendar-picker { + width: 100%; + } + } + } +} diff --git a/src/pages/system/parameter/components/table/EditableCell.js b/src/pages/system/parameter/components/table/EditableCell.js new file mode 100644 index 0000000000000000000000000000000000000000..7cd0c6f7b05e9c2d893ee0555a723939f66dc220 --- /dev/null +++ b/src/pages/system/parameter/components/table/EditableCell.js @@ -0,0 +1,44 @@ +import React from 'react'; +import { Input, Form } from 'antd'; + +const FormItem = Form.Item; + +export const EditableContext = React.createContext(); + +export class EditableCell extends React.Component { + render() { + const { + editing, + dataIndex, + title, + renderEditing, + record, + rules, + index, + ...restProps + } = this.props; + return ( + + {form => { + const { getFieldDecorator } = form; + let formItem = null; + if (editing) { + if (renderEditing instanceof Function) { + formItem = renderEditing({ form, dataIndex, record, rules }); + } else { + formItem = ( + + {getFieldDecorator(dataIndex, { + rules, + initialValue: record[dataIndex], + })()} + + ); + } + } + return ; + }} + + ); + } +} diff --git a/src/pages/system/parameter/components/table/index.js b/src/pages/system/parameter/components/table/index.js new file mode 100644 index 0000000000000000000000000000000000000000..7a228a83da744e33ed07249812c9d7320cedfbb9 --- /dev/null +++ b/src/pages/system/parameter/components/table/index.js @@ -0,0 +1,241 @@ +import React from 'react'; +import { Table, Popconfirm, Form, Icon } from 'antd'; +import { EditableContext, EditableCell } from './EditableCell'; +import styles from './index.less'; + +class EditableTable extends React.Component { + static defaultProps = { + pageSize: 10, + }; + + constructor(props) { + super(props); + const { dataSource } = props; + this.state = { + data: dataSource, + editingKey: '', + }; + this.actionColumns = [ + { + title: '操作', + width: 80, + dataIndex: 'operation', + render: (text, record) => { + const { editingKey } = this.state; + const editable = this.isEditing(record); + const showDelete = this.showDelete(record, editable); + return ( +
+ {editable ? ( + + + {form => ( + this.save(e, form, record)} style={{ marginRight: 8 }}> + + + )} + + this.cancel(record)}> + + + + + + ) : ( + this.edit(record.key)} + > + + + )} + {showDelete && ( + this.delete(record)}> + + + + + )} +
+ ); + }, + }, + ]; + } + + // componentWillReceiveProps + componentWillReceiveProps(nextProps) { + const { dataSource } = this.props; + if (dataSource !== nextProps.dataSource) { + this.setState({ data: nextProps.dataSource }); + } + } + + // 是否显示删除按钮 + showDelete = (record, editable) => { + if (record.action === 'add' || editable) { + return false; + } + return true; + }; + + // eslint-disable-next-line react/destructuring-assignment + isEditing = record => record.key === this.state.editingKey; + + // change + onChangeTable = (pagination, filters, sorter) => { + const { onChangeTable } = this.props; + if (onChangeTable && onChangeTable instanceof Function) { + onChangeTable(pagination, filters, sorter); + } + this.cancel(); + }; + + // 删除 + delete = async record => { + const { onDelete, total, pageNum, pageSize } = this.props; + if (onDelete instanceof Function) { + // do someting + const goPrePage = total === (pageNum - 1) * pageSize + 1; + onDelete({ ...record, goPrePage }).then(() => { + this.cancel(); + }); + } + }; + + // 增加行 + addRow = row => { + const { dataSource } = this.props; + const newData = [...dataSource]; + newData.splice(0, 0, row); + this.setState({ + editingKey: row.key, + data: newData, + }); + setTimeout(() => { + document + .querySelectorAll('tr[data-row-key]:first-child')[0] + .getElementsByTagName('input')[0] + .focus(); + }, 800); + }; + + // 取消 + cancel = record => { + const { data } = this.state; + if (record && record.action === 'add') { + // 去掉第一条记录 + const newData = [...data]; + newData.splice(0, 1); + this.setState({ + data: newData, + }); + } + this.setState({ + editingKey: '', + }); + }; + + /** + * 编辑 + * @param {*} key + */ + edit(key) { + this.setState({ + editingKey: key, + }); + } + + /** + * 保存 + * @param {*} form + * @param {*} key + */ + save(e, form, record) { + e.preventDefault(); + form.validateFields((error, row) => { + if (error) { + return; + } + // 新增需要刷新页面 编辑可不刷新页面 + const { onAdd, onEdit } = this.props; + if (record.action === 'add') { + if (onAdd instanceof Function) { + onAdd({ ...record, ...row }).then(result => { + if (result) { + this.setState({ + editingKey: '', + }); + } + }); + } + } else if (onEdit instanceof Function) { + onEdit({ ...record, ...row }).then(result => { + if (result) { + this.setState({ + editingKey: '', + }); + } + }); + } + }); + } + + render() { + const { data } = this.state; + const { form, pageData, loading, columns = [] } = this.props; + const components = { + body: { + cell: EditableCell, + }, + }; + + const cols = columns.concat(this.actionColumns).map(col => { + if (!col.editable) { + return col; + } + return { + ...col, + onCell: record => ({ + renderEditing: col.renderEditing, + record, + rules: col.rules, + dataIndex: col.dataIndex, + title: col.title, + editing: this.isEditing(record), + }), + }; + }); + + return ( +
+ +
{editing ? formItem : restProps.children}
+ + + ); + } +} + +const EditableFormTable = Form.create()(EditableTable); +export default EditableFormTable; diff --git a/src/pages/system/parameter/components/table/index.less b/src/pages/system/parameter/components/table/index.less new file mode 100644 index 0000000000000000000000000000000000000000..e5e02c5652e1710971a6046cd4e9c83c6bbeb88a --- /dev/null +++ b/src/pages/system/parameter/components/table/index.less @@ -0,0 +1,26 @@ +@import "~@/themes/vars.less"; +.root { + :global { + .anticon { + // font-size: 18px; + } + .editable-row .ant-form-explain { + position: absolute; + font-size: 12px; + margin-top: -4px; + } + .fixedWidthTable { + table { + table-layout: fixed; + } + .ant-table-tbody { + tr { + td { + word-wrap: break-word; + word-break: break-all; + } + } + } + } + } +} diff --git a/src/pages/system/parameter/index.js b/src/pages/system/parameter/index.js new file mode 100644 index 0000000000000000000000000000000000000000..4af140656ec46bb22e9a1af21e0d705229b682c5 --- /dev/null +++ b/src/pages/system/parameter/index.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { Tabs } from 'antd'; +import router from 'umi/router'; + +import Operation from './components/operation'; +import Business from './components/business'; +import styles from './index.less'; + +const { TabPane } = Tabs; +const index = props => { + // console.log(props); + /** + * 切换tab页签 + * @param {*} key + */ + function onChangeTab(key) { + router.push(key); + } + const { + location: { hash }, + } = props; + return ( +
+ + + + + + + + +
+ ); +}; + +export default index; diff --git a/src/pages/system/parameter/index.less b/src/pages/system/parameter/index.less new file mode 100644 index 0000000000000000000000000000000000000000..99d5f0d581b136227268f395314ef621a0ca3ee2 --- /dev/null +++ b/src/pages/system/parameter/index.less @@ -0,0 +1,8 @@ +@import "~@/themes/vars.less"; + +.root { + background-color: #fff; + padding: 16px 24px; + border-radius: 4px; + min-height: calc(100vh - 100px); +} diff --git a/src/pages/system/parameter/models/business.js b/src/pages/system/parameter/models/business.js new file mode 100644 index 0000000000000000000000000000000000000000..5e6b885ba9d7d95075a9139a2d5e572c23bc7437 --- /dev/null +++ b/src/pages/system/parameter/models/business.js @@ -0,0 +1,89 @@ +import * as service from '../services/business'; + +export default { + namespace: 'paramBusiness', + state: { + list: [], + pageData: { + pageSize: 10, + pageNum: 1, + total: 0, + current: 1, + }, + }, + reducers: { + save( + state, + { + payload: { records: list, pageSize, pageNum, total, current }, + }, + ) { + list.forEach(element => { + element.key = element.paramId; + }); + return { + ...state, + list: [...list], + pageData: { pageSize, pageNum, total, current }, + }; + }, + changeList( + state, + { + payload: { list }, + }, + ) { + return { ...state, list: [...list] }; + }, + }, + effects: { + // 获取列表数据 + *getList({ payload }, { call, put }) { + const { data } = yield call(service.getList, payload); + yield put({ + type: 'save', + payload: { ...data }, + }); + }, + // 增加 + *add({ payload }, { call }) { + const { code } = yield call(service.add, payload); + return code === 'sys.success'; + }, + // 更改 + *update({ payload }, { call, put, select }) { + const { code } = yield call(service.update, payload); + const result = code === 'sys.success'; + if (result) { + const list = yield select(({ paramBusiness }) => paramBusiness.list); + const index = list.findIndex(element => payload.key === element.key); + if (index > -1) { + list[index] = { ...list[index], ...payload }; + } + yield put({ + type: 'changeList', + payload: { list }, + }); + } + return result; + }, + // 删除 + *remove({ payload }, { call }) { + const { code } = yield call(service.remove, payload); + return code === 'sys.success'; + }, + *exportParam({ params }, { call }) { + yield call(service.exportParam, { ...params }); + }, + }, + subscriptions: { + // setup({ dispatch, history }) { + // return history.listen(({ pathname, query, hash }) => { + // // 初始化数据加载 也可以在componentDidMount中 + // if (pathname === "/parameter" && (hash === "#business" || !hash)) { + // dispatch({ type: "getList", payload: query }); + // } + // }); + // }, + }, +}; diff --git a/src/pages/system/parameter/models/operation.js b/src/pages/system/parameter/models/operation.js new file mode 100644 index 0000000000000000000000000000000000000000..fb49a7f41e5839d217e21fb0fda6d2a17cf6c326 --- /dev/null +++ b/src/pages/system/parameter/models/operation.js @@ -0,0 +1,89 @@ +import * as service from '../services/operation'; + +export default { + namespace: 'paramOperation', + state: { + list: [], + pageData: { + pageSize: 10, + pageNum: 1, + total: 0, + current: 1, + }, + }, + reducers: { + save( + state, + { + payload: { records: list, pageSize, pageNum, total, current }, + }, + ) { + list.forEach(item => { + item.key = item.paramId; + }); + return { + ...state, + list: [...list], + pageData: { pageSize, pageNum, total, current }, + }; + }, + setList( + state, + { + payload: { list }, + }, + ) { + return { ...state, list: [...list] }; + }, + }, + effects: { + // 获取列表数据 + *getList({ payload }, { call, put }) { + const { data } = yield call(service.getList, payload); + yield put({ + type: 'save', + payload: { ...data }, + }); + }, + // 增加 + *add({ payload }, { call }) { + const { code } = yield call(service.add, payload); + return code === 'sys.success'; + }, + // 更改 + *update({ payload }, { call, put, select }) { + const { code } = yield call(service.update, payload); + const result = code === 'sys.success'; + if (result) { + const list = yield select(({ paramOperation }) => paramOperation.list); + const index = list.findIndex(element => payload.key === element.key); + if (index > -1) { + list[index] = { ...list[index], ...payload }; + } + yield put({ + type: 'changeList', + payload: { list }, + }); + } + return result; + }, + // 删除 + *remove({ payload }, { call }) { + const { code } = yield call(service.remove, payload); + return code === 'sys.success'; + }, + *exportParam({ params }, { call }) { + yield call(service.exportParam, { ...params }); + }, + }, + subscriptions: { + // setup({ dispatch, history }) { + // return history.listen(({ pathname, query, hash }) => { + // // 初始化数据加载 也可以在componentDidMount中 + // if (pathname === "/parameter" && (hash === "#operation" || !hash)) { + // dispatch({ type: "getList", payload: query }); + // } + // }); + // }, + }, +}; diff --git a/src/pages/system/parameter/services/business.js b/src/pages/system/parameter/services/business.js new file mode 100644 index 0000000000000000000000000000000000000000..41a4f2cde03406a3da2cfd0fdbb6a9c611742e21 --- /dev/null +++ b/src/pages/system/parameter/services/business.js @@ -0,0 +1,42 @@ +import { get, put, post, del, uploadFile } from '@/utils/request'; +import { downloadFile } from '@/utils'; + +/** + * 获得列表数据 + * + * @param {*} data + */ +export const getList = data => get('/api/v1/params/businesses', data); +/** + * 添加 + * @param {*} data + */ +export const add = data => post('/api/v1/params/businesses', data); +/** + * 更新 + * @param {*} data + */ +export const update = data => put('/api/v1/params/businesses', data); +/** + * 删除 + * @param {*} data + */ +export const remove = data => del(`/api/v1/params/businesses/${data.paramId}`, data); + +/** + * 导出 + * @param {*} params + */ +export const exportParam = params => + downloadFile('/api/v1/params/businessparameter_export_excel', params); + +/** + * 参数导入 + * @param {*} param0 + */ +export const uploadParams = ({ file, onSuccess }) => + uploadFile({ + action: '/api/v1/params/bp_import', + file, + onSuccess, + }); diff --git a/src/pages/system/parameter/services/operation.js b/src/pages/system/parameter/services/operation.js new file mode 100644 index 0000000000000000000000000000000000000000..67b1fa51f28b064c5c6ac70464671e3ad8d93a45 --- /dev/null +++ b/src/pages/system/parameter/services/operation.js @@ -0,0 +1,42 @@ +import { get, put, post, del, uploadFile } from '@/utils/request'; +import { downloadFile } from '@/utils'; + +/** + * 获得列表数据 + * + * @param {*} data + */ +export const getList = data => get('/api/v1/params/operations', data); +/** + * 添加 + * @param {*} data + */ +export const add = data => post('/api/v1/params/operations', data); +/** + * 更新 + * @param {*} data + */ +export const update = data => put('/api/v1/params/operations', data); +/** + * 删除 + * @param {*} data + */ +export const remove = data => del(`/api/v1/params/operations/${data.paramId}`, data); + +/** + * 导出 + * @param {*} params + */ +export const exportParam = params => + downloadFile('/api/v1/params/operationparameter_export_excel', params); + +/** + * 参数导入 + * @param {*} param0 + */ +export const uploadParams = ({ file, onSuccess }) => + uploadFile({ + action: '/api/v1/params/opp_import', + file, + onSuccess, + });