import React from "react";
|
import { Cascader, Form, Input, InputNumber, Modal, Select, Button, message } from "antd";
|
import '../style/projects.less'
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
import {
|
getUsageTypeOptionsNew,
|
inputLongStyle,
|
projectTypeMapNew, projectTypeRelationMapNew,
|
projectUsageTypeMapNew,
|
provinceArr
|
} from "../../common/constants";
|
import BaseForm from "../../common/edit-form-base";
|
import { createProjectNumber, toOptionsData } from "../../common/common_func";
|
import { getClientOptions } from "../../../api/business";
|
import { getCityList, getDistrictList } from "../../common/address_func";
|
import { flatPath, formatNodeForCascader, getDepartmentRoot } from "../../../api/hierarchy";
|
|
window._AMapSecurityConfig = {
|
securityJsCode: 'ba4138d0c0efb13d1d5fd10df08bb0d1',
|
}
|
|
const { Option } = Select;
|
|
class EditProjectForm extends BaseForm {
|
|
clientOptions = []
|
departmentList = []
|
|
initEditableData() {
|
return {
|
name: '',
|
type: projectTypeMapNew.firstKey,
|
usageType: null,
|
client: null,
|
departmentPath: null,
|
constructionLicense: '',
|
itemCode: createProjectNumber(),
|
branchCompany: '',
|
constructionCompanyInfo: null,
|
supervisorCompanyInfo: null,
|
developmentCompanyInfo: null,
|
addressInfo: null,
|
projectCost: '',
|
scale: '',
|
}
|
}
|
|
initView() {
|
this.getClientOptions()
|
this.getDepartmentRootFunc()
|
|
// 在state中添加cityList和districtList
|
this.setState({
|
cityList: [],
|
districtList: [],
|
keyword: ''
|
})
|
}
|
|
componentWillUnmount() {
|
if (this.map) {
|
this.map.destroy();
|
this.map = null;
|
}
|
}
|
|
getDepartmentRootFunc() {
|
getDepartmentRoot().then((data) => {
|
if (data.data.status === 'OK')
|
this.departmentList = formatNodeForCascader(data.data.data)
|
})
|
}
|
|
getClientOptions = async () => {
|
const result = await getClientOptions()
|
if (result.data.status === 'OK') {
|
this.clientOptions = toOptionsData(result.data.data)
|
}
|
}
|
|
handleProvinceChange = (e) => {
|
this.refreshCityList(e.key, e.label)
|
}
|
|
refreshCityList = (province, provinceLabel) => {
|
getCityList(province, (data) => {
|
this.setState({
|
cityList: data
|
}, () => {
|
if (data && data.length > 0) {
|
const firstCity = data[0];
|
this.props.form.setFieldsValue({
|
city: { key: firstCity.value, label: firstCity.label }, // Adjusted to match the expected format
|
});
|
this.setFieldValue('addressInfo', {
|
...this.state.editableData.addressInfo,
|
province: provinceLabel,
|
city: firstCity.label,
|
district: ''
|
})
|
this.refreshDistrictList(firstCity.value, firstCity.label)
|
} else {
|
// Handle the case where there are no cities (e.g., clear the selection)
|
this.props.form.setFieldsValue({
|
city: { key: '', label: '' }
|
});
|
}
|
})
|
})
|
}
|
handleCityChange = (e) => {
|
this.refreshDistrictList(e.key, e.label)
|
}
|
|
handleTypeChange = (e) => {
|
this.setFieldValue('type', e.key)
|
|
let usageTypeList = projectTypeRelationMapNew[e.key]
|
let usageType = usageTypeList && usageTypeList.length > 0 ? usageTypeList[0] : null
|
this.setFieldValue('usageType', usageType)
|
|
// 同时更新表单中的值,避免显示不同步
|
const label = usageType ? projectUsageTypeMapNew[usageType] : '';
|
this.props.form.setFieldsValue({
|
usageType: { key: usageType || '', label: label || '' }
|
});
|
}
|
|
refreshDistrictList = (city, cityLabel) => {
|
getDistrictList(city, (data) => {
|
this.setState({
|
districtList: data
|
}, () => {
|
if (data && data.length > 0) {
|
const firstDistrict = data[0];
|
this.props.form.setFieldsValue({
|
district: { key: firstDistrict.value, label: firstDistrict.label } // Adjusted to match the expected format
|
});
|
this.setFieldValue('addressInfo', {
|
...this.state.editableData.addressInfo,
|
district: firstDistrict.label
|
})
|
} else {
|
// Handle the case where there are no districts (e.g., clear the selection)
|
this.props.form.setFieldsValue({
|
district: { key: '', label: '' } // Reset or clear the selection
|
});
|
}
|
})
|
})
|
}
|
|
viewWillAppear() {
|
this.initMap();
|
}
|
|
initMap = () => {
|
AMapLoader.load({
|
key: "1c53e2a2bb2218895e9a9f672df36840",
|
plugins: ['AMap.ToolBar', 'AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.Marker'],
|
}).then((AMap) => {
|
this.AMap = AMap;
|
this.geocoder = new AMap.Geocoder({
|
extensions: "all"
|
});
|
const { addressInfo } = this.state.editableData;
|
let center = [104.065617, 30.656952];
|
if (addressInfo && addressInfo.longitude && addressInfo.latitude) {
|
center = [addressInfo.longitude, addressInfo.latitude];
|
}
|
|
if (!this.map) {
|
this.map = new AMap.Map("mapContainer", {
|
zoom: 14,
|
resizeEnable: true,
|
center: center
|
});
|
this.map.on('click', this.onMapClick);
|
} else {
|
this.map.setCenter(center);
|
}
|
|
if (addressInfo && addressInfo.longitude && addressInfo.latitude) {
|
this.addMarker(center);
|
}
|
}).catch(e => {
|
console.error(e);
|
})
|
}
|
|
onMapClick = (e) => {
|
const lng = e.lnglat.getLng();
|
const lat = e.lnglat.getLat();
|
this.addMarker([lng, lat]);
|
this.getAddress(lng, lat);
|
}
|
|
addMarker = (position) => {
|
if (this.marker) {
|
this.marker.setPosition(position);
|
} else {
|
this.marker = new this.AMap.Marker({
|
position: position,
|
map: this.map
|
});
|
}
|
this.map.setCenter(position);
|
}
|
|
updateAddressInfo = (lng, lat) => {
|
// Update form field and state
|
const { form } = this.props;
|
form.setFieldsValue({
|
lonLat: `${lng},${lat}`
|
});
|
|
// Update editableData
|
const { addressInfo } = this.state.editableData;
|
this.setFieldValue('addressInfo', {
|
...addressInfo,
|
longitude: lng,
|
latitude: lat,
|
lonLat: `${lng},${lat}`
|
});
|
}
|
|
getAddress = (lng, lat) => {
|
if (!this.geocoder) return;
|
this.geocoder.getAddress([lng, lat], (status, result) => {
|
if (status === 'complete' && result.regeocode) {
|
const addressComponent = result.regeocode.addressComponent;
|
const formattedAddress = result.regeocode.formattedAddress;
|
|
// Update basic info
|
this.updateAddressInfo(lng, lat);
|
|
// Update Detailed Address
|
const { form } = this.props;
|
form.setFieldsValue({
|
address: formattedAddress
|
});
|
this.setFieldValue('addressInfo', {
|
...this.state.editableData.addressInfo,
|
detail: formattedAddress
|
});
|
|
// Handle Province
|
const pName = addressComponent.province;
|
const pOpt = provinceArr.find(item => pName.includes(item.label) || item.label.includes(pName));
|
|
if (pOpt) {
|
form.setFieldsValue({
|
province: { key: pOpt.value, label: pOpt.label }
|
});
|
this.setFieldValue('addressInfo', {
|
...this.state.editableData.addressInfo,
|
province: pOpt.label
|
});
|
|
// Handle City
|
getCityList(pOpt.value, (cityData) => {
|
this.setState({ cityList: cityData }, () => {
|
let cName = addressComponent.city;
|
if (!cName || cName.length === 0) {
|
cName = pName; // Handle municipality
|
}
|
const cOpt = cityData.find(item => cName.includes(item.label) || item.label.includes(cName));
|
|
if (cOpt) {
|
form.setFieldsValue({
|
city: { key: cOpt.value, label: cOpt.label }
|
});
|
this.setFieldValue('addressInfo', {
|
...this.state.editableData.addressInfo,
|
city: cOpt.label
|
});
|
|
// Handle District
|
getDistrictList(cOpt.value, (districtData) => {
|
this.setState({ districtList: districtData }, () => {
|
const dName = addressComponent.district;
|
const dOpt = districtData.find(item => dName.includes(item.label) || item.label.includes(dName));
|
|
if (dOpt) {
|
form.setFieldsValue({
|
district: { key: dOpt.value, label: dOpt.label }
|
});
|
this.setFieldValue('addressInfo', {
|
...this.state.editableData.addressInfo,
|
district: dOpt.label
|
});
|
}
|
})
|
})
|
}
|
})
|
})
|
}
|
}
|
});
|
}
|
|
handleSearch = () => {
|
const { keyword } = this.state;
|
if (!keyword || !this.AMap) return;
|
|
this.AMap.plugin('AMap.PlaceSearch', () => {
|
const placeSearch = new this.AMap.PlaceSearch({
|
extensions: 'all',
|
});
|
placeSearch.search(keyword, (status, result) => {
|
if (status === 'complete' && result.poiList.pois.length > 0) {
|
const poi = result.poiList.pois[0];
|
const lng = poi.location.lng;
|
const lat = poi.location.lat;
|
this.addMarker([lng, lat]);
|
this.getAddress(lng, lat);
|
message.success(`已定位到: ${poi.name}`);
|
} else {
|
message.warning('未找到相关位置');
|
}
|
});
|
});
|
}
|
|
render() {
|
const { visible, onCancel, onOk, form, currentRowData } = this.props;
|
const { getFieldDecorator } = form;
|
const { name, type, usageType, departmentPath, client, constructionLicense, itemCode, branchCompany, constructionCompanyInfo, supervisorCompanyInfo, developmentCompanyInfo, addressInfo, projectCost, scale } = this.state.editableData;
|
return (
|
<Modal
|
title={currentRowData ? "编辑项目" : "添加项目"}
|
visible={visible}
|
onCancel={onCancel}
|
onOk={onOk}
|
width={900}
|
destroyOnClose
|
>
|
<Form
|
labelCol={{ style: { width: '100%', height: '30px' } }} //label样式
|
labelAlign="left" //label样式
|
>
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="项目名称:">
|
{getFieldDecorator("name", {
|
initialValue: name,
|
rules: [{ required: true, message: '请输入项目名称!' }],
|
onChange: this.handleFieldChange('name')
|
})(<Input />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="项目类型:">
|
{getFieldDecorator("type", {
|
initialValue: type ? { key: type, label: projectTypeMapNew[type] } : { key: '', label: '' },
|
rules: [{ required: true, message: '请选择项目类型!' }],
|
onChange: (e) => this.handleTypeChange(e)
|
})(
|
<Select
|
labelInValue
|
>
|
{projectTypeMapNew.toOptions().map((item, index) => (
|
<Option value={item.value} key={item.value}>{item.label}</Option>
|
))}
|
</Select>
|
)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="用途类型:">
|
{getFieldDecorator("usageType", {
|
initialValue: usageType ? { key: usageType, label: projectUsageTypeMapNew[usageType] } : { key: '', label: '' },
|
rules: [{ required: false, message: '请选择用途类型!' }],
|
onChange: this.handleSelectChange('usageType')
|
})(
|
<Select
|
labelInValue
|
>
|
{getUsageTypeOptionsNew(type).map((item, index) => (
|
<Option value={item.value} key={item.value}>{item.label}</Option>
|
))}
|
</Select>
|
)}
|
</Form.Item>
|
</div>
|
</div>
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="部门:">
|
{getFieldDecorator("departmentPath", {
|
initialValue: departmentPath ? flatPath(departmentPath) : [],
|
onChange: this.handleCascaderChange('departmentPath'),
|
rules: [{ required: false, message: '请选择部门!' }],
|
})(
|
<Cascader
|
options={this.departmentList ? this.departmentList : []}
|
expandTrigger="hover" />
|
)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="委托方:">
|
{getFieldDecorator("clientId", {
|
initialValue: client ? { key: client.id, label: client.name } : undefined,
|
rules: [{ required: true, message: '请选择委托方!' }],
|
onChange: this.handleEntitySelectChange('client')
|
})(
|
<Select
|
labelInValue
|
disabled={this.state.isEdit}
|
>
|
{this.clientOptions.map((item, index) => (
|
<Option value={item.value} key={item.value}>{item.label}</Option>
|
))}
|
</Select>
|
)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="项目规格:">
|
{getFieldDecorator("scale", {
|
initialValue: scale,
|
rules: [{ required: true, message: '请输入项目规格!' }],
|
onChange: this.handleFieldChange('scale')
|
})(
|
<Input placeholder="请输入项目规格" />
|
)}
|
</Form.Item>
|
</div>
|
</div>
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="施工许可证号:">
|
{getFieldDecorator("constructionLicense", {
|
initialValue: constructionLicense,
|
onChange: this.handleFieldChange('constructionLicense')
|
})(<Input placeholder="请输入施工许可证号" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="项目编码:">
|
{getFieldDecorator("itemCode", {
|
initialValue: itemCode,
|
onChange: this.handleFieldChange('itemCode')
|
})(<Input disabled={true} />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="所属分公司:">
|
{getFieldDecorator("branchCompany", {
|
initialValue: branchCompany,
|
onChange: this.handleFieldChange('branchCompany')
|
})(<Input placeholder="请输入所属分公司" />)}
|
</Form.Item>
|
</div>
|
</div>
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="施工单位:">
|
{getFieldDecorator("constructionCompanyInfo.name", {
|
initialValue: constructionCompanyInfo ? constructionCompanyInfo.name : '',
|
onChange: this.handleEntityFieldSelectChange('constructionCompanyInfo', 'name')
|
})(<Input placeholder="施工单位" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="项目经理:">
|
{getFieldDecorator("constructionCompanyInfo.leader", {
|
initialValue: constructionCompanyInfo ? constructionCompanyInfo.leader : '',
|
onChange: this.handleEntityFieldSelectChange('constructionCompanyInfo', 'leader')
|
})(<Input placeholder="项目经理" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="手机号:">
|
{getFieldDecorator("constructionCompanyInfo.phone", {
|
initialValue: constructionCompanyInfo ? constructionCompanyInfo.phone : '',
|
onChange: this.handleEntityFieldSelectChange('constructionCompanyInfo', 'phone')
|
})(<Input placeholder="手机号" />)}
|
</Form.Item>
|
</div>
|
</div>
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="监理单位:">
|
{getFieldDecorator("supervisorCompanyInfo.name", {
|
initialValue: supervisorCompanyInfo ? supervisorCompanyInfo.name : '',
|
onChange: this.handleEntityFieldSelectChange('supervisorCompanyInfo', 'name')
|
})(<Input placeholder="监理单位" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="项目经理:">
|
{getFieldDecorator("supervisorCompanyInfo.leader", {
|
initialValue: supervisorCompanyInfo ? supervisorCompanyInfo.leader : '',
|
onChange: this.handleEntityFieldSelectChange('supervisorCompanyInfo', 'leader')
|
})(<Input placeholder="项目经理" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="手机号:">
|
{getFieldDecorator("supervisorCompanyInfo.phone", {
|
initialValue: supervisorCompanyInfo ? supervisorCompanyInfo.phone : '',
|
onChange: this.handleEntityFieldSelectChange('supervisorCompanyInfo', 'phone')
|
})(<Input placeholder="手机号" />)}
|
</Form.Item>
|
</div>
|
</div>
|
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="开发单位:">
|
{getFieldDecorator("developmentCompanyInfo.name", {
|
initialValue: developmentCompanyInfo ? developmentCompanyInfo.name : '',
|
onChange: this.handleEntityFieldSelectChange('developmentCompanyInfo', 'name')
|
})(<Input placeholder="开发单位" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="项目经理:">
|
{getFieldDecorator("developmentCompanyInfo.leader", {
|
initialValue: developmentCompanyInfo ? developmentCompanyInfo.leader : '',
|
onChange: this.handleEntityFieldSelectChange('developmentCompanyInfo', 'leader')
|
})(<Input placeholder="项目经理" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="手机号:">
|
{getFieldDecorator("developmentCompanyInfo.phone", {
|
initialValue: developmentCompanyInfo ? developmentCompanyInfo.phone : '',
|
onChange: this.handleEntityFieldSelectChange('developmentCompanyInfo', 'phone')
|
})(<Input placeholder="手机号" />)}
|
</Form.Item>
|
</div>
|
</div>
|
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="省:">
|
{getFieldDecorator("province", {
|
initialValue: addressInfo && addressInfo.province ? { key: 0, label: addressInfo.province } : { key: 0, label: '' },
|
onChange: this.handleAddressFieldSelectChange('addressInfo', 'province', this.handleProvinceChange)
|
})(
|
<Select
|
labelInValue
|
>
|
{provinceArr.map((item, index) => (
|
<Option value={item.value} key={item.value}>{item.label}</Option>
|
))}
|
</Select>
|
)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="市:">
|
{getFieldDecorator("city", {
|
initialValue: addressInfo && addressInfo.city ? { key: 0, label: addressInfo.city } : { key: 0, label: '' },
|
onChange: this.handleAddressFieldSelectChange('addressInfo', 'city', this.handleCityChange)
|
})(
|
<Select
|
labelInValue
|
>
|
{this.state.cityList && this.state.cityList.map((item, index) => (
|
<Option value={item.value} key={item.value}>{item.label}</Option>
|
))}
|
</Select>
|
)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="区:">
|
{getFieldDecorator("district", {
|
initialValue: addressInfo && addressInfo.district ? { key: 0, label: addressInfo.district } : { key: 0, label: '' },
|
onChange: this.handleAddressFieldSelectChange('addressInfo', 'district')
|
})(
|
<Select
|
labelInValue
|
>
|
{this.state.districtList && this.state.districtList.map((item, index) => (
|
<Option value={item.value} key={item.value}>{item.label}</Option>
|
))}
|
</Select>
|
)}
|
</Form.Item>
|
</div>
|
</div>
|
<div className="grid grid-1-1-1">
|
<div className="p-10">
|
<Form.Item label="详细地址:">
|
{getFieldDecorator("address", {
|
initialValue: addressInfo && addressInfo.detail ? addressInfo.detail : '',
|
rules: [{ required: true, message: '请输入详细地址!' }],
|
onChange: this.handleEntityFieldSelectChange('addressInfo', 'detail')
|
})(<Input placeholder="详细地址" />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="经纬度:">
|
{getFieldDecorator("lonLat", {
|
initialValue: addressInfo && addressInfo.lonLat && addressInfo.lonLat.length ? addressInfo.lonLat : '',
|
rules: [{ required: true, message: '请选择地图位置或搜索!' }],
|
})(<Input placeholder="请选择地图位置或搜索" readOnly />)}
|
</Form.Item>
|
</div>
|
<div className="p-10">
|
<Form.Item label="工程造价:" >
|
{getFieldDecorator("projectCost", {
|
initialValue: projectCost,
|
onChange: this.handleNumberChange('projectCost')
|
})(<InputNumber style={inputLongStyle} placeholder="工程造价" />)}
|
</Form.Item>
|
</div>
|
</div>
|
<div style={{ padding: '0 10px' }}>
|
<div style={{ marginBottom: 10, display: 'flex' }}>
|
<Input
|
placeholder="请输入搜索关键字"
|
value={this.state.keyword}
|
onChange={(e) => this.setState({ keyword: e.target.value })}
|
style={{ marginRight: 10 }}
|
/>
|
<Button type="primary" onClick={this.handleSearch}>搜索</Button>
|
</div>
|
<div id="mapContainer" className="mapBox" style={{ height: '400px', width: '100%', border: '1px solid #d9d9d9' }}></div>
|
</div>
|
</Form>
|
</Modal>
|
);
|
}
|
}
|
|
export default Form.create({ name: "EditProjectForm" })(EditProjectForm);
|