我目前在一个项目中工作,该项目使用带有 B2C 加速器的 Spartacus 3.2.2 和 SAP Commerce 2011。该项目不遵循传统的购物网站,而是利用 Spartacus 和 SAP Commerce 的功能来实现自己的目的。我们有一个单页访客结帐流程,其中在加载 Angular 组件时使用购物车设置送货地址、付款详细信息和送货模式。
上下文是假设用户有一个表单,他们在其中输入一些信息,如电子邮件和其他一些详细信息,然后单击下一步。将生成一个购物车,其中添加了一个示例产品并关联了电子邮件。用户被重定向到一个页面以查看他们想要提交的信息,该页面是单页访客结帐。当此页面加载时,付款详情、送货地址和送货方式在后台设置,用户不会注意到任何事情。他们点击提交并在后台创建订单,当他们登陆确认页面时,前端将显示其他用户。
问题是当用户在查看信息后提交信息时,订单调用失败并且我们得到“未设置交付模式”并且它是不一致的。
这是我们用于单页访客结帐的示例代码:
@Component({
selector: "review-details",
templateUrl: "./review-details.component.html",
host: { class: "template-component" },
})
export class ReviewDetailsComponent implements OnInit, OnDestroy, AfterViewInit {
hasSetAddress: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
hasSetDeliveryMode: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
hasSetPaymentDetails: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
subscriptions:any = [];
ngOnInit() {
// Just an example address. A proper valid dummy address and region is used for our project.
let address: Address = {
firstName: "No Name",
lastName: "No Name",
email: "NoName@noname.com",
line1: "XYZ Mason Street",
line2: "",
town: "yolotown",
postalCode: "12345",
country: { isocode: "US" },
defaultAddress: false,
region: {
countryIso: "US",
isocode: "US-CA",
isocodeShort: "CA",
name: "California",
},
titleCode: "",
};
let paymentDetails: PaymentDetails = {
cardNumber: "4111111111111111",
expiryMonth: "12",
expiryYear: "2025",
billingAddress: address,
cvn: "123",
accountHolderName: "No Name",
cardType: {
code: "visa",
name: "Visa",
},
defaultPayment: false,
saved: false,
};
}
this.subscriptions = this.subscriptions.concat(
{
key: 'setAddress',
value: this.checkoutDeliveryService.getDeliveryAddress().subscribe((addr: Address) => {
if (_isNil(addr) || (!_isNil(addr) && _isEmpty(addr))) {
this.checkoutDeliveryService.createAndSetAddress(address);
} else {
this.hasSetAddress.next(true);
}
})
},
{
key: 'setDeliveryModeStatus',
value: this.checkoutDeliveryService.getSupportedDeliveryModes().pipe(
withLatestFrom(
this.checkoutDeliveryService
.getSelectedDeliveryMode()
.pipe(map((deliveryMode: DeliveryMode) => deliveryMode && deliveryMode.code ? deliveryMode.code : null))
)
).subscribe(([deliveryModes, code]: [DeliveryMode[], string]) => {
if (_isNil(code)) {
if (!_isNil(deliveryModes) && !_isEmpty(deliveryModes)) {
code = this.checkoutConfigService.getPreferredDeliveryMode(deliveryModes);
if (code) {
this.checkoutDeliveryService.setDeliveryMode(code);
}
}
} else {
this.hasSetDeliveryMode.next(true);
}
})
},
{
key: 'setPaymentDetails',
value: this.checkoutPaymentService.getPaymentDetails().subscribe((paymentInfo: PaymentDetails) => {
if (_isNil(paymentInfo) || (!_isNil(paymentInfo) && _isEmpty(paymentInfo))) {
this.checkoutPaymentService.createPaymentDetails(paymentDetails);
} else {
this.checkoutPaymentService.paymentProcessSuccess();
this.hasSetPaymentDetails.next(true);
}
})
},
{
key: 'placeOrder',
value: this.checkoutService
.getOrderDetails()
.pipe(filter(order => Object.keys(order).length !== 0))
.subscribe(() => {
this.routingService.go({ cxRoute: 'orderConfirmation' });
})
}
)
}
所以现在的问题是:
当它不一致时,我们甚至如何找到这种“未设置交付模式”的根本原因?为了提供更多上下文,对付款、地址和交付模式的请求调用正确,但是当最终购物车对象在请求完成后返回时,我们有时没有设置交付成本。
有没有办法优化代码以排除可能发生的任何竞争条件?考虑到所有添加付款明细、地址和送货方式的操作都是为同一个购物车异步设置的。
任何帮助表示赞赏,甚至欢迎优化想法。
谢谢
参考: