排队支付小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

418 lines
12 KiB

  1. const areaList = require('area-list.js');
  2. const zipCode = require('zipCode.js');
  3. const foramtProvince = require('foramtProvince.js');
  4. let defaultData = [];
  5. const mCity = {};
  6. const mArea = {};
  7. /**
  8. * 处理原始地址数据转换成专用数据
  9. * @param list 原始数据
  10. * @param init 是否初始化 如传空 已转换过不会再次转换
  11. * @returns {boolean}
  12. */
  13. function parseArea(list, init) {
  14. if (!init && defaultData.length) {
  15. return true;
  16. }
  17. defaultData = list;
  18. defaultData.forEach(province => {
  19. if (province.city) {
  20. province.city.forEach(city => {
  21. if (city.name !== '其他') {
  22. if (!mCity[city.name]) {
  23. mCity[city.name] = [];
  24. }
  25. mCity[city.name].push({
  26. p: province.name,
  27. c: city.name,
  28. a: city.area || []
  29. });
  30. }
  31. if (city.area) {
  32. city.area.forEach(area => {
  33. if (area !== '其他') {
  34. if (!mArea[area]) {
  35. mArea[area] = [];
  36. }
  37. mArea[area].push({
  38. p: province.name,
  39. c: city.name
  40. })
  41. }
  42. })
  43. }
  44. })
  45. }
  46. });
  47. }
  48. /**
  49. * 解析邮编
  50. * @param
  51. * @returns <array>
  52. */
  53. function zipCodeFormat() {
  54. let list = []
  55. zipCode.forEach((el) => {
  56. if (el.child) {
  57. el.child.forEach((event) => {
  58. if (event.child) {
  59. event.child.forEach(element => {
  60. list.push(element.zipcode)
  61. })
  62. }
  63. })
  64. }
  65. })
  66. return list;
  67. }
  68. //专用数据处理
  69. let zipCodeList = zipCodeFormat();//邮编
  70. parseArea(areaList);//地址
  71. /**
  72. * 解析
  73. * @param address 任意地址字符串
  74. * @returns {{name: string, mobile: string, detail: string, zip_code: string, phone: string}}
  75. */
  76. function parse(address) {
  77. address = address || '';
  78. const parse = {
  79. name: '',
  80. mobile: '',
  81. detail: '',
  82. zip_code: '',
  83. phone: ''
  84. };
  85. //去除空格...
  86. address = address.replace(/\r\n/g, ' ').replace(/\n/g, ' ').replace(/\t/g, ' ');
  87. address = address.replace(/\s+/g, "");
  88. //自定义去除关键字,可自行添加
  89. const search = ['地址', '收货地址', '收货人', '收件人', '收货', '邮编', '电话', '手机号码', '所在地区','姓名', ':', ':', ';', ';', ',', ',', '。'];
  90. search.forEach(str => {
  91. address = address.replace(new RegExp(str, 'g'), ' ')
  92. });
  93. //多个空格replace为一个
  94. address = address.replace(/ {2,}/g, ' ');
  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. const mobileReg = /(86-[1][0-9]{10})|(86[1][0-9]{10})|([1][0-9]{10})/g;
  99. const mobile = mobileReg.exec(address);
  100. if (mobile) {
  101. parse.mobile = mobile[0];
  102. address = address.replace(mobile[0], ' ')
  103. }
  104. //电话
  105. 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;
  106. const phone = phoneReg.exec(address);
  107. if (phone) {
  108. parse.phone = phone[0];
  109. address = address.replace(phone[0], ' ')
  110. }
  111. //邮编(加入门牌号;考虑到重复邮编问题;去除之前简单的六位数字校验)
  112. for (let index = 0; index < zipCodeList.length; index++) {
  113. if (address.indexOf(zipCodeList[index]) != -1) {
  114. let num = address.indexOf(zipCodeList[index]);
  115. let code = address.slice(num, num + 6);
  116. parse.zip_code = code;
  117. address = address.replace(code, '')
  118. }
  119. }
  120. /*
  121. const zipReg = /([0-9]{6})/g;
  122. const zip = zipReg.exec(address);
  123. if (zip) {
  124. parse.zip_code = zip[0];
  125. address = address.replace(zip[0], '')
  126. }
  127. */
  128. address = address.replace(/ {2,}/, ' ');
  129. let detail = detail_parse_forward(address.trim());
  130. var ignoreArea = detail.province;
  131. if (!detail.city) {
  132. detail = detail_parse(address.trim());
  133. if (detail.area && !detail.city) {
  134. detail = detail_parse(address.trim(), {
  135. ignoreArea: true
  136. });
  137. console.log('smart_parse->ignoreArea(忽略区)');
  138. } else {
  139. // console.log('smart_parse');
  140. }
  141. //这个待完善
  142. const list = address.replace(detail.province, '').replace(detail.city, '').replace(detail.area, '').split(' ').filter(str => str);
  143. //详细住址划分关键字
  144. //注意:只需要填写关键字最后一位即可:比如单元填写元即可!
  145. const address_detail_list = ['室', '楼', '元', '号', '幢', '门', '户'];
  146. if (list.length > 1) {
  147. list.forEach(str => {
  148. if (!parse.name || str && str.length < parse.name.length) {
  149. parse.name = str.trim()
  150. }
  151. });
  152. if (parse.name) {
  153. detail.addr = detail.addr.replace(parse.name, '').trim()
  154. }
  155. } else {//若名字写在详细地址后面,根据address_detail_list进行分割;
  156. let key = [];
  157. address_detail_list.forEach((el) => {
  158. key.push(detail.addr.indexOf(el))
  159. })
  160. var max = key.sort(function (a, b) {
  161. return b - a;
  162. })[0];
  163. if (detail.name) {
  164. parse.name = detail.name
  165. }
  166. if (max != -1) {
  167. let addrBuild = detail.addr.slice(0, max + 1);
  168. let addrNum = detail.addr.replace(addrBuild, '').replace(/[^0-9]+/g, '');
  169. let userName = detail.addr.replace(addrBuild + addrNum, '')
  170. detail.addr = addrBuild + addrNum
  171. parse.name = userName
  172. }
  173. }
  174. } else {
  175. if (detail.name) {
  176. parse.name = detail.name
  177. } else {
  178. const list = detail.addr.split(' ').filter(str => str);
  179. if (list.length > 1) {
  180. parse.name = list[list.length - 1]
  181. }
  182. if (parse.name) {
  183. detail.addr = detail.addr.replace(parse.name, '').trim()
  184. }
  185. }
  186. }
  187. parse.province = detail.province == '' ? ignoreArea : detail.province;
  188. parse.city = detail.city;
  189. parse.area = detail.area;
  190. parse.addr = detail.addr;
  191. parse.result = detail.result;
  192. //添加省以及市(2019.6.21)输出字段后填入省市等等
  193. foramtProvince.forEach(el => {
  194. if (el.name.indexOf(parse.province) == 0) {
  195. parse.province = el.name
  196. }
  197. })
  198. zipCode.forEach(provice => {
  199. if (parse.province.indexOf(provice.name) == 0) {
  200. provice.child.forEach(city => {
  201. if (city.name.indexOf(parse.city) == 0) {
  202. parse.city = city.name
  203. }
  204. })
  205. }
  206. })
  207. return parse;
  208. }
  209. /**
  210. * 正向解析模式
  211. * 从前到后按 province city addr 逐级筛选
  212. * 有city的值即可说明解析成功
  213. * 此模式对地址顺序有要求
  214. * @param address
  215. * @returns {{province: string, city: string, area: string, addr: string}}
  216. */
  217. function detail_parse_forward(address) {
  218. const parse = {
  219. province: '',
  220. city: '',
  221. area: '',
  222. addr: '',
  223. name: '',
  224. };
  225. const provinceKey = ['特别行政区', '古自治区', '维吾尔自治区', '壮族自治区', '回族自治区', '自治区', '省省直辖', '省', '市'];
  226. const cityKey = ['布依族苗族自治州', '苗族侗族自治州', '自治州', '州', '市', '县'];
  227. for (let i in defaultData) {
  228. const province = defaultData[i];
  229. let index = address.indexOf(province.name);
  230. if (index > -1) {
  231. if (index > 0) {
  232. //省份不是在第一位,在省份之前的字段识别为名称
  233. parse.name = address.substr(0, index).trim();
  234. }
  235. parse.province = province.name;
  236. address = address.substr(index + province.name.length);
  237. for (let k in provinceKey) {
  238. if (address.indexOf(provinceKey[k]) === 0) {
  239. address = address.substr(provinceKey[k].length);
  240. }
  241. }
  242. for (let j in province.city) {
  243. const city = province.city[j];
  244. index = address.indexOf(city.name);
  245. if (index > -1 && index < 3) {
  246. parse.city = city.name;
  247. address = address.substr(index + parse.city.length);
  248. for (let k in cityKey) {
  249. if (address.indexOf(cityKey[k]) === 0) {
  250. address = address.substr(cityKey[k].length);
  251. }
  252. }
  253. if (city.area) {
  254. for (let k in city.area) {
  255. const area = city.area[k];
  256. index = address.indexOf(area);
  257. if (index > -1 && index < 3) {
  258. parse.area = area;
  259. address = address.substr(index + parse.area.length);
  260. break;
  261. }
  262. }
  263. }
  264. break;
  265. }
  266. }
  267. parse.addr = address.trim();
  268. break;
  269. }
  270. }
  271. return parse;
  272. }
  273. /**
  274. * 逆向解析 从后往前解析
  275. * 有地区就能大概返回地址了
  276. * @param address
  277. * @param ignoreArea 是否忽视区 因为地址中含有区容易导致匹配错误 山东省蓬莱市黄海花园东区西门宝威学堂 曲荣声收15753572456
  278. * @returns {{province: string, city: string, area: string, name: string, _area: string, addr: string}}
  279. */
  280. function detail_parse(address, {
  281. ignoreArea = false
  282. } = {}) {
  283. const parse = {
  284. province: '',
  285. city: '',
  286. area: '',
  287. name: '',
  288. _area: '',
  289. addr: '',
  290. };
  291. let areaIndex = -1,
  292. cityIndex = -1;
  293. address = address.replace(' ', ' ');
  294. if (!ignoreArea && address.indexOf('县') > -1 || !ignoreArea && address.indexOf('区') > -1 || !ignoreArea && address.indexOf('旗') > -1) {
  295. if (address.indexOf('旗') > -1) {
  296. areaIndex = address.indexOf('旗');
  297. parse.area = address.substr(areaIndex - 1, 2);
  298. }
  299. if (address.indexOf('区') > -1) {
  300. areaIndex = address.indexOf('区');
  301. if (address.lastIndexOf('市', areaIndex) > -1) {
  302. cityIndex = address.lastIndexOf('市', areaIndex);
  303. parse.area = address.substr(cityIndex + 1, areaIndex - cityIndex);
  304. } else {
  305. parse.area = address.substr(areaIndex - 2, 3);
  306. }
  307. }
  308. if (address.indexOf('县') > -1) {
  309. areaIndex = address.lastIndexOf('县');
  310. if (address.lastIndexOf('市', areaIndex) > -1) {
  311. cityIndex = address.lastIndexOf('市', areaIndex);
  312. parse.area = address.substr(cityIndex + 1, areaIndex - cityIndex);
  313. } else {
  314. parse.area = address.substr(areaIndex - 2, 3);
  315. }
  316. }
  317. parse.addr = address.substr(areaIndex + 1);
  318. } else {
  319. if (address.indexOf('市') > -1) {
  320. areaIndex = address.indexOf('市');
  321. console.log(address.split(" "))
  322. if (address.split(" ")[0].indexOf("市") > -1) {
  323. let areindex = address.split(" ")[0].indexOf("市")
  324. parse.area = address.split(" ")[0].substr(0, areindex + 1);
  325. parse.addr = address.split(" ")[0].substr(areindex + 1);
  326. parse.name = address.split(" ")[1]
  327. } else {
  328. let areindex = address.split(" ")[1].indexOf("市")
  329. parse.area = address.split(" ")[1].substr(0, areindex + 1);
  330. parse.addr = address.split(" ")[1].substr(areindex + 1);
  331. parse.name = address.split(" ")[0]
  332. }
  333. } else {
  334. parse.addr = address
  335. }
  336. }
  337. if (address.indexOf('市') > -1 || address.indexOf('盟') > -1 || address.indexOf('州') > -1) {
  338. if (address.indexOf('市') > -1) {
  339. parse._area = address.substr(address.indexOf('市') - 2, 2);
  340. }
  341. if (address.indexOf('盟') > -1 && !mCity[parse._area]) {
  342. parse._area = address.substr(address.indexOf('盟') - 2, 2);
  343. }
  344. if (address.indexOf('州') > -1 && !mCity[parse._area]) {
  345. parse._area = address.substr(address.indexOf('州') - 2, 2);
  346. }
  347. }
  348. parse.area = parse.area.trim();
  349. if (parse.area && mArea[parse.area]) {
  350. if (mArea[parse.area].length === 1) {
  351. parse.province = mArea[parse.area][0].p;
  352. parse.city = mArea[parse.area][0].c
  353. } else {
  354. parse._area = parse._area.trim();
  355. const addr = address.substr(0, areaIndex);
  356. const d = mArea[parse.area].find(item => {
  357. return item.p.indexOf(addr) > -1 || item.c === parse._area;
  358. });
  359. if (d) {
  360. parse.province = d.p;
  361. parse.city = d.c
  362. } else {
  363. parse.result = mArea[parse.area];
  364. }
  365. }
  366. } else {
  367. if (parse._area) {
  368. const city = mCity[parse._area];
  369. if (city) {
  370. parse.province = city[0].p;
  371. parse.city = city[0].c;
  372. parse.addr = address.substr(address.indexOf(parse.city) + parse.city.length + 1);
  373. parse.area = '';
  374. for (let i in city[0].a) {
  375. if (parse.addr.indexOf(city[0].a[i]) === 0) {
  376. parse.area = city[0].a[i];
  377. parse.addr = parse.addr.replace(city[0].a[i], '');
  378. break;
  379. }
  380. }
  381. }
  382. } else {
  383. parse.area = '';
  384. }
  385. }
  386. parse.addr = parse.addr.trim();
  387. return parse
  388. }
  389. export {parseArea}
  390. export {parse};