index.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import Toast from 'tdesign-miniprogram/toast/index';
  2. import { fetchDeliveryAddress } from '../../../../services/address/fetchAddress';
  3. import { areaData } from '../../../../config/index';
  4. import { resolveAddress, rejectAddress } from '../../../../services/address/list';
  5. const innerPhoneReg = '^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$';
  6. const innerNameReg = '^[a-zA-Z\\d\\u4e00-\\u9fa5]+$';
  7. const labelsOptions = [
  8. { id: 0, name: '家' },
  9. { id: 1, name: '公司' },
  10. ];
  11. Page({
  12. options: {
  13. multipleSlots: true,
  14. },
  15. externalClasses: ['theme-wrapper-class'],
  16. data: {
  17. locationState: {
  18. labelIndex: null,
  19. addressId: '',
  20. addressTag: '',
  21. cityCode: '',
  22. cityName: '',
  23. countryCode: '',
  24. countryName: '',
  25. detailAddress: '',
  26. districtCode: '',
  27. districtName: '',
  28. isDefault: false,
  29. name: '',
  30. phone: '',
  31. provinceCode: '',
  32. provinceName: '',
  33. isEdit: false,
  34. isOrderDetail: false,
  35. isOrderSure: false,
  36. },
  37. areaData: areaData,
  38. labels: labelsOptions,
  39. areaPickerVisible: false,
  40. submitActive: false,
  41. visible: false,
  42. labelValue: '',
  43. columns: 3,
  44. },
  45. privateData: {
  46. verifyTips: '',
  47. },
  48. onLoad(options) {
  49. const { id } = options;
  50. this.init(id);
  51. },
  52. onUnload() {
  53. if (!this.hasSava) {
  54. rejectAddress();
  55. }
  56. },
  57. hasSava: false,
  58. init(id) {
  59. if (id) {
  60. this.getAddressDetail(Number(id));
  61. }
  62. },
  63. getAddressDetail(id) {
  64. fetchDeliveryAddress(id).then((detail) => {
  65. this.setData({ locationState: detail }, () => {
  66. const { isLegal, tips } = this.onVerifyInputLegal();
  67. this.setData({
  68. submitActive: isLegal,
  69. });
  70. this.privateData.verifyTips = tips;
  71. });
  72. });
  73. },
  74. onInputValue(e) {
  75. const { item } = e.currentTarget.dataset;
  76. if (item === 'address') {
  77. const { selectedOptions = [] } = e.detail;
  78. this.setData(
  79. {
  80. 'locationState.provinceCode': selectedOptions[0].value,
  81. 'locationState.provinceName': selectedOptions[0].label,
  82. 'locationState.cityName': selectedOptions[1].label,
  83. 'locationState.cityCode': selectedOptions[1].value,
  84. 'locationState.districtCode': selectedOptions[2].value,
  85. 'locationState.districtName': selectedOptions[2].label,
  86. areaPickerVisible: false,
  87. },
  88. () => {
  89. const { isLegal, tips } = this.onVerifyInputLegal();
  90. this.setData({
  91. submitActive: isLegal,
  92. });
  93. this.privateData.verifyTips = tips;
  94. },
  95. );
  96. } else {
  97. const { value = '' } = e.detail;
  98. this.setData(
  99. {
  100. [`locationState.${item}`]: value,
  101. },
  102. () => {
  103. const { isLegal, tips } = this.onVerifyInputLegal();
  104. this.setData({
  105. submitActive: isLegal,
  106. });
  107. this.privateData.verifyTips = tips;
  108. },
  109. );
  110. }
  111. },
  112. onPickArea() {
  113. this.setData({ areaPickerVisible: true });
  114. },
  115. onPickLabels(e) {
  116. const { item } = e.currentTarget.dataset;
  117. const {
  118. locationState: { labelIndex = undefined },
  119. labels = [],
  120. } = this.data;
  121. let payload = {
  122. labelIndex: item,
  123. addressTag: labels[item].name,
  124. };
  125. if (item === labelIndex) {
  126. payload = { labelIndex: null, addressTag: '' };
  127. }
  128. this.setData({
  129. 'locationState.labelIndex': payload.labelIndex,
  130. });
  131. this.triggerEvent('triggerUpdateValue', payload);
  132. },
  133. addLabels() {
  134. this.setData({
  135. visible: true,
  136. });
  137. },
  138. confirmHandle() {
  139. const { labels, labelValue } = this.data;
  140. this.setData({
  141. visible: false,
  142. labels: [...labels, { id: labels[labels.length - 1].id + 1, name: labelValue }],
  143. labelValue: '',
  144. });
  145. },
  146. cancelHandle() {
  147. this.setData({
  148. visible: false,
  149. labelValue: '',
  150. });
  151. },
  152. onCheckDefaultAddress({ detail }) {
  153. const { value } = detail;
  154. this.setData({
  155. 'locationState.isDefault': value,
  156. });
  157. },
  158. onVerifyInputLegal() {
  159. const { name, phone, detailAddress, districtName } = this.data.locationState;
  160. const prefixPhoneReg = String(this.properties.phoneReg || innerPhoneReg);
  161. const prefixNameReg = String(this.properties.nameReg || innerNameReg);
  162. const nameRegExp = new RegExp(prefixNameReg);
  163. const phoneRegExp = new RegExp(prefixPhoneReg);
  164. if (!name || !name.trim()) {
  165. return {
  166. isLegal: false,
  167. tips: '请填写收货人',
  168. };
  169. }
  170. if (!nameRegExp.test(name)) {
  171. return {
  172. isLegal: false,
  173. tips: '收货人仅支持输入中文、英文(区分大小写)、数字',
  174. };
  175. }
  176. if (!phone || !phone.trim()) {
  177. return {
  178. isLegal: false,
  179. tips: '请填写手机号',
  180. };
  181. }
  182. if (!phoneRegExp.test(phone)) {
  183. return {
  184. isLegal: false,
  185. tips: '请填写正确的手机号',
  186. };
  187. }
  188. if (!districtName || !districtName.trim()) {
  189. return {
  190. isLegal: false,
  191. tips: '请选择省市区信息',
  192. };
  193. }
  194. if (!detailAddress || !detailAddress.trim()) {
  195. return {
  196. isLegal: false,
  197. tips: '请完善详细地址',
  198. };
  199. }
  200. if (detailAddress && detailAddress.trim().length > 50) {
  201. return {
  202. isLegal: false,
  203. tips: '详细地址不能超过50个字符',
  204. };
  205. }
  206. return {
  207. isLegal: true,
  208. tips: '添加成功',
  209. };
  210. },
  211. builtInSearch({ code, name }) {
  212. return new Promise((resolve, reject) => {
  213. wx.getSetting({
  214. success: (res) => {
  215. if (res.authSetting[code] === false) {
  216. wx.showModal({
  217. title: `获取${name}失败`,
  218. content: `获取${name}失败,请在【右上角】-小程序【设置】项中,将【${name}】开启。`,
  219. confirmText: '去设置',
  220. confirmColor: '#FA550F',
  221. cancelColor: '取消',
  222. success(res) {
  223. if (res.confirm) {
  224. wx.openSetting({
  225. success(settinRes) {
  226. if (settinRes.authSetting[code] === true) {
  227. resolve();
  228. } else {
  229. console.warn('用户未打开权限', name, code);
  230. reject();
  231. }
  232. },
  233. });
  234. } else {
  235. reject();
  236. }
  237. },
  238. fail() {
  239. reject();
  240. },
  241. });
  242. } else {
  243. resolve();
  244. }
  245. },
  246. fail() {
  247. reject();
  248. },
  249. });
  250. });
  251. },
  252. onSearchAddress() {
  253. this.builtInSearch({ code: 'scope.userLocation', name: '地址位置' }).then(() => {
  254. wx.chooseLocation({
  255. success: (res) => {
  256. if (res.name) {
  257. this.triggerEvent('addressParse', {
  258. address: res.address,
  259. name: res.name,
  260. latitude: res.latitude,
  261. longitude: res.longitude,
  262. });
  263. } else {
  264. Toast({
  265. context: this,
  266. selector: '#t-toast',
  267. message: '地点为空,请重新选择',
  268. icon: '',
  269. duration: 1000,
  270. });
  271. }
  272. },
  273. fail: function (res) {
  274. console.warn(`wx.chooseLocation fail: ${JSON.stringify(res)}`);
  275. if (res.errMsg !== 'chooseLocation:fail cancel') {
  276. Toast({
  277. context: this,
  278. selector: '#t-toast',
  279. message: '地点错误,请重新选择',
  280. icon: '',
  281. duration: 1000,
  282. });
  283. }
  284. },
  285. });
  286. });
  287. },
  288. formSubmit() {
  289. const { submitActive } = this.data;
  290. if (!submitActive) {
  291. Toast({
  292. context: this,
  293. selector: '#t-toast',
  294. message: this.privateData.verifyTips,
  295. icon: '',
  296. duration: 1000,
  297. });
  298. return;
  299. }
  300. const { locationState } = this.data;
  301. this.hasSava = true;
  302. resolveAddress({
  303. saasId: '88888888',
  304. uid: `88888888205500`,
  305. authToken: null,
  306. id: locationState.addressId,
  307. addressId: locationState.addressId,
  308. phone: locationState.phone,
  309. name: locationState.name,
  310. countryName: locationState.countryName,
  311. countryCode: locationState.countryCode,
  312. provinceName: locationState.provinceName,
  313. provinceCode: locationState.provinceCode,
  314. cityName: locationState.cityName,
  315. cityCode: locationState.cityCode,
  316. districtName: locationState.districtName,
  317. districtCode: locationState.districtCode,
  318. detailAddress: locationState.detailAddress,
  319. isDefault: locationState.isDefault === 1 ? 1 : 0,
  320. addressTag: locationState.addressTag,
  321. latitude: locationState.latitude,
  322. longitude: locationState.longitude,
  323. storeId: null,
  324. });
  325. wx.navigateBack({ delta: 1 });
  326. },
  327. getWeixinAddress(e) {
  328. const { locationState } = this.data;
  329. const weixinAddress = e.detail;
  330. this.setData(
  331. {
  332. locationState: { ...locationState, ...weixinAddress },
  333. },
  334. () => {
  335. const { isLegal, tips } = this.onVerifyInputLegal();
  336. this.setData({
  337. submitActive: isLegal,
  338. });
  339. this.privateData.verifyTips = tips;
  340. },
  341. );
  342. },
  343. });