diff --git a/Api/Ewide.Core/applicationconfig.json b/Api/Ewide.Core/applicationconfig.json index 1568099..0266d1e 100644 --- a/Api/Ewide.Core/applicationconfig.json +++ b/Api/Ewide.Core/applicationconfig.json @@ -93,6 +93,7 @@ "sysDictType:dropDowns", "sysFileInfo:upload", "sysFileInfo:download", + "sysFileInfo:detail", "sysFileInfo:preview", "sysUser:updateInfo", "sysUser:updatePwd", diff --git a/Web/src/pages/business/house/info/form/base/aspect.vue b/Web/src/pages/business/house/info/form/base/aspect.vue index 878c07e..90ae890 100644 --- a/Web/src/pages/business/house/info/form/base/aspect.vue +++ b/Web/src/pages/business/house/info/form/base/aspect.vue @@ -104,15 +104,25 @@ export default { if (record) { const fileList = !!record.houseInfo.facadePhoto ? record.houseInfo.facadePhoto.split(',') : []; for (let i = 0; i < fileList.length; i++) { - const file = await PreviewFile(fileList[i]); - const base64 = await BlobToBase64(file); - facadePhoto.push({ - uid: fileList[i], - response: fileList[i], // 用于和新上传的文件一同回传 - name: file.name, - url: base64, - status: 'done', - }); + try { + const file = await PreviewFile(fileList[i]); + const base64 = await BlobToBase64(file); + facadePhoto.push({ + uid: fileList[i], + response: fileList[i], // 用于和新上传的文件一同回传 + name: file.name, + url: base64, + status: 'done', + }); + } catch { + const { data: file } = await this.$api.sysFileInfoDetail({ id: fileList[i] }); + facadePhoto.push({ + uid: fileList[i], + response: '文件已丢失', + name: file.fileOriginName, + status: 'error', + }); + } } } defaultForm.houseInfo.facadePhoto = facadePhoto; diff --git a/Web/src/pages/business/house/info/form/base/attachments.vue b/Web/src/pages/business/house/info/form/base/attachments.vue index db16ab8..69162a5 100644 --- a/Web/src/pages/business/house/info/form/base/attachments.vue +++ b/Web/src/pages/business/house/info/form/base/attachments.vue @@ -173,15 +173,25 @@ export default { const fileList = !form.houseInfo[key] || form.houseInfo[key].length == 0 ? [] : form.houseInfo[key].split(','); for (let i = 0; i < fileList.length; i++) { - const file = await PreviewFile(fileList[i]); - const base64 = await BlobToBase64(file); - fileValue.push({ - uid: fileList[i], - response: fileList[i], // 用于和新上传的文件一同回传 - name: file.name, - url: base64, - status: 'done', - }); + try { + const file = await PreviewFile(fileList[i]); + const base64 = await BlobToBase64(file); + fileValue.push({ + uid: fileList[i], + response: fileList[i], // 用于和新上传的文件一同回传 + name: file.name, + url: base64, + status: 'done', + }); + } catch { + const { data: file } = await this.$api.sysFileInfoDetail({ id: fileList[i] }); + fileValue.push({ + uid: fileList[i], + response: '文件已丢失', + name: file.fileOriginName, + status: 'error', + }); + } } form.houseInfo[key] = fileValue; } diff --git a/web-react/public/seed/form-tabs/index.jsx b/web-react/public/seed/form-tabs/index.jsx index eb0a9c4..3cd7e70 100644 --- a/web-react/public/seed/form-tabs/index.jsx +++ b/web-react/public/seed/form-tabs/index.jsx @@ -16,6 +16,7 @@ export default class index extends Component { actived: '0', loading: true, record: null, + saveDisabled: true, saving: false, } @@ -42,6 +43,16 @@ export default class index extends Component { */ componentDidMount() {} + /** + * 接收到所有子组件已加载完成,并启用提交按钮 + */ + call(child, index) { + this.children[index] = child + if (this.children.filter(p => p).length === tabs.filter(p => p.show).length) { + this.setState({ saveDisabled: false }) + } + } + async onSubmit() { for (const child of this.children) { try { @@ -62,7 +73,7 @@ export default class index extends Component { } render() { - const { actived, loading, record, saving } = this.state + const { actived, loading, record, saveDisabled, saving } = this.state return (
@@ -77,6 +88,7 @@ export default class index extends Component { 取消
) diff --git a/web-react/public/seed/form-tabs/tab/index.jsx b/web-react/public/seed/form-tabs/tab/index.jsx index ee18b7a..c67e687 100644 --- a/web-react/public/seed/form-tabs/tab/index.jsx +++ b/web-react/public/seed/form-tabs/tab/index.jsx @@ -34,11 +34,13 @@ export default class index extends Component { } /** - * DDOM加载完成钩子,在此将自身传递给父级 + * 加载完成,通知父级组件并传递自身 */ - componentDidMount() { - if (this.props.onRef) { - this.props.onRef(this) + call(child, index) { + this.children[index] = child + if (this.children.filter(p => p).length === parts.length) { + const { onRef } = this.props + if (onRef) onRef(this) } } @@ -85,17 +87,17 @@ export default class index extends Component { {parts.map((item, i) => (
- {item.title &&
{parts.title}
} + {item.title &&
{item.title}
} } - wrapperClassName="h-400-min" + wrapperClassName={loading && 'h-400-min'} > {!loading && ( this.children.push(r)} + onRef={child => this.call(child, i)} /> )} diff --git a/web-react/public/seed/form-tabs/tab/parts.jsx b/web-react/public/seed/form-tabs/tab/part.jsx similarity index 90% rename from web-react/public/seed/form-tabs/tab/parts.jsx rename to web-react/public/seed/form-tabs/tab/part.jsx index 0785128..9b70bef 100644 --- a/web-react/public/seed/form-tabs/tab/parts.jsx +++ b/web-react/public/seed/form-tabs/tab/part.jsx @@ -36,17 +36,22 @@ export default class part extends Component { } /** - * DOM加载完成钩子,在此将自身传递给父级,并且绑定数据 + * DOM加载完成钩子,绑定数据 */ componentDidMount() { - if (this.props.onRef) { - this.props.onRef(this) - } this.fillData({ record: this.props.record, }) } + /** + * 加载完成,通知父级组件并传递自身 + */ + call() { + const { onRef } = this.props + if (onRef) onRef(this) + } + /** * 填充数据 * 可以在设置this.record之后对其作出数据结构调整 @@ -59,9 +64,8 @@ export default class part extends Component { //#endregion this.form.current.setFieldsValue(this.record) - this.setState({ - loading: false, - }) + this.setState({ loading: false }) + this.call() } /** diff --git a/web-react/public/seed/form/index.jsx b/web-react/public/seed/form/index.jsx index c2d80e4..2eed1b7 100644 --- a/web-react/public/seed/form/index.jsx +++ b/web-react/public/seed/form/index.jsx @@ -15,6 +15,7 @@ export default class index extends Component { state = { loading: true, record: null, + saveDisabled: true, saving: false, } @@ -44,6 +45,13 @@ export default class index extends Component { */ componentDidMount() {} + call(child, index) { + this.children[index] = child + if (this.children.filter(p => p).length === tabs.filter(p => p.show).length) { + this.setState({ saveDisabled: false }) + } + } + /** * 提交 * [异步,必要] @@ -86,7 +94,7 @@ export default class index extends Component { render() { const { id } = this.props - const { loading, record, saving } = this.state + const { loading, record, saveDisabled, saving } = this.state return (
@@ -98,17 +106,17 @@ export default class index extends Component { {parts.map((item, i) => (
- {item.title &&
{parts.title}
} + {item.title &&
{item.title}
} } - wrapperClassName="h-400-min" + wrapperClassName={loading && 'h-400-min'} > {!loading && ( this.children.push(r)} + onRef={child => this.call(child, i)} /> )} @@ -143,6 +151,7 @@ export default class index extends Component { + + +
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+ + + + ) + } +} diff --git a/web-react/src/components/photo-swipe/index.jsx b/web-react/src/components/photo-swipe/index.jsx deleted file mode 100644 index c3c90aa..0000000 --- a/web-react/src/components/photo-swipe/index.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import React, { Component } from 'react' - -export default class PhotoSwipe extends Component { - render() { - return ( -
- -
- ) - } -} diff --git a/web-react/src/pages/business/house/code/form/index.jsx b/web-react/src/pages/business/house/code/form/index.jsx index e8f16be..ddd7aa4 100644 --- a/web-react/src/pages/business/house/code/form/index.jsx +++ b/web-react/src/pages/business/house/code/form/index.jsx @@ -107,7 +107,7 @@ export default class index extends Component { } - wrapperClassName="h-400-min" + wrapperClassName={loading && 'h-400-min'} > {!loading && ( (item.uid.startsWith('rc-upload') ? item.response : item.uid)) + .join(',') + //#endregion + return postData + } + } + + //#region 自定义方法 + /** + * 表单change事件处理,包括了所有字段的change + * [异步,非必要] + * @param {*} changedValues + * @param {*} allValues + */ + async onValuesChange(changedValues, allValues) {} + + async onFileUpload({ file, onProgress, onSuccess, onError }) { + onProgress({ + percent: 0, + }) + const fd = new FormData() + fd.append('file', file) + try { + const { data: fileId } = await api.sysFileInfoUpload(fd) + onSuccess(fileId) + } catch { + onError() + } + } + + async onFilePreview(file, key) { + const fileList = this.form.current + .getFieldValue(['houseInfo', key]) + .filter(p => p.status === 'done') + const items = [] + for (const _file of fileList) { + const img = new Image() + const src = _file.url || _file.thumbUrl + img.src = src + items.push({ + src, + w: img.naturalWidth, + h: img.naturalHeight, + }) + } + this.photoPreview.current.initPhotoSwipe(items, { + index: fileList.indexOf(file), + }) + } + + async onFileDownload(file) { + const { data, headers } = await api.sysFileInfoDownload({ id: file.response }) + const url = window.URL.createObjectURL(data) + const fileName = GetFileName(headers['content-disposition']) + const a = document.createElement('a') + a.href = url + a.download = fileName + a.click() + window.URL.revokeObjectURL(url) + a.remove() + } + //#endregion + + render() { + const { loading } = this.state + + return ( + }> +
+ this.onValuesChange(changedValues, allValues) + } + > + { + if (Array.isArray(e)) { + return e + } + return e && e.fileList + }} + > + this.onFileUpload(e)} + showUploadList={{ + showRemoveIcon: true, + showDownloadIcon: true, + }} + onPreview={file => this.onFilePreview(file, 'facadePhoto')} + onDownload={file => this.onFileDownload(file)} + > +
+ +
外立面照片
+
+
+
+
+ + +
+ ) + } +} diff --git a/web-react/src/pages/business/house/info/form/base/attachments.jsx b/web-react/src/pages/business/house/info/form/base/attachments.jsx new file mode 100644 index 0000000..2db909c --- /dev/null +++ b/web-react/src/pages/business/house/info/form/base/attachments.jsx @@ -0,0 +1,238 @@ +import React, { Component } from 'react' +import { Button, Form, Spin, Upload } from 'antd' +import { AntIcon } from 'components' +import { cloneDeep, isEqual } from 'lodash' +import { BlobToBase64, GetFileName, PreviewFile } from 'util/file' +import { api } from 'common/api' + +const initialValues = {} + +const layout = { + labelCol: { flex: '150px' }, + wrapperCol: { flex: '1' }, +} + +const uploads = [ + { + key: 'anEntryDocument', + label: '立项文件', + }, + { + key: 'planningPermission', + label: '规划许可', + }, + { + key: 'completionRecord', + label: '竣工验收备案', + }, + { + key: 'monitorDocument', + label: '监理文件', + }, + { + key: 'identificationReport', + label: '鉴定报告', + }, + { + key: 'otherDocument', + label: '其他附件', + }, +] + +export default class attachments extends Component { + state = { + loading: true, + codes: {}, + options: {}, + } + + // 表单实例 + form = React.createRef() + + // 初始化数据 + record = {} + + /** + * 阻止外部组件引发的渲染,提升性能 + * 可自行添加渲染条件 + * [必要] + * @param {*} props + * @param {*} state + * @returns + */ + shouldComponentUpdate(props, state) { + return !isEqual(this.state, state) + } + + /** + * 绑定数据 + */ + componentDidMount() { + this.fillData({ + record: this.props.record, + }) + } + + /** + * DOM加载完成钩子,在此将自身传递给父级 + */ + call() { + if (this.props.onRef) { + this.props.onRef(this) + } + } + + /** + * 填充数据 + * 可以在设置this.record之后对其作出数据结构调整 + * [异步,必要] + * @param {*} params + */ + async fillData(params) { + this.record = cloneDeep(params.record) + //#region 从后端转换成前段所需格式 + if (this.record) { + const { houseInfo } = this.record + const keys = uploads.map(p => p.key) + for (const key of keys) { + const fileValue = [] + const fileList = + !houseInfo[key] || !houseInfo[key].length ? [] : houseInfo[key].split(',') + for (const fileId of fileList) { + try { + const file = await PreviewFile(fileId) + const base64 = await BlobToBase64(file) + fileValue.push({ + uid: fileId, + response: fileId, + name: file.name, + url: base64, + status: 'done', + }) + } catch { + const { data: file } = await api.sysFileInfoDetail({ id: fileId }) + fileValue.push({ + uid: fileId, + response: '文件已丢失', + name: file.fileOriginName, + status: 'error', + }) + } + } + + houseInfo[key] = fileValue + } + } + //#endregion + this.form.current.setFieldsValue(this.record) + + this.setState({ loading: false }) + this.call() + } + + /** + * 获取数据 + * 可以对postData进行数据结构调整 + * [异步,必要] + * @returns + */ + async getData() { + const form = this.form.current + + const valid = await form.validateFields() + if (valid) { + const postData = form.getFieldsValue() + //#region 从前段转换后端所需格式 + const { houseInfo } = postData + for (const key in houseInfo) { + houseInfo[key] = houseInfo[key] + .map(item => (item.uid.startsWith('rc-upload') ? item.response : item.uid)) + .join(',') + } + //#endregion + return postData + } + } + + //#region 自定义方法 + /** + * 表单change事件处理,包括了所有字段的change + * [异步,非必要] + * @param {*} changedValues + * @param {*} allValues + */ + async onValuesChange(changedValues, allValues) {} + + async onFileUpload({ file, onProgress, onSuccess, onError }) { + onProgress({ + percent: 0, + }) + const fd = new FormData() + fd.append('file', file) + try { + const { data: fileId } = await api.sysFileInfoUpload(fd) + onSuccess(fileId) + } catch { + onError() + } + } + + async onFileDownload(file) { + const { data, headers } = await api.sysFileInfoDownload({ id: file.response }) + const url = window.URL.createObjectURL(data) + const fileName = GetFileName(headers['content-disposition']) + const a = document.createElement('a') + a.href = url + a.download = fileName + a.click() + window.URL.revokeObjectURL(url) + a.remove() + } + //#endregion + + render() { + const { loading } = this.state + + return ( + }> +
+ this.onValuesChange(changedValues, allValues) + } + > + {uploads.map((item, i) => ( + { + if (Array.isArray(e)) { + return e + } + return e && e.fileList + }} + > + this.onFileUpload(e)} + showUploadList={{ + showRemoveIcon: true, + showDownloadIcon: true, + }} + onPreview={() => false} + onDownload={file => this.onFileDownload(file)} + > + + + + ))} +
+
+ ) + } +} diff --git a/web-react/src/pages/business/house/info/form/base/building.jsx b/web-react/src/pages/business/house/info/form/base/building.jsx index 39823bb..cb66545 100644 --- a/web-react/src/pages/business/house/info/form/base/building.jsx +++ b/web-react/src/pages/business/house/info/form/base/building.jsx @@ -1,10 +1,22 @@ import React, { Component } from 'react' -import { Row, Col, Form, Input, InputNumber, Radio, Checkbox, Switch, DatePicker, Spin } from 'antd' +import { + Button, + Row, + Col, + Form, + Input, + InputNumber, + Radio, + Checkbox, + Switch, + DatePicker, + Spin, +} from 'antd' import { cloneDeep, isEqual } from 'lodash' -import { api } from 'common/api' import { AntIcon } from 'components' import getDictData from 'util/dic' import moment from 'moment' +import { CITY } from 'util/global' const layout = { labelCol: { flex: '150px' }, @@ -25,6 +37,8 @@ export default class building extends Component { dicHouseBuildingCurtainWall: [], dicHouseElevator: [], }, + + showMap: false, } form = React.createRef() @@ -34,14 +48,17 @@ export default class building extends Component { } componentDidMount() { - if (this.props.onRef) { - this.props.onRef(this) - } this.fillData({ record: this.props.record, }) } + call() { + if (this.props.onRef) { + this.props.onRef(this) + } + } + /** * 填充数据 * 可以在设置this.record之后对其作出数据结构调整 @@ -73,9 +90,9 @@ export default class building extends Component { }) //#endregion this.form.current.setFieldsValue(this.record) - this.setState({ - loading: false, - }) + + this.setState({ loading: false }) + this.call() } /** @@ -101,11 +118,149 @@ export default class building extends Component { } //#region 自定义方法 + onShowMap() { + this.setState({ showMap: true }, async () => { + await this.initMap() + const { lng, lat } = this.record.houseCode + const position = [lng, lat] + this.setMarker(position) + this.map.setCenter(position) + }) + } + + initMap() { + // eslint-disable-next-line no-undef + const amap = AMap + + return new Promise(resolve => { + const city = CITY + + const district = new amap.DistrictSearch({ + subdistrict: 0, + extensions: 'all', + level: 'city', + }) + + district.search(city, (status, result) => { + const bounds = result.districtList[0].boundaries, + mask = [] + for (let i = 0; i < bounds.length; i += 1) { + mask.push([bounds[i]]) + } + + const geocoder = new amap.Geocoder({ city }) + geocoder.getLocation(city, (status, result) => { + if (status !== 'complete' || !(result.geocodes && result.geocodes.length)) + return + + this.citycode = result.geocodes[0].addressComponent.citycode + + this.map = new amap.Map(this.refs.map, { + mask, + zoom: 12, + center: result.geocodes[0].location, + }) + + this.map.on('click', e => { + this.setMarker(e.lnglat, geocoder) + }) + + this.map.on('complete', () => { + this.map.setFitView() + this.map.setZoom(12) + + for (const path of bounds) { + new amap.Polyline({ + path, + strokeColor: '#ccc', + strokeWeight: 4, + map: this.map, + }) + } + + resolve() + }) + + const auto = new amap.AutoComplete({ + input: this.refs['map-search'].input, + city, + citylimit: true, + }) + + const placeSearch = new amap.PlaceSearch({ + city, + citylimit: true, + pageSize: 1, + }) + + auto.on('select', ({ poi: { name: keywords, adcode } }) => { + placeSearch.search(keywords, async (status, result) => { + const { + poiList: { pois }, + } = result + for (const poi of pois) { + await this.setMarker(poi.location, geocoder) + this.map.setCenter(poi.location) + } + }) + }) + }) + }) + }) + } + + setMarker(position, geocoder) { + const set = position => { + if (this.marker) { + this.marker.setPosition(position) + } else { + this.marker = new amap.Marker({ + map: this.map, + icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png', + position, + offset: new amap.Pixel(-13, -30), + }) + } + } + + // eslint-disable-next-line no-undef + const amap = AMap + + return new Promise((resolve, reject) => { + if (geocoder) { + geocoder.getAddress(position, (status, result) => { + if (status === 'complete' && result.regeocode) { + if (result.regeocode.addressComponent.citycode !== this.citycode) { + // 如果选到了别的城市,则中断 + return + } + this.setPosition(result.regeocode.formattedAddress, position) + + set(position) + resolve(position) + } else { + console.error('根据经纬度查询地址失败') + + reject() + } + }) + } else { + set(position) + resolve(position) + } + }) + } + + setPosition(address, { lng, lat }) { + this.form.current.setFieldsValue({ houseCode: { address, lng, lat } }) + } //#endregion render() { + const { loading, codes, showMap } = this.state + return ( - }> + }>
@@ -133,7 +288,7 @@ export default class building extends Component { rules={[{ required: true, message: '请选择土地性质' }]} > - {this.state.codes.dicLandAttribute.map(item => { + {codes.dicLandAttribute.map(item => { return ( {item.value} @@ -181,17 +336,28 @@ export default class building extends Component { -
-
- + {showMap ? ( +
+
+ +
+
-
-
+ ) : ( + + )} @@ -201,7 +367,7 @@ export default class building extends Component { rules={[{ required: true, message: '请选择结构类型' }]} > - {this.state.codes.dicHouseStructureType.map(item => { + {codes.dicHouseStructureType.map(item => { return ( {item.value} @@ -218,7 +384,7 @@ export default class building extends Component { rules={[{ required: true, message: '请选择抗震等级' }]} > - {this.state.codes.dicHouseAseismicGrade.map(item => { + {codes.dicHouseAseismicGrade.map(item => { return ( {item.value} @@ -235,7 +401,7 @@ export default class building extends Component { rules={[{ required: true, message: '请选择基础情况' }]} > - {this.state.codes.dicHouseBaseInfo.map(item => { + {codes.dicHouseBaseInfo.map(item => { return ( {item.value} @@ -251,7 +417,7 @@ export default class building extends Component { name={['houseInfo', 'insulationMaterial']} > - {this.state.codes.dicHouseInsulationMaterial.map(item => { + {codes.dicHouseInsulationMaterial.map(item => { return ( - {this.state.codes.dicHouseWallMaterial.map(item => { + {codes.dicHouseWallMaterial.map(item => { return ( - {this.state.codes.dicHouseFireproofGrade.map(item => { + {codes.dicHouseFireproofGrade.map(item => { return ( {item.value} @@ -316,7 +482,7 @@ export default class building extends Component { rules={[{ required: true, message: '请选择建筑幕墙' }]} > - {this.state.codes.dicHouseBuildingCurtainWall.map(item => { + {codes.dicHouseBuildingCurtainWall.map(item => { return ( {item.value} @@ -327,17 +493,29 @@ export default class building extends Component { - + - + - + @@ -348,7 +526,7 @@ export default class building extends Component { rules={[{ required: true, message: '请选择电梯' }]} > - {this.state.codes.dicHouseElevator.map(item => { + {codes.dicHouseElevator.map(item => { return ( {item.value} diff --git a/web-react/src/pages/business/house/info/form/base/index.jsx b/web-react/src/pages/business/house/info/form/base/index.jsx index 962664c..f83000d 100644 --- a/web-react/src/pages/business/house/info/form/base/index.jsx +++ b/web-react/src/pages/business/house/info/form/base/index.jsx @@ -1,7 +1,7 @@ import React, { Component } from 'react' import ReactDOM from 'react-dom' import { Row, Col, Card, Anchor, Spin } from 'antd' -import { defaultsDeep } from 'lodash' +import { defaultsDeep, merge } from 'lodash' import { AntIcon, ComponentDynamic, Container } from 'components' const parts = [ @@ -9,6 +9,14 @@ const parts = [ title: '建筑物基本信息', component: () => import('./building'), }, + { + title: '相关附件资料', + component: () => import('./attachments'), + }, + { + title: '建筑概貌', + component: () => import('./aspect'), + }, ] export default class index extends Component { @@ -22,9 +30,13 @@ export default class index extends Component { return this.props.loading !== props.loading } - componentDidMount() { - if (this.props.onRef) { - this.props.onRef(this) + // 通知上层组件已加载完毕 + call(child, index) { + this.children[index] = child + if (this.children.filter(p => p).length === parts.length) { + if (this.props.onRef) { + this.props.onRef(this) + } } } @@ -39,10 +51,7 @@ export default class index extends Component { async getData() { for (const child of this.children) { const data = await child.getData() - this.formData = { - ...this.formData, - ...data, - } + merge(this.formData, data) } return this.formData @@ -64,13 +73,13 @@ export default class index extends Component { } - wrapperClassName="h-400-min" + wrapperClassName={loading && 'h-400-min'} > {!loading && ( this.children.push(c)} + onRef={child => this.call(child, i)} /> )} diff --git a/web-react/src/pages/business/house/info/form/index.jsx b/web-react/src/pages/business/house/info/form/index.jsx index f3c5602..b57d8c3 100644 --- a/web-react/src/pages/business/house/info/form/index.jsx +++ b/web-react/src/pages/business/house/info/form/index.jsx @@ -1,6 +1,6 @@ import React, { Component } from 'react' import { Button, Descriptions, message as Message, Spin, Tabs } from 'antd' -import { isEqual, truncate } from 'lodash' +import { merge, isEqual } from 'lodash' import { AntIcon, ComponentDynamic, Container } from 'components' import { api } from 'common/api' @@ -55,6 +55,7 @@ export default class index extends Component { loading: true, record: null, + saveDisabled: true, saving: false, } @@ -79,20 +80,25 @@ export default class index extends Component { } } + call(child, index) { + this.children[index] = child + if (this.children.filter(p => p).length === tabs.filter(p => p.show).length) { + this.setState({ saveDisabled: false }) + } + } + async onSubmit() { for (const child of this.children) { try { const data = await child.getData() - this.formData = { - ...this.formData, - ...data, - } + merge(this.formData, data) } catch (e) { return e } } //#region 提交数据 + console.log(this.formData) this.setState({ saving: true }) setTimeout(() => { @@ -103,7 +109,7 @@ export default class index extends Component { } render() { - const { loading, record, saving } = this.state + const { loading, record, saveDisabled, saving } = this.state return (
@@ -118,6 +124,7 @@ export default class index extends Component { 取消
)