|
|
@@ -0,0 +1,480 @@
|
|
|
+import DictionariesBehavior from "../../../../core/behavior/dictionaries.behavior";
|
|
|
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
|
|
|
+import { handleWeChatPayment } from "../../../../utils/util";
|
|
|
+import { getAddressListMethod, purchaseOfflineTreatmentMethod } from "../../request";
|
|
|
+import tickleBehavior, {
|
|
|
+ getTickleContext,
|
|
|
+} from "../../../../core/behavior/tickle.behavior";
|
|
|
+
|
|
|
+// module/order/pages/confirme-order/confirme-order.ts
|
|
|
+Page({
|
|
|
+ behaviors: [PageContainerBehavior, DictionariesBehavior, tickleBehavior],
|
|
|
+ properties: {},
|
|
|
+ data: {
|
|
|
+ totalGoodsCount: 0,
|
|
|
+ goodsList: [] as Array<{
|
|
|
+ category: string;
|
|
|
+ goods: Array<{
|
|
|
+ id: string;
|
|
|
+ name: string;
|
|
|
+ description?: string;
|
|
|
+ image: string;
|
|
|
+ price: number;
|
|
|
+ quantity: number;
|
|
|
+ checked: boolean;
|
|
|
+ }>;
|
|
|
+ }>,
|
|
|
+ selectAll: true,
|
|
|
+ selectedCount: 0,
|
|
|
+ totalPrice: 0,
|
|
|
+ remark: '',
|
|
|
+ remarkLength: 0,
|
|
|
+ showDetail: false,
|
|
|
+ isPaymentLoading: false, // 支付加载状态
|
|
|
+ name: "",
|
|
|
+ phone: "",
|
|
|
+ address: "",
|
|
|
+ isDefault: '',
|
|
|
+ provinceName: '',
|
|
|
+ cityName: '',
|
|
|
+ areaName: '',
|
|
|
+ },
|
|
|
+ onLoad(options: any) {
|
|
|
+ if (options.isDefault) {
|
|
|
+ this.setData({
|
|
|
+ isDefault: options.isDefault,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.load('');
|
|
|
+ },
|
|
|
+ onShow() {
|
|
|
+ //先接收用户选择的地址,如果接收到用户选择的地址就用用户选择的,如果没有则使用默认地址
|
|
|
+ const selectedAddress = wx.getStorageSync('selectedAddress');
|
|
|
+ if (selectedAddress && this.data.isDefault === '1') {
|
|
|
+ this.setData({
|
|
|
+ showDetail: false,
|
|
|
+ name: selectedAddress.liaison || "",
|
|
|
+ phone: selectedAddress.phone || "",
|
|
|
+ address: `${selectedAddress.provinceName || ""}${selectedAddress.cityName || ""}${selectedAddress.areaName || ""}${selectedAddress.detailAddress || ""}`,
|
|
|
+ provinceName: selectedAddress.provinceName || "",
|
|
|
+ cityName: selectedAddress.cityName || "",
|
|
|
+ areaName: selectedAddress.areaName || "",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.getDefaultAddress();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onHide() {
|
|
|
+ wx.removeStorageSync('selectedAddress');
|
|
|
+ },
|
|
|
+ observers: {
|
|
|
+ 'goodsList': function () {
|
|
|
+ this.calculateSummary();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取用户的默认地址
|
|
|
+ async getDefaultAddress() {
|
|
|
+ wx.showLoading({ title: "加载中" });
|
|
|
+ try {
|
|
|
+ // 获取所有的地址列表
|
|
|
+ const res = await getAddressListMethod("", "");
|
|
|
+ if (res && res.length > 0) {
|
|
|
+ res.forEach((item: any) => {
|
|
|
+ item.fullAddress = `${item.provinceName} ${item.cityName} ${item.areaName} ${item.detailAddress}`;
|
|
|
+ item.tag = item.tagList[0] || "";
|
|
|
+ });
|
|
|
+
|
|
|
+ // 过滤出默认地址
|
|
|
+ const defaultAddress = res.find((item: any) => item.isDefault === "Y");
|
|
|
+
|
|
|
+ if (defaultAddress) {
|
|
|
+ // 有默认地址,直接渲染在页面上
|
|
|
+ this.setData({
|
|
|
+ showDetail: false,
|
|
|
+ name: defaultAddress.liaison || "",
|
|
|
+ phone: defaultAddress.phone || "",
|
|
|
+ address: `${defaultAddress.provinceName || ""}${defaultAddress.cityName || ""}${defaultAddress.areaName || ""}${defaultAddress.detailAddress || ""}`,
|
|
|
+ addressList: res, // 保存所有地址列表,用于修改地址时使用
|
|
|
+ provinceName: defaultAddress.provinceName || "",
|
|
|
+ cityName: defaultAddress.cityName || "",
|
|
|
+ areaName: defaultAddress.areaName || "",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 没有默认地址,显示"请选择配送地址"
|
|
|
+ this.setData({
|
|
|
+ showDetail: true,
|
|
|
+ name: "",
|
|
|
+ phone: "",
|
|
|
+ address: "",
|
|
|
+ addressList: res, // 保存所有地址列表,用于修改地址时使用
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 没有地址数据
|
|
|
+ this.setData({
|
|
|
+ showDetail: true,
|
|
|
+ name: "",
|
|
|
+ phone: "",
|
|
|
+ address: "",
|
|
|
+ addressList: [],
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ getTickleContext.call(this).showWarnMessage(error.errMsg);
|
|
|
+ // 出错时也显示"请选择配送地址"
|
|
|
+ this.setData({
|
|
|
+ showDetail: true,
|
|
|
+ name: "",
|
|
|
+ phone: "",
|
|
|
+ address: "",
|
|
|
+ addressList: [],
|
|
|
+ });
|
|
|
+ }
|
|
|
+ wx.hideLoading();
|
|
|
+ },
|
|
|
+ // 切换收货地址
|
|
|
+ changeAddress() {
|
|
|
+ wx.navigateTo({
|
|
|
+ url:
|
|
|
+ "/module/article/pages/manage-address/manage-address?type=confirmeOrder",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 订单详情
|
|
|
+ async load(_id: string) {
|
|
|
+ wx.showLoading({ title: "加载中" });
|
|
|
+ try {
|
|
|
+ // 使用存储的selectedGoods数据渲染商品列表
|
|
|
+ const selectedGoods = wx.getStorageSync('selectedGoods') || [];
|
|
|
+ const totalPrice = wx.getStorageSync('totalPrice') || 0;
|
|
|
+
|
|
|
+ if (selectedGoods && selectedGoods.length > 0) {
|
|
|
+ // 使用存储的数据渲染商品列表
|
|
|
+ const goodsList = selectedGoods;
|
|
|
+ let totalGoodsCount = 0;
|
|
|
+ goodsList.forEach((category: any) => {
|
|
|
+ if (category.goods && Array.isArray(category.goods)) {
|
|
|
+ totalGoodsCount += category.goods.length;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.setData({
|
|
|
+ goodsList,
|
|
|
+ totalGoodsCount,
|
|
|
+ totalPrice: parseFloat(totalPrice.toString()),
|
|
|
+ });
|
|
|
+ this.calculateSummary();
|
|
|
+ } else {
|
|
|
+ // 如果没有存储数据,提示用户
|
|
|
+ wx.showToast({
|
|
|
+ title: "暂无商品数据",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ wx.showToast({
|
|
|
+ title: error.errMsg || "加载失败",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ wx.hideLoading();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 立即支付
|
|
|
+ async onPayment() {
|
|
|
+ if (this.data.isPaymentLoading) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.setData({ isPaymentLoading: true });
|
|
|
+ try {
|
|
|
+ // 调用支付接口
|
|
|
+ const items = this.data.goodsList.map((item: any) => {
|
|
|
+ return item.goods.map((goods: any) => {
|
|
|
+ return {
|
|
|
+ id: goods.id,
|
|
|
+ quantity: goods.quantity,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }).flat();
|
|
|
+ const healthAnalysisReportId = wx.getStorageSync('healthAnalysisReportId');
|
|
|
+ const params = {
|
|
|
+ healthAnalysisReportId: healthAnalysisReportId,
|
|
|
+ items,
|
|
|
+ remark: this.data.remark || '',
|
|
|
+ liaison: this.data.name || '',
|
|
|
+ phone: this.data.phone || '',
|
|
|
+ detailAddress: this.data.address || '',
|
|
|
+ provinceName: this.data.provinceName || '',
|
|
|
+ cityName: this.data.cityName || '',
|
|
|
+ areaName: this.data.areaName || '',
|
|
|
+ };
|
|
|
+ if (!healthAnalysisReportId) {
|
|
|
+ wx.showToast({
|
|
|
+ title: "健康评估报告ID不能为空",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ this.setData({ isPaymentLoading: false });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const payResult: any = await purchaseOfflineTreatmentMethod(params);
|
|
|
+ if (payResult) {
|
|
|
+ const paymentParams = payResult;
|
|
|
+ handleWeChatPayment(paymentParams, (_res: any) => {
|
|
|
+ // 支付成功,跳转到成功页面
|
|
|
+ wx.redirectTo({
|
|
|
+ url: "/module/article/pages/success-page/success-page?title=订单支付成功",
|
|
|
+ });
|
|
|
+ }, (error: any) => {
|
|
|
+ this.setData({ isPaymentLoading: false });
|
|
|
+ if (error?.errMsg === 'requestPayment:fail cancel') {
|
|
|
+ // 支付取消跳到支付订单页面
|
|
|
+ wx.navigateBack({ delta: 1 });
|
|
|
+ }
|
|
|
+ // wx.showToast({
|
|
|
+ // title: error?.errMsg || error?.message || "支付失败,请重试",
|
|
|
+ // icon: "none",
|
|
|
+ // });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ wx.showToast({
|
|
|
+ title: "支付失败",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ wx.showToast({
|
|
|
+ title: error.errMsg,
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ } finally {
|
|
|
+ this.setData({ isPaymentLoading: false });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 商品复选框变化
|
|
|
+ onGoodsCheckChange(e: any) {
|
|
|
+ const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
|
|
|
+ const checked = e.detail.checked;
|
|
|
+ const goodsList = this.data.goodsList;
|
|
|
+ const goods = goodsList[categoryIndex].goods[goodsIndex];
|
|
|
+
|
|
|
+ goods.checked = checked;
|
|
|
+
|
|
|
+ // 如果勾选且数量为0,设置为1
|
|
|
+ if (checked && goods.quantity === 0) {
|
|
|
+ goods.quantity = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 单价为0的商品,如果勾选,确保数量为1
|
|
|
+ if (checked && goods.price === 0 && goods.quantity !== 1) {
|
|
|
+ goods.quantity = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 数量变化(加减按钮)
|
|
|
+ onQuantityChange(e: any) {
|
|
|
+ const { categoryIndex, goodsIndex, type } = e.currentTarget.dataset;
|
|
|
+ const goodsList = this.data.goodsList;
|
|
|
+ const goods = goodsList[categoryIndex].goods[goodsIndex];
|
|
|
+
|
|
|
+ // 单价为0的商品数量最多只能是1
|
|
|
+ if (goods.price === 0) {
|
|
|
+ if (type === "plus") {
|
|
|
+ // 如果数量已经是1或更多,不能再加
|
|
|
+ if (goods.quantity >= 1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 如果数量为0,增加到1
|
|
|
+ goods.quantity = 1;
|
|
|
+ goods.checked = true;
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ } else if (type === "minus") {
|
|
|
+ // 点击减号,数量为1时弹出确认对话框
|
|
|
+ if (goods.quantity === 1) {
|
|
|
+ wx.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '您想要删除该商品吗?',
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm) {
|
|
|
+ // 用户确认删除
|
|
|
+ this.removeGoods(categoryIndex, goodsIndex);
|
|
|
+ }
|
|
|
+ // 用户取消,不做任何操作,保持数量为1
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else if (goods.quantity === 0) {
|
|
|
+ // 已经是0,不能再减
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ // 其他情况(理论上不应该出现),确保数量不超过1
|
|
|
+ goods.quantity = Math.min(1, goods.quantity - 1);
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 非0价格商品的正常逻辑
|
|
|
+ if (type === "plus") {
|
|
|
+ const newQuantity = goods.quantity + 1;
|
|
|
+ goods.quantity = newQuantity;
|
|
|
+ if (!goods.checked) {
|
|
|
+ goods.checked = true;
|
|
|
+ }
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ } else if (type === "minus") {
|
|
|
+ // 点击减号
|
|
|
+ if (goods.quantity === 1) {
|
|
|
+ // 数量为1时,点击减号会变为0,弹出确认对话框
|
|
|
+ wx.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '您想要删除该商品吗?',
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm) {
|
|
|
+ // 用户确认删除
|
|
|
+ this.removeGoods(categoryIndex, goodsIndex);
|
|
|
+ }
|
|
|
+ // 用户取消,不做任何操作,保持数量为1
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 数量大于1,正常减少
|
|
|
+ const newQuantity = goods.quantity - 1;
|
|
|
+ goods.quantity = newQuantity;
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 删除商品
|
|
|
+ removeGoods(categoryIndex: number, goodsIndex: number) {
|
|
|
+ const goodsList = JSON.parse(JSON.stringify(this.data.goodsList)); // 深拷贝
|
|
|
+ const category = goodsList[categoryIndex];
|
|
|
+
|
|
|
+ // 从该分类中删除商品
|
|
|
+ category.goods.splice(goodsIndex, 1);
|
|
|
+
|
|
|
+ // 如果该分类没有商品了,删除该分类
|
|
|
+ if (category.goods.length === 0) {
|
|
|
+ goodsList.splice(categoryIndex, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 数量输入
|
|
|
+ onQuantityInput(e: any) {
|
|
|
+ const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
|
|
|
+ const value = parseInt(e.detail.value) || 0;
|
|
|
+ const goodsList = this.data.goodsList;
|
|
|
+ const goods = goodsList[categoryIndex].goods[goodsIndex];
|
|
|
+
|
|
|
+ // 单价为0的商品数量最多只能是1
|
|
|
+ if (goods.price === 0) {
|
|
|
+ if (value > 1) {
|
|
|
+ goods.quantity = 1;
|
|
|
+ } else if (value < 0) {
|
|
|
+ goods.quantity = 0;
|
|
|
+ goods.checked = false;
|
|
|
+ } else {
|
|
|
+ goods.quantity = value;
|
|
|
+ // 如果数量为0,取消勾选
|
|
|
+ if (value === 0) {
|
|
|
+ goods.checked = false;
|
|
|
+ } else if (value > 0 && !goods.checked) {
|
|
|
+ goods.checked = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ goods.quantity = Math.max(0, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.setData({ goodsList });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 数量输入失焦
|
|
|
+ onQuantityBlur(e: any) {
|
|
|
+ const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
|
|
|
+ const goodsList = this.data.goodsList;
|
|
|
+ const goods = goodsList[categoryIndex].goods[goodsIndex];
|
|
|
+
|
|
|
+ // 单价为0的商品数量最多只能是1
|
|
|
+ if (goods.price === 0) {
|
|
|
+ if (goods.quantity > 1) {
|
|
|
+ goods.quantity = 1;
|
|
|
+ } else if (goods.quantity === 0) {
|
|
|
+ // 数量为0,取消勾选
|
|
|
+ goods.checked = false;
|
|
|
+ } else if (goods.quantity > 0 && goods.quantity <= 1) {
|
|
|
+ // 数量在0-1之间,如果已勾选但数量小于1,设置为1
|
|
|
+ if (goods.checked && goods.quantity < 1) {
|
|
|
+ goods.quantity = 1;
|
|
|
+ } else if (!goods.checked && goods.quantity > 0) {
|
|
|
+ // 如果数量大于0但未勾选,自动勾选
|
|
|
+ goods.checked = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 非0价格商品的逻辑
|
|
|
+ if (goods.quantity === 0) {
|
|
|
+ goods.checked = false;
|
|
|
+ } else if (!goods.checked) {
|
|
|
+ // 如果数量大于0且未勾选,自动勾选
|
|
|
+ goods.checked = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.setData({ goodsList });
|
|
|
+ this.calculateSummary();
|
|
|
+ },
|
|
|
+
|
|
|
+ // 计算汇总信息
|
|
|
+ calculateSummary() {
|
|
|
+ const goodsList = this.data.goodsList;
|
|
|
+ let selectedCount = 0;
|
|
|
+ let totalGoodsCount = 0; // 所有选中商品的总数量
|
|
|
+ let totalPrice = 0;
|
|
|
+ let allChecked = true;
|
|
|
+
|
|
|
+ goodsList.forEach((category: any) => {
|
|
|
+ category.goods.forEach((goods: any) => {
|
|
|
+ if (goods.checked && goods.quantity > 0) {
|
|
|
+ selectedCount++; // 已选件数 = 选中的商品种类数
|
|
|
+ totalGoodsCount += goods.quantity; // 累加所有选中商品的数量
|
|
|
+ totalPrice += goods.price * goods.quantity;
|
|
|
+ }
|
|
|
+ if (!goods.checked || goods.quantity === 0) {
|
|
|
+ allChecked = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ this.setData({
|
|
|
+ selectedCount,
|
|
|
+ totalPrice: parseFloat(totalPrice.toFixed(2)),
|
|
|
+ selectAll: allChecked,
|
|
|
+ totalGoodsCount: totalGoodsCount
|
|
|
+ });
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ // 备注输入处理
|
|
|
+ onRemarkInput(e: any) {
|
|
|
+ const value = e.detail.value;
|
|
|
+ const length = value.length;
|
|
|
+
|
|
|
+ // 限制最大长度为200
|
|
|
+ if (length > 200) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.setData({
|
|
|
+ remark: value,
|
|
|
+ remarkLength: length
|
|
|
+ });
|
|
|
+ },
|
|
|
+});
|