/** 商品自定义字段协议适配、默认值与提交前校验;服务端仍负责最终字段与规则校验。 */ function e(e) { return e && typeof e == `object` && !Array.isArray(e) ? e : null; } function t(e) { return typeof e == `string` || typeof e == `number` ? String(e) : ``; } function n(e) { return e === !0 || e === 1 || e === `1`; } // 下拉选项兼容对象数组、纯值数组及逗号/换行分隔字符串,最终统一为 value/label。 function r(n) { return ( Array.isArray(n) ? n.flatMap((n) => { let r = e(n); return r ? [ { value: t(r.value ?? r.id ?? r.option_value), label: t(r.label ?? r.name ?? r.option_name ?? r.value), }, ] : [t(n)]; }) : t(n).split(/[,\n]/) ) .map((e) => typeof e == `string` ? { value: e.trim(), label: e.trim(), } : e, ) .filter((e) => e.value !== ``); } /** * 将后端 PCRE 风格 regexpr 的可表达部分转换为 JS RegExp。 * 不支持的高级构造标记 patternServerOnly,不能假装浏览器已经完成等价验证。 */ function i(e) { let n = t(e).trim(); if (!n) return {}; let r = ``, i = n[0], a = { "(": `)`, "[": `]`, "{": `}`, "<": `>`, }; // 识别 /.../i、{...} 等包围符,跳过转义字符并处理成对分隔符的嵌套。 if (/[^a-zA-Z0-9\\\s\0]/.test(i)) { let e = a[i] ?? i, t = 1, o = -1; for (let r = 1; r < n.length; r++) { if (n[r] === `\\`) { r++; continue; } if ((a[i] && n[r] === i && t++, n[r] === e && --t === 0)) { o = r; break; } a[i] || (t = 1); } if (o > 0 && /^[a-zA-Z\s]*$/.test(n.slice(o + 1))) ((r = n.slice(o + 1).replace(/\s/g, ``)), (n = n.slice(1, o)), `\\^$.*+?()[]{}|/`.includes(e) || (n = n.split(`\\${e}`).join(e))); else if (`/#~%!`.includes(i)) throw Error(`自定义字段验证规则无效`); } if (!/^[imsuxADSUXJnr]*$/.test(r)) throw Error(`自定义字段验证规则修饰符无效`); let o = /^\(\?([imsx]+)\)/.exec(n); o && ((r += o[1]), (n = n.slice(o[0].length))); let s = [...new Set(r.replace(/[^imsu]/g, ``))].join(``); if ( /\(\?(?:[>('|&R0-9]|P[=>]|[imsx-]+:)|\(\*|\\[KCG]|(?:[+*?]|\{\d+(?:,\d*)?\})\+/.test( n, ) || r.includes(`r`) || (r.includes(`J`) && /\(\? 0 && n[e - 1] !== `(`) || (t === `}` && /\{\d+(?:,\d*)?\}$/.test(c))) && (n[e + 1] === `?` ? e++ : (c += `?`))); } r.includes(`A`) && (c = `(? n.findIndex((t) => t.id === e.id) === t); } // explain 仅用于说明,不进入提交模型;其他类型初始为空,由控件和校验共同处理。 function o(e) { return Object.fromEntries( e.filter((e) => e.kind !== `explain`).map((e) => [e.id, (e.kind, ``)]), ); } /** 逐字段检查必填、选项值和可本地执行的正则;布尔字段按后端约定归一为 "1"/空串。 */ function s(e, t) { for (let n of e) { if (n.kind === `explain`) continue; let e = t[n.id], r = n.kind === `boolean` ? e === !0 || e === 1 || e === `1` ? `1` : `` : String(e ?? ``).trim(); if (n.required && !r) throw Error(`请填写${n.label}`); if (r) { if (n.kind === `select` && !n.options.some((e) => e.value === r)) throw Error(`${n.label}选项无效`); if (n.pattern && !n.patternServerOnly) { let e; try { e = new RegExp(n.pattern, n.patternFlags); } catch { throw Error(`${n.label}验证规则无效`); } if (!e.test(r)) throw Error(`${n.label}格式不正确`); } } } } export { s as i, i as n, a as r, o as t };