Merge branch 'dev' of http://47.92.113.182:3000/cq_anquan/safety-eval-service-frontend into dev
commit
5fc1a9c8e4
|
|
@ -10,6 +10,7 @@ import {
|
|||
} from "~/enumerate/enterpriseOptions";
|
||||
import { formSelectField } from "~/utils/enterpriseForm";
|
||||
import {
|
||||
coordinatePairRule,
|
||||
creditCodeRule,
|
||||
latitudeRule,
|
||||
longitudeRule,
|
||||
|
|
@ -61,7 +62,11 @@ export function buildOrgInfoFormOptions() {
|
|||
render: FORM_ITEM_RENDER_ENUM.INPUT_NUMBER,
|
||||
useConstraints: false,
|
||||
componentProps: { ...numberFieldProps, min: -180, max: 180, precision: 6 },
|
||||
rules: [longitudeRule(false)],
|
||||
dependencies: ["latitude"],
|
||||
rules: [
|
||||
longitudeRule(false),
|
||||
coordinatePairRule("latitude", "经度", "纬度"),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "latitude",
|
||||
|
|
@ -69,7 +74,11 @@ export function buildOrgInfoFormOptions() {
|
|||
render: FORM_ITEM_RENDER_ENUM.INPUT_NUMBER,
|
||||
useConstraints: false,
|
||||
componentProps: { ...numberFieldProps, min: -90, max: 90, precision: 6 },
|
||||
rules: [latitudeRule(false)],
|
||||
dependencies: ["longitude"],
|
||||
rules: [
|
||||
latitudeRule(false),
|
||||
coordinatePairRule("longitude", "纬度", "经度"),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "registerAddress",
|
||||
|
|
|
|||
|
|
@ -27,10 +27,12 @@ import {
|
|||
import { NS_ORG_INFO } from "~/enumerate/namespace";
|
||||
import { mockUploadFileList } from "~/utils/mockUpload";
|
||||
import {
|
||||
coordinatePairRule,
|
||||
creditCodeRule,
|
||||
latitudeRule,
|
||||
longitudeRule,
|
||||
nonNegativeIntegerRule,
|
||||
normalizeUrl,
|
||||
phoneRule,
|
||||
positiveNumberRule,
|
||||
urlRule,
|
||||
|
|
@ -89,6 +91,9 @@ function OrgInfoPage(props) {
|
|||
? dayjs(formValues.productionDate).format("YYYY-MM-DD")
|
||||
: undefined,
|
||||
attachmentUrls: formValues.attachmentUrls? JSON.stringify(formValues.attachmentUrls) :null,
|
||||
infoDisclosureUrl: formValues.infoDisclosureUrl
|
||||
? normalizeUrl(formValues.infoDisclosureUrl)
|
||||
: undefined,
|
||||
authStatusCode: submitType === "draft" ? 0 : 1,
|
||||
authStatusName: submitType === "draft" ? "草稿" : "已提交",
|
||||
};
|
||||
|
|
@ -205,7 +210,11 @@ function OrgInfoPage(props) {
|
|||
<Form.Item
|
||||
name="longitude"
|
||||
label="所在地坐标经度"
|
||||
rules={[longitudeRule(false)]}
|
||||
dependencies={["latitude"]}
|
||||
rules={[
|
||||
longitudeRule(false),
|
||||
coordinatePairRule("latitude", "经度", "纬度"),
|
||||
]}
|
||||
>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
|
|
@ -220,7 +229,11 @@ function OrgInfoPage(props) {
|
|||
<Form.Item
|
||||
name="latitude"
|
||||
label="所在地坐标纬度"
|
||||
rules={[latitudeRule(false)]}
|
||||
dependencies={["longitude"]}
|
||||
rules={[
|
||||
latitudeRule(false),
|
||||
coordinatePairRule("longitude", "纬度", "经度"),
|
||||
]}
|
||||
>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
|
|
@ -276,6 +289,7 @@ function OrgInfoPage(props) {
|
|||
name="legalRepresentativePhone"
|
||||
label="法定代表人联系电话"
|
||||
rules={[phoneRule("法定代表人联系电话", false)]}
|
||||
normalize={(value) => (typeof value === "string" ? value.trim() : value)}
|
||||
>
|
||||
<Input placeholder="请输入法定代表人联系电话" allowClear />
|
||||
</Form.Item>
|
||||
|
|
@ -294,6 +308,7 @@ function OrgInfoPage(props) {
|
|||
name="principalPhone"
|
||||
label="主要负责人联系电话"
|
||||
rules={[phoneRule("主要负责人联系电话", true)]}
|
||||
normalize={(value) => (typeof value === "string" ? value.trim() : value)}
|
||||
>
|
||||
<Input placeholder="请输入主要负责人联系电话" allowClear />
|
||||
</Form.Item>
|
||||
|
|
@ -308,6 +323,7 @@ function OrgInfoPage(props) {
|
|||
name="safetyDeptManagerPhone"
|
||||
label="安全管理部门负责人联系电话"
|
||||
rules={[phoneRule("安全管理部门负责人联系电话", false)]}
|
||||
normalize={(value) => (typeof value === "string" ? value.trim() : value)}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入安全管理部门负责人联系电话"
|
||||
|
|
@ -325,6 +341,7 @@ function OrgInfoPage(props) {
|
|||
name="safetyDeputyPhone"
|
||||
label="主管安全副总联系电话"
|
||||
rules={[phoneRule("主管安全副总联系电话", false)]}
|
||||
normalize={(value) => (typeof value === "string" ? value.trim() : value)}
|
||||
>
|
||||
<Input placeholder="请输入主管安全副总联系电话" allowClear />
|
||||
</Form.Item>
|
||||
|
|
@ -347,6 +364,7 @@ function OrgInfoPage(props) {
|
|||
name="infoDisclosureUrl"
|
||||
label="信息公开网址"
|
||||
rules={[urlRule("信息公开网址", false)]}
|
||||
normalize={(value) => (typeof value === "string" ? value.trim() : value)}
|
||||
>
|
||||
<Input placeholder="请输入信息公开网址" allowClear />
|
||||
</Form.Item>
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ export const ID_CARD_PATTERN = /^\d{17}[\dX]$/i;
|
|||
/** 手机号 */
|
||||
export const MOBILE_PHONE_PATTERN = /^1[3-9]\d{9}$/;
|
||||
|
||||
/** 固话或手机 */
|
||||
export const PHONE_PATTERN = /^(\d{3,4}-?\d{7,8}|1[3-9]\d{9})$/;
|
||||
/** 固话或手机(去格式符后:手机 11 位 / 固话 10~12 位) */
|
||||
export const PHONE_PATTERN = /^(1[3-9]\d{9}|\d{10,12})$/;
|
||||
|
||||
/** 经度 */
|
||||
export const LONGITUDE_PATTERN = /^-?((1[0-7]\d)|(\d{1,2}))(\.\d+)?$|^180(\.0+)?$/;
|
||||
|
|
@ -16,21 +16,48 @@ export const LONGITUDE_PATTERN = /^-?((1[0-7]\d)|(\d{1,2}))(\.\d+)?$|^180(\.0+)?
|
|||
/** 纬度 */
|
||||
export const LATITUDE_PATTERN = /^-?([1-8]?\d(\.\d+)?|90(\.0+)?)$/;
|
||||
|
||||
/** URL */
|
||||
export const URL_PATTERN = /^(https?:\/\/)[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=.]*$/;
|
||||
/** URL(需含协议或合法域名) */
|
||||
export const URL_PATTERN = /^(https?:\/\/)([\w-]+\.)+[\w-]+([\w\-._~:/?#[\]@!$&'()*+,;=.]*)?$/i;
|
||||
|
||||
const FORMAT_VALIDATE_TRIGGER = ["onBlur", "onChange"];
|
||||
|
||||
function isEmptyValue(value) {
|
||||
return value === undefined || value === null || value === "";
|
||||
}
|
||||
|
||||
/** 电话去空格、括号、横线,并剥离 +86 前缀 */
|
||||
export function normalizePhone(value) {
|
||||
return String(value).replace(/[\s()-]/g, "").replace(/^(\+?86)/, "");
|
||||
}
|
||||
|
||||
/** URL 补全协议后校验 */
|
||||
export function normalizeUrl(value) {
|
||||
const trimmed = String(value).trim();
|
||||
if (!trimmed) {
|
||||
return "";
|
||||
}
|
||||
return /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
|
||||
}
|
||||
|
||||
function hasTooManyDecimals(value, maxDecimals = 6) {
|
||||
const str = String(value);
|
||||
const dotIndex = str.indexOf(".");
|
||||
if (dotIndex === -1) {
|
||||
return false;
|
||||
}
|
||||
return str.slice(dotIndex + 1).length > maxDecimals;
|
||||
}
|
||||
|
||||
export function creditCodeRule(required = true) {
|
||||
return {
|
||||
required,
|
||||
message: required ? "请输入统一社会信用代码" : undefined,
|
||||
pattern: CREDIT_CODE_PATTERN,
|
||||
...(required ? {} : { validateTrigger: "onBlur" }),
|
||||
validateTrigger: FORMAT_VALIDATE_TRIGGER,
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
return required ? Promise.reject(new Error("请输入统一社会信用代码")) : Promise.resolve();
|
||||
}
|
||||
if (!CREDIT_CODE_PATTERN.test(value.trim())) {
|
||||
return Promise.reject(new Error("统一社会信用代码格式不正确"));
|
||||
if (!CREDIT_CODE_PATTERN.test(String(value).trim().toUpperCase())) {
|
||||
return Promise.reject(new Error("统一社会信用代码格式不正确(18位)"));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
|
@ -56,13 +83,15 @@ export function idCardRule(required = true) {
|
|||
export function phoneRule(label = "联系电话", required = true) {
|
||||
return {
|
||||
required,
|
||||
validateTrigger: FORMAT_VALIDATE_TRIGGER,
|
||||
whitespace: true,
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
if (!value || !String(value).trim()) {
|
||||
return required ? Promise.reject(new Error(`请输入${label}`)) : Promise.resolve();
|
||||
}
|
||||
const str = String(value).replace(/\s+/g, "");
|
||||
if (!PHONE_PATTERN.test(str)) {
|
||||
return Promise.reject(new Error(`${label}格式不正确`));
|
||||
const normalized = normalizePhone(value);
|
||||
if (!PHONE_PATTERN.test(normalized)) {
|
||||
return Promise.reject(new Error(`${label}格式不正确(手机11位或固话区号+号码)`));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
|
@ -88,14 +117,18 @@ export function mobileRule(label = "账号", required = true) {
|
|||
export function longitudeRule(required = false) {
|
||||
return {
|
||||
required,
|
||||
validateTrigger: FORMAT_VALIDATE_TRIGGER,
|
||||
validator: (_, value) => {
|
||||
if (value === undefined || value === null || value === "") {
|
||||
if (isEmptyValue(value)) {
|
||||
return required ? Promise.reject(new Error("请输入经度")) : Promise.resolve();
|
||||
}
|
||||
const num = Number(value);
|
||||
if (Number.isNaN(num) || num < -180 || num > 180) {
|
||||
return Promise.reject(new Error("经度格式不正确(-180 ~ 180)"));
|
||||
}
|
||||
if (hasTooManyDecimals(value)) {
|
||||
return Promise.reject(new Error("经度最多保留6位小数"));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
|
|
@ -104,28 +137,60 @@ export function longitudeRule(required = false) {
|
|||
export function latitudeRule(required = false) {
|
||||
return {
|
||||
required,
|
||||
validateTrigger: FORMAT_VALIDATE_TRIGGER,
|
||||
validator: (_, value) => {
|
||||
if (value === undefined || value === null || value === "") {
|
||||
if (isEmptyValue(value)) {
|
||||
return required ? Promise.reject(new Error("请输入纬度")) : Promise.resolve();
|
||||
}
|
||||
const num = Number(value);
|
||||
if (Number.isNaN(num) || num < -90 || num > 90) {
|
||||
return Promise.reject(new Error("纬度格式不正确(-90 ~ 90)"));
|
||||
}
|
||||
if (hasTooManyDecimals(value)) {
|
||||
return Promise.reject(new Error("纬度最多保留6位小数"));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** 经纬度成对填写:填了其中一个则另一个必填 */
|
||||
export function coordinatePairRule(peerField, selfLabel, peerLabel) {
|
||||
return ({ getFieldValue }) => ({
|
||||
validateTrigger: FORMAT_VALIDATE_TRIGGER,
|
||||
validator: (_, value) => {
|
||||
const peerValue = getFieldValue(peerField);
|
||||
const hasSelf = !isEmptyValue(value);
|
||||
const hasPeer = !isEmptyValue(peerValue);
|
||||
if (hasSelf && !hasPeer) {
|
||||
return Promise.reject(new Error(`请同时填写${peerLabel}`));
|
||||
}
|
||||
if (!hasSelf && hasPeer) {
|
||||
return Promise.reject(new Error(`请填写${selfLabel}`));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function urlRule(label = "网址", required = false) {
|
||||
return {
|
||||
required,
|
||||
validateTrigger: FORMAT_VALIDATE_TRIGGER,
|
||||
whitespace: true,
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
if (!value || !String(value).trim()) {
|
||||
return required ? Promise.reject(new Error(`请输入${label}`)) : Promise.resolve();
|
||||
}
|
||||
if (!URL_PATTERN.test(String(value).trim())) {
|
||||
return Promise.reject(new Error(`${label}格式不正确`));
|
||||
const normalized = normalizeUrl(value);
|
||||
if (!URL_PATTERN.test(normalized)) {
|
||||
return Promise.reject(new Error(`${label}格式不正确(如 https://example.com)`));
|
||||
}
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new URL(normalized);
|
||||
} catch {
|
||||
return Promise.reject(new Error(`${label}格式不正确(如 https://example.com)`));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue