@bytenew/bn-bus-ui 1.1.462 → 1.1.463

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/install.js +134 -0
  2. package/package.json +20 -4
  3. package/packages/BnAddress/index.vue +141 -0
  4. package/packages/BnAddressParse/index.vue +75 -0
  5. package/packages/BnAdvancedFilter/BnFilterView.vue +145 -0
  6. package/packages/BnAdvancedFilter/index.vue +345 -0
  7. package/packages/BnAdvancedFilter/util.js +171 -0
  8. package/packages/BnCascader/BnCascader.vue +543 -0
  9. package/packages/BnCascader/BnCascaderPanel.vue +1331 -0
  10. package/packages/BnCascader/cascaderDisplay.js +102 -0
  11. package/packages/BnCheck/BnCheck.vue +253 -0
  12. package/packages/BnColumnConfig/columnConfigDialog.vue +134 -0
  13. package/packages/BnColumnConfig/component/childrenFormSetting/assocTable.vue +143 -0
  14. package/packages/BnColumnConfig/component/childrenFormSetting/assocTableSearch.vue +314 -0
  15. package/packages/BnColumnConfig/component/childrenFormSetting/index.vue +243 -0
  16. package/packages/BnColumnConfig/component/defaultSet/defaultSet.vue +114 -0
  17. package/packages/BnColumnConfig/component/defaultSet/stringDefault.vue +210 -0
  18. package/packages/BnColumnConfig/component/funcExprDialog/funcExprDialog.vue +126 -0
  19. package/packages/BnColumnConfig/component/packageFilter/index.vue +141 -0
  20. package/packages/BnColumnConfig/component/paraExplainSet/index.vue +156 -0
  21. package/packages/BnColumnConfig/component/setOption/setOption.vue +321 -0
  22. package/packages/BnColumnConfig/component/setRelationOption/ConditionList.vue +277 -0
  23. package/packages/BnColumnConfig/component/setRelationOption/LevelHeader.vue +144 -0
  24. package/packages/BnColumnConfig/component/setRelationOption/setRelationOption.vue +642 -0
  25. package/packages/BnColumnConfig/data.js +129 -0
  26. package/packages/BnColumnConfig/index.scss +23 -0
  27. package/packages/BnColumnConfig/index.vue +309 -0
  28. package/packages/BnCondVal/BnCondVal.vue +112 -0
  29. package/packages/BnCondVal/itemVal/dateRegVal.vue +39 -0
  30. package/packages/BnCondVal/itemVal/dateVal.vue +39 -0
  31. package/packages/BnCondVal/itemVal/numRegVal.vue +67 -0
  32. package/packages/BnCondVal/itemVal/numVal.vue +44 -0
  33. package/packages/BnCondVal/itemVal/relationVal.vue +73 -0
  34. package/packages/BnCondVal/itemVal/selectColumnVal.vue +58 -0
  35. package/packages/BnCondVal/itemVal/selectVal.vue +59 -0
  36. package/packages/BnCondVal/itemVal/stringVal.vue +156 -0
  37. package/packages/BnCondition/index.vue +551 -0
  38. package/packages/BnCondition/util.js +232 -0
  39. package/packages/BnDatePicker/BnDatePicker.vue +194 -0
  40. package/packages/BnDrop/BnDrop.vue +917 -0
  41. package/packages/BnEmptyTip/BnEmptyTip.vue +107 -0
  42. package/packages/BnExportOrder/BnExportOrder.vue +241 -0
  43. package/packages/BnExportOrder/validatorCode.vue +94 -0
  44. package/packages/BnFileView/BnFileView.vue +271 -0
  45. package/packages/BnFileView/FileDetail.vue +125 -0
  46. package/packages/BnFileView/videoPreview.vue +70 -0
  47. package/packages/BnFilterOption/BnFilterOption.vue +160 -0
  48. package/packages/BnFunExpr/BnFunExpr.vue +608 -0
  49. package/packages/BnImportOrder/BnImportOrder.vue +323 -0
  50. package/packages/BnImportTemplate/BnImportTemplate.vue +866 -0
  51. package/packages/BnImportTemplate/assets/merge_tip_img.png +0 -0
  52. package/packages/BnImportTemplate/assets/sheet_tip.png +0 -0
  53. package/packages/BnImportTemplate/assets/xls.png +0 -0
  54. package/packages/BnImportTemplate/components/ImportTemplateTrigger.vue +198 -0
  55. package/packages/BnImportTemplate/components/TemplateEditDialog.vue +340 -0
  56. package/packages/BnImportTemplate/components/TemplateFieldsConfig.vue +401 -0
  57. package/packages/BnImportTemplate/components/TemplateListDialog.vue +297 -0
  58. package/packages/BnInpNum/BnInpNum.vue +165 -0
  59. package/packages/BnMenus/BnMenus.vue +502 -0
  60. package/packages/BnMenus/MenuItem.vue +321 -0
  61. package/packages/BnOrderCard/BnOrderCard.vue +389 -0
  62. package/packages/BnOrderCard/orderRemark.vue +178 -0
  63. package/packages/BnOrderCard/util.js +94 -0
  64. package/packages/BnOrderDetail/BnOrderDetail.vue +338 -0
  65. package/packages/BnOrderDetail/filterLogByUser.vue +108 -0
  66. package/packages/BnOrderDetail/orderLogs.vue +53 -0
  67. package/packages/BnOrderDetail/showSubForm/index.vue +41 -0
  68. package/packages/BnOrderDetail/showSubForm/showChildTable.vue +61 -0
  69. package/packages/BnOrderDetail/showSubForm/showTimeLine.vue +131 -0
  70. package/packages/BnOrderDetail/showSubForm/tableCellCopy.vue +84 -0
  71. package/packages/BnOrderShare/index.vue +378 -0
  72. package/packages/BnOrderShare/shareUrlInp.vue +54 -0
  73. package/packages/BnRadio/BnRadio.vue +181 -0
  74. package/packages/BnRelation/BnRelation.vue +120 -0
  75. package/packages/BnSelect/BnSelect.vue +485 -0
  76. package/packages/BnSmartForm/BnBatchForm.vue +334 -0
  77. package/packages/BnSmartForm/BnBatchFormDialog.vue +423 -0
  78. package/packages/BnSmartForm/BnSmartElf/elfLog/index.vue +57 -0
  79. package/packages/BnSmartForm/BnSmartElf/index.vue +95 -0
  80. package/packages/BnSmartForm/BnSmartFormPsychic.js +629 -0
  81. package/packages/BnSmartForm/BnSmartFormUtil.js +524 -0
  82. package/packages/BnSmartForm/addressForm/index.vue +73 -0
  83. package/packages/BnSmartForm/checkboxForm/index.vue +99 -0
  84. package/packages/BnSmartForm/childrenForm/childFormFile.vue +237 -0
  85. package/packages/BnSmartForm/childrenForm/childrenFormBody.vue +260 -0
  86. package/packages/BnSmartForm/childrenForm/index.vue +110 -0
  87. package/packages/BnSmartForm/childrenForm/searchInventory.vue +115 -0
  88. package/packages/BnSmartForm/chooseAssocTable/chooseAssocTable.vue +451 -0
  89. package/packages/BnSmartForm/chooseAssocTable/chooseChildGood.vue +229 -0
  90. package/packages/BnSmartForm/chooseAssocTable/tableCellCopy.vue +84 -0
  91. package/packages/BnSmartForm/chooseChildOrder/chooseChildOrder.vue +158 -0
  92. package/packages/BnSmartForm/chooseIPaasData/chooseIPaasData.vue +307 -0
  93. package/packages/BnSmartForm/chooseIPaasData/tableCellCopy.vue +84 -0
  94. package/packages/BnSmartForm/choosePackage/choosePackage.vue +361 -0
  95. package/packages/BnSmartForm/dateDualForm/index.vue +37 -0
  96. package/packages/BnSmartForm/dateForm/index.vue +38 -0
  97. package/packages/BnSmartForm/fileForm/fileFormData.js +50 -0
  98. package/packages/BnSmartForm/fileForm/index.vue +240 -0
  99. package/packages/BnSmartForm/formItemFooter/formItemFooter.vue +38 -0
  100. package/packages/BnSmartForm/formItemTop/formItemTop.vue +42 -0
  101. package/packages/BnSmartForm/index.vue +1201 -0
  102. package/packages/BnSmartForm/numberForm/index.vue +63 -0
  103. package/packages/BnSmartForm/radioForm/index.vue +72 -0
  104. package/packages/BnSmartForm/receiveForm/index.vue +112 -0
  105. package/packages/BnSmartForm/relationForm/index.vue +82 -0
  106. package/packages/BnSmartForm/scoreForm/index.vue +39 -0
  107. package/packages/BnSmartForm/selectForm/index.vue +55 -0
  108. package/packages/BnSmartForm/showValForm/index.vue +42 -0
  109. package/packages/BnSmartForm/showValForm/showValFormTable.vue +104 -0
  110. package/packages/BnSmartForm/smartFormsCommon.scss +43 -0
  111. package/packages/BnSmartForm/stringForm/index.vue +170 -0
  112. package/packages/BnVirtPopover/index.vue +319 -0
  113. package/packages/BnWebLog/BnWebLog.vue +140 -0
  114. package/packages/BnWorkSettingDrop/advancedOptions.js +112 -0
  115. package/packages/BnWorkSettingDrop/benBenAIUtil.js +89 -0
  116. package/packages/BnWorkSettingDrop/index.vue +292 -0
  117. package/packages/font/iconfont.css +243 -0
  118. package/packages/font/iconfont.ttf +0 -0
  119. package/packages/font/iconfont.woff +0 -0
  120. package/packages/font/iconfont.woff2 +0 -0
  121. package/utils/addressParse-old.js +645 -0
  122. package/utils/addressParse.js +735 -0
  123. package/utils/config.js +68 -0
  124. package/utils/index.js +1171 -0
  125. package/dist/assocTableSearch-CmzOXI5w.js +0 -349
  126. package/dist/assocTableSearch.css +0 -1
  127. package/dist/bn-bus-ui.es.js +0 -65
  128. package/dist/bn-bus-ui.umd.js +0 -49
  129. package/dist/chooseIPaasData-jkTJEMKT.js +0 -391
  130. package/dist/chooseIPaasData.css +0 -1
  131. package/dist/defaultSet-CiYuSOzT.js +0 -297
  132. package/dist/defaultSet.css +0 -1
  133. package/dist/fileFormData-D_Q1vylE.js +0 -53
  134. package/dist/formItemFooter-BpnVUUgV.js +0 -108
  135. package/dist/formItemFooter.css +0 -1
  136. package/dist/funcExprDialog-BMc-n5FL.js +0 -139
  137. package/dist/funcExprDialog.css +0 -1
  138. package/dist/index-8GQJARcF.js +0 -44
  139. package/dist/index-8apT0r8m.js +0 -66
  140. package/dist/index-BOFu3qAH.js +0 -183
  141. package/dist/index-BSKXuSid.js +0 -89
  142. package/dist/index-BhYvDd_Q.js +0 -45
  143. package/dist/index-BhqkeVFc.js +0 -45
  144. package/dist/index-CK7_Ou7F.js +0 -89
  145. package/dist/index-Cfb8D3Fg.js +0 -58
  146. package/dist/index-D1fGD0mX.js +0 -51
  147. package/dist/index-DE_eQGbT.js +0 -746
  148. package/dist/index-DfgiBqzS.js +0 -221
  149. package/dist/index-Dobi0ms9.js +0 -66
  150. package/dist/index-DuyQNxe0.js +0 -118
  151. package/dist/index-DxpJkrN7.js +0 -64
  152. package/dist/index-FGHeG46m.js +0 -109
  153. package/dist/index-P2M7CUTe.js +0 -178
  154. package/dist/index-xCz2zysE.js +0 -135
  155. package/dist/index.css +0 -1
  156. package/dist/index2.css +0 -1
  157. package/dist/index3.css +0 -1
  158. package/dist/index4.css +0 -1
  159. package/dist/index5.css +0 -1
  160. package/dist/index6.css +0 -1
  161. package/dist/index7.css +0 -1
  162. package/dist/install--7IU60oV.js +0 -23103
  163. package/dist/install.css +0 -1
  164. package/dist/setOption-DehYZpZr.js +0 -329
  165. package/dist/setOption.css +0 -1
  166. package/dist/setRelationOption-BL-AFUoF.js +0 -5217
  167. package/dist/setRelationOption.css +0 -1
@@ -0,0 +1,735 @@
1
+ let defaultData = []; //不包括省市级code的数据
2
+
3
+ const mCity = {}; //以市为层级的数据 里面包括 p:省 c:市 a:区列表
4
+
5
+ const mArea = {}; //以区为级别的数据 里面包括 p:省 c:市
6
+
7
+ const mStreet = {}; //以街道为级别的数据 里面包括 c:市 a:区
8
+
9
+ /**
10
+ * 处理原始地址数据转换成专用数据
11
+ * @param list 原始数据
12
+ * @param init 是否初始化 如传空 已转换过不会再次转换
13
+ * @returns {boolean}
14
+ */
15
+ function parseArea(list, init) {
16
+ if (!init && defaultData.length) {
17
+ return true;
18
+ }
19
+ defaultData = list;
20
+ defaultData.forEach(province => {
21
+ if (province.city) {
22
+ province.city.forEach(city => {
23
+ if (city.name !== '其他') {
24
+ if (!mCity[city.name]) {
25
+ mCity[city.name] = [];
26
+ }
27
+ mCity[city.name].push({
28
+ p: province.name,
29
+ c: city.name,
30
+ a: city.area || [],
31
+ s: city.street || [],
32
+ });
33
+ }
34
+ if (city.area) {
35
+ city.area.forEach(area => {
36
+ if (area !== '其他') {
37
+ if (!mArea[area]) {
38
+ mArea[area] = [];
39
+ }
40
+ mArea[area].push({
41
+ p: province.name,
42
+ c: city.name
43
+ })
44
+ }
45
+ if (city.street && city.street[area]) {
46
+ city.street[area].forEach(street => {
47
+ if (street !== '其他') {
48
+ if (!mStreet[street]) {
49
+ mStreet[street] = [];
50
+ }
51
+ mStreet[street].push({
52
+ c: city.name,
53
+ a: area
54
+ })
55
+ }
56
+ })
57
+ }
58
+ })
59
+ }
60
+ })
61
+ }
62
+ });
63
+ }
64
+
65
+ /**
66
+ * 解析地址详情(内部方法,需先调用 parseArea 初始化地址库)
67
+ * @param address 任意地址字符串
68
+ * @param sourceData 组件配置,如 extraInfo.isFourAddress
69
+ * @returns {{name: string, mobile: string, detail: string, zip_code: string, phone: string}}
70
+ */
71
+ function parseAddressDetail(address, sourceData) {
72
+ const parse = {
73
+ name: '',
74
+ mobile: '',
75
+ detail: '',
76
+ zip_code: '',
77
+ phone: '',
78
+ extensionNumber:'', // 淘宝分机号码
79
+ };
80
+
81
+ // 第一步:预处理
82
+ address = joinAddressLines(address);
83
+ var presetName = address.name;
84
+ address = stripAddressLabels(address.text);
85
+
86
+ // 清理特殊字符(包括句号)
87
+ const search = ['详细地址', '收货地址', '联系地址', '收件地址', '邮政编码', '手机号码', '联系电话', '联系方式', '收货人', '收件人', '联系人', '姓名', '名字', '手机号', '邮编', '收货', '地址', '详细', '电话', '固话', ':', ':', ';', ';', ',', ',', '。'];
88
+ search.forEach(str => {
89
+ address = address.replace(new RegExp(str, 'g'), ' ')
90
+ });
91
+
92
+ // 替换多个空格为单个空格
93
+ address = address.replace(/ {2,}/g, ' ');
94
+
95
+ // 处理电话号码格式
96
+ address = address.replace(/(\d{3})-(\d{4})-(\d{4})/g, '$1$2$3');
97
+ address = address.replace(/(\d{3}) (\d{4}) (\d{4})/g, '$1$2$3');
98
+
99
+ // 提取手机号
100
+ const mobileReg = /([1][0-9]{10}((-[0-9]{4})?))|((86-?)?[1][0-9]{10})/g;
101
+ const mobile = mobileReg.exec(address);
102
+ if (mobile) {
103
+ parse.mobile = mobile[0];
104
+ address = address.replace(mobile[0], ' ');
105
+ }
106
+
107
+ // 提取固话
108
+ const phoneReg = /(([0-9]{3,4}-)[0-9]{7,8})|([0-9]{12})|([0-9]{11})|([0-9]{10})|([0-9]{9})|([0-9]{8})|([0-9]{7})/g;
109
+ const phone = phoneReg.exec(address);
110
+ if (phone) {
111
+ //获取分机号码 例:16601795913-9385(11位手机号-xxxx)
112
+ var addressArry = address.split(' ');
113
+ var ext = addressArry.filter((item) => (item.length == 16 && item.indexOf('-')));
114
+ if(ext.length>0){
115
+ //截取分机号赋值
116
+ parse.extensionNumber = ext[0].split('-')[1];
117
+ //空格替换分机号
118
+ var extVal = '-'+parse.extensionNumber;
119
+ address = address.replace(extVal, ' ');
120
+ }
121
+ parse.phone = phone[0];
122
+ address = address.replace(phone[0], ' ');
123
+ }
124
+
125
+ // 提取邮编
126
+ const zipReg = /([0-9]{6})/g;
127
+ const zip = zipReg.exec(address);
128
+ if (zip) {
129
+ parse.zip_code = zip[0];
130
+ address = address.replace(zip[0], '');
131
+ }
132
+
133
+ // 清理多余空格
134
+ address = address.replace(/ {2,}/g, ' ').trim();
135
+
136
+ // ============== 核心解析 ==============
137
+ let detail = detail_parse_forward(address, sourceData);
138
+
139
+ console.log('正向解析结果:', JSON.stringify(detail));
140
+
141
+ if (!detail.city) {
142
+ detail = detail_parse(address);
143
+ console.log('逆向解析结果:', JSON.stringify(detail));
144
+
145
+ if (detail.area && !detail.city) {
146
+ detail = detail_parse(address, { ignoreArea: true });
147
+ console.log('ignoreArea解析结果:', JSON.stringify(detail));
148
+ }
149
+ }
150
+
151
+ // 提取收件人姓名
152
+ if (detail.name) {
153
+ parse.name = detail.name;
154
+ } else {
155
+ // 从地址中提取可能的姓名
156
+ const addrParts = address.replace(detail.province || '', '').replace(detail.city || '', '').replace(detail.area || '', '').split(' ').filter(str => str.trim());
157
+ if (addrParts.length > 1) {
158
+ addrParts.forEach(str => {
159
+ if (!parse.name || (str && str.length < parse.name.length)) {
160
+ parse.name = str.trim();
161
+ }
162
+ });
163
+ if (parse.name) {
164
+ detail.addr = (detail.addr || '').replace(parse.name, '').trim();
165
+ }
166
+ }
167
+ }
168
+
169
+ if(parse.extensionNumber){
170
+ parse.name = parse.name+'[转'+parse.extensionNumber+']';
171
+ }
172
+
173
+ parse.province = detail.province || '';
174
+ parse.city = detail.city || '';
175
+ parse.area = detail.area || '';
176
+ parse.street = detail.street || '';
177
+ parse.addr = detail.addr || '';
178
+
179
+ if (presetName) {
180
+ parse.name = presetName;
181
+ if (parse.addr) {
182
+ parse.addr = parse.addr.replace(presetName, '').trim();
183
+ }
184
+ }
185
+
186
+ // 省份标准化
187
+ if (parse.province === "澳门" || parse.province === "香港") {
188
+ parse.province += "特别行政区";
189
+ } else if (parse.province === "新疆") {
190
+ parse.province = "新疆维吾尔自治区";
191
+ } else if (parse.province === "西藏") {
192
+ parse.province = "西藏自治区";
193
+ } else if (parse.province === "广西") {
194
+ parse.province = "广西壮族自治区";
195
+ } else if (parse.province === "宁夏") {
196
+ parse.province = "宁夏回族自治区";
197
+ } else if (parse.province === "内蒙古") {
198
+ parse.province = "内蒙古自治区";
199
+ }
200
+ console.log('最终解析结果:', JSON.stringify(parse));
201
+ return parse;
202
+ }
203
+
204
+
205
+ /**
206
+ * 正向解析模式
207
+ * 从前到后按 province city addr 逐级筛选
208
+ * 有city的值即可说明解析成功
209
+ * 此模式对地址顺序有要求
210
+ * 正向解析:省 -> area -> 反推城市
211
+ * @param address
212
+ * @returns {{province: string, city: string, area: string, addr: string}}
213
+ */
214
+ function detail_parse_forward(address, sourceData) {
215
+ const parse = {
216
+ province: '',
217
+ city: '',
218
+ area: '',
219
+ street: '',
220
+ addr: address,
221
+ name: '',
222
+ };
223
+
224
+ if (!address || address.length === 0) {
225
+ return parse;
226
+ }
227
+
228
+ // ===== 关键修复:检查 defaultData 是否已初始化 =====
229
+ if (!defaultData || defaultData.length === 0) {
230
+ console.log('defaultData为空,请先调用parseArea初始化');
231
+ // 尝试使用 mArea 进行匹配
232
+ return parse;
233
+ }
234
+
235
+ let remaining = address;
236
+
237
+ // ========== 第一步:匹配省份 ==========
238
+ let matchedProvince = null;
239
+
240
+ // 先检查地址是否以省份名开头
241
+ const provPatterns = [
242
+ { pattern: '广东省', province: '广东省' },
243
+ { pattern: '广东', province: '广东省' },
244
+ { pattern: '北京市', province: '北京市' },
245
+ { pattern: '北京', province: '北京市' },
246
+ { pattern: '天津市', province: '天津市' },
247
+ { pattern: '天津', province: '天津市' },
248
+ { pattern: '上海市', province: '上海市' },
249
+ { pattern: '上海', province: '上海市' },
250
+ { pattern: '重庆市', province: '重庆市' },
251
+ { pattern: '重庆', province: '重庆市' },
252
+ ];
253
+
254
+ // 先尝试快速匹配
255
+ for (const pattern of provPatterns) {
256
+ if (remaining.startsWith(pattern.pattern)) {
257
+ // 在 defaultData 中找到对应的省份数据
258
+ const found = defaultData.find(p => p.name === pattern.province);
259
+ if (found) {
260
+ matchedProvince = found;
261
+ parse.province = pattern.province;
262
+ remaining = remaining.substring(pattern.pattern.length);
263
+ if (remaining.startsWith('省') && pattern.pattern !== pattern.province) {
264
+ remaining = remaining.substring(1);
265
+ }
266
+ console.log('快速匹配到省份:', pattern.province);
267
+ break;
268
+ }
269
+ }
270
+ }
271
+
272
+ // 如果快速匹配失败,遍历 defaultData
273
+ if (!matchedProvince) {
274
+ for (let i = 0; i < defaultData.length; i++) {
275
+ const province = defaultData[i];
276
+ const provName = province.name;
277
+
278
+ // 查找省份名
279
+ let idx = remaining.indexOf(provName);
280
+ if (idx > -1 && idx < 5) {
281
+ if (idx > 0) {
282
+ parse.name = remaining.substring(0, idx).trim();
283
+ }
284
+ matchedProvince = province;
285
+ parse.province = provName;
286
+ remaining = remaining.substring(idx + provName.length);
287
+ console.log('遍历匹配到省份(全名):', provName, '剩余:', remaining);
288
+ break;
289
+ }
290
+
291
+ // 查找简称
292
+ const provShort = provName.replace('省', '').replace('市', '');
293
+ if (provShort !== provName && provShort.length >= 2) {
294
+ idx = remaining.indexOf(provShort);
295
+ if (idx > -1 && idx < 5) {
296
+ if (idx > 0) {
297
+ parse.name = remaining.substring(0, idx).trim();
298
+ }
299
+ matchedProvince = province;
300
+ parse.province = provName;
301
+ remaining = remaining.substring(idx + provShort.length);
302
+ if (remaining.startsWith('省')) {
303
+ remaining = remaining.substring(1);
304
+ }
305
+ console.log('遍历匹配到省份(简称):', provName, '剩余:', remaining);
306
+ break;
307
+ }
308
+ }
309
+ }
310
+ }
311
+
312
+ if (!matchedProvince) {
313
+ console.log('未匹配到省份,defaultData前3个:', defaultData.slice(0, 3).map(p => p.name));
314
+ // 尝试通过 mArea 反查
315
+ const reverseResult = findProvinceByArea(remaining);
316
+ if (reverseResult) {
317
+ parse.province = reverseResult.province;
318
+ parse.city = reverseResult.city;
319
+ parse.area = reverseResult.area;
320
+ parse.addr = reverseResult.addr || remaining;
321
+ return parse;
322
+ }
323
+ return parse;
324
+ }
325
+
326
+ // ========== 第二步:在省份内查找 area,反推城市 ==========
327
+ if (matchedProvince.city && matchedProvince.city.length > 0) {
328
+
329
+ // 收集所有 area
330
+ let allAreas = [];
331
+ for (const city of matchedProvince.city) {
332
+ if (city.area && city.area.length > 0) {
333
+ for (const areaName of city.area) {
334
+ if (areaName && areaName !== '其他' && areaName !== '其它区' && areaName !== '其他区' && areaName.length >= 2) {
335
+ allAreas.push({
336
+ areaName: areaName,
337
+ cityName: city.name,
338
+ cityData: city
339
+ });
340
+ }
341
+ }
342
+ }
343
+ }
344
+
345
+ // 按长度降序
346
+ allAreas.sort((a, b) => b.areaName.length - a.areaName.length);
347
+
348
+ // 查找匹配的 area
349
+ for (const areaItem of allAreas) {
350
+ const idx = remaining.indexOf(areaItem.areaName);
351
+ if (idx > -1 && idx < 10) {
352
+ parse.city = areaItem.cityName;
353
+ parse.area = areaItem.areaName;
354
+
355
+ let afterArea = remaining.substring(idx + areaItem.areaName.length);
356
+
357
+ console.log('匹配到area:', areaItem.areaName, '城市:', areaItem.cityName);
358
+
359
+ // 尝试匹配街道
360
+ if (areaItem.cityData.street && areaItem.cityData.street[areaItem.areaName]) {
361
+ const streets = areaItem.cityData.street[areaItem.areaName];
362
+ if (streets && streets.length > 0) {
363
+ const sortedStreets = streets
364
+ .filter(s => s && s !== '其他' && s !== '其它区' && s !== '其他区' && s.length >= 2)
365
+ .sort((a, b) => b.length - a.length);
366
+
367
+ console.log('该area下的街道:', sortedStreets.slice(0, 5));
368
+
369
+ for (const streetName of sortedStreets) {
370
+ // 完整匹配
371
+ let streetIdx = afterArea.indexOf(streetName);
372
+ if (streetIdx > -1 && streetIdx < 8) {
373
+ parse.street = streetName;
374
+ afterArea = afterArea.substring(streetIdx + streetName.length);
375
+ console.log('匹配到街道(完整):', streetName);
376
+ break;
377
+ }
378
+
379
+ // 模糊匹配:去掉后缀
380
+ const streetShort = streetName.replace('街道', '').replace('镇', '').replace('乡', '');
381
+ if (streetShort !== streetName && streetShort.length >= 2) {
382
+ streetIdx = afterArea.indexOf(streetShort);
383
+ if (streetIdx > -1 && streetIdx < 8) {
384
+ parse.street = streetName;
385
+ afterArea = afterArea.substring(streetIdx + streetShort.length);
386
+ if (afterArea.startsWith('区')) {
387
+ afterArea = afterArea.substring(1);
388
+ }
389
+ console.log('匹配到街道(模糊):', streetShort, '->', streetName);
390
+ break;
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+
397
+ parse.addr = afterArea.trim();
398
+ return parse;
399
+ }
400
+ }
401
+
402
+ console.log('未匹配到area,尝试直接匹配城市');
403
+
404
+ // 如果没找到 area,尝试直接匹配城市名
405
+ for (const city of matchedProvince.city) {
406
+ const cityName = city.name;
407
+ const idx = remaining.indexOf(cityName);
408
+ if (idx > -1 && idx < 10) {
409
+ parse.city = cityName;
410
+ remaining = remaining.substring(idx + cityName.length);
411
+
412
+ // 尝试在剩余部分找 area
413
+ if (city.area && city.area.length > 0) {
414
+ const sortedAreas = [...city.area]
415
+ .filter(a => a && a.length >= 2)
416
+ .sort((a, b) => b.length - a.length);
417
+
418
+ for (const areaName of sortedAreas) {
419
+ const areaIdx = remaining.indexOf(areaName);
420
+ if (areaIdx > -1 && areaIdx < 10) {
421
+ parse.area = areaName;
422
+ remaining = remaining.substring(areaIdx + areaName.length);
423
+ break;
424
+ }
425
+ }
426
+ }
427
+
428
+ parse.addr = remaining.trim();
429
+ return parse;
430
+ }
431
+ }
432
+ }
433
+
434
+ parse.addr = remaining;
435
+ return parse;
436
+ }
437
+
438
+ /**
439
+ * 新增:通过 area 反查省份和城市(当正向匹配省份失败时使用)
440
+ */
441
+ function findProvinceByArea(address) {
442
+ if (!mArea) return null;
443
+
444
+ // 收集所有 area
445
+ let allAreas = [];
446
+ for (const areaName in mArea) {
447
+ if (areaName && areaName.length >= 2) {
448
+ const idx = address.indexOf(areaName);
449
+ if (idx > -1 && idx < 10) {
450
+ allAreas.push({
451
+ name: areaName,
452
+ index: idx,
453
+ data: mArea[areaName]
454
+ });
455
+ }
456
+ }
457
+ }
458
+
459
+ // 按位置排序,取最早出现的
460
+ allAreas.sort((a, b) => a.index - b.index);
461
+
462
+ if (allAreas.length > 0) {
463
+ const bestMatch = allAreas[0];
464
+ const areaData = bestMatch.data;
465
+
466
+ if (areaData && areaData.length >= 1) {
467
+ return {
468
+ province: areaData[0].p,
469
+ city: areaData[0].c,
470
+ area: bestMatch.name,
471
+ addr: address.substring(bestMatch.index + bestMatch.name.length)
472
+ };
473
+ }
474
+ }
475
+
476
+ return null;
477
+ }
478
+
479
+ /**
480
+ * 逆向解析 从后【县,区,旗】往前解析
481
+ * 有地区就能大概返回地址了
482
+ * @param address
483
+ * @param ignoreArea 是否忽视区 因为地址中含有区容易导致匹配错误 例:山东省蓬莱市黄海花园东区西门宝威学堂 曲荣声收15753572456
484
+ * @returns {{province: string, city: string, area: string, name: string, _area: string, addr: string}}
485
+ */
486
+ function detail_parse(address, {ignoreArea = false} = {}) {
487
+ const parse = {
488
+ province: '',
489
+ city: '',
490
+ area: '',
491
+ name: '',
492
+ _area: '',
493
+ addr: address,
494
+ };
495
+
496
+ if (!address || address.length === 0) {
497
+ return parse;
498
+ }
499
+
500
+ address = address.replace(/ {2,}/g, ' ').trim();
501
+
502
+ // 查找 area
503
+ if (!ignoreArea && mArea) {
504
+ let bestMatch = null;
505
+
506
+ for (const areaName in mArea) {
507
+ if (!areaName || areaName === '其他' || areaName === '其它区' || areaName === '其他区' || areaName.length < 2) {
508
+ continue;
509
+ }
510
+
511
+ const idx = address.indexOf(areaName);
512
+ if (idx > -1) {
513
+ if (!bestMatch || idx < bestMatch.index || (idx === bestMatch.index && areaName.length > bestMatch.name.length)) {
514
+ bestMatch = {
515
+ name: areaName,
516
+ index: idx,
517
+ data: mArea[areaName]
518
+ };
519
+ }
520
+ }
521
+ }
522
+
523
+ if (bestMatch) {
524
+ console.log('逆向匹配到area:', bestMatch.name, '位置:', bestMatch.index);
525
+
526
+ parse.area = bestMatch.name;
527
+ parse.addr = address.substring(bestMatch.index + bestMatch.name.length).trim();
528
+
529
+ const areaData = bestMatch.data;
530
+
531
+ if (areaData.length === 1) {
532
+ parse.province = areaData[0].p;
533
+ parse.city = areaData[0].c;
534
+ console.log('逆向确定省市:', parse.province, parse.city);
535
+ } else {
536
+ console.log('该area有多个城市:', areaData.map(d => d.c));
537
+
538
+ // 通过上下文判断
539
+ for (const candidate of areaData) {
540
+ if (address.includes(candidate.c)) {
541
+ parse.province = candidate.p;
542
+ parse.city = candidate.c;
543
+ break;
544
+ }
545
+ }
546
+
547
+ if (!parse.city) {
548
+ for (const candidate of areaData) {
549
+ const cityShort = candidate.c.replace('市', '');
550
+ if (cityShort.length >= 2 && address.includes(cityShort)) {
551
+ parse.province = candidate.p;
552
+ parse.city = candidate.c;
553
+ break;
554
+ }
555
+ }
556
+ }
557
+ }
558
+ }
559
+ }
560
+
561
+ // 通过城市名匹配
562
+ if (!parse.city && mCity) {
563
+ for (const cityName in mCity) {
564
+ if (cityName && cityName.length >= 2 && address.includes(cityName)) {
565
+ parse.city = cityName;
566
+ parse.province = mCity[cityName][0].p;
567
+ console.log('通过城市名匹配:', parse.province, parse.city);
568
+ break;
569
+ }
570
+ }
571
+ }
572
+
573
+ return parse;
574
+ }
575
+
576
+ const MUNICIPALITIES = ['上海', '北京', '天津', '重庆'];
577
+
578
+ /**
579
+ * 统一换行符格式
580
+ */
581
+ function normalizeLineBreaks(address) {
582
+ return String(address || '')
583
+ .replace(/\r\n/g, '\n')
584
+ .replace(/\r/g, '\n')
585
+ .replace(/\t/g, ' ');
586
+ }
587
+
588
+ /**
589
+ * 常见地址字段标签(姓名:、详细地址: 等),较长标签优先匹配
590
+ */
591
+ var ADDRESS_LABEL_PATTERN = '(?:详细地址|收货地址|联系地址|收件地址|邮政编码|手机号码|联系电话|联系方式|收货人|收件人|联系人|姓名|名字|手机号|邮编|收货|地址|详细|固话|电话)[::]';
592
+ var ADDRESS_LABEL_REG = new RegExp(ADDRESS_LABEL_PATTERN, 'g');
593
+ var ADDRESS_LABEL_TEST_REG = new RegExp(ADDRESS_LABEL_PATTERN);
594
+
595
+ /**
596
+ * 去除「姓名:」「详细地址:」等字段标签前缀
597
+ */
598
+ function stripAddressLabels(text) {
599
+ return String(text || '').replace(ADDRESS_LABEL_REG, ' ');
600
+ }
601
+
602
+ var NAME_LABELS = ['姓名', '名字', '联系人', '收货人', '收件人'];
603
+ var PHONE_LABELS = ['电话', '手机号', '手机号码', '联系电话', '联系方式', '固话'];
604
+
605
+ /**
606
+ * 解析「标签:值」格式的单行
607
+ */
608
+ function matchLabeledLine(line) {
609
+ var match = line.match(/^([\u4e00-\u9fa5A-Za-z0-9]+)[::]\s*(.+)$/);
610
+ if (!match) {
611
+ return null;
612
+ }
613
+ return { label: match[1], value: match[2].trim() };
614
+ }
615
+
616
+ /**
617
+ * 按换行符拆分段落,去除行内空白后用空格拼接为单行
618
+ * 若每行是「标签:值」格式,则按标签分类提取姓名、电话和地址
619
+ */
620
+ function joinAddressLines(address) {
621
+ var normalized = normalizeLineBreaks(address);
622
+ var lines = normalized.split('\n').filter(function(line) {
623
+ return line.replace(/[ \t\f\v]+/g, ' ').trim();
624
+ });
625
+ if (lines.length === 1) {
626
+ var singleLine = lines[0].replace(/[ \t\f\v]+/g, ' ').trim();
627
+ if ((singleLine.match(/[::]/g) || []).length > 1 && ADDRESS_LABEL_TEST_REG.test(singleLine)) {
628
+ return {
629
+ text: stripAddressLabels(singleLine).replace(/ {2,}/g, ' ').trim(),
630
+ name: '',
631
+ phoneHint: '',
632
+ };
633
+ }
634
+ }
635
+ var parts = [];
636
+ var extracted = { name: '', phoneHint: '' };
637
+ for (var i = 0; i < lines.length; i++) {
638
+ var line = lines[i].replace(/[ \t\f\v]+/g, ' ').trim();
639
+ if (!line) {
640
+ continue;
641
+ }
642
+ var labeled = matchLabeledLine(line);
643
+ if (labeled) {
644
+ if (NAME_LABELS.indexOf(labeled.label) > -1) {
645
+ extracted.name = labeled.value;
646
+ } else if (PHONE_LABELS.indexOf(labeled.label) > -1) {
647
+ extracted.phoneHint = labeled.value;
648
+ } else {
649
+ parts.push(labeled.value);
650
+ }
651
+ } else {
652
+ parts.push(line);
653
+ }
654
+ }
655
+ return {
656
+ text: parts.join(' '),
657
+ name: extracted.name,
658
+ phoneHint: extracted.phoneHint,
659
+ };
660
+ }
661
+
662
+ /**
663
+ * 从全局变量或 options 中获取 areaList(CDN 加载后挂载在 window.areaList)
664
+ * @param {object} options
665
+ * @param {array} [options.areaList] 地址库原始数据,不传则从全局 areaList 读取
666
+ * @returns {array|null}
667
+ */
668
+ function getGlobalAreaList(options = {}) {
669
+ if (options.areaList) {
670
+ return options.areaList;
671
+ }
672
+ if (typeof window !== 'undefined' && window.areaList) {
673
+ return window.areaList;
674
+ }
675
+ try {
676
+ // CDN 场景下 areaList 为全局变量
677
+ // eslint-disable-next-line no-undef
678
+ if (typeof areaList !== 'undefined') {
679
+ // eslint-disable-next-line no-undef
680
+ return areaList;
681
+ }
682
+ } catch (e) {
683
+ // areaList 未定义时忽略
684
+ }
685
+ return null;
686
+ }
687
+
688
+ /**
689
+ * 判断直辖市名称在前 8 个字符中是否只出现一次(用于补全省份前缀)
690
+ */
691
+ function checkMunicipalityChars(str, name) {
692
+ const prefix = str.substring(0, 8);
693
+ const firstIndex = prefix.indexOf(name);
694
+ const lastIndex = prefix.lastIndexOf(name);
695
+ return firstIndex !== -1 && firstIndex === lastIndex;
696
+ }
697
+
698
+ /**
699
+ * 预处理地址字符串:去空格,并为缺少省份前缀的直辖市地址补全
700
+ */
701
+ function preprocessAddress(address) {
702
+ var cleanAddress = normalizeLineBreaks(address).replace(/[ \t\f\v]+/g, '');
703
+ cleanAddress = cleanAddress.replace(/\n+/g, '\n').replace(/^\n+|\n+$/g, '');
704
+ MUNICIPALITIES.forEach(function(name) {
705
+ if (cleanAddress.indexOf('\n') > -1) {
706
+ var lines = cleanAddress.split('\n');
707
+ for (var i = 0; i < lines.length; i++) {
708
+ if (checkMunicipalityChars(lines[i], name)) {
709
+ lines[i] = name + lines[i];
710
+ }
711
+ }
712
+ cleanAddress = lines.join('\n');
713
+ } else if (checkMunicipalityChars(cleanAddress, name)) {
714
+ cleanAddress = name + cleanAddress;
715
+ }
716
+ });
717
+ return cleanAddress;
718
+ }
719
+
720
+ /**
721
+ * 自动识别地址信息,格式化为省市区街道和收件人等信息
722
+ * @param {string} address 原始地址字符串(可含空格、姓名、手机号等)
723
+ * @param {object} [sourceData] 组件 sourceData,用于四级地址等配置(extraInfo.isFourAddress)
724
+ * @param {object} [options] 可选配置
725
+ * @param {array} [options.areaList] 地址库原始数据,默认从全局 areaList 获取
726
+ * @returns {{name: string, mobile: string, phone: string, zip_code: string, extensionNumber: string, province: string, city: string, area: string, street: string, addr: string, result: *}}
727
+ */
728
+ export function addressParse(address, sourceData, options = {}) {
729
+ const list = getGlobalAreaList(options);
730
+ if (list) {
731
+ parseArea(list);
732
+ }
733
+ const cleanAddress = preprocessAddress(address);
734
+ return parseAddressDetail(cleanAddress, sourceData || {});
735
+ }