@rolatech/angular-order 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/lib/components/order-course-item/order-course-item.component.mjs +19 -0
- package/esm2022/lib/components/order-item/order-item.component.mjs +26 -0
- package/esm2022/lib/components/order-product-item/order-product-item.component.mjs +23 -0
- package/esm2022/lib/components/order-return-request/order-return-request.component.mjs +19 -0
- package/esm2022/lib/components/order-variant-item/order-variant-item.component.mjs +12 -0
- package/esm2022/lib/interfaces/index.mjs +2 -0
- package/esm2022/lib/interfaces/order.mjs +64 -0
- package/esm2022/lib/orders.routes.mjs +18 -0
- package/esm2022/lib/pages/order-detail/order-detail.component.mjs +156 -0
- package/esm2022/lib/pages/order-qrcodepay/order-qrcodepay.component.mjs +70 -0
- package/esm2022/lib/pages/orders-index/order-index.component.mjs +87 -0
- package/esm2022/rolatech-angular-order.mjs +5 -0
- package/fesm2022/rolatech-angular-order.mjs +453 -0
- package/fesm2022/rolatech-angular-order.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/lib/components/order-course-item/order-course-item.component.d.ts +8 -0
- package/lib/components/order-item/order-item.component.d.ts +10 -0
- package/lib/components/order-product-item/order-product-item.component.d.ts +11 -0
- package/lib/components/order-return-request/order-return-request.component.d.ts +7 -0
- package/lib/components/order-variant-item/order-variant-item.component.d.ts +5 -0
- package/lib/interfaces/index.d.ts +1 -0
- package/lib/interfaces/order.d.ts +103 -0
- package/lib/orders.routes.d.ts +2 -0
- package/lib/pages/order-detail/order-detail.component.d.ts +36 -0
- package/lib/pages/order-qrcodepay/order-qrcodepay.component.d.ts +22 -0
- package/lib/pages/orders-index/order-index.component.d.ts +27 -0
- package/package.json +25 -0
- package/src/assets/pay_wechat.png +0 -0
- package/themes/_default.scss +1 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, computed, Component, inject, output, model, Renderer2, viewChild } from '@angular/core';
|
|
3
|
+
import { Title } from '@angular/platform-browser';
|
|
4
|
+
import * as i1 from '@angular/router';
|
|
5
|
+
import { ActivatedRoute, RouterModule, RouterLink } from '@angular/router';
|
|
6
|
+
import { ImagePlaceholderComponent, ThumbnailComponent, ContainerComponent, TabsComponent, TabComponent, ToolbarComponent, ListComponent, EmptyComponent, BaseComponent, SpinnerComponent, TitleComponent } from '@rolatech/angular-components';
|
|
7
|
+
import { OrderService, ProductService, NavigationService } from '@rolatech/angular-services';
|
|
8
|
+
import * as i3 from '@angular/material/icon';
|
|
9
|
+
import { MatIconModule, MatIcon } from '@angular/material/icon';
|
|
10
|
+
import { NgClass, CommonModule, AsyncPipe } from '@angular/common';
|
|
11
|
+
import { sumBy } from 'lodash';
|
|
12
|
+
import * as i1$1 from '@angular/material/button';
|
|
13
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
14
|
+
import moment from 'moment';
|
|
15
|
+
import { map } from 'rxjs';
|
|
16
|
+
import { CourseType, CourseService } from '@rolatech/angular-course';
|
|
17
|
+
import * as i1$2 from '@angular/material/form-field';
|
|
18
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
19
|
+
import * as i2 from '@angular/material/input';
|
|
20
|
+
import { MatInputModule } from '@angular/material/input';
|
|
21
|
+
import * as QRCode from 'qrcode';
|
|
22
|
+
|
|
23
|
+
var OrderStatus;
|
|
24
|
+
(function (OrderStatus) {
|
|
25
|
+
OrderStatus[OrderStatus["CREATED"] = '待付款'] = "CREATED";
|
|
26
|
+
OrderStatus[OrderStatus["PAID"] = '已支付'] = "PAID";
|
|
27
|
+
OrderStatus[OrderStatus["COMPLETED"] = '已完成'] = "COMPLETED";
|
|
28
|
+
OrderStatus[OrderStatus["CLOSED"] = '交易关闭'] = "CLOSED";
|
|
29
|
+
OrderStatus[OrderStatus["CANCELED"] = '交易取消'] = "CANCELED";
|
|
30
|
+
OrderStatus[OrderStatus["REFUNDED"] = '已退款'] = "REFUNDED";
|
|
31
|
+
})(OrderStatus || (OrderStatus = {}));
|
|
32
|
+
var OrderType;
|
|
33
|
+
(function (OrderType) {
|
|
34
|
+
OrderType[OrderType["COURSE"] = '课程'] = "COURSE";
|
|
35
|
+
OrderType[OrderType["PRODUCT"] = '商品'] = "PRODUCT";
|
|
36
|
+
OrderType[OrderType["BOOKING"] = '预定'] = "BOOKING";
|
|
37
|
+
})(OrderType || (OrderType = {}));
|
|
38
|
+
var OrderReturnStatus;
|
|
39
|
+
(function (OrderReturnStatus) {
|
|
40
|
+
OrderReturnStatus[OrderReturnStatus["CREATED"] = '等待审核'] = "CREATED";
|
|
41
|
+
OrderReturnStatus[OrderReturnStatus["CANCELED"] = '用户取消'] = "CANCELED";
|
|
42
|
+
OrderReturnStatus[OrderReturnStatus["APPROVED"] = '已通过'] = "APPROVED";
|
|
43
|
+
OrderReturnStatus[OrderReturnStatus["REJECTED"] = '已拒绝'] = "REJECTED";
|
|
44
|
+
OrderReturnStatus[OrderReturnStatus["PROCESSING"] = '平台处理中'] = "PROCESSING";
|
|
45
|
+
OrderReturnStatus[OrderReturnStatus["RETURNED"] = '已退款'] = "RETURNED";
|
|
46
|
+
})(OrderReturnStatus || (OrderReturnStatus = {}));
|
|
47
|
+
var OrderItemStatus;
|
|
48
|
+
(function (OrderItemStatus) {
|
|
49
|
+
OrderItemStatus[OrderItemStatus["CREATED"] = '创建'] = "CREATED";
|
|
50
|
+
OrderItemStatus[OrderItemStatus["CANCELED"] = '已取消'] = "CANCELED";
|
|
51
|
+
OrderItemStatus[OrderItemStatus["CLOSED"] = '已关闭'] = "CLOSED";
|
|
52
|
+
OrderItemStatus[OrderItemStatus["RETURN_REQUESTED"] = '等待审核'] = "RETURN_REQUESTED";
|
|
53
|
+
OrderItemStatus[OrderItemStatus["RETURN_APPROVED"] = '商家同意退款'] = "RETURN_APPROVED";
|
|
54
|
+
OrderItemStatus[OrderItemStatus["RETURN_REJECTED"] = '商家拒绝退款'] = "RETURN_REJECTED";
|
|
55
|
+
OrderItemStatus[OrderItemStatus["RETURN_PROCESSING"] = '退款处理中'] = "RETURN_PROCESSING";
|
|
56
|
+
OrderItemStatus[OrderItemStatus["REFUNDED"] = '已退款'] = "REFUNDED";
|
|
57
|
+
})(OrderItemStatus || (OrderItemStatus = {}));
|
|
58
|
+
var OrderTimelineStatus;
|
|
59
|
+
(function (OrderTimelineStatus) {
|
|
60
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_CREATE"] = '交易创建'] = "ORDER_CREATE";
|
|
61
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_CLOSED"] = '交易关闭'] = "ORDER_CLOSED";
|
|
62
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_CANCELED"] = '交易取消'] = "ORDER_CANCELED";
|
|
63
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_PAID"] = '订单已支付'] = "ORDER_PAID";
|
|
64
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_REFUNDED"] = '订单已退款'] = "ORDER_REFUNDED";
|
|
65
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_COMPLETED"] = '订单已完成'] = "ORDER_COMPLETED";
|
|
66
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_RETURN_REQUESTED"] = '退款申请'] = "ORDER_RETURN_REQUESTED";
|
|
67
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_RETURN_APPROVED"] = '商家同意退款'] = "ORDER_RETURN_APPROVED";
|
|
68
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_RETURN_REJECTED"] = '商家拒绝退款'] = "ORDER_RETURN_REJECTED";
|
|
69
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_RETURN_PROCESSING"] = '退款处理中'] = "ORDER_RETURN_PROCESSING";
|
|
70
|
+
OrderTimelineStatus[OrderTimelineStatus["ORDER_RETURN_REFUNDED"] = '退款处理完成,已入账'] = "ORDER_RETURN_REFUNDED";
|
|
71
|
+
})(OrderTimelineStatus || (OrderTimelineStatus = {}));
|
|
72
|
+
var OrderPayoutStatus;
|
|
73
|
+
(function (OrderPayoutStatus) {
|
|
74
|
+
OrderPayoutStatus[OrderPayoutStatus["CREATED"] = '创建'] = "CREATED";
|
|
75
|
+
OrderPayoutStatus[OrderPayoutStatus["PENDING"] = '处理中'] = "PENDING";
|
|
76
|
+
OrderPayoutStatus[OrderPayoutStatus["PAID"] = '已支付'] = "PAID";
|
|
77
|
+
OrderPayoutStatus[OrderPayoutStatus["CANCELED"] = '已取消'] = "CANCELED";
|
|
78
|
+
OrderPayoutStatus[OrderPayoutStatus["FAILED"] = '失败'] = "FAILED";
|
|
79
|
+
})(OrderPayoutStatus || (OrderPayoutStatus = {}));
|
|
80
|
+
var OrderPayoutType;
|
|
81
|
+
(function (OrderPayoutType) {
|
|
82
|
+
OrderPayoutType[OrderPayoutType["BANK"] = '银行转账'] = "BANK";
|
|
83
|
+
OrderPayoutType[OrderPayoutType["CARD"] = '银行卡'] = "CARD";
|
|
84
|
+
OrderPayoutType[OrderPayoutType["WECHAT"] = '微信零钱'] = "WECHAT";
|
|
85
|
+
})(OrderPayoutType || (OrderPayoutType = {}));
|
|
86
|
+
|
|
87
|
+
class OrderItemComponent {
|
|
88
|
+
constructor() {
|
|
89
|
+
this.order = input.required();
|
|
90
|
+
this.status = OrderStatus;
|
|
91
|
+
this.total = computed(() => {
|
|
92
|
+
return (this.order().total / 100).toFixed(2);
|
|
93
|
+
// const price = sumBy(this.order().items, (item: any) => item.total);
|
|
94
|
+
// return (price / 100).toFixed(2);
|
|
95
|
+
});
|
|
96
|
+
this.quantity = computed(() => sumBy(this.order().items, (item) => item.quantity));
|
|
97
|
+
}
|
|
98
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
99
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: OrderItemComponent, isStandalone: true, selector: "rolatech-order-item", inputs: { order: { classPropertyName: "order", publicName: "order", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col hover:bg-[--rt-raised-background] cursor-pointer p-3\">\n <div class=\"flex justify-between w-full mb-2\">\n <span>\u8BA2\u5355\u53F7: {{ order().orderNo }}</span>\n <span class=\"font-medium text-sm\">{{ status[order().status] }}</span>\n </div>\n <div>\n @if (order().items; as items) {\n @if (items.length > 1) {\n } @else {}\n <div class=\"flex flex-col overflow-x-scroll scrollbar-hide\">\n @for (item of items; track $index) {\n <div class=\"flex flex-row py-2\">\n @if (item.media) {\n <div class=\"min-w-24 w-36 object-cover aspect-video rounded-lg mr-3\">\n @defer (on viewport()) {\n <rolatech-thumbnail [src]=\"item.media[0].url + '!w400'\" size=\"medium\"> </rolatech-thumbnail>\n } @placeholder {\n <div class=\"bg-gray-200 h-full w-full object-cover aspect-video rounded-lg\"></div>\n }\n </div>\n } @else {\n <div class=\"min-w-24 w-36 object-cover aspect-video rounded-lg mr-3\">\n <rolatech-image-placeholder></rolatech-image-placeholder>\n </div>\n }\n <div class=\"flex w-full justify-between\">\n <div class=\"flex justify-between w-full\">\n <div>\n <div>{{ item.name }}</div>\n </div>\n <div>\n <div class=\"text-sm\">\u00A5{{ (item.total / 100).toFixed(2) }}</div>\n <div class=\"text-sm mt-2\">\u6570\u91CF{{ item.quantity }}</div>\n </div>\n <!-- <div>\n <div class=\"text-sm\">\u00A5{{ total() }}</div>\n <div class=\"text-sm mt-2\">\u6570\u91CF{{ quantity() }}</div>\n </div> -->\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</div>\n<hr />\n", styles: [".scrollbar-hide::-webkit-scrollbar{display:none}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: ImagePlaceholderComponent, selector: "rolatech-image-placeholder" }], deferBlockDependencies: [() => [ThumbnailComponent]] }); }
|
|
100
|
+
}
|
|
101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderItemComponent, decorators: [{
|
|
102
|
+
type: Component,
|
|
103
|
+
args: [{ selector: 'rolatech-order-item', standalone: true, imports: [MatIconModule, ThumbnailComponent, ImagePlaceholderComponent, NgClass], template: "<div class=\"flex flex-col hover:bg-[--rt-raised-background] cursor-pointer p-3\">\n <div class=\"flex justify-between w-full mb-2\">\n <span>\u8BA2\u5355\u53F7: {{ order().orderNo }}</span>\n <span class=\"font-medium text-sm\">{{ status[order().status] }}</span>\n </div>\n <div>\n @if (order().items; as items) {\n @if (items.length > 1) {\n } @else {}\n <div class=\"flex flex-col overflow-x-scroll scrollbar-hide\">\n @for (item of items; track $index) {\n <div class=\"flex flex-row py-2\">\n @if (item.media) {\n <div class=\"min-w-24 w-36 object-cover aspect-video rounded-lg mr-3\">\n @defer (on viewport()) {\n <rolatech-thumbnail [src]=\"item.media[0].url + '!w400'\" size=\"medium\"> </rolatech-thumbnail>\n } @placeholder {\n <div class=\"bg-gray-200 h-full w-full object-cover aspect-video rounded-lg\"></div>\n }\n </div>\n } @else {\n <div class=\"min-w-24 w-36 object-cover aspect-video rounded-lg mr-3\">\n <rolatech-image-placeholder></rolatech-image-placeholder>\n </div>\n }\n <div class=\"flex w-full justify-between\">\n <div class=\"flex justify-between w-full\">\n <div>\n <div>{{ item.name }}</div>\n </div>\n <div>\n <div class=\"text-sm\">\u00A5{{ (item.total / 100).toFixed(2) }}</div>\n <div class=\"text-sm mt-2\">\u6570\u91CF{{ item.quantity }}</div>\n </div>\n <!-- <div>\n <div class=\"text-sm\">\u00A5{{ total() }}</div>\n <div class=\"text-sm mt-2\">\u6570\u91CF{{ quantity() }}</div>\n </div> -->\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</div>\n<hr />\n", styles: [".scrollbar-hide::-webkit-scrollbar{display:none}.scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}\n"] }]
|
|
104
|
+
}] });
|
|
105
|
+
|
|
106
|
+
class OrderIndexComponent {
|
|
107
|
+
constructor() {
|
|
108
|
+
this.orderService = inject(OrderService);
|
|
109
|
+
this.title = inject(Title);
|
|
110
|
+
this.route = inject(ActivatedRoute);
|
|
111
|
+
this.links = [
|
|
112
|
+
{
|
|
113
|
+
name: '全部',
|
|
114
|
+
icon: 'dashboard',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: '待付款',
|
|
118
|
+
icon: 'category',
|
|
119
|
+
status: 'created',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: '已支付',
|
|
123
|
+
icon: 'category',
|
|
124
|
+
status: 'paid',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: '已退款',
|
|
128
|
+
icon: 'category',
|
|
129
|
+
status: 'refunded',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: '已取消',
|
|
133
|
+
icon: 'category',
|
|
134
|
+
status: 'canceled',
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
this.orders = [];
|
|
138
|
+
this.status = OrderStatus;
|
|
139
|
+
this.select = 0;
|
|
140
|
+
}
|
|
141
|
+
ngOnInit() {
|
|
142
|
+
this.title.setTitle('我的订单 - 拼小课');
|
|
143
|
+
this.route.queryParams.subscribe(({ status }) => {
|
|
144
|
+
this.select = this.links.findIndex((item) => item.status === status);
|
|
145
|
+
this.findOrders(status);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
findOrders(status) {
|
|
149
|
+
const options = {
|
|
150
|
+
sort: 'updatedAt desc',
|
|
151
|
+
};
|
|
152
|
+
if (status) {
|
|
153
|
+
options['filter'] = `status:${status}`;
|
|
154
|
+
}
|
|
155
|
+
this.orderService.me(options).subscribe({
|
|
156
|
+
next: (res) => {
|
|
157
|
+
this.orders = res.data;
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderIndexComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
162
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: OrderIndexComponent, isStandalone: true, selector: "rolatech-order-index", ngImport: i0, template: "<rolatech-container>\n <rolatech-toolbar title=\"\u6211\u7684\u8BA2\u5355\" large>\n <button mat-button>\n <span>\u8FC7\u6EE4</span>\n <mat-icon>tune</mat-icon>\n </button>\n </rolatech-toolbar>\n <rolatech-tabs [select]=\"select\">\n @for (item of links; track item) {\n @if (item.status) {\n <rolatech-tab [label]=\"item.name\" routerLink=\"./\" [queryParams]=\"{ status: item.status }\"></rolatech-tab>\n } @else {\n <rolatech-tab [label]=\"item.name\" routerLink=\"./\"></rolatech-tab>\n }\n }\n </rolatech-tabs>\n <rolatech-list>\n @if (orders) {\n @for (item of orders; track item) {\n <rolatech-order-item [routerLink]=\"['./', item.id]\" [order]=\"item\"></rolatech-order-item>\n }\n } @else {\n <rolatech-empty></rolatech-empty>\n }\n </rolatech-list>\n</rolatech-container>\n", styles: [""], dependencies: [{ kind: "component", type: ContainerComponent, selector: "rolatech-container" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: TabsComponent, selector: "rolatech-tabs", inputs: ["select", "loading"], outputs: ["selectChange"] }, { kind: "component", type: TabComponent, selector: "rolatech-tab", inputs: ["label"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: ListComponent, selector: "rolatech-list" }, { kind: "component", type: OrderItemComponent, selector: "rolatech-order-item", inputs: ["order"] }, { kind: "component", type: EmptyComponent, selector: "rolatech-empty" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
|
|
163
|
+
}
|
|
164
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderIndexComponent, decorators: [{
|
|
165
|
+
type: Component,
|
|
166
|
+
args: [{ selector: 'rolatech-order-index', standalone: true, imports: [
|
|
167
|
+
ContainerComponent,
|
|
168
|
+
RouterModule,
|
|
169
|
+
TabsComponent,
|
|
170
|
+
TabComponent,
|
|
171
|
+
ToolbarComponent,
|
|
172
|
+
ListComponent,
|
|
173
|
+
OrderItemComponent,
|
|
174
|
+
EmptyComponent,
|
|
175
|
+
MatButtonModule,
|
|
176
|
+
MatIconModule,
|
|
177
|
+
], template: "<rolatech-container>\n <rolatech-toolbar title=\"\u6211\u7684\u8BA2\u5355\" large>\n <button mat-button>\n <span>\u8FC7\u6EE4</span>\n <mat-icon>tune</mat-icon>\n </button>\n </rolatech-toolbar>\n <rolatech-tabs [select]=\"select\">\n @for (item of links; track item) {\n @if (item.status) {\n <rolatech-tab [label]=\"item.name\" routerLink=\"./\" [queryParams]=\"{ status: item.status }\"></rolatech-tab>\n } @else {\n <rolatech-tab [label]=\"item.name\" routerLink=\"./\"></rolatech-tab>\n }\n }\n </rolatech-tabs>\n <rolatech-list>\n @if (orders) {\n @for (item of orders; track item) {\n <rolatech-order-item [routerLink]=\"['./', item.id]\" [order]=\"item\"></rolatech-order-item>\n }\n } @else {\n <rolatech-empty></rolatech-empty>\n }\n </rolatech-list>\n</rolatech-container>\n" }]
|
|
178
|
+
}] });
|
|
179
|
+
|
|
180
|
+
class OrderReturnRequestComponent {
|
|
181
|
+
constructor() {
|
|
182
|
+
this.output = output();
|
|
183
|
+
this.reason = model();
|
|
184
|
+
}
|
|
185
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderReturnRequestComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
186
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.1.4", type: OrderReturnRequestComponent, isStandalone: true, selector: "rolatech-order-return-request", inputs: { reason: { classPropertyName: "reason", publicName: "reason", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { output: "output", reason: "reasonChange" }, ngImport: i0, template: "<div class=\"py-2\">\n <h2 class=\"mb-2\">\u5728\u4E0B\u9762\u8F93\u5165\u9000\u6B3E\u7406\u7531</h2>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u9000\u6B3E\u7406\u7531 </mat-label>\n <textarea matInput required [value]=\"reason()\"></textarea>\n </mat-form-field>\n</div>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] }); }
|
|
187
|
+
}
|
|
188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderReturnRequestComponent, decorators: [{
|
|
189
|
+
type: Component,
|
|
190
|
+
args: [{ selector: 'rolatech-order-return-request', standalone: true, imports: [MatFormFieldModule, MatInputModule], template: "<div class=\"py-2\">\n <h2 class=\"mb-2\">\u5728\u4E0B\u9762\u8F93\u5165\u9000\u6B3E\u7406\u7531</h2>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u9000\u6B3E\u7406\u7531 </mat-label>\n <textarea matInput required [value]=\"reason()\"></textarea>\n </mat-form-field>\n</div>\n", styles: ["mat-form-field{width:100%}\n"] }]
|
|
191
|
+
}] });
|
|
192
|
+
|
|
193
|
+
class OrderCourseItemComponent {
|
|
194
|
+
constructor() {
|
|
195
|
+
this.course = input.required();
|
|
196
|
+
this.type = CourseType;
|
|
197
|
+
}
|
|
198
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderCourseItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
199
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: OrderCourseItemComponent, isStandalone: true, selector: "rolatech-order-course-item", inputs: { course: { classPropertyName: "course", publicName: "course", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col\">\n <div class=\"hover:!bg-[--rt-base-background] cursor-pointer py-2\">\n <div class=\"flex justify-between items-center\">\n <div class=\"flex flex-row w-full\">\n <div class=\"w-2/5 sm:w-1/4 aspect-video bg-[--rt-raised-background] h-fit\">\n @if (course().media) {\n <div class=\"object-cover aspect-video\">\n @defer (on viewport()) {\n <rolatech-thumbnail [src]=\"course().media[0].url + '!w400'\" size=\"medium\"> </rolatech-thumbnail>\n } @placeholder {\n <div class=\"bg-[--rt-raised-background] h-full w-full object-cover aspect-video\"></div>\n }\n </div>\n }\n </div>\n <div class=\"w-3/5 sm:w-3/4 ml-3 flex flex-col justify-between\">\n <span class=\"font-bold break-words line-clamp-2\">{{ course().name }}</span>\n <span class=\"text-sm text-gray-600\">\u7C7B\u578B: {{ type[course().type] }}</span>\n </div>\n </div>\n <div class=\"pl-2\">\n <mat-icon>navigate_next</mat-icon>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], deferBlockDependencies: [() => [import('@rolatech/angular-components').then(m => m.ThumbnailComponent)]] }); }
|
|
200
|
+
}
|
|
201
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "18.1.4", ngImport: i0, type: OrderCourseItemComponent, resolveDeferredDeps: () => [import('@rolatech/angular-components').then(m => m.ThumbnailComponent)], resolveMetadata: ThumbnailComponent => ({ decorators: [{
|
|
202
|
+
type: Component,
|
|
203
|
+
args: [{ selector: 'rolatech-order-course-item', standalone: true, imports: [CommonModule, ThumbnailComponent, MatIconModule], template: "<div class=\"flex flex-col\">\n <div class=\"hover:!bg-[--rt-base-background] cursor-pointer py-2\">\n <div class=\"flex justify-between items-center\">\n <div class=\"flex flex-row w-full\">\n <div class=\"w-2/5 sm:w-1/4 aspect-video bg-[--rt-raised-background] h-fit\">\n @if (course().media) {\n <div class=\"object-cover aspect-video\">\n @defer (on viewport()) {\n <rolatech-thumbnail [src]=\"course().media[0].url + '!w400'\" size=\"medium\"> </rolatech-thumbnail>\n } @placeholder {\n <div class=\"bg-[--rt-raised-background] h-full w-full object-cover aspect-video\"></div>\n }\n </div>\n }\n </div>\n <div class=\"w-3/5 sm:w-3/4 ml-3 flex flex-col justify-between\">\n <span class=\"font-bold break-words line-clamp-2\">{{ course().name }}</span>\n <span class=\"text-sm text-gray-600\">\u7C7B\u578B: {{ type[course().type] }}</span>\n </div>\n </div>\n <div class=\"pl-2\">\n <mat-icon>navigate_next</mat-icon>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
204
|
+
}], ctorParameters: null, propDecorators: null }) });
|
|
205
|
+
|
|
206
|
+
class OrderVariantItemComponent {
|
|
207
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderVariantItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
208
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.4", type: OrderVariantItemComponent, isStandalone: true, selector: "rolatech-order-variant-item", ngImport: i0, template: "<p>order-variant-item works!</p>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
209
|
+
}
|
|
210
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderVariantItemComponent, decorators: [{
|
|
211
|
+
type: Component,
|
|
212
|
+
args: [{ selector: 'rolatech-order-variant-item', standalone: true, imports: [CommonModule], template: "<p>order-variant-item works!</p>\n" }]
|
|
213
|
+
}] });
|
|
214
|
+
|
|
215
|
+
class OrderProductItemComponent {
|
|
216
|
+
constructor() {
|
|
217
|
+
this.thumbnail = input();
|
|
218
|
+
this.title = input.required();
|
|
219
|
+
this.description = input();
|
|
220
|
+
this.quantity = input(0);
|
|
221
|
+
this.total = input.required();
|
|
222
|
+
this.priceDisplay = computed(() => {
|
|
223
|
+
return (this.total() / 100)?.toFixed(2);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderProductItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
227
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: OrderProductItemComponent, isStandalone: true, selector: "rolatech-order-product-item", inputs: { thumbnail: { classPropertyName: "thumbnail", publicName: "thumbnail", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, quantity: { classPropertyName: "quantity", publicName: "quantity", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex justify-between py-3\">\n <div class=\"flex w-full\">\n <div class=\"w-1/4 aspect-video bg-gray-200 rounded-lg h-fit\">\n <div class=\"object-cover aspect-video\">\n @defer (on viewport()) {\n <rolatech-thumbnail [src]=\"thumbnail()\" size=\"medium\" mode=\"full\"> </rolatech-thumbnail>\n } @placeholder {\n <div class=\"bg-gray-200 h-full w-full object-cover aspect-video\"></div>\n }\n </div>\n </div>\n <div class=\"w-3/4 ml-3 flex flex-col justify-between\">\n <!-- info -->\n <div class=\"flex justify-between\">\n <div class=\"flex flex-col\">\n <span class=\"text-lg font-bold\">{{ title() }}</span>\n <span class=\"text-sm text-gray-600 mt-2\">{{ description() }}</span>\n </div>\n <div>\u00A5{{ priceDisplay() }}</div>\n </div>\n <!-- action -->\n <div class=\"flex justify-between items-center w-full\">\n <div class=\"flex items-center text-sm\">\n <span class=\"mr-3\">\u6570\u91CF</span>\n <span class=\"w-11 text-center\">{{ quantity() }}</span>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }], deferBlockDependencies: [() => [import('@rolatech/angular-components').then(m => m.ThumbnailComponent)]] }); }
|
|
228
|
+
}
|
|
229
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "18.1.4", ngImport: i0, type: OrderProductItemComponent, resolveDeferredDeps: () => [import('@rolatech/angular-components').then(m => m.ThumbnailComponent)], resolveMetadata: ThumbnailComponent => ({ decorators: [{
|
|
230
|
+
type: Component,
|
|
231
|
+
args: [{ selector: 'rolatech-order-product-item', standalone: true, imports: [CommonModule, ThumbnailComponent, MatIcon], template: "<div class=\"flex justify-between py-3\">\n <div class=\"flex w-full\">\n <div class=\"w-1/4 aspect-video bg-gray-200 rounded-lg h-fit\">\n <div class=\"object-cover aspect-video\">\n @defer (on viewport()) {\n <rolatech-thumbnail [src]=\"thumbnail()\" size=\"medium\" mode=\"full\"> </rolatech-thumbnail>\n } @placeholder {\n <div class=\"bg-gray-200 h-full w-full object-cover aspect-video\"></div>\n }\n </div>\n </div>\n <div class=\"w-3/4 ml-3 flex flex-col justify-between\">\n <!-- info -->\n <div class=\"flex justify-between\">\n <div class=\"flex flex-col\">\n <span class=\"text-lg font-bold\">{{ title() }}</span>\n <span class=\"text-sm text-gray-600 mt-2\">{{ description() }}</span>\n </div>\n <div>\u00A5{{ priceDisplay() }}</div>\n </div>\n <!-- action -->\n <div class=\"flex justify-between items-center w-full\">\n <div class=\"flex items-center text-sm\">\n <span class=\"mr-3\">\u6570\u91CF</span>\n <span class=\"w-11 text-center\">{{ quantity() }}</span>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
232
|
+
}], ctorParameters: null, propDecorators: null }) });
|
|
233
|
+
|
|
234
|
+
class OrderDetailComponent extends BaseComponent {
|
|
235
|
+
constructor() {
|
|
236
|
+
super(...arguments);
|
|
237
|
+
this.status = OrderStatus;
|
|
238
|
+
this.type = CourseType;
|
|
239
|
+
this.orderType = OrderType;
|
|
240
|
+
this.orderService = inject(OrderService);
|
|
241
|
+
this.courseService = inject(CourseService);
|
|
242
|
+
this.productService = inject(ProductService);
|
|
243
|
+
this.navigationService = inject(NavigationService);
|
|
244
|
+
this.info = false;
|
|
245
|
+
this.loadingTimeline = false;
|
|
246
|
+
this.timelineStatus = OrderTimelineStatus;
|
|
247
|
+
this.countDown = '';
|
|
248
|
+
}
|
|
249
|
+
ngOnInit() {
|
|
250
|
+
this.get();
|
|
251
|
+
}
|
|
252
|
+
get() {
|
|
253
|
+
this.orderService.get(this.id).subscribe({
|
|
254
|
+
next: (res) => {
|
|
255
|
+
this.order = res.data;
|
|
256
|
+
if (this.order.type?.toString() === 'PRODUCT') {
|
|
257
|
+
this.getVariant();
|
|
258
|
+
}
|
|
259
|
+
else if (this.order.type?.toString() === 'COURSE') {
|
|
260
|
+
this.getCourse();
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
this.getCourse();
|
|
264
|
+
}
|
|
265
|
+
if (this.order.status === 'CREATED') {
|
|
266
|
+
setInterval(() => {
|
|
267
|
+
const start = moment();
|
|
268
|
+
const end = moment(this.order.createdAt).add(15, 'minute');
|
|
269
|
+
const diff = end.diff(start);
|
|
270
|
+
const duration = moment.duration(diff);
|
|
271
|
+
this.countDown = moment.utc(duration.as('milliseconds')).format('mm:ss');
|
|
272
|
+
}, 1000);
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
back() {
|
|
278
|
+
this.navigationService.back();
|
|
279
|
+
}
|
|
280
|
+
getCourse() {
|
|
281
|
+
const { productId } = this.order.items[0];
|
|
282
|
+
this.course$ = this.courseService.get(productId).pipe(map((res) => res.data));
|
|
283
|
+
}
|
|
284
|
+
getVariant() {
|
|
285
|
+
const { variantId } = this.order.items[0];
|
|
286
|
+
if (variantId) {
|
|
287
|
+
this.productService
|
|
288
|
+
.getVariant(variantId)
|
|
289
|
+
.pipe(map((res) => res.data))
|
|
290
|
+
.subscribe({
|
|
291
|
+
next: (res) => { },
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
refund() {
|
|
296
|
+
const options = {
|
|
297
|
+
width: '500px',
|
|
298
|
+
title: '申请退款',
|
|
299
|
+
height: '90%',
|
|
300
|
+
cancelText: '取消',
|
|
301
|
+
confirmText: '确认',
|
|
302
|
+
component: OrderReturnRequestComponent,
|
|
303
|
+
data: {
|
|
304
|
+
reason: '',
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
this.dialogService.open(options);
|
|
308
|
+
this.dialogService.confirmed().subscribe((res) => {
|
|
309
|
+
if (res) {
|
|
310
|
+
this.orderService.refund(this.id, res).subscribe({
|
|
311
|
+
next: (res) => {
|
|
312
|
+
this.snackBarService.open('退款申请成功, 等待审核');
|
|
313
|
+
},
|
|
314
|
+
error: (error) => {
|
|
315
|
+
this.snackBarService.open(error.message);
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
cancel() {
|
|
322
|
+
this.orderService.cancel(this.id).subscribe({
|
|
323
|
+
next: (res) => {
|
|
324
|
+
this.order.status = OrderStatus[OrderStatus.CANCELED];
|
|
325
|
+
this.snackBarService.open('取消成功');
|
|
326
|
+
},
|
|
327
|
+
error: (error) => {
|
|
328
|
+
this.snackBarService.open(error.message);
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
pay() {
|
|
333
|
+
this.router.navigateByUrl(`/orders/${this.id}/qrcodepay`);
|
|
334
|
+
}
|
|
335
|
+
timeline() {
|
|
336
|
+
this.info = true;
|
|
337
|
+
this.loadingTimeline = true;
|
|
338
|
+
this.orderService.timeline(this.id).subscribe({
|
|
339
|
+
next: (res) => {
|
|
340
|
+
this.timelineData = res.data;
|
|
341
|
+
this.loadingTimeline = false;
|
|
342
|
+
},
|
|
343
|
+
error: (error) => {
|
|
344
|
+
this.loadingTimeline = false;
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderDetailComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
349
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: OrderDetailComponent, isStandalone: true, selector: "rolatech-order-detail", usesInheritance: true, ngImport: i0, template: "@if (order) {\n <rolatech-container>\n <rolatech-toolbar [title]=\"status[order.status]\" large link=\"../\">\n <button mat-button (click)=\"timeline()\">\n <mat-icon>history</mat-icon>\n <span>\u8BA2\u5355\u72B6\u6001</span>\n </button>\n </rolatech-toolbar>\n <div>\n <div>\n @if (order.status === 'CREATED') {\n <div class=\"text-orange-600 font-bold\">\u652F\u4ED8\u5012\u8BA1\u65F6: {{ countDown }}</div>\n }\n </div>\n <div>\n <div>\n @if (course$ | async; as course) {\n <div class=\"text-lg py-3\">\u8BFE\u7A0B\u4FE1\u606F</div>\n <rolatech-order-course-item [routerLink]=\"['/courses/', course.id]\" [course]=\"course\"></rolatech-order-course-item>\n } @else {\n <div class=\"text-lg py-3\">\u5546\u54C1\u4FE1\u606F</div>\n @for (item of order.items; track $index) {\n <!-- [description]=\"variant.options | options\"\n [thumbnail]=\"variant.media ? variant.media[0].url + '!w200' : product.media[0].url + '!w200'\" -->\n <rolatech-order-product-item\n [thumbnail]=\"item.media[0].url + '!w200 '\"\n [routerLink]=\"['/products/', item.productId]\"\n [title]=\"item.name\"\n [total]=\"item.total\"\n [quantity]=\"item.quantity\"\n ></rolatech-order-product-item>\n }\n }\n </div>\n <div class=\"mt-3\">\n <div class=\"text-lg py-3 font-medium\">\u8BA2\u5355\u4FE1\u606F</div>\n <div class=\"flex items-center justify-between py-1\">\n <label class=\"font-medium\">\u8BA2\u5355\u53F7</label>\n <span class=\"text-sm\"> {{ order.orderNo }}</span>\n </div>\n <div class=\"flex items-center justify-between py-1\">\n <label class=\"font-medium\">\u4E0B\u5355\u65F6\u95F4</label>\n <span class=\"text-sm\"> {{ order.createdAt }}</span>\n </div>\n <div class=\"flex items-center justify-between py-1\">\n <label class=\"font-medium\">\u5E94\u4ED8\u91D1\u989D</label>\n <span class=\"text-sm\">\u00A5{{ order.total / 100 }}</span>\n </div>\n </div>\n @if (order.status.toString() === 'CREATED' || order.status.toString() === 'PAID') {\n <div class=\"mt-6\">\n <div class=\"text-lg pb-3 font-medium\">\u652F\u4ED8\u65B9\u5F0F</div>\n <div class=\"flex\">\n <img class=\"w-6 h-6\" src=\"assets/pay_wechat.png\" />\n <span class=\"ml-1\">\u5FAE\u4FE1\u652F\u4ED8</span>\n </div>\n </div>\n }\n </div>\n <!-- safe area -->\n <div class=\"pb-16 sm:pb-3\"></div>\n <div class=\"\">\n @if (order.status.toString() === 'PAID') {\n <button mat-flat-button class=\"w-32 min-h-11\" (click)=\"refund()\">\u7533\u8BF7\u9000\u6B3E</button>\n }\n <div class=\"flex items-center justify-end\">\n @if (order.status.toString() === 'CREATED') {\n <span class=\"underline text-sm underline-offset-4 mr-6 cursor-pointer hover:text-orange-400\" (click)=\"cancel()\"\n >\u53D6\u6D88\u8BA2\u5355</span\n >\n }\n @if (order.status.toString() === 'CREATED') {\n <button mat-flat-button class=\"w-32 min-h-11\" (click)=\"pay()\">\u652F\u4ED8\u8BA2\u5355</button>\n }\n </div>\n </div>\n </div>\n </rolatech-container>\n}\n<div\n [ngClass]=\"info ? 'translate-none' : 'translate-x-full'\"\n class=\"fixed top-0 right-0 z-[1001] h-screen p-4 overflow-y-auto transition-transform bg-[--rt-raised-background] w-80 sm:w-[300px] shadow-xl\"\n>\n <div class=\"flex justify-between items-center sm:p-4\">\n <div class=\"text-xl font-bold\">\u8BA2\u5355\u72B6\u6001</div>\n <button mat-icon-button (click)=\"info = !info\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n @if (!loadingTimeline) {\n <div class=\"mt-3 p-1 sm:p-4\">\n <ol class=\"relative border-l border-[--rt-border-color]\">\n @for (item of timelineData; track item) {\n <li class=\"mb-8 ml-4\">\n <div\n class=\"absolute w-3 h-3 rounded-full mt-1.5 -left-1.5 border border-[--rt-raised-background] bg-[--rt-text-primary]\"\n ></div>\n <div class=\"text-md font-bold mb-1\">{{ timelineStatus[item.status] }}</div>\n @if (item.status === 'BOOKING_RETURN_REJECTED') {\n <div class=\"text-sm mb-1\">{{ item.return.note }}</div>\n }\n @if (item.status === 'BOOKING_RETURN_REQUESTED') {\n <div class=\"text-sm mb-1\">{{ item.return.reason }}</div>\n }\n <div class=\"text-sm text-gray-400\">{{ item.date }}</div>\n </li>\n }\n </ol>\n </div>\n }\n @if (loadingTimeline) {\n <div>\n <rolatech-spinner></rolatech-spinner>\n </div>\n }\n</div>\n<div\n (click)=\"info = !info\"\n [ngClass]=\"info ? 'visible' : 'invisible'\"\n class=\"bg-[--rt-10-percent-layer] fixed inset-0 z-[1000]\"\n></div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i1$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: SpinnerComponent, selector: "rolatech-spinner", inputs: ["title"] }, { kind: "component", type: ContainerComponent, selector: "rolatech-container" }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: OrderCourseItemComponent, selector: "rolatech-order-course-item", inputs: ["course"] }, { kind: "component", type: OrderProductItemComponent, selector: "rolatech-order-product-item", inputs: ["thumbnail", "title", "description", "quantity", "total"] }] }); }
|
|
350
|
+
}
|
|
351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderDetailComponent, decorators: [{
|
|
352
|
+
type: Component,
|
|
353
|
+
args: [{ selector: 'rolatech-order-detail', standalone: true, imports: [
|
|
354
|
+
MatButtonModule,
|
|
355
|
+
MatIconModule,
|
|
356
|
+
RouterLink,
|
|
357
|
+
NgClass,
|
|
358
|
+
AsyncPipe,
|
|
359
|
+
SpinnerComponent,
|
|
360
|
+
ContainerComponent,
|
|
361
|
+
ThumbnailComponent,
|
|
362
|
+
ToolbarComponent,
|
|
363
|
+
TitleComponent,
|
|
364
|
+
OrderCourseItemComponent,
|
|
365
|
+
OrderProductItemComponent,
|
|
366
|
+
OrderVariantItemComponent,
|
|
367
|
+
], template: "@if (order) {\n <rolatech-container>\n <rolatech-toolbar [title]=\"status[order.status]\" large link=\"../\">\n <button mat-button (click)=\"timeline()\">\n <mat-icon>history</mat-icon>\n <span>\u8BA2\u5355\u72B6\u6001</span>\n </button>\n </rolatech-toolbar>\n <div>\n <div>\n @if (order.status === 'CREATED') {\n <div class=\"text-orange-600 font-bold\">\u652F\u4ED8\u5012\u8BA1\u65F6: {{ countDown }}</div>\n }\n </div>\n <div>\n <div>\n @if (course$ | async; as course) {\n <div class=\"text-lg py-3\">\u8BFE\u7A0B\u4FE1\u606F</div>\n <rolatech-order-course-item [routerLink]=\"['/courses/', course.id]\" [course]=\"course\"></rolatech-order-course-item>\n } @else {\n <div class=\"text-lg py-3\">\u5546\u54C1\u4FE1\u606F</div>\n @for (item of order.items; track $index) {\n <!-- [description]=\"variant.options | options\"\n [thumbnail]=\"variant.media ? variant.media[0].url + '!w200' : product.media[0].url + '!w200'\" -->\n <rolatech-order-product-item\n [thumbnail]=\"item.media[0].url + '!w200 '\"\n [routerLink]=\"['/products/', item.productId]\"\n [title]=\"item.name\"\n [total]=\"item.total\"\n [quantity]=\"item.quantity\"\n ></rolatech-order-product-item>\n }\n }\n </div>\n <div class=\"mt-3\">\n <div class=\"text-lg py-3 font-medium\">\u8BA2\u5355\u4FE1\u606F</div>\n <div class=\"flex items-center justify-between py-1\">\n <label class=\"font-medium\">\u8BA2\u5355\u53F7</label>\n <span class=\"text-sm\"> {{ order.orderNo }}</span>\n </div>\n <div class=\"flex items-center justify-between py-1\">\n <label class=\"font-medium\">\u4E0B\u5355\u65F6\u95F4</label>\n <span class=\"text-sm\"> {{ order.createdAt }}</span>\n </div>\n <div class=\"flex items-center justify-between py-1\">\n <label class=\"font-medium\">\u5E94\u4ED8\u91D1\u989D</label>\n <span class=\"text-sm\">\u00A5{{ order.total / 100 }}</span>\n </div>\n </div>\n @if (order.status.toString() === 'CREATED' || order.status.toString() === 'PAID') {\n <div class=\"mt-6\">\n <div class=\"text-lg pb-3 font-medium\">\u652F\u4ED8\u65B9\u5F0F</div>\n <div class=\"flex\">\n <img class=\"w-6 h-6\" src=\"assets/pay_wechat.png\" />\n <span class=\"ml-1\">\u5FAE\u4FE1\u652F\u4ED8</span>\n </div>\n </div>\n }\n </div>\n <!-- safe area -->\n <div class=\"pb-16 sm:pb-3\"></div>\n <div class=\"\">\n @if (order.status.toString() === 'PAID') {\n <button mat-flat-button class=\"w-32 min-h-11\" (click)=\"refund()\">\u7533\u8BF7\u9000\u6B3E</button>\n }\n <div class=\"flex items-center justify-end\">\n @if (order.status.toString() === 'CREATED') {\n <span class=\"underline text-sm underline-offset-4 mr-6 cursor-pointer hover:text-orange-400\" (click)=\"cancel()\"\n >\u53D6\u6D88\u8BA2\u5355</span\n >\n }\n @if (order.status.toString() === 'CREATED') {\n <button mat-flat-button class=\"w-32 min-h-11\" (click)=\"pay()\">\u652F\u4ED8\u8BA2\u5355</button>\n }\n </div>\n </div>\n </div>\n </rolatech-container>\n}\n<div\n [ngClass]=\"info ? 'translate-none' : 'translate-x-full'\"\n class=\"fixed top-0 right-0 z-[1001] h-screen p-4 overflow-y-auto transition-transform bg-[--rt-raised-background] w-80 sm:w-[300px] shadow-xl\"\n>\n <div class=\"flex justify-between items-center sm:p-4\">\n <div class=\"text-xl font-bold\">\u8BA2\u5355\u72B6\u6001</div>\n <button mat-icon-button (click)=\"info = !info\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n @if (!loadingTimeline) {\n <div class=\"mt-3 p-1 sm:p-4\">\n <ol class=\"relative border-l border-[--rt-border-color]\">\n @for (item of timelineData; track item) {\n <li class=\"mb-8 ml-4\">\n <div\n class=\"absolute w-3 h-3 rounded-full mt-1.5 -left-1.5 border border-[--rt-raised-background] bg-[--rt-text-primary]\"\n ></div>\n <div class=\"text-md font-bold mb-1\">{{ timelineStatus[item.status] }}</div>\n @if (item.status === 'BOOKING_RETURN_REJECTED') {\n <div class=\"text-sm mb-1\">{{ item.return.note }}</div>\n }\n @if (item.status === 'BOOKING_RETURN_REQUESTED') {\n <div class=\"text-sm mb-1\">{{ item.return.reason }}</div>\n }\n <div class=\"text-sm text-gray-400\">{{ item.date }}</div>\n </li>\n }\n </ol>\n </div>\n }\n @if (loadingTimeline) {\n <div>\n <rolatech-spinner></rolatech-spinner>\n </div>\n }\n</div>\n<div\n (click)=\"info = !info\"\n [ngClass]=\"info ? 'visible' : 'invisible'\"\n class=\"bg-[--rt-10-percent-layer] fixed inset-0 z-[1000]\"\n></div>\n" }]
|
|
368
|
+
}] });
|
|
369
|
+
|
|
370
|
+
class OrderQrcodepayComponent extends BaseComponent {
|
|
371
|
+
constructor() {
|
|
372
|
+
super(...arguments);
|
|
373
|
+
this.status = OrderStatus;
|
|
374
|
+
this.orderService = inject(OrderService);
|
|
375
|
+
this.renderer = inject(Renderer2);
|
|
376
|
+
this.needPay = true;
|
|
377
|
+
this.qrcElement = viewChild.required('qrcode');
|
|
378
|
+
}
|
|
379
|
+
ngOnInit() {
|
|
380
|
+
this.getOrder();
|
|
381
|
+
}
|
|
382
|
+
getOrder() {
|
|
383
|
+
this.orderService.get(this.id).subscribe({
|
|
384
|
+
next: (res) => {
|
|
385
|
+
this.order = res.data;
|
|
386
|
+
this.needPay = this.order.status.toString() === 'CREATED';
|
|
387
|
+
if (this.needPay) {
|
|
388
|
+
this.getQRCodeUrl();
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
getQRCodeUrl() {
|
|
394
|
+
this.orderService.pay(this.id).subscribe({
|
|
395
|
+
next: (res) => {
|
|
396
|
+
this.genQRCode(res.data.qrCodeUrl);
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
genQRCode(url) {
|
|
401
|
+
const element = this.renderer.createElement('canvas');
|
|
402
|
+
this.toCanvas(element, url)
|
|
403
|
+
.then(() => {
|
|
404
|
+
this.renderElement(element);
|
|
405
|
+
})
|
|
406
|
+
.catch((e) => {
|
|
407
|
+
this.removeElementChildren();
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
toCanvas(canvas, url) {
|
|
411
|
+
return QRCode.toCanvas(canvas, url, {
|
|
412
|
+
errorCorrectionLevel: 'M',
|
|
413
|
+
width: 200,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
renderElement(element) {
|
|
417
|
+
this.removeElementChildren();
|
|
418
|
+
this.renderer.appendChild(this.qrcElement().nativeElement, element);
|
|
419
|
+
}
|
|
420
|
+
removeElementChildren() {
|
|
421
|
+
for (const node of this.qrcElement().nativeElement.childNodes) {
|
|
422
|
+
this.renderer.removeChild(this.qrcElement().nativeElement, node);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderQrcodepayComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
426
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: OrderQrcodepayComponent, isStandalone: true, selector: "rolatech-order-qrcodepay", viewQueries: [{ propertyName: "qrcElement", first: true, predicate: ["qrcode"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (order) {\n <rolatech-container>\n <rolatech-toolbar [title]=\"status[order.status]\" link=\"../\" large></rolatech-toolbar>\n <div>\n <div>\n <a class=\"text-orange-600\" routerLink=\"..\"\n ><span>\u8BA2\u5355: </span><span class=\"underline\">#{{ this.id }}</span></a\n >\n </div>\n <div class=\"mt-6\">\n @if (needPay) {\n <div>\n <div>\u8BF7\u4F7F\u7528\u5FAE\u4FE1\u626B\u7801\u652F\u4ED8, \u6211\u4EEC\u4F1A\u5728\u6536\u5230\u4ED8\u6B3E\u540E\u5904\u7406\u60A8\u7684\u8BA2\u5355</div>\n <div class=\"w-52 h-56 flex flex-col justify-end items-center\">\n <div #qrcode></div>\n <span class=\"text-md\">\u5FAE\u4FE1\u652F\u4ED8\u4E8C\u7EF4\u7801</span>\n </div>\n </div>\n } @else {\n <div>\u8BF7\u786E\u8BA4\u5F53\u524D\u8BA2\u5355\u72B6\u6001, \u5982\u5DF2\u7ECF\u4ED8\u6B3E, \u8BF7\u8FD4\u56DE\u67E5\u770B</div>\n }\n </div>\n </div>\n </rolatech-container>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: ContainerComponent, selector: "rolatech-container" }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }] }); }
|
|
427
|
+
}
|
|
428
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: OrderQrcodepayComponent, decorators: [{
|
|
429
|
+
type: Component,
|
|
430
|
+
args: [{ selector: 'rolatech-order-qrcodepay', standalone: true, imports: [RouterLink, ContainerComponent, ToolbarComponent], template: "@if (order) {\n <rolatech-container>\n <rolatech-toolbar [title]=\"status[order.status]\" link=\"../\" large></rolatech-toolbar>\n <div>\n <div>\n <a class=\"text-orange-600\" routerLink=\"..\"\n ><span>\u8BA2\u5355: </span><span class=\"underline\">#{{ this.id }}</span></a\n >\n </div>\n <div class=\"mt-6\">\n @if (needPay) {\n <div>\n <div>\u8BF7\u4F7F\u7528\u5FAE\u4FE1\u626B\u7801\u652F\u4ED8, \u6211\u4EEC\u4F1A\u5728\u6536\u5230\u4ED8\u6B3E\u540E\u5904\u7406\u60A8\u7684\u8BA2\u5355</div>\n <div class=\"w-52 h-56 flex flex-col justify-end items-center\">\n <div #qrcode></div>\n <span class=\"text-md\">\u5FAE\u4FE1\u652F\u4ED8\u4E8C\u7EF4\u7801</span>\n </div>\n </div>\n } @else {\n <div>\u8BF7\u786E\u8BA4\u5F53\u524D\u8BA2\u5355\u72B6\u6001, \u5982\u5DF2\u7ECF\u4ED8\u6B3E, \u8BF7\u8FD4\u56DE\u67E5\u770B</div>\n }\n </div>\n </div>\n </rolatech-container>\n}\n" }]
|
|
431
|
+
}] });
|
|
432
|
+
|
|
433
|
+
const orderRoutes = [
|
|
434
|
+
{
|
|
435
|
+
path: '',
|
|
436
|
+
component: OrderIndexComponent,
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
path: ':id',
|
|
440
|
+
component: OrderDetailComponent,
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
path: ':id/qrcodepay',
|
|
444
|
+
component: OrderQrcodepayComponent,
|
|
445
|
+
},
|
|
446
|
+
];
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Generated bundle index. Do not edit.
|
|
450
|
+
*/
|
|
451
|
+
|
|
452
|
+
export { OrderItemStatus, OrderPayoutStatus, OrderPayoutType, OrderReturnStatus, OrderStatus, OrderTimelineStatus, OrderType, orderRoutes };
|
|
453
|
+
//# sourceMappingURL=rolatech-angular-order.mjs.map
|