| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
- // import parseAddress from "../../../../utils/address-parse";
- import AddressParse from "address-parse";
- import tickleBehavior, {
- getTickleContext,
- } from "../../../../core/behavior/tickle.behavior";
- import { getAddressDetailByPatientIdMethod } from "../../request";
- import { areaList } from "@vant/area-data";
- import {
- addAddressMethod,
- deleteAddressMethod,
- updateAddressMethod,
- } from "../../request";
- // module/diet/pages/delivery-address/delivery-address.ts
- // import parseAddress from '../../utils/smart-parse-address';
- Page({
- behaviors: [PageContainerBehavior, tickleBehavior],
- properties: {},
- data: {
- type: "",
- areaList,
- id: "",
- formData: {
- id: "",
- provinceCode: "",
- provinceName: "",
- cityCode: "",
- cityName: "",
- areaCode: "",
- areaName: "",
- liaison: "",
- phone: "",
- isDefault: "N",
- detailAddress: "",
- tagList: [],
- },
- region: "", // 展示在输入框的省市区字符串
- regionValue: [], // picker 选中的值
- regionPickerVisible: false,
- tagList: ["家", "公司", "学校"],
- selectedTag: "",
- focusName: false,
- focusPhone: false,
- focusDetail: false,
- smartPasteValue: "",
- smartPasteFocus: false,
- smartPastePlaceholder: "点击此处粘贴地址信息,可快速识别姓名、电话、地址",
- saving: false,
- },
- onClearDetail() {
- this.setData({ detail: "" });
- },
- onRegionConfirm(e: any) {
- this.setData({
- region:
- e.detail.values[0].name +
- ", " +
- e.detail.values[1].name +
- "," +
- e.detail.values[2].name,
- regionValue: e.detail.values,
- regionPickerVisible: false,
- "formData.provinceCode": e.detail.values[0].code,
- "formData.provinceName": e.detail.values[0].name,
- "formData.cityCode": e.detail.values[1].code,
- "formData.cityName": e.detail.values[1].name,
- "formData.areaCode": e.detail.values[2].code,
- "formData.areaName": e.detail.values[2].name,
- });
- },
- onRegionCancel(e: any) {
- this.setData({
- regionPickerVisible: false,
- });
- },
- // 输入框双向绑定
- onInput(e) {
- const { field } = e.currentTarget.dataset;
- // 这里 field 必须是 'name'、'phone'、'detail' 之一
- this.setData({ [field]: e.detail.value });
- },
- // 收货人
- onFocusInput() {
- this.setData({ focusName: true });
- },
- onBlurInput() {
- this.setData({ focusName: false });
- },
- // 手机号
- onFocusPhone() {
- this.setData({ focusPhone: true });
- },
- onBlurPhone() {
- this.setData({ focusPhone: false });
- },
- // 详细地址
- onFocusDetail() {
- this.setData({ focusDetail: true });
- },
- onBlurDetail() {
- this.setData({ focusDetail: false });
- },
- // 地区选择
- onShowRegionPicker() {
- this.setData({ regionPickerVisible: true });
- },
- // 标签选择
- onTagSelect(e) {
- const tag = e.currentTarget.dataset.tag;
- this.setData({ selectedTag: tag });
- },
- // 默认地址开关
- onDefaultChange(e) {
- if (e.detail.value) {
- this.setData({ "formData.isDefault": "Y" });
- } else {
- this.setData({ "formData.isDefault": "N" });
- }
- },
- // 添加地址
- async onAddress(params: any) {
- const res = await addAddressMethod(params);
- wx.showToast({ title: "添加成功", icon: "success" });
- },
- // 更新地址
- async onUpdate(params: any) {
- const res = await updateAddressMethod(params);
- wx.showToast({ title: "更新成功", icon: "success" });
- },
- // 保存
- async onSave() {
- if (this.data.saving) return; // 防重复
- try {
- const { liaison, phone, detailAddress } = this.data.formData;
- if (!liaison) {
- wx.showToast({ title: "收货人为空", icon: "none" });
- return;
- }
- if (!phone) {
- wx.showToast({ title: "手机号为空", icon: "none" });
- return;
- }
- // 手机号校验
- if (!/^1\d{10}$/.test(phone)) {
- wx.showToast({ title: "您填写的手机号有误", icon: "none" });
- return;
- }
- if (!this.data.region) {
- wx.showToast({ title: "所在地区为空", icon: "none" });
- return;
- }
- if (!detailAddress) {
- wx.showToast({ title: "详细地址为空", icon: "none" });
- return;
- }
- this.setData({
- "formData.tagList": [this.data.selectedTag],
- });
- this.setData({ saving: true });
- if (this.data.id) {
- this.data.formData.id = this.data.id;
- await this.onUpdate(this.data.formData);
- } else {
- await this.onAddress(this.data.formData);
- }
- this.setData({ saving: false });
- // 返回上一页(避免 redirectTo 造成 manage-address 重复入栈)
- const pages = getCurrentPages();
- if (pages.length > 1) {
- wx.navigateBack();
- } else {
- // 极端情况下没有上一页(比如被 reLaunch 打开),兜底回地址管理
- wx.redirectTo({
- url: "/module/article/pages/manage-address/manage-address",
- });
- }
- // 保存成功后可自动跳转或提示
- } catch (error: any) {
- wx.showToast({ title: error.errMsg, icon: "none" });
- this.setData({ saving: false }); // 无论成功失败都重置
- }
- },
- // 输入框聚焦
- onSmartPasteFocus() {
- this.setData({
- smartPasteFocus: true,
- smartPastePlaceholder:
- "粘贴或输入地址信息,如:张三,1801889955,上海市浦东新区浦东大道100号,可自动识别并填充文本",
- });
- },
- // 输入框失焦
- onSmartPasteBlur() {
- if (this.data.smartPasteValue) {
- this.setData({
- smartPasteFocus: true,
- });
- } else {
- this.setData({
- smartPasteFocus: false,
- smartPastePlaceholder:
- "点击此处粘贴地址信息,可快速识别姓名、电话、地址",
- });
- }
- },
- // 输入内容
- onSmartPasteInput(e: any) {
- this.setData({ smartPasteValue: e.detail.value });
- },
- // 清空
- onClearSmartPaste() {
- this.setData({ smartPasteValue: "" });
- },
- // 获取省市区编码
- getCodeByName(list: any, name: any) {
- for (const code in list) {
- if (list[code] === name) {
- return code;
- }
- }
- return "";
- },
- // 删除地址
- async onDelete() {
- const that = this;
- wx.showModal({
- title: "确定删除地址?",
- content: "删除后地址不可恢复",
- confirmColor: "#1D6FF6",
- cancelColor: "#999",
- cancelText: "取消",
- confirmText: "删除",
- success: async (res) => {
- if (res.confirm) {
- const res = await deleteAddressMethod(that.data.id);
- wx.showToast({ title: "删除成功", icon: "success" });
- wx.navigateBack();
- }
- },
- });
- },
- // 识别
- async onRecognizeSmartPaste() {
- let value = this.data.smartPasteValue.trim();
- if (!value) return;
- // 1. 统一分隔符,兼容各种输入
- value = value.replace(/[\n,、;;::]/g, ",").replace(/\s+/g, ",");
- // 2. 提取手机号
- const phoneMatch = value.match(/1\\d{10}/);
- let phone = phoneMatch ? phoneMatch[0] : "";
- if (phone) value = value.replace(phone, ",");
- // 3. 提取姓名(2-4个汉字,通常在最前面)
- let name = "";
- let nameMatch = value.match(/^[\\u4e00-\\u9fa5]{2,4}/);
- if (nameMatch) {
- name = nameMatch[0];
- value = value.replace(name, ",");
- }
- // 5. 用智能库进一步解析省市区
- let [result] = AddressParse.parse(this.data.smartPasteValue);
- result = {
- ...result,
- name: result.name,
- phone: result.phone || result.mobile,
- detailAddress: result.details,
- county: result.area,
- provinceCode: result.provinceCode,
- cityCode: result.cityCode,
- areaCode: result.areaCode,
- };
- // 6. 校验
- if (!result.name || !result.phone) {
- wx.showToast({ title: "请按照提示输入正确的地址信息", icon: "none" });
- return;
- }
- if (!/^1\\d{10}$/.test(result.phone)) {
- wx.showToast({ title: "请按照提示输入正确的地址信息", icon: "none" });
- }
- // 7. 省市区识别
- const { province, city, county } = result;
- const { province_list, city_list, county_list } = this.data.areaList;
- if (province && city) {
- const provinceCode = this.getCodeByName(province_list, province);
- const cityCode = this.getCodeByName(city_list, city);
- const areaCode = this.getCodeByName(county_list, county);
- this.setData({
- "formData.provinceName": province,
- "formData.cityName": city,
- "formData.areaName": county || "",
- "formData.provinceCode": provinceCode,
- "formData.cityCode": cityCode,
- "formData.areaCode": areaCode,
- "formData.detailAddress": result.details,
- region: `${province},${city}${county ? "," + county : ""}`,
- });
- } else {
- wx.showToast({ title: "请按照提示输入正确的地址信息", icon: "none" });
- }
- // 其他字段(如姓名、手机号、详细地址)可以单独 setData,不受省市影响
- this.setData({
- "formData.liaison": result.name,
- "formData.phone": result.phone || result.mobile,
- });
- wx.showToast({ title: "已识别", icon: "success" });
- },
- // 获取地址详情
- async getAddressDetail(id: string) {
- try {
- const res = await getAddressDetailByPatientIdMethod(id);
- if (res && res.data) {
- this.setData({
- "formData.isDefault": res.data.isDefault,
- "formData.liaison": res.data.liaison,
- "formData.phone": res.data.phone,
- "formData.detailAddress": res.data.detailAddress,
- "formData.provinceName": res.data.provinceName,
- "formData.cityName": res.data.cityName,
- "formData.areaName": res.data.areaName,
- "formData.provinceCode": res.data.provinceCode,
- "formData.cityCode": res.data.cityCode,
- "formData.areaCode": res.data.areaCode,
- region: `${res.data.provinceName} ${res.data.cityName} ${res.data.areaName}`,
- });
- // 标签
- this.setData({
- "formData.tagList": res.data.tagList,
- });
- this.setData({
- selectedTag: res.data.tagList[0] || "",
- });
- }
- } catch (error: any) {
- getTickleContext.call(this).showWarnMessage(error.errMsg);
- }
- },
- onLoad(options) {
- if (options.id) {
- this.setData({ id: options.id });
- this.getAddressDetail(options.id);
- }
- if (options.type) {
- this.setData({ type: options.type });
- }
- if (options.imported) {
- const imported = JSON.parse(decodeURIComponent(options.imported));
- const { provinceName, cityName, areaName } = imported;
- const { province_list, city_list, county_list } = this.data.areaList;
- if (provinceName && cityName) {
- const provinceCode = this.getCodeByName(province_list, provinceName);
- const cityCode = this.getCodeByName(city_list, cityName);
- const areaCode = this.getCodeByName(county_list, areaName);
- this.setData({
- "formData.isDefault": imported.isDefault || "N",
- "formData.liaison": imported.liaison,
- "formData.phone": imported.phone,
- "formData.detailAddress": imported.detailAddress,
- "formData.provinceName": imported.provinceName,
- "formData.cityName": imported.cityName,
- "formData.areaName": imported.areaName,
- "formData.provinceCode": provinceCode,
- "formData.cityCode": cityCode,
- "formData.areaCode": areaCode,
- region: imported.region,
- });
- this.setData({
- selectedTag: "",
- type: "imported",
- });
- }
- }
- },
- });
|