diff --git a/src/components/AttachmentUpload/index.js b/src/components/AttachmentUpload/index.js
index db65e5d..16f6684 100644
--- a/src/components/AttachmentUpload/index.js
+++ b/src/components/AttachmentUpload/index.js
@@ -1,10 +1,10 @@
-import { Form, Image, Upload } from "antd";
+import { Form, Image, Upload, message } from "antd";
import { useState } from "react";
import { PlusOutlined } from "@ant-design/icons";
const isImage = (url) =>
/\.(png|jpe?g|gif|bmp|webp|svg)(\?.*)?$/i.test(url || "");
-export default function AttachmentUpload({ name, label, disabled = false, maxCount, accept }) {
+export default function AttachmentUpload({ name, label, disabled = false, maxCount, accept, extra }) {
const [previewImage, setPreviewImage] = useState("");
return (
@@ -12,25 +12,31 @@ export default function AttachmentUpload({ name, label, disabled = false, maxCou
{
-
if (Array.isArray(value)) {
return { fileList: value };
}
- return {
- fileList: value
- ? value.split(",").map((item) => ({
- url: item,
- uid: item,
- status: "done",
- name: "附件",
- }))
- : [],
- };
+ if (typeof value === "string" && value) {
+ try {
+ const parsed = JSON.parse(value);
+ if (Array.isArray(parsed)) {
+ return { fileList: parsed };
+ }
+ } catch {}
+ return {
+ fileList: value.split(",").map((item) => ({
+ url: item,
+ uid: item,
+ status: "done",
+ name: "附件",
+ })),
+ };
+ }
+ return { fileList: [] };
}}
getValueFromEvent={({ fileList }) => {
-
return (
fileList?.map((file) => ({
url: file.response?.data?.url || file.url,
@@ -43,11 +49,32 @@ export default function AttachmentUpload({ name, label, disabled = false, maxCou
}}
>
{
+ if (!accept) return true;
+ const rules = accept.split(",").map((e) => e.trim().toLowerCase());
+ const ext = "." + file.name.split(".").pop().toLowerCase();
+ const matchExt = rules.includes(ext);
+ const matchMime = rules.some((r) => {
+ if (r.endsWith("/*")) {
+ const prefix = r.slice(0, -1);
+ return file.type && file.type.toLowerCase().startsWith(prefix);
+ }
+ return false;
+ });
+ if (!matchExt && !matchMime) {
+ message.error(`仅支持 ${accept} 格式文件`);
+ return Upload.LIST_IGNORE;
+ }
+ return true;
+ }}
onPreview={(file) => {
if (isImage(file.url || file.thumbUrl)) {
setPreviewImage(file.url || file.thumbUrl);
diff --git a/src/components/BaiduMapPicker/index.js b/src/components/BaiduMapPicker/index.js
new file mode 100644
index 0000000..cc01e97
--- /dev/null
+++ b/src/components/BaiduMapPicker/index.js
@@ -0,0 +1,136 @@
+import React, { useEffect, useRef, useState } from 'react';
+import { Modal, Input, message } from 'antd';
+import './index.less';
+
+const BaiduMapPicker = ({ visible, onCancel, onConfirm }) => {
+ const mapRef = useRef(null);
+ const mapInstanceRef = useRef(null);
+ const markerRef = useRef(null);
+ const [loaded, setLoaded] = useState(false);
+ const [selectedPoint, setSelectedPoint] = useState(null);
+
+ // 动态加载百度地图脚本
+ useEffect(() => {
+ if (!visible) return;
+ if (window.BMap) {
+ // 如果已有 BMap,等 DOM 渲染后再初始化
+ setTimeout(() => setLoaded(true), 100);
+ return;
+ }
+
+ const scriptId = 'baiduMapScript';
+ if (document.getElementById(scriptId)) return;
+
+ window.__onBMapLoaded = () => {
+ setLoaded(true);
+ };
+
+ const script = document.createElement('script');
+ script.id = scriptId;
+ script.src = `https://api.map.baidu.com/api?v=3.0&ak=6lkWDSnHTCcvUenZhovQPER9nkhFfT9A&callback=__onBMapLoaded`;
+ script.async = true;
+ document.body.appendChild(script);
+ }, [visible]);
+
+ // 初始化地图
+ useEffect(() => {
+ if (!loaded || !visible || !mapRef.current) return;
+ // 避免重复初始化
+ if (mapInstanceRef.current) return;
+
+ const map = new window.BMap.Map(mapRef.current);
+ // 默认以重庆市中心为中心
+ map.centerAndZoom(new window.BMap.Point(106.55, 29.57), 12);
+ map.enableScrollWheelZoom(true);
+ mapInstanceRef.current = map;
+
+ // 点击地图获取坐标
+ map.addEventListener('click', (e) => {
+ const point = e.point;
+ setSelectedPoint(point);
+ if (markerRef.current) {
+ map.removeOverlay(markerRef.current);
+ }
+ const marker = new window.BMap.Marker(point);
+ map.addOverlay(marker);
+ markerRef.current = marker;
+ });
+
+ // 搜索自动完成
+ const ac = new window.BMap.Autocomplete({
+ input: 'baiduSearchInput',
+ location: map,
+ });
+ ac.addEventListener('onconfirm', (e) => {
+ const value = e.item.value;
+ const local = new window.BMap.LocalSearch(map, {
+ onSearchComplete: (results) => {
+ if (results.getCurrentNumPois() > 0) {
+ const poi = results.getPoi(0);
+ const point = poi.point;
+ setSelectedPoint(point);
+ map.centerAndZoom(point, 15);
+ if (markerRef.current) {
+ map.removeOverlay(markerRef.current);
+ }
+ const marker = new window.BMap.Marker(point);
+ map.addOverlay(marker);
+ markerRef.current = marker;
+ }
+ },
+ });
+ local.search(
+ [value.province, value.city, value.district, value.street, value.business]
+ .filter(Boolean)
+ .join(''),
+ );
+ });
+
+ return () => {
+ mapInstanceRef.current = null;
+ };
+ }, [loaded, visible]);
+
+ // 弹窗关闭时重置
+ useEffect(() => {
+ if (!visible) {
+ setLoaded(false);
+ setSelectedPoint(null);
+ markerRef.current = null;
+ mapInstanceRef.current = null;
+ }
+ }, [visible]);
+
+ const handleConfirm = () => {
+ if (!selectedPoint) {
+ message.warning('请在地图上选择位置');
+ return;
+ }
+ onConfirm({
+ lng: selectedPoint.lng,
+ lat: selectedPoint.lat,
+ });
+ };
+
+ return (
+
+
+
+
+ );
+};
+
+export default BaiduMapPicker;
diff --git a/src/components/BaiduMapPicker/index.less b/src/components/BaiduMapPicker/index.less
new file mode 100644
index 0000000..cc8763f
--- /dev/null
+++ b/src/components/BaiduMapPicker/index.less
@@ -0,0 +1,33 @@
+.baidu-map-search {
+ width: 100%;
+ height: 36px;
+ padding: 4px 11px;
+ border: 1px solid #d9d9d9;
+ border-radius: 6px;
+ outline: none;
+ box-sizing: border-box;
+ margin-bottom: 12px;
+ font-size: 14px;
+ transition: border-color 0.2s;
+
+ &:focus {
+ border-color: #4096ff;
+ box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
+ }
+
+ &::placeholder {
+ color: #bfbfbf;
+ }
+}
+
+.baidu-map-container {
+ width: 100%;
+ height: 480px;
+ border-radius: 6px;
+ overflow: hidden;
+}
+
+/* 百度地图 Autocomplete 联想面板默认 z-index 过低,被 Modal 遮挡 */
+.tangram-suggestion-main {
+ z-index: 10000 !important;
+}
diff --git a/src/pages/Container/RegisterMore/index.js b/src/pages/Container/RegisterMore/index.js
index afdbde9..588cd00 100644
--- a/src/pages/Container/RegisterMore/index.js
+++ b/src/pages/Container/RegisterMore/index.js
@@ -15,7 +15,6 @@ import {
InputNumber,
DatePicker,
Space,
- Modal,
} from "antd";
import { NS_REGISTER } from "~/enumerate/namespace";
import AttachmentUpload from "~/components/AttachmentUpload";
@@ -40,6 +39,7 @@ import {
REGISTERED_ORG_FILING_TYPE_SEARCH_OPTIONS,
REGISTERED_ORG_FILING_RECORD_STATUS_OPTIONS,
} from "~/enumerate/enterpriseOptions";
+import BaiduMapPicker from "~/components/BaiduMapPicker";
import "./index.less";
const { router } = tools;
@@ -47,6 +47,7 @@ const { router } = tools;
const RegisterMore = (props) => {
const { orgInfoSave, register, syncUserToGBS } = props;
const [current, setCurrent] = useState(0);
+ const [mapPickerVisible, setMapPickerVisible] = useState(false);
const [form] = Form.useForm();
const { registerLoading, syncUserToGBSLoading } = register;
const hasRegisterContext = Boolean(
@@ -109,6 +110,11 @@ const RegisterMore = (props) => {
}
};
+ const handleMapConfirm = ({ lng, lat }) => {
+ form.setFieldsValue({ longitude: lng, latitude: lat });
+ setMapPickerVisible(false);
+ };
+
const handleLogin = () => {
message.success("即将跳转到登录页面,请稍候...");
setTimeout(() => {
@@ -173,11 +179,11 @@ const RegisterMore = (props) => {
@@ -235,47 +249,64 @@ const RegisterMore = (props) => {
label="所属镇、街道"
rules={[{ required: true, message: "请输入所属镇街道" }]}
>
-
+
-
+
-
-
+
+
+
+
+
+
+
+
@@ -319,7 +350,11 @@ const RegisterMore = (props) => {
label="注册地址"
rules={[{ required: true, message: "请输入注册地址" }]}
>
-
+
@@ -328,12 +363,20 @@ const RegisterMore = (props) => {
label="经营地址"
rules={[{ required: true, message: "请输入经营地址" }]}
>
-
+
-
+
@@ -341,7 +384,11 @@ const RegisterMore = (props) => {
name="economyIndustryCode"
label="国民经济行业分类(GB/T4754-2017)"
>
-
+
@@ -350,7 +397,11 @@ const RegisterMore = (props) => {
label="法定代表人"
rules={[{ required: true, message: "请输入法定代表人" }]}
>
-
+
@@ -359,7 +410,11 @@ const RegisterMore = (props) => {
label="法定代表人联系电话"
rules={[phoneRule("法定代表人联系电话", false)]}
>
-
+
@@ -368,7 +423,11 @@ const RegisterMore = (props) => {
label="主要负责人"
rules={[{ required: true, message: "请输入主要负责人" }]}
>
-
+
@@ -377,7 +436,11 @@ const RegisterMore = (props) => {
label="主要负责人联系电话"
rules={[phoneRule("主要负责人联系电话", true)]}
>
-
+
@@ -385,7 +448,11 @@ const RegisterMore = (props) => {
name="safetyDeptManager"
label="安全管理部门负责人"
>
-
+
@@ -401,7 +468,7 @@ const RegisterMore = (props) => {
/>
-
+
{
-
+
@@ -434,7 +505,11 @@ const RegisterMore = (props) => {
label="信息公开网址"
rules={[urlRule("信息公开网址", false)]}
>
-
+
@@ -446,6 +521,7 @@ const RegisterMore = (props) => {
@@ -460,6 +536,7 @@ const RegisterMore = (props) => {
@@ -476,6 +553,7 @@ const RegisterMore = (props) => {
@@ -492,6 +570,7 @@ const RegisterMore = (props) => {
@@ -504,7 +583,10 @@ const RegisterMore = (props) => {
placeholder="请选择企业状态"
allowClear
onChange={(value, option) => {
- form.setFieldValue("enterpriseStatusName", option?.label || "");
+ form.setFieldValue(
+ "enterpriseStatusName",
+ option?.label || "",
+ );
}}
/>
@@ -517,7 +599,10 @@ const RegisterMore = (props) => {
placeholder="请选择企业规模"
allowClear
onChange={(value, option) => {
- form.setFieldValue("enterpriseScaleName", option?.label || "");
+ form.setFieldValue(
+ "enterpriseScaleName",
+ option?.label || "",
+ );
}}
/>
@@ -553,10 +638,21 @@ const RegisterMore = (props) => {
-
+
+ setMapPickerVisible(false)}
+ onConfirm={handleMapConfirm}
+ />
{/*