| | |
| | | import { DndProvider } from 'react-dnd' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { Button, Card, Modal, Collapse, notification, Select, List, Icon, Empty } from 'antd' |
| | | import moment from 'moment' |
| | | import DragElement from './dragelement' |
| | | import SourceElement from './dragelement/source' |
| | | import Api from '@/api' |
| | | import ModalForm from './modalform' |
| | | import SettingForm from './settingform' |
| | | import GroupForm from './groupform' |
| | | import EditCard from './editcard' |
| | | import MenuForm from './menuform' |
| | | import zhCN from '@/locales/zh-CN/comtable.js' |
| | |
| | | } |
| | | |
| | | state = { |
| | | operaType: '', // 操作类型,新建或编辑 |
| | | dict: CommonDict, // 字典 |
| | | config: null, // 页面配置 |
| | | visible: false, // 搜索条件、按钮、显示列,模态框显示控制 |
| | | tableVisible: false, // 数据表字段模态框 |
| | | addType: '', // 添加类型-搜索条件或显示列 |
| | | tableColumns: [], // 表格显示列 |
| | | fields: null, // 搜索条件及显示列,可选字段 |
| | | modalformlist: null, // 基本信息表单字段 |
| | | formlist: null, // 搜索条件、按钮、显示列表单字段 |
| | | card: null, // 编辑元素 |
| | | loading: false, // 搜索条件加载中 |
| | | menuloading: false, // 菜单保存中 |
| | | dict: CommonDict, // 字典 |
| | | config: null, // 页面配置,包括模板类型、模态框设置、添加表名、表单列表 |
| | | visible: false, // 表单编辑模态框,显示控制 |
| | | tableVisible: false, // 数据表字段列表模态框,显示控制 |
| | | tableColumns: [], // 表格字段名列表 |
| | | fields: null, // 表单,可选字段(去重后) |
| | | modalformlist: null, // 基本信息表单字段 |
| | | formlist: null, // 表单编辑模态框,可编辑字段 |
| | | card: null, // 编辑元素 |
| | | loading: false, // 表单刷新时使用 |
| | | menuloading: false, // 菜单保存中 |
| | | settingVisible: false, // 全局配置模态框 |
| | | closeVisible: false, // 关闭模态框 |
| | | tables: [], // 可用表名 |
| | | selectedTables: [], // 已选表名 |
| | | originMenu: null // 原始菜单 |
| | | closeVisible: false, // 关闭模态框 |
| | | tables: [], // 可用表名 |
| | | selectedTables: [], // 已选表名 |
| | | originMenu: null, // 原始菜单 |
| | | groupVisible: false, // 全局配置模态框 |
| | | } |
| | | |
| | | /** |
| | | * @description 数据预处理 |
| | | * 1、按钮配置存在时使用按钮配置,不存在时使用默认配置(示例) |
| | | * 2、模态框标题不存在时,使用按钮标题 |
| | | * 3、设置已选表 |
| | | * 4、设置按钮基本信息 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const {menu, editAction} = this.props |
| | | |
| | | let _config = '' |
| | | let _operaType = 'add' |
| | | if (editAction.pageParam) { |
| | | _config = editAction.pageParam |
| | | _operaType = 'edit' |
| | | } else { |
| | | _config = JSON.parse(JSON.stringify((Source.baseConfig))) |
| | | _config.groups[0].sublist = _config.fields.map(field => field.uuid) |
| | | } |
| | | |
| | | if (!_config.setting.title) { |
| | | _config.setting.title = editAction.label |
| | | } |
| | | |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | operaType: _operaType, |
| | | selectedTables: _config.tables || [], |
| | | modalformlist: [ |
| | | { |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 获取数据表信息 |
| | | * 1、获取系统中全部表名 |
| | | * 2、根据已选表名,获取表格字段列表 |
| | | */ |
| | | componentDidMount () { |
| | | let _text = 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0' |
| | | _text = Utils.formatOptions(_text) |
| | | let param = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0', |
| | | obj_name: 'data', |
| | | arr_field: 'TbName,Remark' |
| | | } |
| | | |
| | | Api.getSystemConfig({func: 'sPC_Get_SelectedList', LText: _text, obj_name: 'data', arr_field: 'TbName,Remark'}).then(res => { |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000' |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | Api.getSystemConfig(param).then(res => { |
| | | if (res.status) { |
| | | this.setState({ |
| | | tables: res.data |
| | |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | // 获取字段后数据处理,根据类型分为text、number、datetime、date |
| | | Promise.all(deffers).then(response => { |
| | | let _columns = [] |
| | | response.forEach(res => { |
| | |
| | | } else if (/^decimal/.test(_type)) { |
| | | _decimal = _type.split(',')[1] |
| | | _decimal = parseInt(_decimal) |
| | | if (_decimal > 4) { |
| | | _decimal = 4 |
| | | } |
| | | _type = 'number' |
| | | } else if (/^decimal/.test(_type)) { |
| | | _decimal = _type.split(',')[1] |
| | | _decimal = parseInt(_decimal) |
| | | if (_decimal > 4) { |
| | | _decimal = 4 |
| | | } |
| | | _type = 'number' |
| | | } else if (/^datetime/.test(_type)) { |
| | | _type = 'datetime' |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 表单变化 |
| | | * 1、表单拖拽添加时,检查是否存在示例表单,如存在则去除示例 |
| | | * 2、表单移动后,保存移动后的顺序 |
| | | */ |
| | | handleList = (list) => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | |
| | | if (list.length > _config.fields.length) { |
| | | _config.fields = list.filter(item => !item.origin) |
| | | |
| | | this.setState({ |
| | | loading: true, |
| | | config: _config |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 表单编辑 |
| | | * 1、显示编辑弹窗 |
| | | * 2、保存编辑项 |
| | | * 3、设置编辑参数项 |
| | | */ |
| | | handleForm = (card) => { |
| | | this.setState({ |
| | | visible: true, |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 编辑后提交 |
| | | * 1、获取编辑后的表单信息 |
| | | * 2、去除可能存在的示例表单 |
| | | * 3、通过loading刷新 |
| | | */ |
| | | handleSubmit = () => { |
| | | this.formRef.handleConfirm().then(res => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | console.log(res) |
| | | |
| | | _config.fields = _config.fields.map(item => { |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 表单删除并刷新 |
| | | */ |
| | | closeForm = (card) => { |
| | | let _this = this |
| | | |
| | |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | changeTemplate = () => { |
| | | this.props.handleConfig('template') |
| | | } |
| | | |
| | | submitConfig = () => { |
| | |
| | | if (response.status) { |
| | | this.setState({ |
| | | menuloading: false, |
| | | operaType: 'edit', |
| | | originMenu: { |
| | | ...originMenu, |
| | | LongParam: _config, |
| | |
| | | } |
| | | }) |
| | | |
| | | if (this.state.operaType === 'add') { |
| | | |
| | | } else { |
| | | let param = { |
| | | func: 'sPC_TrdMenu_Upt', |
| | | ParentID: res.parentId, |
| | | MenuID: menu.MenuID, |
| | | MenuNo: res.menuNo, |
| | | Template: menu.PageParam.Template || '', |
| | | MenuName: res.menuName, |
| | | PageParam: JSON.stringify(_pageParam), |
| | | LongParam: _LongParam |
| | | } |
| | | this.setState({ |
| | | menuloading: true |
| | | }) |
| | | // let param = { |
| | | // func: 'sPC_TrdMenu_Upt', |
| | | // ParentID: res.parentId, |
| | | // MenuID: menu.MenuID, |
| | | // MenuNo: res.menuNo, |
| | | // Template: menu.PageParam.Template || '', |
| | | // MenuName: res.menuName, |
| | | // PageParam: JSON.stringify(_pageParam), |
| | | // LongParam: _LongParam |
| | | // } |
| | | this.setState({ |
| | | menuloading: true |
| | | }) |
| | | |
| | | Api.getSystemConfig(param).then(response => { |
| | | if (response.status) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功', |
| | | duration: 10 |
| | | }) |
| | | if (this.state.closeVisible) { |
| | | this.props.handleConfig('') |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false, |
| | | originMenu: { |
| | | ...originMenu, |
| | | LongParam: _config, |
| | | PageParam: _pageParam, |
| | | MenuName: res.menuName, |
| | | MenuNo: res.menuNo, |
| | | ParentID: res.parentId |
| | | } |
| | | }) |
| | | } |
| | | Api.getSystemConfig(param).then(response => { |
| | | if (response.status) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功', |
| | | duration: 10 |
| | | }) |
| | | if (this.state.closeVisible) { |
| | | this.props.handleConfig('') |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: response.message, |
| | | duration: 10 |
| | | menuloading: false, |
| | | originMenu: { |
| | | ...originMenu, |
| | | LongParam: _config, |
| | | PageParam: _pageParam, |
| | | MenuName: res.menuName, |
| | | MenuNo: res.menuNo, |
| | | ParentID: res.parentId |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: response.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | }, () => { |
| | | notification.warning({ |
| | | top: 92, |
| | |
| | | const { config, originMenu } = this.state |
| | | let _this = this |
| | | |
| | | if (this.state.operaType === 'add') { |
| | | let isOrigin = config.fields.filter(item => item.origin).length > 0 |
| | | if (isOrigin) { |
| | | confirm({ |
| | | content: '菜单尚未提交,确定放弃保存吗?', |
| | | okText: this.state.dict['header.confirm'], |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 通过表字段添加表单 |
| | | * 1、检查是否已选表名,为选时警告提示 |
| | | * 2、表字段名通过map去重 |
| | | * 3、检查表单中的已选字段,并标记已选 |
| | | */ |
| | | queryField = () => { |
| | | const {selectedTables, tableColumns, config} = this.state |
| | | if (selectedTables.length === 0) { |
| | |
| | | |
| | | config.fields.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | columns.set(item.field, {...item, selected: true, type: item.type}) |
| | | columns.set(item.field, {...item, selected: true}) |
| | | } |
| | | }) |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 选择字段后提交 |
| | | * 1、没有可选字段时,直接关闭 |
| | | * 2、获取已选字段 |
| | | * 3、与已有字段对比 |
| | | * 4、添加新增字段 |
| | | */ |
| | | addFieldSubmit = () => { |
| | | if (!this.state.fields || this.state.fields.length === 0) { |
| | | this.setState({ |
| | |
| | | if (columns.has(item.field)) { |
| | | let cell = columns.get(item.field) |
| | | |
| | | if (cell.selected && cell.type === item.type) { // 数据未修改 |
| | | if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加 |
| | | items.push(item) |
| | | } else if (cell.selected) { // 数据类型修改 |
| | | } else if (cell.selected) { // 数据类型修改时,重置类型及初始值 |
| | | item.type = cell.type |
| | | item.initval = '' |
| | | items.push(item) |
| | | } |
| | | columns.delete(item.field) |
| | | } else if (!item.origin) { |
| | | } else if (!item.origin) { // 过滤示例项 |
| | | items.push(item) |
| | | } |
| | | }) |
| | |
| | | let indexes = items.map(card => {return card.id}) |
| | | let id = Math.max(...indexes, 0) + 1 |
| | | |
| | | _columns.forEach(item => { |
| | | _columns.forEach(item => { // 循环添加新增字段 |
| | | if (item.selected) { |
| | | let newcard = { |
| | | id: id, |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 添加表名 |
| | | * 1、获取表信息 |
| | | * 2、检验是否已经添加,已添加时跳过 |
| | | * 3、通过表名获取字段集,并设置数据类型 |
| | | */ |
| | | onTableChange = (value) => { |
| | | const {tables, selectedTables, tableColumns} = this.state |
| | | |
| | | let _table = tables.filter(item => item.TbName === value)[0] |
| | | let isSelected = !!selectedTables.filter(cell => cell.TbName === value)[0] |
| | | if (!isSelected) { |
| | | this.setState({ |
| | | selectedTables: [...selectedTables, _table] |
| | | }) |
| | | Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: value}).then(res => { |
| | | if (res.status) { |
| | | let tabmsg = { |
| | | tableName: _table.name, |
| | | columns: res.FDName.map(item => { |
| | | let _type = item.FieldType.toLowerCase() |
| | | let _decimal = 0 |
| | | if (/^nvarchar/.test(_type)) { |
| | | _type = 'text' |
| | | } else if (/^int/.test(_type)) { |
| | | _type = 'number' |
| | | } else if (/^decimal/.test(_type)) { |
| | | _decimal = _type.split(',')[1] |
| | | _decimal = parseInt(_decimal) |
| | | _type = 'number' |
| | | } else if (/^datetime/.test(_type)) { |
| | | _type = 'datetime' |
| | | } else if (/^date/.test(_type)) { |
| | | _type = 'date' |
| | | } else { |
| | | _type = 'text' |
| | | } |
| | | |
| | | return { |
| | | field: item.FieldName, |
| | | label: item.FieldDec, |
| | | type: _type, |
| | | decimal: _decimal |
| | | } |
| | | }) |
| | | } |
| | | this.setState({ |
| | | tableColumns: [...tableColumns, tabmsg] |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | if (isSelected) return |
| | | |
| | | this.setState({ |
| | | selectedTables: [...selectedTables, _table] |
| | | }) |
| | | Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: value}).then(res => { |
| | | if (res.status) { |
| | | let tabmsg = { |
| | | tableName: _table.name, |
| | | columns: res.FDName.map(item => { |
| | | let _type = item.FieldType.toLowerCase() |
| | | let _decimal = 0 |
| | | if (/^nvarchar/.test(_type)) { |
| | | _type = 'text' |
| | | } else if (/^int/.test(_type)) { |
| | | _type = 'number' |
| | | } else if (/^decimal/.test(_type)) { |
| | | _decimal = _type.split(',')[1] |
| | | _decimal = parseInt(_decimal) |
| | | _type = 'number' |
| | | } else if (/^datetime/.test(_type)) { |
| | | _type = 'datetime' |
| | | } else if (/^date/.test(_type)) { |
| | | _type = 'date' |
| | | } else { |
| | | _type = 'text' |
| | | } |
| | | |
| | | return { |
| | | field: item.FieldName, |
| | | label: item.FieldDec, |
| | | type: _type, |
| | | decimal: _decimal |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | this.setState({ |
| | | tableColumns: [...tableColumns, tabmsg] |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 删除表名,删除对应字段集 |
| | | */ |
| | | deleteTable = (table) => { |
| | | const {selectedTables, tableColumns} = this.state |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 全局设置模态框 |
| | | */ |
| | | changeSetting = () => { |
| | | this.setState({ |
| | | settingVisible: true |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 保存全局设置 |
| | | */ |
| | | settingSave = () => { |
| | | const {config} = this.state |
| | | this.settingRef.handleConfirm().then(res => { |
| | |
| | | }) |
| | | } |
| | | |
| | | handleGroup = () => { |
| | | |
| | | } |
| | | |
| | | handleGroupSave = () => { |
| | | |
| | | } |
| | | |
| | | render () { |
| | | const { config } = this.state |
| | | |
| | |
| | | <DndProvider backend={HTML5Backend}> |
| | | <div className="tools"> |
| | | <Collapse accordion defaultActiveKey="0" bordered={false}> |
| | | <Panel header="基本信息" key="0" id="modal-basedata"> |
| | | <MenuForm |
| | | dict={this.state.dict} |
| | | formlist={this.state.modalformlist} |
| | | wrappedComponentRef={(inst) => this.menuformRef = inst} |
| | | /> |
| | | <Panel header={this.state.dict['header.menu.basedata']} key="0" id="modal-basedata"> |
| | | <MenuForm |
| | | dict={this.state.dict} |
| | | formlist={this.state.modalformlist} |
| | | wrappedComponentRef={(inst) => this.menuformRef = inst} |
| | | /> |
| | | <div className="ant-col ant-form-item-label"> |
| | | <label title="添加表名">添加表名</label> |
| | | <label title={this.state.dict['header.menu.table.add']}> |
| | | {this.state.dict['header.menu.table.add']} |
| | | </label> |
| | | </div> |
| | | <Select |
| | | showSearch |
| | | className="tables" |
| | | style={{ width: '100%' }} |
| | | optionFilterProp="children" |
| | | value={'请选择表名'} |
| | | value={this.state.dict['header.menu.table.placeholder']} |
| | | onChange={this.onTableChange} |
| | | showArrow={false} |
| | | getPopupContainer={() => document.getElementById('modal-basedata')} |
| | |
| | | </List.Item>} |
| | | />} |
| | | </Panel> |
| | | <Panel header="表单" key="1"> |
| | | <Panel header={this.state.dict['header.menu.form']} key="1"> |
| | | <div className="search-element"> |
| | | {Source.searchItems.map((item, index) => { |
| | | return (<SourceElement key={index} content={item}/>) |
| | | })} |
| | | </div> |
| | | <Button type="primary" block onClick={() => this.queryField()}>添加表单</Button> |
| | | <Button type="primary" block onClick={() => this.queryField()}>{this.state.dict['header.menu.form.add']}</Button> |
| | | <Button type="primary" block onClick={() => this.handleGroup()}>{this.state.dict['header.menu.group.add']}</Button> |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className="setting"> |
| | | <Card title="表单配置" bordered={false} extra={ |
| | | <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={ |
| | | <div> |
| | | <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['header.save']}</Button> |
| | | <Button onClick={this.cancelConfig}>{this.state.dict['header.return']}</Button> |
| | |
| | | </div> |
| | | <div className="ant-modal-body"> |
| | | <div className="modal-form"> |
| | | {!this.state.loading ? |
| | | {!this.state.loading && config.groups.length > 1 && |
| | | config.groups.map(group => { |
| | | return ( |
| | | <div key={group.uuid}> |
| | | <p className="group-title">{group.label}</p> |
| | | <DragElement |
| | | list={config.fields} |
| | | setting={config.setting} |
| | | placeholder={this.state.dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> |
| | | </div> |
| | | ) |
| | | }) |
| | | } |
| | | {!this.state.loading && config.groups.length === 1? |
| | | <DragElement |
| | | list={config.fields} |
| | | setting={config.setting} |
| | |
| | | </div> |
| | | <div className="ant-modal-footer"> |
| | | <div> |
| | | <button type="button" className="ant-btn"><span>取 消</span></button> |
| | | <button type="button" className="ant-btn ant-btn-primary"><span>确 定</span></button> |
| | | <button type="button" className="ant-btn"> |
| | | <span>{this.state.dict['header.cancel']}</span> |
| | | </button> |
| | | <button type="button" className="ant-btn ant-btn-primary"> |
| | | <span>{this.state.dict['header.confirm']}</span> |
| | | </button> |
| | | </div> |
| | | <div className="action-mask"></div> |
| | | </div> |
| | |
| | | title={this.state.dict['header.edit']} |
| | | visible={this.state.visible} |
| | | width={700} |
| | | onCancel={() => { |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | }} |
| | | onCancel={() => { this.setState({ visible: false }) }} |
| | | onOk={this.handleSubmit} |
| | | destroyOnClose |
| | | > |
| | |
| | | width={'65vw'} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | onOk={this.addFieldSubmit} |
| | | onCancel={() => { |
| | | this.setState({ |
| | | tableVisible: false |
| | | }) |
| | | }} |
| | | onCancel={() => { this.setState({ tableVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | {this.state.fields && this.state.fields.length > 0 ? |
| | |
| | | visible={this.state.settingVisible} |
| | | width={700} |
| | | onOk={this.settingSave} |
| | | onCancel={() => { |
| | | this.setState({ |
| | | settingVisible: false |
| | | }) |
| | | }} |
| | | onCancel={() => { this.setState({ settingVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | |
| | | ]} |
| | | destroyOnClose |
| | | > |
| | | 菜单配置已修改,是否保存配置信息? |
| | | {this.state.dict['header.menu.config.placeholder']} |
| | | </Modal> |
| | | <Modal |
| | | title={this.state.dict['header.menu.group.manage']} |
| | | visible={this.state.groupVisible} |
| | | width={700} |
| | | onOk={this.handleGroupSave} |
| | | onCancel={() => { this.setState({ groupVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <GroupForm |
| | | data={config.setting} |
| | | dict={this.state.dict} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |