diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json
index 743881b3..0dd6cec0 100644
--- a/.hbuilderx/launch.json
+++ b/.hbuilderx/launch.json
@@ -2,7 +2,7 @@
"version" : "1.0",
"configurations" : [
{
- "customPlaygroundType" : "local",
+ "customPlaygroundType" : "device",
"localRepoPath" : "D:/companyproject/mall",
"packageName" : "com.huawei.hisuite",
"playground" : "standard",
diff --git a/pages/main/cart.uvue b/pages/main/cart.uvue
index 58facd48..486d5018 100644
--- a/pages/main/cart.uvue
+++ b/pages/main/cart.uvue
@@ -1,4 +1,4 @@
-
+
@@ -103,6 +103,7 @@
合计:
¥{{ totalPrice }}
+ 会员已省¥{{ memberSavedAmount }}
-
-
-
-
- {{ num }}
-
-
-
- 0
-
-
- ⌫
-
-
-
@@ -415,6 +414,20 @@ const getMethodIcon = (methodId: string): string => {
return '💳'
}
+// 获取支付品牌图片
+const getMethodBrandIcon = (methodId: string): string => {
+ if (methodId === 'wechat') {
+ return '/static/logo.png' // 替换为真实的微信支付图标路径
+ } else if (methodId === 'alipay') {
+ return '/static/logo.png' // 替换为真实的支付宝图标路径
+ } else if (methodId === 'balance') {
+ return '/static/logo.png' // 替换为真实的余额支付图标路径
+ } else if (methodId === 'bankcard') {
+ return '/static/logo.png' // 替换为真实的银行卡支付图标路径
+ }
+ return '/static/logo.png'
+}
+
// 选择支付方式
const selectMethod = (method: PaymentMethodType) => {
if (!method.enabled) {
@@ -426,10 +439,17 @@ const selectMethod = (method: PaymentMethodType) => {
}
selectedMethod.value = method.id
- showPassword.value = method.id === 'balance' || method.id === 'bankcard'
+ // 切换方式时,除非点击支付,否则不自动弹出密码
+ showPassword.value = false
password.value = '' // 清空密码
}
+// 关闭密码弹窗
+const closePasswordPopup = () => {
+ showPassword.value = false
+ password.value = ''
+}
+
// 获取支付按钮文本
const getPayButtonText = (): string => {
if (selectedMethod.value === 'balance' && userBalance.value < amount.value) {
@@ -457,9 +477,9 @@ const getPayButtonText = (): string => {
const confirmPayment = async () => {
if (isPaying.value) return
- // 余额支付检查
- if (selectedMethod.value === 'balance') {
- if (userBalance.value < amount.value) {
+ // 余额支付或银行卡支付检查密码
+ if (selectedMethod.value === 'balance' || selectedMethod.value === 'bankcard') {
+ if (selectedMethod.value === 'balance' && userBalance.value < amount.value) {
uni.showToast({
title: '余额不足',
icon: 'none'
@@ -469,6 +489,7 @@ const confirmPayment = async () => {
if (!showPassword.value) {
showPassword.value = true
+ password.value = ''
return
}
@@ -649,137 +670,133 @@ onUnmounted(() => {
.payment-content {
flex: 1;
/* overflow-y: auto; */
+ background-color: #f8f8f8;
}
-/* 价格明细部分 */
-.price-detail-section {
+.payment-amount-header {
background-color: #ffffff;
- padding: 20px 15px;
- margin-bottom: 10px;
-}
-
-.price-detail {
- padding: 15px;
- background-color: #f8f9fa;
- border-radius: 8px;
- margin-bottom: 15px;
-}
-
-.price-row {
+ padding: 40px 15px;
display: flex;
- justify-content: space-between;
+ flex-direction: column;
align-items: center;
- padding: 8px 0;
+ justify-content: center;
+ margin-bottom: 12px;
}
-.price-row.total {
- border-top: 1px solid #e5e5e5;
- margin-top: 8px;
- padding-top: 15px;
-}
-
-.price-label {
+.amount-label {
font-size: 14px;
- color: #666666;
-}
-
-.price-value {
- font-size: 14px;
- color: #333333;
-}
-
-.price-value.discount {
- color: #4caf50;
-}
-
-.price-value.total-price {
- font-size: 18px;
- color: #ff4757;
- font-weight: bold;
-}
-
-.order-no {
- /* display: block; */
- font-size: 12px;
- color: #999999;
- text-align: center;
-}
-
-.methods-section {
- background-color: #ffffff;
- padding: 20px 15px;
+ color: #666;
margin-bottom: 10px;
}
+.amount-value-row {
+ display: flex;
+ flex-direction: row;
+ align-items: baseline;
+ margin-bottom: 10px;
+}
+
+.amount-currency {
+ font-size: 20px;
+ font-weight: bold;
+ color: #333;
+ margin-right: 4px;
+}
+
+.amount-number {
+ font-size: 40px;
+ font-weight: bold;
+ color: #333;
+}
+
+.order-no-text {
+ font-size: 13px;
+ color: #999;
+}
+
+.methods-section-new {
+ background-color: #ffffff;
+ margin: 0 12px;
+ border-radius: 12px;
+ padding: 15px;
+}
+
+.section-header {
+ margin-bottom: 15px;
+}
+
.section-title {
- /* display: block; */
font-size: 16px;
font-weight: bold;
color: #333333;
- margin-bottom: 15px;
}
.method-list {
display: flex;
flex-direction: column;
- /* gap: 10px; */
}
-.method-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 15px;
- border: 1px solid #e5e5e5;
- border-radius: 8px;
- margin-bottom: 10px;
+.method-item-modern {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ padding: 16px 0;
+ border-bottom: 0.5px solid #f5f5f5;
}
-.method-item.selected {
- border-color: #007aff;
- background-color: #f0f8ff;
+.method-item-modern:last-child {
+ border-bottom: none;
}
.method-left {
- display: flex;
- align-items: center;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
}
-.method-icon {
- font-size: 24px;
- margin-right: 15px;
+.method-img {
+ width: 28px;
+ height: 28px;
+ margin-right: 12px;
}
.method-info {
- display: flex;
- flex-direction: column;
+ display: flex;
+ flex-direction: column;
}
.method-name {
- font-size: 16px;
- font-weight: bold;
- color: #333333;
- margin-bottom: 5px;
+ font-size: 15px;
+ color: #333;
}
.method-desc {
- font-size: 12px;
- color: #999999;
+ font-size: 11px;
+ color: #999;
+ margin-top: 2px;
}
-.method-selected {
- width: 24px;
- height: 24px;
- border-radius: 12px;
- background-color: #007aff;
- display: flex;
- align-items: center;
- justify-content: center;
+.radio-circle {
+ width: 20px;
+ height: 20px;
+ border-radius: 10px;
+ border: 1px solid #ddd;
+ display: flex;
+ align-items: center;
+ justify-content: center;
}
-.selected-icon {
- color: #ffffff;
- font-size: 14px;
+.radio-circle.checked {
+ border-color: #ff5000;
+ background-color: #ff5000;
+}
+
+.radio-inner {
+ width: 10px;
+ height: 10px;
+ border-radius: 5px;
+ background-color: #ffffff;
}
.balance-section {
@@ -817,52 +834,186 @@ onUnmounted(() => {
color: #ff4757;
}
-.password-section {
- background-color: #ffffff;
- padding: 30px 15px;
- text-align: center;
- margin-bottom: 10px;
+/* 密码输入弹窗 */
+.password-popup-mask {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.6);
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ z-index: 1000;
}
-.password-title {
- /* display: block; */
+.password-popup-content {
+ background-color: #ffffff;
+ border-radius: 16px 16px 0 0;
+ padding: 20px 0; /* 减少左右内边距,让键盘撑满 */
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ animation: slideUp 0.3s ease-out;
+ width: 100%;
+}
+
+@keyframes slideUp {
+ from { transform: translateY(100%); }
+ to { transform: translateY(0); }
+}
+
+.popup-header {
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 30px;
+ padding: 0 20px;
+}
+
+.popup-close {
+ font-size: 20px;
+ color: #999;
+ padding: 4px;
+}
+
+.popup-title {
font-size: 16px;
- color: #333333;
+ font-weight: bold;
+ color: #333;
+}
+
+.popup-placeholder {
+ width: 28px;
+}
+
+.popup-amount-info {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
margin-bottom: 30px;
}
-.password-input {
+.popup-amount-label {
+ font-size: 14px;
+ color: #666;
+ margin-bottom: 8px;
+}
+
+.popup-amount-row {
display: flex;
+ flex-direction: row;
+ align-items: baseline;
+}
+
+.popup-currency {
+ font-size: 18px;
+ font-weight: bold;
+ color: #333;
+ margin-right: 2px;
+}
+
+.popup-value {
+ font-size: 32px;
+ font-weight: bold;
+ color: #333;
+}
+
+.password-input-row {
+ display: flex;
+ flex-direction: row;
justify-content: center;
- /* gap: 15px; */
margin-bottom: 20px;
}
-.password-dot {
- width: 12px;
- height: 12px;
- border-radius: 6px;
- background-color: #333333;
+.password-box {
+ width: 45px;
+ height: 45px;
+ border: 1px solid #ddd;
+ border-right: none;
display: flex;
align-items: center;
justify-content: center;
- margin: 0 7.5px;
+ background-color: #f9f9f9;
}
-.password-dot-text {
- color: #ffffff;
- font-size: 8px;
+.password-box:first-child {
+ border-radius: 4px 0 0 4px;
}
-.forgot-password {
- color: #007aff;
- font-size: 14px;
+.password-box:last-child {
+ border-right: 1px solid #ddd;
+ border-radius: 0 4px 4px 0;
+}
+
+.password-dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 5px;
+ background-color: #000;
+}
+
+.forgot-password-link {
+ font-size: 13px;
+ color: #576b95;
+ margin-bottom: 20px;
+}
+
+.password-section {
+ /* 移除旧的样式或保持隐藏 */
+ display: none;
+}
+
+/* 弹窗专用键盘样式 */
+.password-keyboard-popup {
+ width: 100%;
+ background-color: #f5f5f5;
+ padding: 6px;
+ padding-bottom: env(safe-area-inset-bottom);
+}
+
+/* 键盘样式优化 */
+.password-keyboard {
+ display: none; /* 隐藏独立键盘 */
+}
+
+.keyboard-grid {
+ display: flex;
+ flex-wrap: wrap;
+ background-color: #f5f5f5;
+}
+
+.keyboard-key {
+ width: 33.33%;
+ background-color: #ffffff;
+ height: 54px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 3px solid #f5f5f5;
+ box-sizing: border-box;
+ border-radius: 8px;
+}
+
+.keyboard-key:active {
+ background-color: #e0e0e0;
+}
+
+.key-text {
+ font-size: 22px;
+ font-weight: 500;
+ color: #333333;
}
.payment-bottom {
background-color: #ffffff;
- border-top: 1px solid #e5e5e5;
- padding: 15px;
+ border-top: 1px solid #f0f0f0;
+ padding: 12px 16px;
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
display: flex;
align-items: center;
justify-content: space-between;
@@ -870,30 +1021,33 @@ onUnmounted(() => {
.price-summary {
display: flex;
- align-items: flex-end;
+ flex-direction: row;
+ align-items: baseline;
}
.summary-label {
font-size: 14px;
color: #333333;
- margin-right: 5px;
+ margin-right: 4px;
}
.summary-price {
- font-size: 20px;
- color: #ff4757;
+ font-size: 24px;
+ color: #ff5000;
font-weight: bold;
}
.pay-btn {
- background-color: #007aff;
+ background-color: #ff5000;
color: #ffffff;
padding: 0 40px;
- height: 45px;
- border-radius: 22.5px;
+ height: 44px;
+ line-height: 44px;
+ border-radius: 22px;
font-size: 16px;
font-weight: bold;
border: none;
+ margin: 0;
}
.pay-btn.disabled {
diff --git a/pages/mall/consumer/product-detail copy 2.uvue b/pages/mall/consumer/product-detail copy 2.uvue
new file mode 100644
index 00000000..257c510e
--- /dev/null
+++ b/pages/mall/consumer/product-detail copy 2.uvue
@@ -0,0 +1,1815 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentImageIndex + 1 }} / {{ product.images.length }}
+
+
+
+
+
+ ¥{{ product.price }}
+ 会员价 ¥{{ memberPrice }}
+ ¥{{ product.original_price }}
+
+
+ 会员专享 {{ memberDiscount }}折优惠
+
+ {{ product.name }}
+ 已售{{ product.sales }}件 · 库存{{ product.stock }}件
+
+
+
+
+
+
+ {{ merchant.shop_name }}
+
+ 评分: {{ merchant.rating.toFixed(1) }}
+ 销量: {{ merchant.total_sales }}
+
+
+ 进店 ❯
+
+
+
+
+ 功能主治
+ {{ product.usage }}
+
+
+
+
+ 优惠
+
+
+ {{ coupon.name }}
+
+
+ 领券 ❯
+
+
+
+
+ 参数
+
+ {{ getParamsSummary() }}
+
+ ❯
+
+
+
+
+ 规格
+
+ {{ selectedSpec != '' ? selectedSpec : '请选择规格' }}
+
+ ❯
+
+
+
+
+ 数量
+
+
+
+ -
+
+
+
+ +
+
+
+ 库存{{ getAvailableStock() }}件
+
+
+
+
+
+ 商品详情
+ {{ product.description ?? '暂无详细描述' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 客服
+
+
+
+ 购物车
+
+
+
+ {{ isFavorite ? '已收藏' : '收藏' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请选择规格
+
+
+
+
+
+ 规格
+
+
+ {{ getSkuSpecText(sku) }}
+
+
+
+
+
+
+ 数量
+
+
+ -
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 规格
+ {{ product.specification }}
+
+
+ 功能主治
+ {{ product.usage }}
+
+
+ 副作用
+ {{ product.side_effects }}
+
+
+ 注意事项
+ {{ product.precautions }}
+
+
+ 有效期
+ {{ product.expiry_date }}
+
+
+ 储存条件
+ {{ product.storage_conditions }}
+
+
+ 批准文号
+ {{ product.approval_number }}
+
+
+ 标签
+ {{ product.tags!.join(', ') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mall/consumer/product-detail.uvue b/pages/mall/consumer/product-detail.uvue
index 6e39d85d..379ad3da 100644
--- a/pages/mall/consumer/product-detail.uvue
+++ b/pages/mall/consumer/product-detail.uvue
@@ -14,16 +14,30 @@
+
- ¥{{ product.price }}
-
-
- ¥{{ product.original_price }}
+
+
+
+
+
+ ¥
+ {{ memberPrice > 0 && memberPrice < product.price ? memberPrice : product.price }}
+ ¥{{ product.price }}
+ ¥{{ product.original_price }}
+
+
+
+
+ 已省 ¥{{ (product.price - memberPrice).toFixed(2) }}
+
-
-
+
{{ product.name }}
已售{{ product.sales }}件 · 库存{{ product.stock }}件
@@ -137,9 +151,13 @@
-
+
+
+
+ 请选择规格
+
-
-
+
@@ -230,7 +233,7 @@
-
+
@@ -1025,6 +1028,7 @@ const goBack = () => {
flex: 1;
padding: 12px;
box-sizing: border-box;
+ height: 0; /* 配合 flex: 1 实现自适应高度 */
}
/* 模块通用头部 */
diff --git a/pages/mall/consumer/shop-detail.uvue b/pages/mall/consumer/shop-detail.uvue
index c343af45..4e51f619 100644
--- a/pages/mall/consumer/shop-detail.uvue
+++ b/pages/mall/consumer/shop-detail.uvue
@@ -1,4 +1,4 @@
-
+
@@ -853,24 +853,15 @@ const goToProduct = (id: string) => {
background: #fff;
border-radius: 8px;
overflow: hidden;
- width: 48% !important;
+ width: 48%;
margin-bottom: 12px;
- margin-right: 0 !important;
+ margin-right: 2%;
border: 1px solid #f0f0f0;
box-sizing: border-box;
}
-.result-item:nth-child(2n-1) {
- margin-right: 4% !important;
-}
-
.result-item:nth-child(2n) {
- margin-right: 0 !important;
-}
-
-.result-item:hover {
- transform: translateY(-5px);
- box-shadow: 0 5px 15px rgba(0,0,0,0.1);
+ margin-right: 0;
}
.product-image {
@@ -933,22 +924,22 @@ const goToProduct = (id: string) => {
.result-item {
width: 23%;
- margin-right: 2% !important;
+ margin-right: 2%;
}
.result-item:nth-child(2n) {
- margin-right: 2% !important;
+ margin-right: 2%;
}
.result-item:nth-child(4n) {
- margin-right: 0 !important;
+ margin-right: 0;
}
}
/* 大桌面端 (1400px以上) */
@media screen and (min-width: 1400px) {
.result-item {
- width: 23.5%;
+ width: 23%;
}
}
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773220378663.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773220378663.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773220378663.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773220805552.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773220805552.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773220805552.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773221180327.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773221180327.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773221180327.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773221313747.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773221313747.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773221313747.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773277785288.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773277785288.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773277785288.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773278310518.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773278310518.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773278310518.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773278877919.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773278877919.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773278877919.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773278960314.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773278960314.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773278960314.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773279883162.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773279883162.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773279883162.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773279913669.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773279913669.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773279913669.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773279990478.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773279990478.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773279990478.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773281318383.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773281318383.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773281318383.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773281761772.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773281761772.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773281761772.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773284934718.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773284934718.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773284934718.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773285006797.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773285006797.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773285006797.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773285624654.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773285624654.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773285624654.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773285698015.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773285698015.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773285698015.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773298280394.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773298280394.kotlin_module
new file mode 100644
index 00000000..379a9d26
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773298280394.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773298944933.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773298944933.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773298944933.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773298973496.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773298973496.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773298973496.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/META-INF/main-1773299706099.kotlin_module b/unpackage/cache/.app-android/class/META-INF/main-1773299706099.kotlin_module
new file mode 100644
index 00000000..ef915de2
Binary files /dev/null and b/unpackage/cache/.app-android/class/META-INF/main-1773299706099.kotlin_module differ
diff --git a/unpackage/cache/.app-android/class/ktClasss.ser b/unpackage/cache/.app-android/class/ktClasss.ser
index d18d5cf3..d03ac24f 100644
Binary files a/unpackage/cache/.app-android/class/ktClasss.ser and b/unpackage/cache/.app-android/class/ktClasss.ser differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddAddressParams.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddAddressParams.class
index 4d913478..ec64c861 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddAddressParams.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddAddressParams.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address.class
index c529a007..ce3c9ead 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressForm.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressForm.class
index df82b389..6b6dd205 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressForm.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressForm.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressFormReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressFormReactiveObject.class
index c26bbce7..97052504 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressFormReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressFormReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItem.class
index 1eb47b4c..35bd0a90 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItemReactiveObject.class
index 9718033c..7dc16c7a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressReactiveObject.class
index cc18c665..787ae74d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressType.class
index 3cb1a0e7..65426506 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressTypeReactiveObject.class
index 5ae12bbd..568ebe1a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AddressTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address__1.class
index 65590662..a6f82290 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Address__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1$doOnce$1$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1$doOnce$1$1$1$1.class
index 3c1963b1..24ffb194 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1$doOnce$1$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1$doOnce$1$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1.class
index ead054d0..d9ab438b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$request$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$1.class
index 7c14a32e..9be1475e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$2.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$2.class
index e51e3367..99d5dc85 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$2.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion$upload$1$2.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion.class
index 5d0bbc21..e2bf48a4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq.class
index c69349da..fa232fad 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReq.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqOptions.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqOptions.class
index fce2825c..48a815cf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqOptions.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqOptions.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqResponse.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqResponse.class
index 461cb907..9d663cc6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqResponse.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqResponse.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqUploadOptions.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqUploadOptions.class
index 4a2071d6..60047c33 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqUploadOptions.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkReqUploadOptions.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa$select$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa$select$1.class
index 135d04f6..e23988ed 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa$select$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa$select$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa.class
index 8273cb34..32b3da83 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupa.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaCondition.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaCondition.class
index a0f3c216..cf505ffb 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaCondition.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaCondition.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder$executeAs$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder$executeAs$1.class
index d6bdad5e..023f98f2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder$executeAs$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder$executeAs$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder.class
index 72bf7a96..0d1a806e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaQueryBuilder.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1$1$payload$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1$1$payload$1.class
index e0b75fba..4b9d73fa 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1$1$payload$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1$1$payload$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1.class
index 02fe44c1..69366ca1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel$_checkUpdates$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel.class
index 7c390863..ecafd32a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaRealtimeChannel.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSelectOptions.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSelectOptions.class
index f85f0ce9..0cbb2e30 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSelectOptions.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSelectOptions.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSessionInfo.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSessionInfo.class
index 4abb8400..61b4956e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSessionInfo.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSessionInfo.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSignInResult.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSignInResult.class
index 61b85e16..4341a57b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSignInResult.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaSignInResult.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageApi.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageApi.class
index e4a8063b..d9a1c3a5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageApi.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageApi.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket$upload$1$formData$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket$upload$1$formData$1.class
index 3fa7d7e4..bae87e8a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket$upload$1$formData$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket$upload$1$formData$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket.class
index 71048ac0..1dce2e07 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/AkSupaStorageBucket.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecord.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecord.class
index 87f844bd..685800b1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecord.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecord.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecordReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecordReactiveObject.class
index 5b4f4644..14b2ba48 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecordReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BalanceRecordReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard.class
index f82c2191..2c0cc511 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardForm.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardForm.class
index a4d921df..a6d509c3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardForm.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardForm.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardFormReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardFormReactiveObject.class
index d004ae1a..e7e6aeb0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardFormReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardFormReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardReactiveObject.class
index 46232822..844e0a29 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCardReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1.class
index a39e0747..2dc94275 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1ReactiveObject.class
index 3b94e08a..51fd1550 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BankCard__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Brand.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Brand.class
index a32e5e8f..b2c0e622 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Brand.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Brand.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BrandReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BrandReactiveObject.class
index f67a93a7..def896ed 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BrandReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BrandReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerType.class
index 2c67bdf4..7f69f0fc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerTypeReactiveObject.class
index abf371ea..0873b6b2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/BuyerTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CalendarDay.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CalendarDay.class
index 47da709a..02c4e648 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CalendarDay.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CalendarDay.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartGroup.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartGroup.class
index dfc256e4..0eff21b0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartGroup.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartGroup.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartItem.class
index 443f0c8a..7bee0ca2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CartItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Category.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Category.class
index 26eb64a4..440d481e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Category.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Category.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CategoryReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CategoryReactiveObject.class
index 3f271ed3..170f90a1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CategoryReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CategoryReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatMessage.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatMessage.class
index 4253aec4..163f0c9a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatMessage.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatMessage.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatRoom.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatRoom.class
index c326c118..049c8539 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatRoom.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ChatRoom.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemType.class
index a99d6daa..b280cac5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemTypeReactiveObject.class
index 6b8b1e5b..df422fc2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CheckoutItemTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConfirmReceiptResponse.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConfirmReceiptResponse.class
index b5bb88f5..0c3b19c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConfirmReceiptResponse.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConfirmReceiptResponse.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsType.class
index 156cfd07..3e9096b5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsTypeReactiveObject.class
index 4875da81..cc02c8cc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ConsumptionStatsTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Coupon.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Coupon.class
index 4df83d70..d10b863f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Coupon.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Coupon.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponReactiveObject.class
index f330768a..9d69adb0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType.class
index 1de4c296..60d980a2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateTypeReactiveObject.class
index 21eef81f..c26b7005 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1.class
index 1967087f..ef62a407 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1ReactiveObject.class
index 0ad38c7e..eb10437f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTemplateType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponType.class
index 81876249..3474a5c2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTypeReactiveObject.class
index 52f3968f..da85543e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CouponTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CreateOrderParams.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CreateOrderParams.class
index 51e8ac98..7bb0fc53 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CreateOrderParams.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/CreateOrderParams.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoType.class
index aefc6f94..40f2c5f9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoTypeReactiveObject.class
index bf4be3f2..cfbd7f4f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryInfoTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionType.class
index ae3b485e..10d376cd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionTypeReactiveObject.class
index 3c550e50..f9d65b68 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeliveryOptionTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfo.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfo.class
index 81334cdd..97d1e1c5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfo.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfo.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfoReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfoReactiveObject.class
index 0d36903d..ae8d4143 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfoReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceInfoReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceState.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceState.class
index 64174fa1..2a324543 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceState.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceState.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceStateReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceStateReactiveObject.class
index 624352ce..3b12d089 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceStateReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/DeviceStateReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecord.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecord.class
index ad62a8db..31c19355 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecord.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecord.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecordReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecordReactiveObject.class
index cf8714ee..776b1ac1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecordReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExchangeRecordReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetail.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetail.class
index b7ced0cd..68270c04 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetail.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetail.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetailReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetailReactiveObject.class
index 30118a98..73583d62 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetailReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExpiringDetailReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItem.class
index 024e4dbc..8f8aa483 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItemReactiveObject.class
index 4c6923c9..3e702a67 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ExtraInfoItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteType.class
index d1a791cd..4910fea1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteTypeReactiveObject.class
index f31fb1b5..f5d43a10 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FavoriteTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShop.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShop.class
index 436653ab..c3ad6107 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShop.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShop.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShopReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShopReactiveObject.class
index e9c0fc49..4a338ac2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShopReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FollowedShopReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintGroup.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintGroup.class
index 49e09828..af89ef5b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintGroup.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintGroup.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintItemType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintItemType.class
index 4c9ee170..b76df276 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintItemType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintItemType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintSaveType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintSaveType.class
index a08870ea..5f1648cd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintSaveType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintSaveType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintType.class
index d731a26d..459223c1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintTypeReactiveObject.class
index fb505802..a27190e5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/FootprintTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp$Companion.class
index a67a7095..347363cf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp.class
index 90397c89..598bf2c7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenApp.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$addToCart$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$addToCart$1$1.class
index b6c5c717..ce0f02c5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$addToCart$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$addToCart$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$decreaseQuantity$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$decreaseQuantity$1$1.class
index b87abba3..30c56c61 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$decreaseQuantity$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$decreaseQuantity$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$deleteSelectedItems$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$deleteSelectedItems$1$1.class
index 0af233ea..7a06dda6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$deleteSelectedItems$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$deleteSelectedItems$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$goToCheckout$1$selectedItems$2$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$goToCheckout$1$selectedItems$2$1.class
index a1395fef..9fdec653 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$goToCheckout$1$selectedItems$2$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$goToCheckout$1$selectedItems$2$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$increaseQuantity$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$increaseQuantity$1$1.class
index 8a22f3bd..cb1fc3f5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$increaseQuantity$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$increaseQuantity$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$loadCartData$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$loadCartData$1$1.class
index f6b3ff6a..9c09ad7b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$loadCartData$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$loadCartData$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$refreshRecommend$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$refreshRecommend$1$1.class
index 501610ac..54696c95 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$refreshRecommend$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$refreshRecommend$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelect$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelect$1$1.class
index 0e38b036..4e6b68c5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelect$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelect$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelectAll$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelectAll$1$1.class
index 9c7515d4..1ea51935 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelectAll$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleSelectAll$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleShopSelect$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleShopSelect$1$1.class
index 26cc79d7..91638cba 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleShopSelect$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion$setup$1$toggleShopSelect$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion.class
index 2a4ebf12..7f755a08 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart.class
index d4d26e64..c6625e68 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCart.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_addToCart_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_addToCart_fn$1.class
index e016aa66..e2db8d0a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_addToCart_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_addToCart_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadCategories_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadCategories_fn$1.class
index 6fa6dcbf..1fbaf792 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadCategories_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadCategories_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1$1.class
index ddbb5ba0..6d0e56c3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1.class
index 64e081d1..b7502529 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadProducts_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadSubCategories_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadSubCategories_fn$1.class
index d0979a70..8625c3fd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadSubCategories_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_loadSubCategories_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectPrimaryCategory_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectPrimaryCategory_fn$1.class
index f987d354..63a006b4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectPrimaryCategory_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectPrimaryCategory_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectSubCategory_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectSubCategory_fn$1.class
index 89bdbc57..1e527eb3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectSubCategory_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion$setup$1$gen_selectSubCategory_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion.class
index b0edcd18..a155d121 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory.class
index 3813cd26..b76fce9d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainCategory.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$addToCart$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$addToCart$1$1.class
index 353d17c7..743bf81c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$addToCart$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$addToCart$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$doLoadHotProducts$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$doLoadHotProducts$1$1.class
index b6ff652c..7a73e4fe 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$doLoadHotProducts$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$doLoadHotProducts$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadBrands$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadBrands$1$1.class
index fa8d1c74..c3fbc8de 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadBrands$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadBrands$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadCategories$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadCategories$1$1.class
index 92044808..26aac886 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadCategories$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadCategories$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadHotKeywords$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadHotKeywords$1$1.class
index c8126ab8..b01fff86 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadHotKeywords$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadHotKeywords$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadMore$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadMore$1$1.class
index cca6178a..84695364 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadMore$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadMore$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadSubCategories$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadSubCategories$1$1.class
index bb74a45e..09de0c84 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadSubCategories$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$loadSubCategories$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$onRefresh$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$onRefresh$1$1.class
index dea9c631..a73b125b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$onRefresh$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion$setup$1$onRefresh$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion.class
index 4a36e18c..cbde876b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex.class
index fbdd2673..57bdb5a2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMainIndex.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$doUploadImage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$doUploadImage$1.class
new file mode 100644
index 00000000..c4a5d449
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$doUploadImage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_doUploadImage_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_doUploadImage_fn$1.class
new file mode 100644
index 00000000..0e7bc55e
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_doUploadImage_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadChatHistory_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadChatHistory_fn$1.class
index a8d1296f..31892e1b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadChatHistory_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadChatHistory_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadMerchantInfo_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadMerchantInfo_fn$1.class
index 1b5af1e0..c0c51df0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadMerchantInfo_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_loadMerchantInfo_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_setupRealtimeSubscription_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_setupRealtimeSubscription_fn$1.class
index 16d16027..f273bf7f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_setupRealtimeSubscription_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$gen_setupRealtimeSubscription_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$getCurrentTime$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$getCurrentTime$1.class
index cb15728f..fa20e02d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$getCurrentTime$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$getCurrentTime$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$insertEmoji$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$insertEmoji$1.class
index b0a4d46e..71b53d77 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$insertEmoji$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$insertEmoji$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadChatHistory$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadChatHistory$1.class
index 9cbdc3b5..04fadc3e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadChatHistory$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadChatHistory$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadMerchantInfo$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadMerchantInfo$1.class
index c1656add..99105948 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadMerchantInfo$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$loadMerchantInfo$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$onScrollToUpper$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$onScrollToUpper$1.class
index 8c50ada9..ed652b04 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$onScrollToUpper$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$onScrollToUpper$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$previewImage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$previewImage$1.class
new file mode 100644
index 00000000..67e5d226
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$previewImage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$scrollToBottom$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$scrollToBottom$1.class
index 4547d68f..cd9ba35b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$scrollToBottom$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$scrollToBottom$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$sendMessage$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$sendMessage$1$1.class
index 7035044c..23ac6d81 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$sendMessage$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$sendMessage$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$setupRealtimeSubscription$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$setupRealtimeSubscription$1.class
index 07fef24f..1d52f20a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$setupRealtimeSubscription$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$setupRealtimeSubscription$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showEmojiPicker$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showEmojiPicker$1.class
index 51c5afe3..2c6e2394 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showEmojiPicker$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showEmojiPicker$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showImagePicker$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showImagePicker$1.class
index edbb680a..49e62772 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showImagePicker$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showImagePicker$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreActions$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreActions$1.class
index 7b2e83e6..607e51e1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreActions$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreActions$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreTools$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreTools$1.class
index 70803384..964f0a63 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreTools$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion$setup$1$showMoreTools$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion.class
index 1d64ec8b..2fe3c7e4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat.class
index eba2857a..52456b62 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerChat.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$formatSpecs$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$formatSpecs$1.class
index 71f99285..e15bb87b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$formatSpecs$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$formatSpecs$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_initCheckoutData_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_initCheckoutData_fn$1.class
new file mode 100644
index 00000000..a72d5701
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_initCheckoutData_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1$1$1.class
index b2586932..6a99e81d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1.class
index e2dc0874..1f3c81e5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadAddressList_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1$1$1.class
index 3ea686eb..a0a670d3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1.class
index 5ae917e4..b4d1ca27 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadDefaultAddress_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadFromLocalStorage_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadFromLocalStorage_fn$1.class
new file mode 100644
index 00000000..7d593de3
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$gen_loadFromLocalStorage_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getCurrentUserId$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getCurrentUserId$1.class
index 9ea9b21b..44c1e184 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getCurrentUserId$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getCurrentUserId$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getObjectKeys$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getObjectKeys$1.class
index 773299e7..7684976e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getObjectKeys$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$getObjectKeys$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1$1$1.class
index 0915d726..24b9fd89 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1.class
index 23eb84ae..2659e77e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$handleSaveConfirm$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$initCheckoutData$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$initCheckoutData$1.class
new file mode 100644
index 00000000..c4d32a46
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$initCheckoutData$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadAddressList$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadAddressList$1.class
index f120e34b..9c768eeb 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadAddressList$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadAddressList$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadCheckoutData$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadCheckoutData$1.class
index 90c8e44e..3cdbb985 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadCheckoutData$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadCheckoutData$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadDefaultAddress$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadDefaultAddress$1.class
index abaa502b..92b862af 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadDefaultAddress$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadDefaultAddress$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadFromLocalStorage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadFromLocalStorage$1.class
index f9a3b36c..924d82c0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadFromLocalStorage$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$loadFromLocalStorage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$onShow__1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$onShow__1$1.class
index 45ab049f..a851aa0d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$onShow__1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$onShow__1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1$1.class
new file mode 100644
index 00000000..66e47118
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1.class
index 9500511e..9b3fd25b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1.class
new file mode 100644
index 00000000..96116389
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$processCheckoutItems$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$saveNewAddress$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$saveNewAddress$1$1.class
index 64c0057f..9f07dbc9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$saveNewAddress$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$saveNewAddress$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$1.class
index 4253ebdb..68f72c6f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$2$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$2$1.class
index 5cc449da..04f5f05d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$2$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1$1$2$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1.class
index e8a1b5b9..f699c1bf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion$setup$1$submitOrder$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion.class
index a250f885..8de4d46f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout.class
index 4ed7d584..9807ff40 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerCheckout.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1$1.class
index 20aae617..4d8c5139 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1.class
index 11560d19..3a11edf5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$cancelPayment$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1$1.class
index 33a47710..834425dd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1.class
index fd755ea2..a6d4d58b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$confirmPayment$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadOrderInfo$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadOrderInfo$1$1.class
index 5660b237..7a0f7e4d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadOrderInfo$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadOrderInfo$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadUserBalance$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadUserBalance$1$1.class
index 129aa6ee..cc614e62 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadUserBalance$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$loadUserBalance$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$verifyPassword$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$verifyPassword$1$1.class
index d996d52b..b05cb1c9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$verifyPassword$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion$setup$1$verifyPassword$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion.class
index d5199865..3415f896 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment.class
index 3237b10c..14f92204 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerPayment.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$1$1.class
index f7c10e0c..a4637f0e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$Companion.class
index 4272045e..03a0fe0b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$addToCart$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$addToCart$1.class
index 781f5b3a..67b4767c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$addToCart$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$addToCart$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$buyNow$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$buyNow$1.class
index d8a7783c..196bcb6e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$buyNow$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$buyNow$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavorite$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavorite$1.class
index d3f85f12..fd1756ad 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavorite$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavorite$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavoriteStatus$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavoriteStatus$1.class
index 55343283..b844d56e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavoriteStatus$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$checkFavoriteStatus$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$claimCoupon$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$claimCoupon$1.class
index 37d54045..5166c7c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$claimCoupon$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$claimCoupon$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$contactMerchant$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$contactMerchant$1.class
index 3ff5c9fc..e3b7b9da 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$contactMerchant$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$contactMerchant$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$decreaseQuantity$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$decreaseQuantity$1.class
index 148f420f..a3ead49f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$decreaseQuantity$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$decreaseQuantity$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$formatDate$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$formatDate$1.class
index 14639158..946eb568 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$formatDate$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$formatDate$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_addToCart_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_addToCart_fn$1.class
index 7dae549e..2b4696c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_addToCart_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_addToCart_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_checkFavorite_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_checkFavorite_fn$1.class
index 1a6b14cf..d82cc56e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_checkFavorite_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_checkFavorite_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_claimCoupon_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_claimCoupon_fn$1.class
index 719e6290..93371208 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_claimCoupon_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_claimCoupon_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadCoupons_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadCoupons_fn$1.class
index 1bd750f6..f8f8f43d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadCoupons_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadCoupons_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMemberPrice_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMemberPrice_fn$1.class
index d4919223..9d061150 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMemberPrice_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMemberPrice_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMerchantInfo_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMerchantInfo_fn$1.class
index c04d3192..c476adee 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMerchantInfo_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadMerchantInfo_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1$1$specs$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1$1$specs$1.class
index c676a1d5..a3b50080 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1$1$specs$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1$1$specs$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1.class
index 73ee4c87..135dbb03 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_loadProductSkus_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_toggleFavorite_fn$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_toggleFavorite_fn$1.class
index 1b620ef2..9414f787 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_toggleFavorite_fn$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$gen_toggleFavorite_fn$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getAvailableStock$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getAvailableStock$1.class
index cb1d4f51..96bdbfcf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getAvailableStock$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getAvailableStock$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getMaxQuantity$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getMaxQuantity$1.class
index 8e4a102c..a6f89b35 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getMaxQuantity$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getMaxQuantity$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getParamsSummary$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getParamsSummary$1.class
index 2c81e45d..15c48e23 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getParamsSummary$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getParamsSummary$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuImage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuImage$1.class
index 94ebda08..3271cb4f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuImage$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuImage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuPrice$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuPrice$1.class
index 49e025e8..ad54896d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuPrice$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuPrice$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuStock$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuStock$1.class
index 9e83c1ca..bc168dac 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuStock$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSelectedSkuStock$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSkuSpecText$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSkuSpecText$1.class
index cbcc097c..754f958a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSkuSpecText$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$getSkuSpecText$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToCart$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToCart$1.class
index fa95a772..b847fcac 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToCart$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToCart$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToHome$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToHome$1.class
index c9750a44..85344766 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToHome$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToHome$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToShop$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToShop$1.class
index 0b026ad1..67db75a2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToShop$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$goToShop$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideCouponModal$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideCouponModal$1.class
index ef04e108..ec4d4ace 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideCouponModal$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideCouponModal$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideParamsModal$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideParamsModal$1.class
index 6656917a..67cba3c0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideParamsModal$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideParamsModal$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideSpecModal$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideSpecModal$1.class
index 7b3ce7db..3f974664 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideSpecModal$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$hideSpecModal$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$increaseQuantity$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$increaseQuantity$1.class
index 196b869d..134cdd98 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$increaseQuantity$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$increaseQuantity$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadCoupons$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadCoupons$1.class
index 82c46a3c..8bc4d9a6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadCoupons$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadCoupons$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMemberPrice$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMemberPrice$1.class
index 84f90efb..69529a32 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMemberPrice$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMemberPrice$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMerchantInfo$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMerchantInfo$1.class
index efcf1150..bfe1a380 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMerchantInfo$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadMerchantInfo$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductDetail$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductDetail$1.class
index b2b66891..f78c6dbc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductDetail$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductDetail$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductSkus$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductSkus$1.class
index 2e2c4100..27b9147c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductSkus$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$loadProductSkus$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$onSwiperChange$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$onSwiperChange$1.class
index 168395ce..620ca14c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$onSwiperChange$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$onSwiperChange$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$previewImage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$previewImage$1.class
index 0065884a..a77c5a35 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$previewImage$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$previewImage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$saveFootprint$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$saveFootprint$1.class
index 2ecc2a01..e994048d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$saveFootprint$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$saveFootprint$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$selectSku$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$selectSku$1.class
index 37e6245e..839da812 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$selectSku$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$selectSku$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showCouponModal$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showCouponModal$1.class
index 6f03df0e..18ae9d85 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showCouponModal$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showCouponModal$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showParamsModal$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showParamsModal$1.class
index 57d48733..8bf3ba6a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showParamsModal$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showParamsModal$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showSpecModal$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showSpecModal$1.class
index bcc1ad2f..7f63fdc5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showSpecModal$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$showSpecModal$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$toggleFavorite$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$toggleFavorite$1.class
index d558f586..c5eadb08 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$toggleFavorite$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$toggleFavorite$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$validateQuantity$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$validateQuantity$1.class
index 6fae6a18..52befc6d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$validateQuantity$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail$validateQuantity$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail.class
index 66955737..d3697413 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerProductDetail.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$addToCart$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$addToCart$1$1.class
index 8ecb916a..4f07f5c9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$addToCart$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$addToCart$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadData$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadData$1$1.class
index a4e15244..3176e903 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadData$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadData$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadMore$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadMore$1$1.class
index 4f3914d6..c07d9544 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadMore$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$loadMore$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$performSearch$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$performSearch$1$1.class
index 0533fa92..224dd5f2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$performSearch$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion$setup$1$performSearch$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion.class
index c81c4940..ba3119c0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch.class
index d96cba7f..c7a52c06 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerSearch.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail$Companion.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail$Companion.class
index 111009d5..c1e4a0b7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail$Companion.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail$Companion.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail.class
index 1e449639..4d7f9563 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenPagesMallConsumerShopDetail.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenUniApp.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenUniApp.class
index 7667ed41..8d24d251 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenUniApp.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GenUniApp.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemType.class
index 1c8c4d31..4ea9dcab 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemTypeReactiveObject.class
index 6f2bfca6..91e5f180 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/GuessItemTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemType.class
index 620e735d..ea7bfddd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemTypeReactiveObject.class
index 36e7afd7..8c0c559f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/HotSearchItemTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nGlobal.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nGlobal.class
index d048fc79..4d9dc3c9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nGlobal.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nGlobal.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nInstance.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nInstance.class
index 05e3dd22..33bd2e68 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nInstance.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/I18nInstance.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ADDRESS_LABEL$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ADDRESS_LABEL$1.class
index a925ad41..d7bb940d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ADDRESS_LABEL$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ADDRESS_LABEL$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$COUPON_TYPE$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$COUPON_TYPE$1.class
index d611ea42..b5a7087b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$COUPON_TYPE$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$COUPON_TYPE$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$DELIVERY_STATUS$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$DELIVERY_STATUS$1.class
index ab72080c..2394765e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$DELIVERY_STATUS$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$DELIVERY_STATUS$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$FAVORITE_TYPE$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$FAVORITE_TYPE$1.class
index 42880239..d47d220e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$FAVORITE_TYPE$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$FAVORITE_TYPE$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$MALL_USER_TYPE$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$MALL_USER_TYPE$1.class
index e004aca6..7414419b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$MALL_USER_TYPE$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$MALL_USER_TYPE$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ORDER_STATUS$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ORDER_STATUS$1.class
index 0c7d3e46..d5e60a9f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ORDER_STATUS$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ORDER_STATUS$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$PAYMENT_METHOD$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$PAYMENT_METHOD$1.class
index c4114eaa..0cb510d8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$PAYMENT_METHOD$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$PAYMENT_METHOD$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_PERIOD$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_PERIOD$1.class
index 288c9bc3..31ae93ec 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_PERIOD$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_PERIOD$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_STATUS$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_STATUS$1.class
index 43661705..75f8634f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_STATUS$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$SUBSCRIPTION_STATUS$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$VERIFICATION_STATUS$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$VERIFICATION_STATUS$1.class
index bc197974..dc801914 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$VERIFICATION_STATUS$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$VERIFICATION_STATUS$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1$1.class
index 96347b33..420106fa 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1.class
index 194a8c38..0c71ee07 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt$ensureUserProfile$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt.class
index d0b1b8db..f6233c35 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/IndexKt.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLog.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLog.class
index b98e9983..29697f5f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLog.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLog.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLogReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLogReactiveObject.class
index 2f1c9b36..a689ffa2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLogReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LevelLogReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItem.class
index 410ac851..47278460 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItemReactiveObject.class
index c5b584a2..37627ccb 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCartItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategory.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategory.class
index 71d3747a..6cca33f6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategory.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategory.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategoryReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategoryReactiveObject.class
index 5a2e7c7b..e887ca56 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategoryReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocalCategoryReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocaleWrapper.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocaleWrapper.class
index 3c569bff..63894a9e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocaleWrapper.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/LocaleWrapper.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfo.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfo.class
index 75e6bc8b..3ec43462 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfo.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfo.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfoReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfoReactiveObject.class
index c49292d8..d45e3813 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfoReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberInfoReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevel.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevel.class
index f245cfbb..aebf7935 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevel.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevel.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevelReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevelReactiveObject.class
index d92857a0..9a5e29b7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevelReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MemberLevelReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingType.class
index 199845c8..bb9c5801 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingTypeReactiveObject.class
index c88f669f..333e8dc9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantRatingTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType.class
index ca87541b..ad8fc84f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantTypeReactiveObject.class
index 206872b0..98c52489 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1.class
index d99e6574..f96200e7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1ReactiveObject.class
index 62e27e86..f92a4b0a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MerchantType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItem.class
index 803d6726..3a5db4cd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItemReactiveObject.class
index c7f2d041..7e5c2327 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTab.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTab.class
index f4e1f447..3888cfde 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTab.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTab.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTabReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTabReactiveObject.class
index 773eaaed..e0ffe168 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTabReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTabReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageType.class
index 00c3b91e..d21457f4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTypeReactiveObject.class
index 606d2a31..756fe56b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MessageTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MockAddress.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MockAddress.class
index d222ffd8..e902297b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MockAddress.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MockAddress.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItem.class
index 4b051fc5..c0989dd6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItemReactiveObject.class
index 89ce549c..2261ed70 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/MyReviewItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressData.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressData.class
index b46b4e25..323bc134 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressData.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressData.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressForm.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressForm.class
index 06647190..f199c918 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressForm.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressForm.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressFormReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressFormReactiveObject.class
index 92ac1602..9f167eef 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressFormReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NewAddressFormReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Notification.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Notification.class
index 69c09331..33ed6a78 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Notification.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Notification.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationType.class
index f4571f9e..483b03cc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationTypeReactiveObject.class
index dc77bfa0..e1eaf5e0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/NotificationTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsType.class
index 3e2ce29b..16df1adc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsTypeReactiveObject.class
index 1cff95c0..04c1e3a1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderCountsTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItem.class
index 345da3a3..45f6d3fc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemReactiveObject.class
index 1a333514..e4d08562 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType.class
index 682d960f..796f0aa5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemTypeReactiveObject.class
index 15ee578a..2932154d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1.class
index 460b655a..6a8c673e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1ReactiveObject.class
index d6c21b79..229763c3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2.class
index 0ccf2e06..e64a403f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2ReactiveObject.class
index 2b4de00a..0290f7ca 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderItemType__2ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderOptions.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderOptions.class
index d7dafebf..665b23c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderOptions.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderOptions.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProduct.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProduct.class
index 1ecfdf55..e1f7c4d6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProduct.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProduct.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProductReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProductReactiveObject.class
index bc5a3c8b..3e70293c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProductReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderProductReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItem.class
index a8d0f86d..468c1cd4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItemReactiveObject.class
index a0ba9408..b063fb54 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTabItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType.class
index 2b1fb97b..8a77bdca 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTypeReactiveObject.class
index 9ff39ec9..3b108b5c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1.class
index 7b8cedd6..b32ed231 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1ReactiveObject.class
index 726bf263..114a5891 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/OrderType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaginatedResponse.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaginatedResponse.class
index c22414bc..393e3e9c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaginatedResponse.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaginatedResponse.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodType.class
index 97c3075d..2b924011 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodTypeReactiveObject.class
index c0e0b099..2a7fec6c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PaymentMethodTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItem.class
index 102241ca..a708bf13 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItemReactiveObject.class
index 3ee91a1d..898552ce 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PendingItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProduct.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProduct.class
index 3673f386..fce5b22b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProduct.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProduct.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProductReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProductReactiveObject.class
index 11d172be..a168ec8a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProductReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointProductReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecord.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecord.class
index 32ccf4cd..911d811b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecord.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecord.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecordReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecordReactiveObject.class
index 99f6bd60..f31cae6d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecordReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PointRecordReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyType.class
index a4025f7f..1be2e030 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyTypeReactiveObject.class
index 93bf5a38..18513a42 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/PrivacyTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Product.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Product.class
index 02ad7712..6b1017ad 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Product.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Product.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductReactiveObject.class
index e5040c57..ea5b51b5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSku.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSku.class
index fcddded3..54841f4c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSku.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSku.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuType.class
index 959dd053..dfed122b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuTypeReactiveObject.class
index 33e6684f..058d378c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductSkuTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductType.class
index 7908c65b..7f9f61af 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductTypeReactiveObject.class
index 4e01e3a0..970d4aec 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProductTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileType.class
index 45d2f17b..1197cdff 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileTypeReactiveObject.class
index 815c9419..eab30ac9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ProfileTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProduct.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProduct.class
index 68068e9b..21881d5a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProduct.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProduct.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProductReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProductReactiveObject.class
index 60409e5d..dc102e81 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProductReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RecommendProductReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacket.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacket.class
index 901f8379..2d316bd7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacket.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacket.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacketReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacketReactiveObject.class
index 9b863cf8..1383575c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacketReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RedPacketReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfo.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfo.class
index 4323f72b..cb0320a0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfo.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfo.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfoReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfoReactiveObject.class
index bc3372b2..3bf24a05 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfoReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderInfoReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItem.class
index 13587815..e81cb438 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItemReactiveObject.class
index 18f3a4a0..42369d88 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundOrderItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfo.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfo.class
index a25e082c..1a605546 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfo.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfo.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfoReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfoReactiveObject.class
index 87df6803..f489893d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfoReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundProductInfoReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundResponse.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundResponse.class
index 185aadc7..6295a61c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundResponse.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundResponse.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItem.class
index c64a0ed6..6d03baf2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItemReactiveObject.class
index ea2beba9..8dce6b41 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundStatusHistoryItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundType.class
index 34a39328..ae13b7be 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundTypeReactiveObject.class
index c958e098..208061f1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/RefundTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItem.class
index 8a55de85..5a1e267d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItemReactiveObject.class
index 8a966950..b31fd58f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ReviewItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultType.class
index de838574..6ecb251c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultTypeReactiveObject.class
index b2525ee7..fba4eebc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SearchResultTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsType.class
index 15151fad..5de184ef 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsTypeReactiveObject.class
index a1afab92..6f5f8714 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ServiceCountsTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecord.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecord.class
index 736881cd..b8e0c02b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecord.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecord.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordReactiveObject.class
index 039777dd..8b11166e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordType.class
index 1a4cf53d..716797d7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordTypeReactiveObject.class
index aa9b8046..a6b7664c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShareRecordTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Shop.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Shop.class
index 061be23b..4ceb49ba 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Shop.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/Shop.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopGroupType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopGroupType.class
index 779c1496..d63c8fff 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopGroupType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopGroupType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderParams.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderParams.class
index a19029ae..315da405 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderParams.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderParams.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderResponse.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderResponse.class
index 2a60c77f..6d8fa38f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderResponse.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopOrderResponse.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultType.class
index 7784a1f1..4b5051b7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultTypeReactiveObject.class
index 5c7a1093..00b62c2d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/ShopResultTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SortTab.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SortTab.class
index 85e346fb..5cb7f4b7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SortTab.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SortTab.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/State.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/State.class
index 02964d8b..f2c9430b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/State.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/State.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StateReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StateReactiveObject.class
index 1ef1ab3f..07d98efb 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StateReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StateReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodType.class
index 685c473f..aefeef4f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodTypeReactiveObject.class
index 05253ccb..f9159a76 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsPeriodTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType.class
index 6c094f6b..f462e111 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsTypeReactiveObject.class
index c982ce7d..61a37253 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1.class
index 51684bf7..9c0435b7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1ReactiveObject.class
index 3bbfdd6d..ec23eeb1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/StatsType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1$response$1.class
index db358b43..417812c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1.class
index 356458d6..2ac1dd1e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addAddress$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addBankCard$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addBankCard$1.class
index e397a7e6..b1e44ead 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addBankCard$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addBankCard$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1$updateRes$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1$updateRes$1.class
index c26d2eb3..07e0a57b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1$updateRes$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1$updateRes$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1.class
index 48b8695b..9419c9fc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addFootprint$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addPoints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addPoints$1.class
index 85655a68..d20770a9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addPoints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addPoints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1$1.class
index 30b387d2..6e2ca2fa 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1.class
index 4ffb18e0..88aec028 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$addToCart$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$appendReview$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$appendReview$1.class
index fec4282b..1f6a3c97 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$appendReview$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$appendReview$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1$response$1.class
index b3a1a700..08eb882d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1.class
index ba3cf4ba..015c9057 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$applyRefund$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchDeleteCartItems$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchDeleteCartItems$1.class
index 44df66fb..c28ca23f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchDeleteCartItems$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchDeleteCartItems$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchUpdateCartItemSelection$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchUpdateCartItemSelection$1.class
index 42dec4d5..d384b101 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchUpdateCartItemSelection$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$batchUpdateCartItemSelection$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1$response$1.class
index bf468f6e..a1688a01 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1.class
index abbf808e..1fb40cae 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelOrder$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$orderUpdateResponse$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$orderUpdateResponse$1.class
index 883ef8c3..c063871f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$orderUpdateResponse$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$orderUpdateResponse$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$refundUpdateResponse$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$refundUpdateResponse$1.class
index a106267f..c7be07ff 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$refundUpdateResponse$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1$refundUpdateResponse$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1.class
index 57933f28..5ceb15d1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$cancelRefund$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$checkFavorite$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$checkFavorite$1.class
index bcd5b627..8a5dc95f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$checkFavorite$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$checkFavorite$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimCoupon$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimCoupon$1.class
index 6873a7fe..70413316 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimCoupon$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimCoupon$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$fallbackData$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$fallbackData$1.class
index 501b4d82..aecdd68a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$fallbackData$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$fallbackData$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$insertData$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$insertData$1.class
index d9d40eca..5ac0e591 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$insertData$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1$insertData$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1.class
index 3201ccfd..eb7c4558 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$claimShopCoupon$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearCart$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearCart$1.class
index 24bcfe71..61204ad7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearCart$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearCart$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1$1.class
index 89fba0c4..e2356173 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1.class
index 1353dec8..7dc511a5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearDefaultAddress$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearFootprints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearFootprints$1.class
index 938bd025..659caaaa 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearFootprints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$clearFootprints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1$response$1.class
index 6fd3395b..2302a53c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1.class
index 2c572086..0197a4bd 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmOrderReceived$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmReceipt$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmReceipt$1.class
index 5900efab..784c94ed 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmReceipt$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$confirmReceipt$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrder$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrder$1.class
index 364b2802..84899e58 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrder$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrder$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrdersByShop$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrdersByShop$1.class
index 24c5a604..46df0625 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrdersByShop$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createOrdersByShop$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$payload$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$payload$1.class
index 2d5915bf..15431bf5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$payload$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$payload$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$updateResponse$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$updateResponse$1.class
index fa0eb900..de5c0f4c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$updateResponse$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1$updateResponse$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1.class
index aea4e548..52fdf60d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createRefund$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createShareRecord$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createShareRecord$1.class
index f972dbe0..fe5fb18d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createShareRecord$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$createShareRecord$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deductPoints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deductPoints$1.class
index 74126953..578be95c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deductPoints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deductPoints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteAddress$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteAddress$1.class
index db5d58d5..79674390 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteAddress$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteAddress$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteBankCard$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteBankCard$1.class
index 1be68678..87897ae7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteBankCard$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteBankCard$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteCartItem$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteCartItem$1.class
index 296b9396..e2b2d6b3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteCartItem$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteCartItem$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprint$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprint$1.class
index 99e9b742..df9dad02 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprint$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprint$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprints$1.class
index 4a0a429e..6ea5d496 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteFootprints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteOrder$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteOrder$1.class
index 57988c53..fb0de3ef 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteOrder$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteOrder$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteRefund$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteRefund$1.class
index d8c24314..f972175f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteRefund$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteRefund$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteReview$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteReview$1.class
index 42b66595..87ff1cbf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteReview$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$deleteReview$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$ensureSession$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$ensureSession$1.class
index 267ed9e6..c5b72ca0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$ensureSession$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$ensureSession$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$exchangeProduct$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$exchangeProduct$1.class
index 14b34ecc..377db8d1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$exchangeProduct$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$exchangeProduct$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$fetchShopCoupons$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$fetchShopCoupons$1.class
index ce33586d..b30224fb 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$fetchShopCoupons$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$fetchShopCoupons$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1$res$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1$res$1.class
index fa5b18d7..87a69763 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1$res$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1$res$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1.class
index 0d65e976..f7f49c32 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$followShop$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressById$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressById$1.class
index 56746d86..de847950 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressById$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressById$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressList$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressList$1.class
index 5ec0d596..14f79e93 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressList$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddressList$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddresses$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddresses$1.class
index 372e2c13..3eeb88e0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddresses$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAddresses$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAvailableCoupons$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAvailableCoupons$1.class
index 13b23d77..801ff106 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAvailableCoupons$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getAvailableCoupons$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBalanceRecords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBalanceRecords$1.class
index 62754a74..dbf137a6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBalanceRecords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBalanceRecords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBrands$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBrands$1.class
index dae09788..183a1dc4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBrands$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getBrands$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCartItems$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCartItems$1.class
index 0030d297..198e3d78 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCartItems$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCartItems$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategories$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategories$1.class
index 8f17be08..85576240 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategories$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategories$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategoryById$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategoryById$1.class
index a3b2ff4f..fd390a82 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategoryById$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getCategoryById$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatMessages$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatMessages$1.class
index 31864049..e76f1018 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatMessages$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatMessages$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatRooms$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatRooms$1.class
index 192ad6d6..6f8374e7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatRooms$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getChatRooms$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getDiscountProducts$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getDiscountProducts$1.class
index 915e486c..8e0d6f57 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getDiscountProducts$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getDiscountProducts$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExchangeRecords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExchangeRecords$1.class
index f77ddd9b..28a0b6fc 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExchangeRecords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExchangeRecords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiringPoints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiringPoints$1.class
index ce9b38fa..80aac5f5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiringPoints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiringPoints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiryNotifications$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiryNotifications$1.class
index 0c1b2c53..1ae653d9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiryNotifications$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getExpiryNotifications$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFavorites$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFavorites$1.class
index f2945005..64e39567 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFavorites$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFavorites$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFollowedShops$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFollowedShops$1.class
index e0d6b28a..8016f977 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFollowedShops$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFollowedShops$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFootprints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFootprints$1.class
index f3b17ae8..81dd9254 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFootprints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFootprints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFreeOrderRewards$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFreeOrderRewards$1.class
index 33513915..c462d69e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFreeOrderRewards$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getFreeOrderRewards$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1$KeywordEntry.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1$KeywordEntry.class
index 3f01eca1..956abe38 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1$KeywordEntry.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1$KeywordEntry.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1.class
index 9bb71ddd..ce4e0806 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotKeywords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotProducts$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotProducts$1.class
index e5301a4e..ef2fb217 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotProducts$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getHotProducts$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevelLogs$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevelLogs$1.class
index 5152c851..ab15e769 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevelLogs$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevelLogs$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevels$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevels$1.class
index db7e4e46..1d0a1bb2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevels$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMemberLevels$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMerchantPromotionConfig$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMerchantPromotionConfig$1.class
index 7aaa30bc..6bd1697d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMerchantPromotionConfig$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMerchantPromotionConfig$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyReviews$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyReviews$1.class
index bcb60726..b461c45a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyReviews$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyReviews$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyShareRecords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyShareRecords$1.class
index fd9bd63f..5993a9c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyShareRecords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getMyShareRecords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderById$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderById$1.class
index 643ed091..64e2caaf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderById$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderById$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderDetail$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderDetail$1.class
index 6409ae20..b31d5859 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderDetail$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrderDetail$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrders$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrders$1.class
index 698d3d6d..83f44d7b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrders$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getOrders$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getParentCategories$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getParentCategories$1.class
index e3981774..49632afe 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getParentCategories$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getParentCategories$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointProducts$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointProducts$1.class
index 2f9cc15f..228460f1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointProducts$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointProducts$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointRecords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointRecords$1.class
index 1586faa7..5f291996 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointRecords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointRecords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointsOverview$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointsOverview$1.class
index 268c15da..1db9f669 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointsOverview$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getPointsOverview$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductById$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductById$1.class
index 21af9def..cf4a8e7a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductById$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductById$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1$query$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1$query$1.class
index 7b86e091..e2b4d88a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1$query$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1$query$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1.class
index 359d2454..68ac27b5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductReviews$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductSkus$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductSkus$1.class
index b08ebc1d..d73873b3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductSkus$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductSkus$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategories$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategories$1.class
index f60ed432..e5dfebce 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategories$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategories$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1$response$1.class
index 73adfa0a..08b8c9f4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1.class
index ad06ebc1..3f55ab60 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByCategory$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query$1.class
index daa5f06a..21a6fe00 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query2$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query2$1.class
index d81a60af..8b0774ca 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query2$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1$query2$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1.class
index 0f3c27ea..2bc61d17 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByMerchantId$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByNewest$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByNewest$1.class
index 99b232d2..34ddf561 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByNewest$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByNewest$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByPrice$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByPrice$1.class
index c45f55c3..969e78d6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByPrice$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByPrice$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsBySales$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsBySales$1.class
index a35276eb..7549424f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsBySales$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsBySales$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query$1.class
index 4a07e3d9..df974cc9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query2$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query2$1.class
index e7258996..87c5c024 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query2$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1$query2$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1.class
index fee88ec4..09377335 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getProductsByShopId$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRecommendedProducts$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRecommendedProducts$1.class
index d185447c..b887f38d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRecommendedProducts$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRecommendedProducts$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRefunds$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRefunds$1.class
index c761a21c..32418a05 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRefunds$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getRefunds$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getReviewStats$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getReviewStats$1.class
index d56b947a..d6c699e9 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getReviewStats$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getReviewStats$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShareDetail$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShareDetail$1.class
index 67d6a152..89cc314f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShareDetail$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShareDetail$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShopByMerchantId$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShopByMerchantId$1.class
index 4d22ec35..55f1f797 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShopByMerchantId$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getShopByMerchantId$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSigninRecords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSigninRecords$1.class
index 0eb3ab20..5991abd2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSigninRecords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSigninRecords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSmartRecommendations$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSmartRecommendations$1.class
index 378f5c81..b0568a05 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSmartRecommendations$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSmartRecommendations$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSubCategories$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSubCategories$1.class
index bee384e5..445ab62f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSubCategories$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getSubCategories$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTodaySigninStatus$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTodaySigninStatus$1.class
index 72a3615c..b0cdde18 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTodaySigninStatus$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTodaySigninStatus$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTotalEarned$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTotalEarned$1.class
index b056befd..124a3064 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTotalEarned$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTotalEarned$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTransactions$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTransactions$1.class
index 240760b1..356e65d7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTransactions$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getTransactions$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalance$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalance$1.class
index 39ef8351..9e581a35 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalance$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalance$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalanceNumber$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalanceNumber$1.class
index 537e068c..7d8a5da0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalanceNumber$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBalanceNumber$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBankCards$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBankCards$1.class
index 45287379..d2b59d31 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBankCards$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBankCards$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBrowseCategories$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBrowseCategories$1.class
index 5d83a358..49d56dc2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBrowseCategories$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserBrowseCategories$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserChatMessages$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserChatMessages$1.class
index ff2e6dd2..96c189b2 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserChatMessages$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserChatMessages$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1$response$1.class
index 2b8dd052..57992065 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1.class
index ff57053d..9edb6f31 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCouponCount$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCoupons$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCoupons$1.class
index 45290208..8f2023a4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCoupons$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserCoupons$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserMemberInfo$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserMemberInfo$1.class
index 05ea4292..590d3143 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserMemberInfo$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserMemberInfo$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserNotifications$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserNotifications$1.class
index 57c41b2e..2b7a579e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserNotifications$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserNotifications$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserPoints$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserPoints$1.class
index 203ff441..735a7a45 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserPoints$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserPoints$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserRedPackets$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserRedPackets$1.class
index 32ab6dba..cc126607 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserRedPackets$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserRedPackets$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserSearchHistory$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserSearchHistory$1.class
index e8cfa4ab..1ab0d15c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserSearchHistory$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$getUserSearchHistory$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShareFreeEnabled$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShareFreeEnabled$1.class
index 5fd893ad..2b3cc62d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShareFreeEnabled$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShareFreeEnabled$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1$res$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1$res$1.class
index d2aeeaf9..4e192362 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1$res$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1$res$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1.class
index bc15f5af..d75ee0b3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$isShopFollowed$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1$res$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1$res$1.class
index a524644b..76b80f87 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1$res$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1$res$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1.class
index 391ca834..d4e14a98 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markNotificationRead$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1$response$1.class
index 1cf32faa..234fc8e6 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1.class
index 9a2ab796..a082ea9f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$markRead$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$payOrder$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$payOrder$1.class
index ccfb4091..fad23795 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$payOrder$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$payOrder$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rePurchase$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rePurchase$1.class
index c2691991..6d35174a 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rePurchase$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rePurchase$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1$res$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1$res$1.class
index 8ec27432..cbe1f19f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1$res$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1$res$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1.class
index e929ae73..5efd8695 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$rechargeBalance$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordBrowse$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordBrowse$1.class
index 99fc1f0d..581961f8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordBrowse$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordBrowse$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordSearch$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordSearch$1.class
index 5801c930..8116d5b8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordSearch$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$recordSearch$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1$query$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1$query$1.class
index e769d7ec..f8d0ad31 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1$query$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1$query$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1.class
index 8f7657b9..8763c994 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProducts$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProductsByKeywords$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProductsByKeywords$1.class
index a4415768..dbc17df7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProductsByKeywords$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchProductsByKeywords$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1$response$1.class
index 6fd6f0b3..276b9d3f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1.class
index 133a19d1..e69f70f7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$searchShops$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendChatMessage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendChatMessage$1.class
index 323e6a85..41afecf4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendChatMessage$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendChatMessage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendMessage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendMessage$1.class
index 82192a7b..ece3d920 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendMessage$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$sendMessage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1$response$1.class
index e1d1747f..faf890b1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1.class
index 181195b4..5dea3267 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$setDefaultAddress$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$signin$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$signin$1.class
index 0a5088e6..6cf8fc56 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$signin$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$signin$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitProductReviews$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitProductReviews$1.class
index 49e25b33..a697a239 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitProductReviews$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitProductReviews$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitShopReview$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitShopReview$1.class
index 086b37de..01db1514 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitShopReview$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$submitShopReview$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1$response$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1$response$1.class
index 05e26fcc..728716aa 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1$response$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1$response$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1.class
index 6b221f52..a081c113 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleFavorite$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleReviewLike$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleReviewLike$1.class
index 53439257..a9a7639c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleReviewLike$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$toggleReviewLike$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$triggerPointsMaintenance$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$triggerPointsMaintenance$1.class
index 2ef5d439..74002e8c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$triggerPointsMaintenance$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$triggerPointsMaintenance$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$unfollowShop$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$unfollowShop$1.class
index 0d122e5a..59e851a0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$unfollowShop$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$unfollowShop$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1$updateData$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1$updateData$1.class
index 5a3771c8..2c0f75cf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1$updateData$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1$updateData$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1.class
index c6aedabc..e42df213 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateAddress$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemQuantity$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemQuantity$1.class
index 53e333cc..5eac901d 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemQuantity$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemQuantity$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemSelection$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemSelection$1.class
index f63e5480..faecf625 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemSelection$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateCartItemSelection$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateOrderStatus$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateOrderStatus$1.class
index bc946d07..73bea009 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateOrderStatus$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$updateOrderStatus$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$uploadChatImage$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$uploadChatImage$1.class
new file mode 100644
index 00000000..0fc3d821
Binary files /dev/null and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$uploadChatImage$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$validateShareCode$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$validateShareCode$1.class
index 48b6813b..2398fb80 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$validateShareCode$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$validateShareCode$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1$res$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1$res$1.class
index 230341e8..58b1711c 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1$res$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1$res$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1.class
index 35e5888d..f53b3f66 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService$withdrawBalance$1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService.class
index 457157a6..25a73bf0 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/SupabaseService.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsType.class
index 073f2db7..88627001 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsTypeReactiveObject.class
index 89aecf1c..c8826d57 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TabCountsTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TimelineStepType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TimelineStepType.class
index 6eac93e5..5ca658c4 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TimelineStepType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TimelineStepType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItem.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItem.class
index 5ccd622c..717c3735 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItem.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItem.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItemReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItemReactiveObject.class
index 573b6b66..9fc2daed 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItemReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TrackItemReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionType.class
index 07e4b6ee..e1249b00 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionTypeReactiveObject.class
index c986ccdd..ca1ffbef 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/TransactionTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessage.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessage.class
index c419f5cf..ea9000a7 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessage.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessage.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessageReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessageReactiveObject.class
index f0028c03..5f17f50f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessageReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UiChatMessageReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UniAppConfig.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UniAppConfig.class
index 8b9d3711..ee03c4a5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UniAppConfig.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UniAppConfig.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UpdateAddressParams.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UpdateAddressParams.class
index 42099917..dd8327e5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UpdateAddressParams.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UpdateAddressParams.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserAddress.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserAddress.class
index 370b8b0e..a32627c1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserAddress.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserAddress.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCoupon.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCoupon.class
index ab877f7b..101899e3 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCoupon.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCoupon.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponType.class
index 6caf927c..d81baac5 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponTypeReactiveObject.class
index bf81023f..bf9eda57 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserCouponTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfile.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfile.class
index 186dd3a9..8e864caf 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfile.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfile.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfileReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfileReactiveObject.class
index 16fed69c..b4e5c110 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfileReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserProfileReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType.class
index 26a74fff..031e84da 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsTypeReactiveObject.class
index bb9d3b2a..301ed171 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1.class
index 50e0f005..18bb7b7e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1ReactiveObject.class
index 78b5c784..ed0c997b 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserStatsType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType.class
index 5c161c33..debcb51e 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserTypeReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserTypeReactiveObject.class
index dd4684e9..1c7725f1 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserTypeReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserTypeReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1.class
index 233893f0..f5fa644f 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1.class differ
diff --git a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1ReactiveObject.class b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1ReactiveObject.class
index ea65f4eb..f03376c8 100644
Binary files a/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1ReactiveObject.class and b/unpackage/cache/.app-android/class/uni/UNIEC68BC3/UserType__1ReactiveObject.class differ
diff --git a/unpackage/cache/.app-android/dex/index/classes.dex b/unpackage/cache/.app-android/dex/index/classes.dex
new file mode 100644
index 00000000..f31bad8d
Binary files /dev/null and b/unpackage/cache/.app-android/dex/index/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/main/cart/classes.dex b/unpackage/cache/.app-android/dex/pages/main/cart/classes.dex
index 1cd0453e..244261a6 100644
Binary files a/unpackage/cache/.app-android/dex/pages/main/cart/classes.dex and b/unpackage/cache/.app-android/dex/pages/main/cart/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/main/category/classes.dex b/unpackage/cache/.app-android/dex/pages/main/category/classes.dex
index 0f51688d..6f71e177 100644
Binary files a/unpackage/cache/.app-android/dex/pages/main/category/classes.dex and b/unpackage/cache/.app-android/dex/pages/main/category/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/main/index/classes.dex b/unpackage/cache/.app-android/dex/pages/main/index/classes.dex
index c521d8f7..9538954a 100644
Binary files a/unpackage/cache/.app-android/dex/pages/main/index/classes.dex and b/unpackage/cache/.app-android/dex/pages/main/index/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/mall/consumer/chat/classes.dex b/unpackage/cache/.app-android/dex/pages/mall/consumer/chat/classes.dex
index 82490734..6bc3c05d 100644
Binary files a/unpackage/cache/.app-android/dex/pages/mall/consumer/chat/classes.dex and b/unpackage/cache/.app-android/dex/pages/mall/consumer/chat/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/mall/consumer/checkout/classes.dex b/unpackage/cache/.app-android/dex/pages/mall/consumer/checkout/classes.dex
new file mode 100644
index 00000000..95adc9ad
Binary files /dev/null and b/unpackage/cache/.app-android/dex/pages/mall/consumer/checkout/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/mall/consumer/payment/classes.dex b/unpackage/cache/.app-android/dex/pages/mall/consumer/payment/classes.dex
index f26d39be..db76e91d 100644
Binary files a/unpackage/cache/.app-android/dex/pages/mall/consumer/payment/classes.dex and b/unpackage/cache/.app-android/dex/pages/mall/consumer/payment/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/mall/consumer/product-detail/classes.dex b/unpackage/cache/.app-android/dex/pages/mall/consumer/product-detail/classes.dex
index fc936a8d..a9c6903d 100644
Binary files a/unpackage/cache/.app-android/dex/pages/mall/consumer/product-detail/classes.dex and b/unpackage/cache/.app-android/dex/pages/mall/consumer/product-detail/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/mall/consumer/search/classes.dex b/unpackage/cache/.app-android/dex/pages/mall/consumer/search/classes.dex
index 964e318f..802523af 100644
Binary files a/unpackage/cache/.app-android/dex/pages/mall/consumer/search/classes.dex and b/unpackage/cache/.app-android/dex/pages/mall/consumer/search/classes.dex differ
diff --git a/unpackage/cache/.app-android/dex/pages/mall/consumer/shop-detail/classes.dex b/unpackage/cache/.app-android/dex/pages/mall/consumer/shop-detail/classes.dex
index de636012..50a21f15 100644
Binary files a/unpackage/cache/.app-android/dex/pages/mall/consumer/shop-detail/classes.dex and b/unpackage/cache/.app-android/dex/pages/mall/consumer/shop-detail/classes.dex differ
diff --git a/unpackage/cache/.app-android/sourcemap/index.kt.map b/unpackage/cache/.app-android/sourcemap/index.kt.map
index 005e32bd..23b12e6c 100644
--- a/unpackage/cache/.app-android/sourcemap/index.kt.map
+++ b/unpackage/cache/.app-android/sourcemap/index.kt.map
@@ -1 +1 @@
-{"version":3,"sources":["../../../../../../../HBuilderX/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/socket.ts","uni_modules/ak-req/ak-req.uts","App.uvue","../../../../../../../HBuilderX/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts","uni_modules/ak-req/interface.uts","ak/config.uts","uni_modules/i18n/index.uts","utils/utils.uts","components/supadb/aksupa.uts","components/supadb/aksupainstance.uts","types/mall-types.uts","pages/sense/types.uts","utils/sapi.uts","utils/store.uts","main.uts","utils/supabaseService.uts","pages/user/center.uvue","pages/main/index.uvue","pages/main/category.uvue","pages/main/messages.uvue","pages/main/cart.uvue","pages/main/profile.uvue","pages/mall/consumer/settings.uvue","pages/mall/consumer/wallet.uvue","pages/mall/consumer/withdraw.uvue","pages/mall/consumer/search.uvue","pages/mall/consumer/shop-detail.uvue","pages/mall/consumer/coupons.uvue","pages/mall/consumer/favorites.uvue","pages/mall/consumer/footprint.uvue","pages/mall/consumer/address-list.uvue","pages/mall/consumer/address-edit.uvue","pages/mall/consumer/checkout.uvue","pages/mall/consumer/payment.uvue","pages/mall/consumer/orders.uvue","pages/mall/consumer/order-detail.uvue","pages/mall/consumer/logistics.uvue","pages/mall/consumer/review.uvue","pages/mall/consumer/refund.uvue","pages/mall/consumer/chat.uvue","pages/mall/consumer/subscription/followed-shops.uvue","pages/mall/consumer/points/index.uvue","pages/mall/consumer/points/signin.uvue","pages/mall/consumer/points/exchange.uvue","pages/mall/consumer/points/exchange-records.uvue","pages/mall/consumer/product-reviews.uvue","pages/mall/consumer/my-reviews.uvue","pages/mall/consumer/balance/index.uvue","pages/mall/consumer/share/index.uvue","pages/mall/consumer/share/detail.uvue","pages/mall/consumer/member/index.uvue","pages/mall/consumer/message-detail.uvue","pages/mall/consumer/red-packets/index.uvue","pages/mall/consumer/bank-cards/index.uvue","pages/mall/consumer/bank-cards/add.uvue"],"sourcesContent":["/// \n// 之所以又写了一份,是因为外层的socket,connectSocket的时候必须传入multiple:true\n// 但是android又不能传入,目前代码里又不能写条件编译之类的。\nexport function initRuntimeSocket(\n hosts: string,\n port: string,\n id: string\n): Promise {\n if (hosts == '' || port == '' || id == '') return Promise.resolve(null)\n return hosts\n .split(',')\n .reduce>(\n (\n promise: Promise,\n host: string\n ): Promise => {\n return promise.then((socket): Promise => {\n if (socket != null) return Promise.resolve(socket)\n return tryConnectSocket(host, port, id)\n })\n },\n Promise.resolve(null)\n )\n}\n\nconst SOCKET_TIMEOUT = 500\nfunction tryConnectSocket(\n host: string,\n port: string,\n id: string\n): Promise {\n return new Promise((resolve, reject) => {\n const socket = uni.connectSocket({\n url: `ws://${host}:${port}/${id}`,\n fail() {\n resolve(null)\n },\n })\n const timer = setTimeout(() => {\n // @ts-expect-error\n socket.close({\n code: 1006,\n reason: 'connect timeout',\n } as CloseSocketOptions)\n resolve(null)\n }, SOCKET_TIMEOUT)\n\n socket.onOpen((e) => {\n clearTimeout(timer)\n resolve(socket)\n })\n socket.onClose((e) => {\n clearTimeout(timer)\n resolve(null)\n })\n socket.onError((e) => {\n clearTimeout(timer)\n resolve(null)\n })\n })\n}\n","import { AkReqUploadOptions, AkReqOptions, AkReqResponse, AkReqError } from './interface.uts';\r\nimport { SUPA_URL, SUPA_KEY, IS_TEST_MODE } from '@/ak/config.uts';\r\n\r\n// token 持久化 key\r\nconst ACCESS_TOKEN_KEY = 'akreq_access_token';\r\nconst REFRESH_TOKEN_KEY = 'akreq_refresh_token';\r\nconst EXPIRES_AT_KEY = 'akreq_expires_at';\r\n\r\n// 优化:用静态变量缓存 token,只有 set/clear 时同步 storage\r\nlet _accessToken : string | null = null;\r\nlet _refreshToken : string | null = null;\r\nlet _expiresAt : number | null = null;\r\n\r\nexport class AkReq {\r\n\tstatic setToken(token : string, refreshToken : string, expiresAt : number) {\r\n\t\t_accessToken = token;\r\n\t\t_refreshToken = refreshToken;\r\n\t\t_expiresAt = expiresAt;\r\n\t\tuni.setStorageSync(ACCESS_TOKEN_KEY, token);\r\n\t\tuni.setStorageSync(REFRESH_TOKEN_KEY, refreshToken);\r\n\t\tuni.setStorageSync(EXPIRES_AT_KEY, expiresAt);\r\n\t}\r\n\tstatic getToken() : string | null {\r\n\t\tif (_accessToken != null) return _accessToken;\r\n\t\tconst t = uni.getStorageSync(ACCESS_TOKEN_KEY) as string | null;\r\n\t\t_accessToken = t;\r\n\t\treturn t;\r\n\t}\r\n\tstatic getRefreshToken() : string | null {\r\n\t\tif (_refreshToken != null) return _refreshToken;\r\n\t\tconst t = uni.getStorageSync(REFRESH_TOKEN_KEY) as string | null;\r\n\t\t_refreshToken = t;\r\n\t\treturn t;\r\n\t} static getExpiresAt() : number | null {\r\n\t\tconst val = _expiresAt;\r\n\t\tif (val != null) return val;\r\n\t\tconst t = uni.getStorageSync(EXPIRES_AT_KEY) as number | null;\r\n\t\t_expiresAt = t;\r\n\t\treturn t;\r\n\t}\r\n\tstatic clearToken() {\r\n\t\t_accessToken = null;\r\n\t\t_refreshToken = null;\r\n\t\t_expiresAt = null;\r\n\t\tuni.removeStorageSync(ACCESS_TOKEN_KEY);\r\n\t\tuni.removeStorageSync(REFRESH_TOKEN_KEY);\r\n\t\tuni.removeStorageSync(EXPIRES_AT_KEY);\r\n\t}\t// 判断 token 是否即将过期(提前5分钟刷新)\r\n\tstatic isTokenExpiring() : boolean {\r\n\t\tconst expiresAt = this.getExpiresAt();\r\n\t\tif (expiresAt === null || expiresAt == 0) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tconst now = Math.floor(Date.now() / 1000);\r\n\t\treturn (expiresAt - now) < 300; // 提前5分钟刷新\r\n\t}\r\n\r\n\t// 自动刷新 token,返回 true=已刷新,false=未刷新\r\n\tstatic async refreshTokenIfNeeded(apikey ?: string) : Promise {\r\n\t\t// 没有 access_token 直接返回,不刷新\r\n\t\tconst accessToken = this.getToken();\r\n\t\tif (accessToken === null || accessToken === \"\") {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (!this.isTokenExpiring()) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tconst refreshToken = this.getRefreshToken();\r\n\t\tif (refreshToken === null || refreshToken === \"\") {\r\n\t\t\tthis.clearToken();\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\t// 构造 header,必须带 apikey\r\n\t\tlet headers = new UTSJSONObject();\r\n\t\tif (apikey !== null && apikey !== \"\") {\r\n\t\t\theaders.set('apikey', apikey)\r\n\t\t}\r\n\t\tconst reqData = new UTSJSONObject()\r\n\t\treqData.set('refresh_token', refreshToken)\r\n\t\ttry {\r\n\t\t\tconst res = await this.request({\r\n\t\t\t\turl: SUPA_URL + '/auth/v1/token?grant_type=refresh_token',\r\n\t\t\t\tmethod: 'POST',\r\n\t\t\t\tdata: reqData,\r\n\t\t\t\theaders: headers,\r\n\t\t\t\tcontentType: 'application/json'\r\n\t\t\t}, true); // skipRefresh=true,避免递归\r\n\t\t\tconst data = res.data as UTSJSONObject | null;\r\n\t\t\tlet accessToken : string | null = null;\r\n\t\t\tlet refreshTokenNew : string | null = null;\r\n\t\t\tlet expiresAt : number | null = null;\r\n\t\t\tif (data != null && typeof data.getString === 'function' && typeof data.getNumber === 'function') {\r\n\t\t\t\taccessToken = data.getString('access_token');\r\n\t\t\t\trefreshTokenNew = data.getString('refresh_token');\r\n\t\t\t\texpiresAt = data.getNumber('expires_at');\r\n\t\t\t}\r\n\t\t\tif (accessToken !== null && refreshTokenNew !== null && expiresAt !== null) {\r\n\t\t\t\tthis.setToken(accessToken, refreshTokenNew, expiresAt);\r\n\t\t\t\treturn true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.clearToken();\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t} catch (e) {\r\n\t\t\tthis.clearToken();\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\t// options: AkReqOptions, skipRefresh: boolean = false\r\n\tstatic async request(options : AkReqOptions, skipRefresh ?: boolean) : Promise> {\r\n\t\t// 自动刷新 token\r\n\t\tif (skipRefresh != true) {\r\n\t\t\tlet apikey : string | null = null;\r\n\t\t\tconst headersObj = options.headers;\r\n\t\t\tif (headersObj != null && typeof headersObj.getString === 'function') {\r\n\t\t\t\tapikey = headersObj.getString('apikey');\r\n\t\t\t}\r\n\t\t\tawait this.refreshTokenIfNeeded(apikey);\r\n\t\t}\r\n\r\n\t\t// 构建新的 headers 对象,确保所有字段都被正确传递\r\n\t\tconst newHeaders = new UTSJSONObject()\r\n\t\t\r\n\t\t// 首先复制原始 headers\r\n\t\tif (options.headers != null) {\r\n\t\t\tconst originalHeaders = options.headers\r\n\t\t\tif (typeof originalHeaders.getString === 'function') {\r\n\t\t\t\t// 复制 apikey\r\n\t\t\t\tconst apikeyStr = originalHeaders.getString('apikey')\r\n\t\t\t\tif (apikeyStr != null) {\r\n\t\t\t\t\tnewHeaders.set('apikey', apikeyStr)\r\n\t\t\t\t}\r\n\t\t\t\t// 复制 Content-Type\r\n\t\t\t\tconst contentType = originalHeaders.getString('Content-Type')\r\n\t\t\t\tif (contentType != null) {\r\n\t\t\t\t\tnewHeaders.set('Content-Type', contentType)\r\n\t\t\t\t}\r\n\t\t\t\t// 复制 Prefer\r\n\t\t\t\tconst prefer = originalHeaders.getString('Prefer')\r\n\t\t\t\tif (prefer != null) {\r\n\t\t\t\t\tnewHeaders.set('Prefer', prefer)\r\n\t\t\t\t}\r\n\t\t\t\t// 复制 Authorization(如果存在)\r\n\t\t\t\tconst auth = originalHeaders.getString('Authorization')\r\n\t\t\t\tif (auth != null) {\r\n\t\t\t\t\tnewHeaders.set('Authorization', auth)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// 补齐 apikey (如果 headers 中没有,则直接使用 SUPA_KEY 补全)\r\n\t\tif (newHeaders.getString('apikey') == null) {\r\n\t\t\tif (SUPA_KEY != null && SUPA_KEY != \"\") {\r\n\t\t\t\tnewHeaders.set('apikey', SUPA_KEY)\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// 添加/更新 Authorization\r\n\t\tconst token = this.getToken();\r\n\t\tif (token != null && token != \"\") {\r\n\t\t\tnewHeaders.set('Authorization', `Bearer ${token}`)\r\n\t\t}\r\n\t\t\r\n\t\t// 确保 Content-Type 存在\r\n\t\tif (newHeaders.getString('Content-Type') == null) {\r\n\t\t\tconst contentType = options.contentType ?? 'application/json'\r\n\t\t\tif (contentType != null && contentType != \"\") {\r\n\t\t\t\tnewHeaders.set('Content-Type', contentType)\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// 添加 Accept\r\n\t\tnewHeaders.set('Accept', 'application/json')\r\n\t\t\r\n\t\t__f__('log','at uni_modules/ak-req/ak-req.uts:175','[AkReq.request] headers:', JSON.stringify(newHeaders))\r\n\t\t\r\n\t\tconst headers = newHeaders\r\n\r\n\t\tconst timeout = options.timeout ?? 10000;\r\n\t\tconst maxRetry = Math.max(0, options.retryCount ?? 0);\r\n\t\tconst baseDelay = Math.max(0, options.retryDelayMs ?? 300);\r\n\r\n\t\tconst doOnce = (): Promise> => {\r\n\t\t\treturn new Promise>((resolve) => {\r\n\t\t\t\tuni.request({\r\n\t\t\t\t\turl: options.url,\r\n\t\t\t\t\tmethod: options.method ?? 'GET',\r\n\t\t\t\t\tdata: options.data,\r\n\t\t\t\t\theader: headers,\r\n\t\t\t\t\ttimeout: timeout,\r\n\t\t\t\t\tsuccess: (res) => {\r\n\t\t\t\t\t\t// HEAD 请求特殊处理:没有响应体,只有 headers\r\n\t\t\t\t\t\tif (options.method == 'HEAD') {\r\n\t\t\t\t\t\t\tconst result = AkReq.createResponse(\r\n\t\t\t\t\t\t\t\tres.statusCode,\r\n\t\t\t\t\t\t\t\t[] as Array,\r\n\t\t\t\t\t\t\t\tres.header as UTSJSONObject\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\tresolve(result);\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// 兼容 res.data 可能为 string 或 UTSJSONObject 或 UTSArray\r\n\t\t\t\t\t\tlet data : UTSJSONObject | Array | null;\r\n\t\t\t\t\t\tif (typeof res.data == 'string') {\r\n\t\t\t\t\t\t\tconst strData = res.data as string;\r\n\t\t\t\t\t\t\tif (strData.length > 0 && /[^\\s]/.test(strData)) {\r\n\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\tdata = JSON.parse(strData) as UTSJSONObject;\r\n\t\t\t\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t\t\t\t// 非 JSON 响应(例如纯文本/空响应/数字等),保持原始字符串,避免 JSON.parse 崩溃\r\n\t\t\t\t\t\t\t\t\tdata = new UTSJSONObject({ raw: strData });\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tdata = null;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else if (Array.isArray(res.data)) {\r\n\t\t\t\t\t\t\tdata = res.data as UTSJSONObject[];\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tconst objData = res.data as UTSJSONObject | null;\r\n\t\t\t\t\t\t\tdata = objData;\r\n\t\t\t\t\t\t\tif (objData != null) {\r\n\t\t\t\t\t\t\t\tconst accessToken = objData.getString('access_token');\r\n\t\t\t\t\t\t\t\tconst refreshTokenNew = objData.getString('refresh_token');\r\n\t\t\t\t\t\t\t\tconst expiresAt = objData.getNumber('expires_at');\r\n\t\t\t\t\t\t\t\tif (accessToken !== null && refreshTokenNew !== null && expiresAt !== null) {\r\n\t\t\t\t\t\t\t\t\tAkReq.setToken(accessToken, refreshTokenNew, expiresAt);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tconst result = AkReq.createResponse(\r\n\t\t\t\t\t\t\tres.statusCode,\r\n\t\t\t\t\t\t\tdata ?? {},\r\n\t\t\t\t\t\t\tres.header as UTSJSONObject\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tresolve(result);\r\n\t\t\t\t\t},\r\n\t\t\t\t\tfail: (err) => {\r\n\t\t\t\t\t\tconst errStatus = (err.errCode != null && typeof err.errCode === 'number') ? err.errCode : 0;\r\n\t\t\t\t\t\tconst result = AkReq.createResponse(\r\n\t\t\t\t\t\t\terrStatus,\r\n\t\t\t\t\t\t\t{} as UTSJSONObject,\r\n\t\t\t\t\t\t\t{} as UTSJSONObject,\r\n\t\t\t\t\t\t\tnew UniError('uni-request', errStatus, err.errMsg ?? 'request fail')\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tresolve(result);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t};\r\n\r\n\t\tlet attempt = 0;\r\n\t\tlet lastRes: AkReqResponse | null = null;\r\n\t\twhile (attempt <= maxRetry) {\r\n\t\t\tconst res = await doOnce();\r\n\t\t\tlastRes = res;\r\n\t\t\t// 仅网络失败/超时(errCode 非 0 且 status 非 2xx/3xx)时重试\r\n\t\t\tconst status = res.status ?? 0;\r\n\t\t\tconst isOk = status >= 200 && status < 400;\r\n\t\t\tif (isOk) return res;\r\n\t\t\tif (attempt === maxRetry) break;\r\n\t\t\t// 简单退避\r\n\t\t\tconst delay = baseDelay * Math.pow(2, attempt);\r\n await new Promise((r) => { setTimeout(() => { r(); }, delay); });\r\n\t\t\tattempt++;\r\n\t\t}\r\n\t\tconst finalRes = lastRes!!;\r\n\t\t// 全局处理 401 未授权:在非 refresh 场景下,清理 token。\r\n\t\t// 测试模式下不强制跳登录页,避免影响任意跳转调试。\r\n\t\tif ((finalRes.status === 401) && (skipRefresh !== true)) {\r\n\t\t\ttry {\r\n\t\t\t\tthis.clearToken();\r\n\t\t\t\tuni.showToast({ title: '未授权或登录已过期,请重新登录', icon: 'none' });\r\n\t\t\t} catch (e) {}\r\n\t\t\ttry {\r\n\t\t\t\t// 动态读取配置,避免 ak-req 模块与业务工程强耦合\r\n\t\t\t\t// const cfg = require('@/ak/config.uts') as any\r\n\t\t\t\t// const isTest = cfg != null ? (cfg.IS_TEST_MODE === true) : false\r\n const isTest = IS_TEST_MODE\r\n\t\t\t\t// if (!isTest) {\r\n\t\t\t\t// \tuni.reLaunch({ url: '/pages/user/login' });\r\n\t\t\t\t// }\r\n\t\t\t} catch (e) {\r\n\t\t\t\t// try { uni.reLaunch({ url: '/pages/user/login' }); } catch (e2) {}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn finalRes;\r\n\t}\r\n\r\n\t// 新增 upload 方法,支持 uni.uploadFile,自动带 token/apikey\t\r\n\tstatic async upload(options : AkReqUploadOptions) : Promise> {\r\n\t\t// 上传前尝试刷新 token(若即将过期)。优先从 options.headers 或 apikey 字段获取 apikey\r\n\t\tlet apikey: string | null = null;\r\n\t\tconst hdr = options.headers;\r\n\t\tif (hdr != null && typeof hdr.getString === 'function') {\r\n\t\t\tapikey = hdr.getString('apikey');\r\n\t\t}\r\n if (apikey == null && options.apikey != null) apikey = options.apikey;\r\n await this.refreshTokenIfNeeded(apikey != null ? apikey : null);\r\n\r\n\t\tlet headers = options.headers ?? ({} as UTSJSONObject);\r\n\t\tconst token = this.getToken();\r\n\t\tif (token != null && token !== \"\") {\r\n\t\t\theaders = Object.assign({}, headers, { Authorization: `Bearer ${token}` }) as UTSJSONObject;\r\n\t\t}\r\n if (apikey != null && apikey !== \"\") {\r\n\t\t\theaders = Object.assign({}, headers, { apikey: apikey }) as UTSJSONObject;\r\n\t\t}\r\n\t\t// 默认 Accept\r\n\t\theaders = Object.assign({ Accept: 'application/json' } as UTSJSONObject, headers) as UTSJSONObject;\r\n\r\n\t\tconst timeout = options.timeout ?? 10000;\r\n\t\tconst maxRetry = Math.max(0, options.retryCount ?? 0);\r\n\t\tconst baseDelay = Math.max(0, options.retryDelayMs ?? 300);\r\n\r\n\t\tconst doOnce = (): Promise> => {\r\n\t\t\treturn new Promise>((resolve) => {\r\n\t\tconst task = uni.uploadFile({\r\n\t\t\turl: options.url,\r\n\t\t\tfilePath: options.filePath,\r\n\t\t\tname: options.name,\r\n\t\t\tformData: options.formData ?? {},\r\n\t\t\theader: headers,\r\n\t\t\ttimeout: timeout,\r\n\t\t\tsuccess: (res : UploadFileSuccess) => {\r\n\t\t\t\tlet parsed: UTSJSONObject | null = null;\r\n\t\t\t\ttry {\r\n\t\t\t\t\tparsed = JSON.parse(res.data) as UTSJSONObject;\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tparsed = null;\r\n\t\t\t\t}\r\n\t\t\t\tif (parsed != null) {\r\n\t\t\t\t\tconst accessToken = parsed.getString('access_token');\r\n\t\t\t\t\tconst refreshTokenNew = parsed.getString('refresh_token');\r\n\t\t\t\t\tconst expiresAt = parsed.getNumber('expires_at');\r\n\t\t\t\t\tif (accessToken !== null && refreshTokenNew !== null && expiresAt !== null) {\r\n\t\t\t\t\t\tAkReq.setToken(accessToken, refreshTokenNew, expiresAt);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tconst result = AkReq.createResponse(\r\n\t\t\t\t\tres.statusCode,\r\n\t\t\t\t\tparsed ?? {},\r\n\t\t\t\t\theaders\r\n\t\t\t\t);\r\n\t\t\t\tresolve(result);\r\n\t\t\t},\r\n\t\t\tfail: (err) => {\r\n\t\t\t\tconst errStatus = (err.errCode != null && typeof err.errCode === 'number') ? err.errCode : 0;\r\n\t\t\t\tconst result = AkReq.createResponse(\r\n\t\t\t\t\terrStatus,\r\n\t\t\t\t\t{} as UTSJSONObject,\r\n\t\t\t\t\t{} as UTSJSONObject,\r\n\t\t\t\t\tnew UniError('uni-upload', errStatus, err.errMsg ?? 'upload fail')\r\n\t\t\t\t);\r\n\t\t\t\tresolve(result);\r\n\t\t\t}\r\n\t\t});\r\n\t\tif (options.onProgress != null && task != null) {\r\n\t\t\tconst progressCallback = (res: OnProgressUpdateResult) => {\r\n\t\t\t\tconst percent = res.progress as number; // 0-100\r\n\t\t\t\tconst sent = res.totalBytesSent as number | null;\r\n\t\t\t\tconst expected = res.totalBytesExpectedToSend as number | null;\r\n\t\t\t\tif (options.onProgress != null) {\r\n\t\t\t\t\toptions.onProgress(percent, sent, expected);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\ttask.onProgressUpdate(progressCallback);\r\n\t\t}\r\n\t\t\t});\r\n\t\t};\r\n\r\n\t\tlet attempt = 0;\r\n\t\tlet lastRes: AkReqResponse | null = null;\r\n\t\twhile (attempt <= maxRetry) {\r\n\t\t\tconst res = await doOnce();\r\n\t\t\tlastRes = res;\r\n\t\t\tconst status = res.status ?? 0;\r\n\t\t\tconst isOk = status >= 200 && status < 400;\r\n\t\t\tif (isOk) return res;\r\n\t\t\tif (attempt === maxRetry) break;\r\n\t\t\tconst delay = baseDelay * Math.pow(2, attempt);\r\n\t\t\tawait new Promise((resolve) => {\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\tresolve();\r\n\t\t\t\t}, delay);\r\n\t\t\t});\r\n\t\t\tattempt++;\r\n\t\t}\r\n\t\treturn lastRes!!;\r\n\t}\r\n\t// 辅助方法:创建 AkReqResponse 对象,避免类型推断问题\r\n\tstatic createResponse(\r\n\t\tstatus: number,\r\n\t\tdata: T | Array ,\r\n\t\theaders: UTSJSONObject,\r\n\t\terror: UniError | null = null,\r\n\t\ttotal: number | null = null,\r\n\t\tpage: number | null = null,\r\n\t\tlimit: number | null = null,\r\n\t\thasmore: boolean | null = null,\r\n\t\torigin: any | null = null\r\n\t): AkReqResponse {\r\n\t\treturn {\r\n\t\t\tstatus,\r\n\t\t\tdata,\r\n\t\t\theaders,\r\n\t\t\terror,\r\n\t\t\ttotal,\r\n\t\t\tpage,\r\n\t\t\tlimit,\r\n\t\t\thasmore,\r\n\t\t\torigin\r\n\t\t};\r\n\t}\r\n\r\n}\r\n\r\nexport default AkReq;","\r\n\r\n\r\n","import { initRuntimeSocket } from './socket'\n\nexport function initRuntimeSocketService(): Promise {\n const hosts: string = process.env.UNI_SOCKET_HOSTS\n const port: string = process.env.UNI_SOCKET_PORT\n const id: string = process.env.UNI_SOCKET_ID\n if (hosts == '' || port == '' || id == '') return Promise.resolve(false)\n let socketTask: SocketTask | null = null\n __registerWebViewUniConsole(\n (): string => {\n return process.env.UNI_CONSOLE_WEBVIEW_EVAL_JS_CODE\n },\n (data: string) => {\n socketTask?.send({\n data,\n } as SendSocketMessageOptions)\n }\n )\n return Promise.resolve()\n .then((): Promise => {\n return initRuntimeSocket(hosts, port, id).then((socket): boolean => {\n if (socket == null) {\n return false\n }\n socketTask = socket\n return true\n })\n })\n .catch((): boolean => {\n return false\n })\n}\n\ninitRuntimeSocketService()\n","// ak-req 类型定义\r\nexport type AkReqOptions = {\r\n url: string;\r\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' |'HEAD';\r\n data?: UTSJSONObject | Array;\r\n headers?: UTSJSONObject;\r\n timeout?: number;\r\n contentType?: string; // 新增,支持顶级 contentType\r\n // 可选:重试设置(仅网络错误/超时触发)。默认重试 0 次\r\n retryCount?: number; // 最大重试次数,默认 0\r\n retryDelayMs?: number; // 首次重试延迟,默认 300ms,指数退避\r\n};\r\n// 上传参数类型定义\r\nexport type AkReqUploadOptions = {\r\n url: string,\r\n filePath: string,\r\n name: string,\r\n formData?: UTSJSONObject,\r\n headers?: UTSJSONObject,\r\n apikey?: string,\r\n timeout?: number,\r\n // 进度回调,0-100(注意:H5/APP 平台支持不同)\r\n onProgress?: (progress: number, transferredBytes?: number, totalBytes?: number) => void,\r\n // 可选:重试设置(仅网络错误/超时触发)。默认 0\r\n retryCount?: number,\r\n retryDelayMs?: number\r\n};\r\n\r\nexport type AkReqResponse = {\r\n status: number;\r\n data: T | Array | null; // 支持 null\r\n headers: UTSJSONObject;\r\n error: UniError | null;\r\n total:number |null;\r\n page: number |null;\r\n limit: number |null;\r\n hasmore:boolean |null;\r\n origin: any | null;\r\n};\r\n\r\nexport class AkReqError extends Error {\r\n code: number;\r\n constructor(message: string, code: number = 0) {\r\n super(message);\r\n this.code = code;\r\n this.name = 'AkReqError';\r\n }\r\n}\r\n","// Supabase 配置\r\n// 内网环境 - 本地部署的 Supabase\r\n// IP: 192.168.1.62\r\n// Kong HTTP Port: 8000\r\n\r\n//export const SUPA_URL: string = 'http://192.168.1.61:18000'\r\n//export const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlLTEiLCJpYXQiOjE3Njk2NzY0OTgsImV4cCI6MTkyNzM1NjQ5OH0.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'\r\nexport const SUPA_URL: string = 'http://119.146.131.237:9126'\r\nexport const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlLTEiLCJpYXQiOjE3Njk2NzY0OTgsImV4cCI6MTkyNzM1NjQ5OH0.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'\r\n\r\n// WebSocket 实时连接(内网使用 ws:// 而非 wss://)\r\nexport const WS_URL: string = 'ws://119.146.131.237:9126/realtime/v1/websocket'\r\n//export const WS_URL: string = 'ws://localhost:18000/realtime/v1/websocket'\r\n\r\n// 备用配置(已注释,如需切换可取消注释)\r\n// 开发环境 - 其他内网地址\r\n// export const SUPA_URL: string = 'http://192.168.0.150:8080'\r\n// export const SUPA_KEY: string = 'your-anon-key'\r\n// export const WS_URL: string = 'ws://192.168.0.150:8080/realtime/v1/websocket'\r\n\r\n// 生产环境 - Supabase 云服务(已注释)\r\n// export const SUPA_URL: string = 'https://ak3.oulog.com'\r\n// export const SUPA_KEY: string = 'your-anon-key'\r\n// export const WS_URL: string = 'wss://ak3.oulog.com/realtime/v1/websocket'\r\n\r\n// 指向你的 Supabase 服务(开发/私有部署)\r\n// export const SUPA_URL: string = 'http://192.168.1.64:3000'\r\n// export const SUPA_KEY: string = 'your-anon-key'\r\n// export const WS_URL: string = 'ws://192.168.1.64:3000/realtime/v1'\r\n\r\n// 路由配置\r\nexport const HOME_REDIRECT: string = '/pages/main/index'\r\nexport const TABORPAGE: string = '/pages/main/index'\r\n\r\n// 测试模式:放开任意跳转(禁用启动页/登录/401 的强制重定向)\r\nexport const IS_TEST_MODE: boolean = true","// i18n 国际化配置\r\n// 这是一个简化的 i18n 实现,用于支持多语言切换\r\n\r\n// 语言资源\r\nconst messages: UTSJSONObject = new UTSJSONObject()\r\n\r\n// 默认语言\r\nconst defaultLocale = 'zh-CN'\r\n\r\n// 当前语言(响应式)\r\nlet currentLocale = defaultLocale\r\n\r\n// 翻译函数\r\nfunction t(key: string, values: UTSJSONObject | null = null, locale: string | null = null): string {\r\n\tconst targetLocale = locale ?? currentLocale\r\n\t// 这里应该从 messages 中获取翻译,简化实现直接返回 key\r\n\t// 实际项目中应该加载语言资源文件\r\n\treturn key\r\n}\r\n\r\n// 创建响应式 locale 对象\r\nclass LocaleWrapper {\r\n get value(): string {\r\n return currentLocale\r\n }\r\n set value(newLocale: string) {\r\n currentLocale = newLocale\r\n }\r\n}\r\nconst localeObj = new LocaleWrapper()\r\n\r\n// I18n Global Context\r\nclass I18nGlobal {\r\n\tt(key: string, values: UTSJSONObject | null = null, locale: string | null = null): string {\r\n\t\treturn t(key, values, locale)\r\n\t}\r\n\tlocale: LocaleWrapper = localeObj\r\n}\r\n\r\n// I18n Instance\r\nclass I18nInstance {\r\n\tglobal: I18nGlobal = new I18nGlobal()\r\n}\r\n\r\n// 导出 i18n 对象\r\nconst i18n = new I18nInstance()\r\nexport default i18n\r\n","// 通用 UTSJSONObject 转任意 type 的函数\r\n// UTS 2024\r\n\r\nimport i18n from '@/uni_modules/i18n/index.uts';\r\n\r\n/**\r\n * 切换应用语言设置\r\n * @param locale 语言代码,如 'zh-CN' 或 'en-US'\r\n */\r\nexport function switchLocale(locale: string) {\r\n // 设置存储\r\n uni.setStorageSync('uVueI18nLocale', locale);\r\n \r\n // 设置 i18n 语言\r\n try {\r\n if (i18n != null && i18n.global != null) {\r\n i18n.global.locale.value = locale;\r\n }\r\n } catch (err) {\r\n __f__('error','at utils/utils.uts:20','Failed to switch locale:', err);\r\n }\r\n}\r\n\r\n/**\r\n * 获取当前语言设置\r\n * @returns 当前语言代码\r\n */\r\nexport function getCurrentLocale(): string {\r\n const locale = uni.getStorageSync('uVueI18nLocale') as string;\r\n if (locale == null || locale == '') {\r\n return 'zh-CN';\r\n }\r\n return locale;\r\n}\r\n\r\n/**\r\n * 确保语言设置正确初始化\r\n */\r\nexport function ensureLocaleInitialized() {\r\n const currentLocale = getCurrentLocale();\r\n if (currentLocale == null || currentLocale == '') {\r\n switchLocale('zh-CN');\r\n }\r\n}\r\n/**\r\n * 将任意错误对象转换为标准的 UniError\r\n * @param error 任意类型的错误对象\r\n * @param defaultMessage 默认错误消息\r\n * @returns 标准化的 UniError 对象\r\n */\r\nexport function toUniError(error: any, defaultMessage: string = '操作失败'): UniError {\r\n // 如果已经是 UniError,直接返回\r\n if (error instanceof UniError) {\r\n return error\r\n }\r\n let errorMessage = defaultMessage\r\n let errorCode = -1\r\n \r\n try {\r\n // 如果是普通 Error 对象\r\n if (error instanceof Error) {\r\n errorMessage = error.message != null && error.message != '' ? error.message : defaultMessage\r\n }\r\n // 如果是字符串\r\n else if (typeof error === 'string') {\r\n errorMessage = error\r\n } // 如果是对象,尝试提取错误信息\r\n else if (error != null && typeof error === 'object') {\r\n const errorObj = error as UTSJSONObject\r\n let message: string = ''\r\n \r\n // 逐个检查字段,避免使用 || 操作符\r\n if (errorObj['message'] != null) {\r\n const msgValue = errorObj['message']\r\n if (typeof msgValue === 'string') {\r\n message = msgValue\r\n }\r\n } else if (errorObj['errMsg'] != null) {\r\n const msgValue = errorObj['errMsg']\r\n if (typeof msgValue === 'string') {\r\n message = msgValue\r\n }\r\n } else if (errorObj['error'] != null) {\r\n const msgValue = errorObj['error']\r\n if (typeof msgValue === 'string') {\r\n message = msgValue\r\n }\r\n } else if (errorObj['details'] != null) {\r\n const msgValue = errorObj['details']\r\n if (typeof msgValue === 'string') {\r\n message = msgValue\r\n }\r\n } else if (errorObj['msg'] != null) {\r\n const msgValue = errorObj['msg']\r\n if (typeof msgValue === 'string') {\r\n message = msgValue\r\n }\r\n }\r\n \r\n if (message != '') {\r\n errorMessage = message\r\n }\r\n \r\n // 尝试提取错误码\r\n let code: number = 0\r\n if (errorObj['code'] != null) {\r\n const codeValue = errorObj['code']\r\n if (typeof codeValue === 'number') {\r\n code = codeValue\r\n }\r\n } else if (errorObj['errCode'] != null) {\r\n const codeValue = errorObj['errCode']\r\n if (typeof codeValue === 'number') {\r\n code = codeValue\r\n }\r\n } else if (errorObj['status'] != null) {\r\n const codeValue = errorObj['status']\r\n if (typeof codeValue === 'number') {\r\n code = codeValue\r\n }\r\n }\r\n \r\n if (code != 0) {\r\n errorCode = code\r\n }\r\n }\r\n } catch (e) {\r\n __f__('error','at utils/utils.uts:128','Error converting to UniError:', e)\r\n errorMessage = defaultMessage\r\n }\r\n // 创建标准 UniError\r\n const uniError = new UniError('AppError', errorCode, errorMessage)\r\n return uniError\r\n}\r\n\r\n/**\r\n * 响应式状态管理\r\n * @returns 响应式状态对象\r\n */\r\nexport function responsiveState() {\r\n const screenInfo = uni.getSystemInfoSync()\r\n const screenWidth = screenInfo.screenWidth\r\n \r\n return {\r\n isLargeScreen: screenWidth >= 768,\r\n isSmallScreen: screenWidth < 576,\r\n screenWidth: screenWidth,\r\n cardColumns: screenWidth >= 768 ? 3 : screenWidth >= 576 ? 2 : 1\r\n }\r\n}\r\n\r\nexport function goToLogin(redirectUrl?: string | null) {\r\n try {\r\n const target = redirectUrl != null && redirectUrl.length > 0 ? redirectUrl : ''\r\n if (target.length > 0) {\r\n const redirect = encodeURIComponent(target)\r\n uni.navigateTo({ url: `/pages/user/login?redirect=${redirect}` })\r\n } else {\r\n uni.navigateTo({ url: '/pages/user/login' })\r\n }\r\n } catch (e) {\r\n uni.navigateTo({ url: '/pages/user/login' })\r\n }\r\n}\r\n\r\n/**\r\n * 兼容 UTS Android 的剪贴板写入\r\n * @param text 要写入剪贴板的文本\r\n */\r\nexport function setClipboard(text: string): void {\r\n\r\n\r\n\r\n}\r\n\r\n/**\r\n * 格式化时间,显示为相对时间(如:刚刚,几小时前)\r\n * @param dateStr ISO 格式的日期字符串\r\n * @returns 格式化后的相对时间字符串\r\n */\r\nexport function formatTime(dateStr: string): string {\r\n if (dateStr == '') return ''\r\n try {\r\n const date = new Date(dateStr)\r\n const now = new Date()\r\n const diff = now.getTime() - date.getTime()\r\n const hours = Math.floor(diff / (1000 * 60 * 60))\r\n \r\n if (hours < 1) {\r\n return '刚刚'\r\n } else if (hours < 24) {\r\n return `${hours}小时前`\r\n } else {\r\n return `${Math.floor(hours / 24)}天前`\r\n }\r\n } catch (e) {\r\n __f__('error','at utils/utils.uts:197','formatTime error:', e)\r\n return dateStr.replace('T', ' ').split('.')[0]\r\n }\r\n}\r\n\r\n","import { AkReqResponse, AkReqUploadOptions, AkReq } from '@/uni_modules/ak-req/index.uts'\r\nimport type { AkReqOptions } from '@/uni_modules/ak-req/index.uts'\r\nimport { toUniError } from '@/utils/utils.uts'\r\n\r\nexport type AkSupaSignInResult = {\r\n\taccess_token : string;\r\n\trefresh_token : string;\r\n\texpires_at : number;\r\n\tuser : UTSJSONObject | null;\r\n\ttoken_type ?: string;\r\n\texpires_in ?: number;\r\n\traw : UTSJSONObject;\r\n}\r\n\r\n// Count 选项枚举\r\nexport type CountOption = 'exact' | 'planned' | 'estimated';\r\n\r\n// 定义查询选项类型,兼容 UTS\r\nexport type AkSupaSelectOptions = {\r\n\tlimit ?: number;\r\n\torder ?: string;\r\n\tgetcount ?: string; // 保持向后兼容\r\n\tcount ?: CountOption; // 新增:更清晰的 count 选项\r\n\thead ?: boolean; // 新增:head 模式,只返回元数据\r\n\tcolumns ?: string;\r\n\tsingle ?: boolean; // 新增,支持 single-object\r\n\trangeFrom ?: number; // 新增:range 分页起始位置\r\n\trangeTo ?: number; // 新增:range 分页结束位置\r\n};\r\n\r\n// 新增:order方法参数类型\r\nexport type OrderOptions = {\r\n\tascending ?: boolean;\r\n};\r\n\r\n// 新增类型定义,便于 getSession 返回类型复用\r\nexport type AkSupaSessionInfo = {\r\n\tsession : AkSupaSignInResult | null;\r\n\tuser : UTSJSONObject | null;\r\n};\r\n\r\n// 链式请求构建器\r\n// 强类型条件定义\r\ntype AkSupaCondition = {\r\n\tfield : string; // 已经 encodeURIComponent 过\r\n\top : string;\r\n\tvalue : any;\r\n\tlogic : string; // 'and' | 'or'\r\n};\r\n\r\nexport class AkSupaQueryBuilder {\r\n\tprivate _supa : AkSupa;\r\n\tprivate _table : string;\r\n\tprivate _filter : UTSJSONObject | null = null;\r\n\tprivate _options : AkSupaSelectOptions = {};\r\n\tprivate _values : UTSJSONObject | Array | null = null;\r\n\tprivate _single : boolean = false;\r\n\tprivate _conditions : Array = [];\r\n\tprivate _nextLogic : string = 'and';\r\n\t// 新增:记录当前操作类型\r\n\tprivate _action : 'select' | 'insert' | 'update' | 'delete' | 'rpc' | null = null;\r\n\tprivate _orString : string | null = null; // 新增:支持 or 字符串\r\n\tprivate _rpcFunction : string | null = null;\r\n\tprivate _rpcParams : UTSJSONObject | null = null;\r\n\tprivate _page : number = 1; // 新增:当前页码\r\n\r\n\tconstructor(supa : AkSupa, table : string) {\r\n\t\tthis._supa = supa;\r\n\t\tthis._table = table;\r\n\t}\r\n\r\n\t// 链式条件方法\r\n\teq(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'eq', value); }\r\n\tneq(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'neq', value); }\r\n\tgt(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'gt', value); }\r\n\tgte(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'gte', value); }\r\n\tlt(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'lt', value); }\r\n\tlte(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'lte', value); }\r\n\tlike(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'like', value); }\r\n\tilike(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'ilike', value); }\r\n\tin(field : string, value : any[]) : AkSupaQueryBuilder { return this._addCond(field, 'in', value); }\r\n\tis(field : string, value : any | null) : AkSupaQueryBuilder { return this._addCond(field, 'is', value); }\r\n\tcontains(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'cs', value); }\r\n\tcontainedBy(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'cd', value); }\r\n\tnot(field : string, opOrValue : any, value: any | null = null) : AkSupaQueryBuilder {\r\n\t\tif (value != null) {\r\n\t\t\t// 三元形式:field, operator, value\r\n\t\t\t// 例如 not('badge', 'is', null) -> badge=not.is.null\r\n\t\t\tconst combinedOp = 'not.' + opOrValue;\r\n\t\t\t// 将 null 转换为字符串 'null',避免构造对象时缺少 value 属性\r\n\t\t\tlet safeValue = value;\r\n\t\t\tif (value === null) {\r\n\t\t\t\tsafeValue = 'null';\r\n\t\t\t}\r\n\t\t\treturn this._addCond(field, combinedOp, safeValue);\r\n\t\t} else {\r\n\t\t\t// 二元形式:field, value\r\n\t\t\tlet safeValue = opOrValue;\r\n\t\t\tif (opOrValue === null) {\r\n\t\t\t\tsafeValue = 'null';\r\n\t\t\t}\r\n\t\t\treturn this._addCond(field, 'not', safeValue);\r\n\t\t}\r\n\t}\r\n\r\n\tand() : AkSupaQueryBuilder { this._nextLogic = 'and'; return this; }\r\n\tor(str ?: string) : AkSupaQueryBuilder {\r\n\t\tif (typeof str == 'string') {\r\n\t\t\tthis._orString = str;\r\n\t\t} else {\r\n\t\t\tthis._nextLogic = 'or';\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n\tprivate _addCond(afield : string, op : string, value : any | null) : AkSupaQueryBuilder {\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:117','add cond:', op, afield, value)\r\n\t\tconst field = encodeURIComponent(afield)!!\r\n\t\t// 将值安全存储,避免安卓端类型转换问题\r\n\t\tlet safeValue: any | null = value;\r\n\t\tif (value === null) {\r\n\t\t\tsafeValue = 'null';\r\n\t\t} else if (Array.isArray(value)) {\r\n\t\t\t// 数组类型保持原样,用于 in 操作符\r\n\t\t\tsafeValue = value;\r\n\t\t} else if (typeof value === 'number') {\r\n\t\t\t// 数字类型保持原样\r\n\t\t\tsafeValue = value;\r\n\t\t} else if (typeof value === 'boolean') {\r\n\t\t\t// 布尔类型保持原样\r\n\t\t\tsafeValue = value;\r\n\t\t} else if (typeof value !== 'string') {\r\n\t\t\t// 其他类型尝试转换为字符串\r\n\t\t\ttry {\r\n\t\t\t\tsafeValue = value.toString();\r\n\t\t\t} catch (e) {\r\n\t\t\t\tsafeValue = '';\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._conditions.push({ field, op, value: safeValue ?? '', logic: this._nextLogic });\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:141',this._conditions)\r\n\t\tthis._nextLogic = 'and';\r\n\t\treturn this;\r\n\t}\r\n\r\n\t// 支持原有 where 方式\r\n\twhere(filter : UTSJSONObject) : AkSupaQueryBuilder {\r\n\t\tthis._filter = filter;\r\n\t\treturn this;\r\n\t}\r\n\r\n\tpage(page : number) : AkSupaQueryBuilder {\r\n\t\tthis._page = page;\r\n\t\t// 如果已设置 limit,则自动设置 range\r\n\t\tlet limit = 0;\r\n\t\tif (typeof this._options.limit == 'number') {\r\n\t\t\tlimit = this._options.limit ?? 0;\r\n\t\t}\r\n\t\tif (limit > 0) {\r\n\t\t\tconst from = (page - 1) * limit;\r\n\t\t\tconst to = from + limit - 1;\r\n\t\t\tthis.range(from, to);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\tlimit(limit : number) : AkSupaQueryBuilder {\r\n\t\tthis._options.limit = limit;\r\n\t\t// 总是为 limit 设置对应的 range,确保限制生效\r\n\t\tconst from = (this._page - 1) * limit;\r\n\t\tconst to = from + limit - 1;\r\n\t\tthis.range(from, to);\r\n\t\treturn this;\r\n\t}\r\n\r\n\torder(order : string, options ?: OrderOptions) : AkSupaQueryBuilder {\r\n\t\tif (options != null && options.ascending == false) {\r\n\t\t\tthis._options.order = order + '.desc';\r\n\t\t} else {\r\n\t\t\tthis._options.order = order + '.asc';\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\tcolumns(columns : string) : AkSupaQueryBuilder {\r\n\t\tthis._options.columns = columns;\r\n\t\treturn this;\r\n\t}\r\n\r\n\t// 新增:专门的 count 方法\r\n\tcount(option : CountOption = 'exact') : AkSupaQueryBuilder {\r\n\t\tthis._options.count = option;\r\n\t\tthis._options.head = true; // count 操作默认使用 head 模式\r\n\t\treturn this;\r\n\t}\r\n\r\n\t// 新增:便捷的 count 方法\r\n\tcountExact() : AkSupaQueryBuilder {\r\n\t\treturn this.count('exact');\r\n\t}\r\n\r\n\tcountEstimated() : AkSupaQueryBuilder {\r\n\t\treturn this.count('estimated');\r\n\t}\r\n\r\n\tcountPlanned() : AkSupaQueryBuilder {\r\n\t\treturn this.count('planned');\r\n\t}\r\n\r\n\t// 新增:head 模式方法\r\n\thead(enable : boolean = true) : AkSupaQueryBuilder {\r\n\t\tthis._options.head = enable;\r\n\t\treturn this;\r\n\t}\r\n\r\n\tvalues(values : UTSJSONObject) : AkSupaQueryBuilder {\r\n\t\tthis._values = values;\r\n\t\treturn this;\r\n\t}\r\n\tsingle() : AkSupaQueryBuilder {\r\n\t\tthis._single = true;\r\n\t\treturn this;\r\n\t}\r\n\trange(from : number, to : number) : AkSupaQueryBuilder {\r\n\t\tthis._options.rangeFrom = from;\r\n\t\tthis._options.rangeTo = to;\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:225','设置 range:', from, 'to', to);\r\n\t\treturn this;\r\n\t}\r\n\r\n\t// 辅助函数:安全地将值转换为字符串\r\n\tprivate _valToStr(val: any): string {\r\n\t\tif (val == null) return '';\r\n\t\ttry {\r\n\t\t\t// 尝试直接调用 toString\r\n\t\t\treturn val.toString();\r\n\t\t} catch (e) {\r\n\t\t\ttry {\r\n\t\t\t\t// 尝试 JSON 序列化\r\n\t\t\t\treturn JSON.stringify(val);\r\n\t\t\t} catch (e2) {\r\n\t\t\t\treturn '';\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// 将 _conditions 强类型直接转换为 Supabase/PostgREST 查询字符串(不再用 UTSJSONObject 做中转)\r\n\tprivate _buildFilter() : string | null {\r\n\t\tif (this._conditions.length == 0 && (this._orString==null || this._orString == \"\")) {\r\n\t\t\t// 兼容 where(filter) 方式\r\n\t\t\tif (this._filter == null) return null;\r\n\t\t\t// 兼容旧的 UTSJSONObject filter\r\n\t\t\treturn buildSupabaseFilterQuery(this._filter);\r\n\t\t}\r\n\r\n\t\t// 先分组 and/or,全部用 AkSupaCondition 强类型\r\n\t\tconst ands: AkSupaCondition[] = [];\r\n\t\tconst ors: AkSupaCondition[] = [];\r\n\t\tfor (const c of this._conditions) {\r\n\t\t\tif (c.logic == \"or\") {\r\n\t\t\t\tors.push(c);\r\n\t\t\t} else {\r\n\t\t\t\tands.push(c);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst params: string[] = [];\r\n\t\t// 处理 and 条件\r\n\t\tfor (const cond of ands) {\r\n\t\t\tconst k = cond.field;\r\n\t\t\tconst op = cond.op;\r\n\t\t\tconst val = cond.value;\r\n\t\t\tif ((op == 'in' || op == 'not.in') && Array.isArray(val)) {\r\n\t\t\t\tparams.push(`${k}=${op}.(${val.map(x => this._valToStr(x)).map(x => encodeURIComponent(x)).join(',')})`);\r\n\t\t\t} else if ((op == 'is' || op == 'not.is') && (val == null || val == 'null')) {\r\n\t\t\t\tparams.push(`${k}=${op}.null`);\r\n\t\t\t} else if (op == 'like' || op == 'ilike') {\r\n\t\t\t\tparams.push(`${k}=${op}.${this._valToStr(val)}`);\r\n\t\t\t} else {\r\n\t\t\t\tparams.push(`${k}=${op}.${encodeURIComponent(this._valToStr(val))}`);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// 处理 or 条件\r\n\t\tif (ors.length > 0) {\r\n\t\t\tconst orStr = ors.map(o => {\r\n\t\t\t\tconst k = o.field;\r\n\t\t\t\tconst op = o.op;\r\n\t\t\t\tconst val = o.value;\r\n\t\t\t\tif (op == \"in\" && Array.isArray(val)) {\r\n\t\t\t\t\treturn `${k}.in.(${val.map(x => encodeURIComponent(this._valToStr(x))).join(\",\")})`;\r\n\t\t\t\t}\r\n\t\t\t\tif (op == \"is\" && (val == null)) {\r\n\t\t\t\t\treturn `${k}.is.null`;\r\n\t\t\t\t}\r\n\t\t\t\tif (op == \"like\" || op == \"ilike\") {\r\n\t\t\t\t\treturn `${k}.${op}.${this._valToStr(val)}`;\r\n\t\t\t\t}\r\n\t\t\t\treturn `${k}.${op}.${encodeURIComponent(this._valToStr(val))}`;\r\n\t\t\t}).join(\",\");\r\n\t\t\tparams.push(`or=(${orStr})`);\r\n\t\t}\r\n\t\tif (this._orString!=null && this._orString !== \"\") {\r\n\t\t\t__f__('log','at components/supadb/aksupa.uts:301','[AkSupaQueryBuilder] or字符串:', this._orString)\r\n\t\t\tparams.push(`or=(${this._orString!!})`);\r\n\t\t}\r\n\t\treturn params.length > 0 ? params.join('&') : null;\r\n\t}\r\n\r\n\tselect(columns : string = \"*\", opt : UTSJSONObject | null = null) : AkSupaQueryBuilder {\r\n\t\tthis._action = 'select';\r\n\t\tif (columns != null) {\r\n\t\t\tthis._options.columns = columns;\r\n\t\t}\r\n\t\tif (opt != null) {\r\n\t\t\t// 合并 opt 到 this._options\r\n\t\t\tObject.assign(this._options, opt);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\tinsert(values : UTSJSONObject | Array) : AkSupaQueryBuilder {\r\n\t\tthis._action = 'insert';\r\n\t\t// 检查是否为空\r\n\t\tif (Array.isArray(values)) {\r\n\t\t\tif (values.length == 0) throw toUniError('No values set for insert', 'Insert操作缺少数据');\r\n\t\t} else {\r\n\t\t\tif (UTSJSONObject.keys(values).length == 0) throw toUniError('No values set for insert', 'Insert操作缺少数据');\r\n\t\t}\r\n\t\tthis._values = values;\r\n\t\treturn this;\r\n\t}\r\n\tupdate(values : UTSJSONObject) : AkSupaQueryBuilder {\r\n\t\tthis._action = 'update';\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:331','ak update', this._action)\r\n\t\tif (UTSJSONObject.keys(values).length == 0) throw toUniError('No values set for update', '更新操作缺少数据');\r\n\t\tthis._values = values;\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:334','ak update', values)\r\n\t\treturn this;\r\n\t}\r\n\tdelete() : AkSupaQueryBuilder {\r\n\t\tthis._action = 'delete';\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:339','delete action now')\r\n\t\tconst filter = this._buildFilter();\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:341',filter)\r\n\t\tif (filter == null) throw toUniError('No filter set for delete', '删除操作缺少筛选条件');\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:343','delete action')\r\n\t\treturn this;\r\n\t}\r\n\r\n\trpc(functionName : string, params ?: UTSJSONObject) : AkSupaQueryBuilder {\r\n\t\tthis._action = 'rpc';\r\n\t\tthis._rpcFunction = functionName;\r\n\t\tthis._rpcParams = params;\r\n\t\treturn this;\r\n\t}\r\n\t// 链式请求最终执行方法 - 返回 UTSJSONObject\r\n\tasync execute() : Promise> {\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:355','execute')\r\n\t\tconst filter = this._buildFilter();\r\n\t\t__f__('log','at components/supadb/aksupa.uts:357','[AkSupaQueryBuilder] execute - 表:', this._table, 'filter:', filter)\r\n\t\tlet res : any;\r\n\t\tswitch (this._action) {\r\n\t\t\tcase 'select': {\r\n\t\t\t\t// 传递 single 状态到 options\r\n\t\t\t\tif (this._single) {\r\n\t\t\t\t\tthis._options.single = true;\r\n\t\t\t\t\t// 如果是 single 请求,自动设置 limit 为 1\r\n\t\t\t\t\tif (this._options.limit == null) {\r\n\t\t\t\t\t\tthis._options.limit = 1;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t//__f__('log','at components/supadb/aksupa.uts:368',this._options)\r\n\t\t\t\t}\t\t\t\t// 保证分页统计\r\n\t\t\t\tif (this._options.limit != null) {\r\n\t\t\t\t\tif (this._options.getcount == null && this._options.count == null) {\r\n\t\t\t\t\t\tthis._options.count = 'exact'; // 优先使用新的 count 选项\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tres = await this._supa.select(this._table, filter, this._options);\r\n\t\t\t\t// 解析 content-range header\r\n\t\t\t\tlet total = 0;\r\n\t\t\t\tlet hasmore = false;\r\n\t\t\t\tconst page = this._page;\r\n\t\t\t\tlet resdata = res.data\r\n\t\t\t\tlet limit = 0;\r\n\t\t\t\tif (typeof this._options.limit == 'number') {\r\n\t\t\t\t\tlimit = this._options.limit ?? 0;\r\n\t\t\t\t} else if (Array.isArray(resdata)) {\r\n\t\t\t\t\tlimit = resdata.length;\r\n\t\t\t\t}\r\n\t\t\t\tlet contentRange : string | null = null;\r\n\t\t\t\tif (res.headers != null) {\r\n\t\t\t\t\tlet theheader = res.headers as UTSJSONObject\r\n\t\t\t\t\tif (typeof theheader.get == 'function') {\r\n\r\n\t\t\t\t\t\tcontentRange = theheader.get('content-range') as string | null;\r\n\t\t\t\t\t} else if (typeof theheader['content-range'] == 'string') {\r\n\t\t\t\t\t\tcontentRange = theheader['content-range'] as string;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (contentRange != null) {\r\n\t\t\t\t\tconst match = /\\/(\\d+)$/.exec(contentRange);\r\n\t\t\t\t\tif (match != null) {\r\n\t\t\t\t\t\ttotal = parseInt(match[1] ?? \"0\");\r\n\t\t\t\t\t\thasmore = (page * limit) < total;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (total == 0) {\r\n\t\t\t\t\t// 使用 JSON 序列化访问 res 对象\r\n\t\t\t\t\tconst resStr = JSON.stringify(res)\r\n\t\t\t\t\tconst resParsed = JSON.parse(resStr)\r\n\t\t\t\t\tif (resParsed != null) {\r\n\t\t\t\t\t\tconst resObj = resParsed as UTSJSONObject\r\n\t\t\t\t\t\tconst countVal = resObj.getNumber('count')\r\n\t\t\t\t\t\tif (countVal != null) {\r\n\t\t\t\t\t\t\ttotal = countVal\r\n\t\t\t\t\t\t} else if (Array.isArray(resdata)) {\r\n\t\t\t\t\t\t\ttotal = resdata.length\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\ttotal = 0\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else if (Array.isArray(resdata)) {\r\n\t\t\t\t\t\ttotal = resdata.length\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\ttotal = 0\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!hasmore) hasmore = (page * limit) < total;\t\t\t\t// 如果是 head 模式,只返回 count 信息\r\n\t\t\t\tif (this._options.head == true) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tdata: null, // head 模式不返回数据\r\n\t\t\t\t\t\ttotal,\r\n\t\t\t\t\t\tpage,\r\n\t\t\t\t\t\tlimit,\r\n\t\t\t\t\t\thasmore: false, // head 模式不需要分页信息\r\n\t\t\t\t\t\torigin: res,\r\n\t\t\t\t\t\tstatus: res.status,\r\n\t\t\t\t\t\theaders: res.headers,\r\n\t\t\t\t\t\terror: res.error\r\n\t\t\t\t\t} as AkReqResponse;\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn {\r\n\t\t\t\t\tdata: res.data,\r\n\t\t\t\t\ttotal,\r\n\t\t\t\t\tpage,\r\n\t\t\t\t\tlimit,\r\n\t\t\t\t\thasmore,\r\n\t\t\t\t\torigin: res,\r\n\t\t\t\t\tstatus: res.status,\r\n\t\t\t\t\theaders: res.headers,\r\n\t\t\t\t\terror: res.error\r\n\t\t\t\t} as AkReqResponse;\r\n\t\t\t}\r\n\t\t\tcase 'insert': {\r\n\t\t\t\tconst insertValues = this._values;\r\n\t\t\t\tif (insertValues == null) throw toUniError('No values set for insert', '插入操作缺少数据');\r\n\t\t\t\tres = await this._supa.insert(this._table, insertValues);\r\n\t\t\t\tbreak;\r\n\t\t\t} case 'update': {\r\n\t\t\t\tconst updateValues = this._values;\r\n\t\t\t\tif (updateValues == null) throw toUniError('No values set for update', '更新操作缺少数据');\r\n\t\t\t\tif (filter == null) throw toUniError('No filter set for update', '更新操作缺少筛选条件');\r\n\t\t\t\t// Update操作只支持单个对象,不支持数组\r\n\t\t\t\tif (Array.isArray(updateValues)) throw toUniError('Update does not support array values', '更新操作不支持数组数据');\r\n\t\t\t\tres = await this._supa.update(this._table, filter, updateValues as UTSJSONObject);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tcase 'delete': {\r\n\t\t\t\tif (filter == null) throw toUniError('No filter set for delete', '删除操作缺少筛选条件');\r\n\t\t\t\tres = await this._supa.delete(this._table, filter);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tcase 'rpc': {\r\n\t\t\t\tif (this._rpcFunction == null) throw toUniError('No RPC function specified', 'RPC调用缺少函数名');\r\n\t\t\t\tres = await this._supa.rpc(this._rpcFunction as string, this._rpcParams);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tdefault: {\r\n\t\t\t\tres = await this._supa.select(this._table, filter, this._options);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// 保证 data 字段存在(不能赋null,赋空对象或空字符串)\r\n\t\tif (res[\"data\"] == null) res[\"data\"] = {};\r\n\t\treturn res;\r\n\t}\t// 新增:支持类型转换的执行方法\r\n\tasync executeAs() : Promise> {\r\n\t\tconst result = await this.execute();\r\n\r\n\t\tif (result.data == null) {\r\n\t\t\treturn result as AkReqResponse;\r\n\t\t}\r\n\r\n\t\tlet convertedData : any | null = null;\r\n\r\n\t\ttry {\r\n\t\t\tif (Array.isArray(result.data)) {\r\n\t\t\t\tconst dataArray = result.data;\r\n\t\t\t\tconst convertedArray : Array = [];\r\n\t\t\t\tfor (let i = 0; i < dataArray.length; i++) {\r\n\t\t\t\t\tconst item = dataArray[i];\r\n\t\t\t\t\tif (item instanceof UTSJSONObject) {\r\n\r\n\t\t\t\t\t\tconst parsed = item.parse();\r\n\r\n\r\n\r\n\r\n\t\t\t\t\t\tif (parsed != null) {\r\n\t\t\t\t\t\t\tconvertedArray.push(parsed);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t__f__('warn','at components/supadb/aksupa.uts:508','转换失败,使用原始对象:', item);\r\n\t\t\t\t\t\t\tconvertedArray.push(item);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst jsonObj = new UTSJSONObject(item);\r\n\r\n\t\t\t\t\t\tconst parsed = jsonObj.parse();\r\n\r\n\r\n\r\n\r\n\t\t\t\t\t\tif (parsed != null) {\r\n\t\t\t\t\t\t\tconvertedArray.push(parsed);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t__f__('warn','at components/supadb/aksupa.uts:523','转换失败,使用原始对象:', item);\r\n\t\t\t\t\t\t\tconvertedArray.push(item);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tconvertedData = convertedArray;\r\n\r\n\t\t\t} else {\r\n\t\t\t\tconst convertedArray : Array = [];\r\n\t\t\t\tif (result.data instanceof UTSJSONObject) {\r\n\t\t\t\t\tconst parsed = result.data.parse();\r\n\r\n\t\t\t\t\tif (parsed != null) {\r\n\t\t\t\t\t\tconvertedArray.push(parsed);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\t//__f__('log','at components/supadb/aksupa.uts:539','转换失败:', result.data)\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst jsonObj = new UTSJSONObject(result.data);\r\n\t\t\t\t\tconst parsed = jsonObj.parse();\r\n\t\t\t\t\tif (parsed != null) {\r\n\t\t\t\t\t\tconvertedArray.push(parsed);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\t//__f__('log','at components/supadb/aksupa.uts:548','转换失败:', result.data)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tconvertedData = convertedArray;\r\n\t\t\t}\r\n\t\t} catch (e) {\r\n\t\t\t__f__('warn','at components/supadb/aksupa.uts:554','数据类型转换失败,使用原始数据:', e);\r\n\t\t\t__f__('log','at components/supadb/aksupa.uts:555',result.data)\r\n\t\t\tconvertedData = result.data as any;\r\n\t\t}\r\n\t\tresult.data = convertedData\r\n\t\treturn result as AkReqResponse;\r\n\r\n\t}\r\n}\r\n\r\n// 新增:链式 Storage 上传\r\nexport class AkSupaStorageUploadBuilder {\r\n\tprivate _supa : AkSupa;\r\n\tprivate _bucket : string = '';\r\n\tprivate _path : string = '';\r\n private _file : string = '';\r\n\tprivate _options : UTSJSONObject = {};\r\n\r\n\tconstructor(supa : AkSupa, bucket : string) {\r\n\t\tthis._supa = supa;\r\n\t\tthis._bucket = bucket;\r\n\t}\r\n\r\n\tpath(path : string) : AkSupaStorageUploadBuilder {\r\n\t\tthis._path = path;\r\n\t\treturn this;\r\n\t}\r\n\r\n file(file : string) : AkSupaStorageUploadBuilder {\r\n\t\tthis._file = file;\r\n\t\treturn this;\r\n\t}\r\n\r\n\toptions(options : UTSJSONObject) : AkSupaStorageUploadBuilder {\r\n\t\tthis._options = options;\r\n\t\treturn this;\r\n\t}\r\n\tasync upload() : Promise> {\r\n if (this._bucket == '' || this._path == '' || this._file == '') {\r\n\t\t\tthrow toUniError('bucket, path, file are required', '上传文件缺少必要参数');\r\n\t\t}\r\n\t\tconst url = `${this._supa.baseUrl}/storage/v1/object/${this._bucket}/${this._path}`;\r\n\t\tconst apikey = this._supa.apikey;\r\n\t\t// 适配 uni.uploadFile\r\n\t\tconst uploadOptions : AkReqUploadOptions = {\r\n\t\t\turl,\r\n\t\t\tfilePath: this._file, // 这里假设 file 是本地路径\r\n\t\t\tname: 'file', // 默认字段名\r\n\t\t\theaders: {},\r\n\t\t\tapikey,\r\n\t\t\tformData: this._options\r\n\t\t};\r\n\t\treturn await AkReq.upload(uploadOptions);\r\n\t}\r\n}\r\n\r\n// 新增:明确的 StorageBucket 类,支持链式 upload\r\nclass AkSupaStorageBucket {\r\n\tprivate supa : AkSupa;\r\n\tprivate bucket : string;\r\n\tconstructor(supa : AkSupa, bucket : string) {\r\n\t\tthis.supa = supa;\r\n\t\tthis.bucket = bucket;\r\n\t}\r\n\tasync upload(path : string, filePath : string, options ?: UTSJSONObject) : Promise> {\r\n\t\tconst url = `${this.supa.baseUrl}/storage/v1/object/${this.bucket}/${path}`;\r\n\t\tlet headers : UTSJSONObject = { apikey: this.supa.apikey };\r\n\t\tconst formData : UTSJSONObject = {};\r\n\t\tif (options != null && typeof options == 'object') {\r\n\t\t\tif (typeof options.get == 'function' && options.get('x-upsert') != null) {\r\n\t\t\t\theaders['x-upsert'] = options.get('x-upsert');\r\n\t\t\t}\r\n\t\t\tconst keys = UTSJSONObject.keys(options);\r\n\t\t\tfor (let i = 0; i < keys.length; i++) {\r\n\t\t\t\tconst k = keys[i];\r\n\t\t\t\tif (k != 'x-upsert') formData[k] = options.get(k);\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst token = AkReq.getToken();\r\n\t\tif (token != null && !(token == '')) {\r\n\t\t\theaders['Authorization'] = `Bearer ${token}`;\r\n\t\t}\r\n\t\treturn await AkReq.upload({\r\n\t\t\turl,\r\n\t\t\tfilePath,\r\n\t\t\tname: 'file',\r\n\t\t\tapikey: this.supa.apikey,\r\n\t\t\tformData,\r\n\t\t\theaders\r\n\t\t});\r\n\t}\r\n}\r\n\r\nexport class AkSupaStorageApi {\r\n\tprivate _supa : AkSupa;\r\n\tconstructor(supa : AkSupa) {\r\n\t\tthis._supa = supa;\r\n\t}\r\n\tfrom(bucket : string) : AkSupaStorageBucket {\r\n\t\treturn new AkSupaStorageBucket(this._supa, bucket);\r\n\t}\r\n}\r\n\r\nexport class AkSupa {\r\n\tbaseUrl : string;\r\n\tapikey : string;\r\n\tsession : AkSupaSignInResult | null = null;\r\n\tuser : UTSJSONObject | null = null;\r\n\tstorage : AkSupaStorageApi;\r\n\r\n\tconstructor(baseUrl : string, apikey : string) {\r\n\t\tthis.baseUrl = baseUrl;\r\n\t\tthis.apikey = apikey;\r\n\t\tthis.storage = new AkSupaStorageApi(this);\r\n\t\t// [CHANGE][2026-01-30] hydrate user/session from persisted token (see docs: components/supadb/docs/CHANGELOG.md)\r\n\t\ttry {\r\n\t\t\tthis.hydrateSessionFromStorage();\r\n\t\t} catch (e) {\r\n\t\t\t// ignore\r\n\t\t}\r\n\t}\r\n\r\n\t// [CHANGE][2026-01-30] hydrate user from /auth/v1/user when token exists in storage\r\n\tasync hydrateSessionFromStorage() : Promise {\r\n\t\ttry {\r\n\t\t\tconst token = AkReq.getToken();\r\n\t\t\tif (token == null || token == '') return false;\r\n\t\t\tconst res = await AkReq.request({\r\n\t\t\t\turl: this.baseUrl + '/auth/v1/user',\r\n\t\t\t\tmethod: 'GET',\r\n\t\t\t\theaders: {\r\n\t\t\t\t\tapikey: this.apikey,\r\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\r\n\t\t\t\t\t'Content-Type': 'application/json'\r\n\t\t\t\t} as UTSJSONObject\r\n\t\t\t}, false);\r\n\t\t\tconst status = res.status ?? 0;\r\n\t\t\tif (!(status >= 200 && status < 400)) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\tlet user: UTSJSONObject | null = null;\r\n\t\t\ttry {\r\n\t\t\t\tuser = new UTSJSONObject(res.data);\r\n\t\t\t} catch (e) {\r\n\t\t\t\tuser = null;\r\n\t\t\t}\r\n\t\t\tif (user == null) return false;\r\n\t\t\tthis.user = user;\r\n\t\t\t// 仅补齐最小 session 结构,供 getSession / UI 判断登录态使用\r\n\t\t\tif (this.session == null) {\r\n\t\t\t\tthis.session = {\r\n\t\t\t\t\taccess_token: token,\r\n\t\t\t\t\trefresh_token: AkReq.getRefreshToken() ?? '',\r\n\t\t\t\t\texpires_at: AkReq.getExpiresAt() ?? 0,\r\n\t\t\t\t\tuser: user,\r\n\t\t\t\t\ttoken_type: 'bearer',\r\n\t\t\t\t\texpires_in: 0,\r\n\t\t\t\t\traw: user\r\n\t\t\t\t} as AkSupaSignInResult;\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t} catch (e) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\tasync resetPassword(email : string) : Promise {\r\n\t\tconst res = await AkReq.request({\r\n\t\t\turl: this.baseUrl + '/auth/v1/recover',\r\n\t\t\tmethod: 'POST',\r\n\t\t\theaders: {\r\n\t\t\t\tapikey: this.apikey,\r\n\t\t\t\t'Content-Type': 'application/json'\r\n\t\t\t} as UTSJSONObject,\r\n\t\t\tdata: { email } as UTSJSONObject,\r\n\t\t\tcontentType: 'application/json'\r\n\t\t}, false);\r\n\r\n\t\t// Supabase returns 200 when the reset email is sent successfully\r\n\t\treturn res.status == 200;\r\n\t}\r\n\tasync signOut() {\r\n\t\tthis.session = null\r\n\t\tthis.user = null\r\n\t}\r\n\tasync signIn(email : string, password : string) : Promise {\r\n\t\t// 提前检查 apikey 配置是否为占位符,避免发送无效请求导致 401\r\n\t\tif (this.apikey == null || this.apikey.trim() === '' || this.apikey === 'your-anon-key') {\r\n\t\t\tthrow new Error('Supabase 配置错误:请在 ak/config.uts 中设置 SUPA_KEY(当前为占位符)');\r\n\t\t}\r\n\t\tconst headers = new UTSJSONObject()\r\n\t\theaders.set('apikey', this.apikey)\r\n\t\theaders.set('Content-Type', 'application/json')\r\n\t\tconst reqData = new UTSJSONObject()\r\n\t\treqData.set('email', email)\r\n\t\treqData.set('password', password)\r\n\t\tconst res = await AkReq.request({\r\n\t\t\turl: this.baseUrl + '/auth/v1/token?grant_type=password',\r\n\t\t\tmethod: 'POST',\r\n\t\t\theaders: headers,\r\n\t\t\tdata: reqData,\r\n\t\t\tcontentType: 'application/json'\r\n\t\t}, false);\r\n\t\t// 如果响应不是 2xx(例如 401),提取后端错误信息并抛出,便于上层显示具体原因\r\n\t\tconst status = res.status ?? 0;\r\n\t\tif (!(status >= 200 && status < 400)) {\r\n\t\t\tlet msg = 'user.login.login_failed';\r\n\t\t\ttry {\r\n\t\t\t\tif (res.data != null) {\r\n\t\t\t\t\tconst obj = new UTSJSONObject(res.data);\r\n\t\t\t\t\tconst rawMsg = obj.getString('message') ?? obj.getString('error') ?? obj.getString('msg') ?? obj.getString('description') ?? obj.getString('error_description') ?? '';\r\n\t\t\t\t\t\r\n\t\t\t\t\t// 核心修复:在这里拦截英文错误并转换为中文\r\n\t\t\t\t\tif (rawMsg.includes('Invalid login credentials')) {\r\n\t\t\t\t\t\tmsg = '用户名或密码错误';\r\n\t\t\t\t\t} else if (rawMsg != '') {\r\n\t\t\t\t\t\tmsg = rawMsg;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\t// ignore\r\n\t\t\t}\r\n\t\t\tthrow new Error(msg);\r\n\t\t}\r\n\t\t// 解析成功的返回体\r\n\t\tlet data: UTSJSONObject;\r\n\t\ttry {\r\n\t\t\tdata = new UTSJSONObject(res.data);\r\n\t\t} catch (e) {\r\n\t\t\tdata = new UTSJSONObject({});\r\n\t\t}\r\n\t\tconst access_token = data.getString('access_token') ?? '';\r\n\t\tconst refresh_token = data.getString('refresh_token') ?? '';\r\n\t\tconst expires_at = data.getNumber('expires_at') ?? 0;\r\n\t\tconst user = data.getJSON('user');\r\n\t\tAkReq.setToken(access_token, refresh_token, expires_at);\r\n\t\tconst session : AkSupaSignInResult = {\r\n\t\t\taccess_token: access_token,\r\n\t\t\trefresh_token: refresh_token,\r\n\t\t\texpires_at: expires_at,\r\n\t\t\tuser: user,\r\n\t\t\ttoken_type: data.getString('token_type') ?? '',\r\n\t\t\texpires_in: data.getNumber('expires_in') ?? 0,\r\n\t\t\traw: data\r\n\t\t};\r\n\t\tthis.session = session;\r\n\t\tthis.user = user;\r\n\t\treturn session;\r\n\t}\r\n\r\n\t/**\r\n\t * 获取当前 session 和 user\r\n\t */\r\n\tgetSession() : AkSupaSessionInfo {\r\n\t\treturn {\r\n\t\t\tsession: this.session,\r\n\t\t\tuser: this.user\r\n\t\t};\r\n\t}\r\n\r\n\tasync signUp(email : string, password : string, options : UTSJSONObject | null = null) : Promise {\r\n\t\tconst headers = new UTSJSONObject()\r\n\t\theaders.set('apikey', this.apikey)\r\n\t\theaders.set('Content-Type', 'application/json')\r\n\t\tconst data = new UTSJSONObject()\r\n\t\tdata.set('email', email)\r\n\t\tdata.set('password', password)\r\n\t\t\r\n\t\tif (options != null) {\r\n\t\t\tconst dataField = options.getJSON('data')\r\n\t\t\tif (dataField != null) {\r\n\t\t\t\tdata.set('data', dataField)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst res = await AkReq.request({\r\n\t\t\turl: this.baseUrl + '/auth/v1/signup',\r\n\t\t\tmethod: 'POST',\r\n\t\t\theaders: headers,\r\n\t\t\tdata: data,\r\n\t\t\tcontentType: 'application/json'\r\n\t\t}, false);\r\n\t\treturn res.data as UTSJSONObject;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * 查询表数据(GET方式,支持多条件、limit等,filter自动转为supabase风格query)\r\n\t * filter 支持:\r\n\t * { usr_id: { lt: 800 }, name: { ilike: '%foo%' }, status: 'active', age: { gte: 18, lte: 30 } }\r\n\t * 操作符支持 eq, neq, lt, lte, gt, gte, like, ilike, in, is, not, contains, containedBy, range, fts, plfts, phfts, wfts\r\n\t */\r\nasync select(table : string, filter ?: string | null, options ?: AkSupaSelectOptions) : Promise> {\r\n\tlet url = this.baseUrl + '/rest/v1/' + table;\r\n\tlet headers = new UTSJSONObject()\r\n\theaders.set('apikey', this.apikey)\r\n\theaders.set('Content-Type', 'application/json')\r\n\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\tlet params : string[] = [];\r\n\tif (options != null) {\r\n\t\tif (options.columns != null && !(options.columns == \"\")) params.push('select=' + encodeURIComponent(options.columns ?? \"\"));\r\n\t\tif (options.limit != null) {\r\n\t\t\tparams.push('limit=' + options.limit);\r\n\t\t\t//__f__('log','at components/supadb/aksupa.uts:857','设置 limit 参数:', options.limit);\r\n\t\t}\r\n\t\tif (options.order != null && !(options.order == \"\")) params.push('order=' + encodeURIComponent(options.order ?? \"\"));\r\n\t\tif (options.rangeFrom != null && options.rangeTo != null) {\r\n\t\t\theaders['Range'] = `${options.rangeFrom}-${options.rangeTo}`;\r\n\t\t\theaders['Range-Unit'] = 'items';\r\n\t\t\t//__f__('log','at components/supadb/aksupa.uts:863','设置 Range 头部:', `${options.rangeFrom}-${options.rangeTo}`);\r\n\t\t}\r\n\r\n\t\t// 向后兼容:支持旧的 getcount 参数\r\n\t\tlet countOption = options.count ?? options.getcount;\r\n\t\tif (countOption != null) {\r\n\t\t\theaders['Prefer'] = `count=${countOption}`;\r\n\t\t}\r\n\t\t// 新增:head 模式支持\r\n\t\tif (options.head == true) {\r\n\t\t\t//__f__('log','at components/supadb/aksupa.uts:873','使用 head 模式,只返回元数据');\r\n\t\t\t// HEAD 请求用于只获取 count,不返回数据\r\n\t\t\tif (headers['Prefer'] != null) {\r\n\t\t\t\theaders['Prefer'] = (headers['Prefer'] as string) + ',return=minimal';\r\n\t\t\t} else {\r\n\t\t\t\theaders['Prefer'] = 'return=minimal';\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (options.single == true) {\r\n\t\t\t//__f__('log','at components/supadb/aksupa.uts:883','使用 single() 模式');\r\n\t\t\tif (headers['Prefer'] != null) {\r\n\t\t\t\theaders['Prefer'] = (headers['Prefer'] as string) + ',return=representation,single-object';\r\n\t\t\t} else {\r\n\t\t\t\theaders['Prefer'] = 'return=representation,single-object';\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// 确保有 select 参数\r\n\t\tif (options.columns == null) {\r\n\t\t\tparams.push('select=*');\r\n\t\t} else if (options.columns == \"\") {\r\n\t\t\tparams.push('select=*');\r\n\t\t}\r\n\t} else {\r\n\t\tparams.push('select=*');\r\n\t}\r\n\t// 直接用 string filter\r\n\tif (filter!=null && filter !== \"\") {\r\n\t\tparams.push(filter!!);\r\n\t}\r\n\tif (params.length > 0) {\r\n\t\turl += '?' + params.join('&');\r\n\t}\r\n\r\n\t//__f__('log','at components/supadb/aksupa.uts:908',url)\r\n\r\n\t// 确定HTTP方法:如果是head模式,使用HEAD方法\r\n\tlet httpMethod: 'GET' | 'HEAD' = 'GET';\r\n\tif (options != null && options.head == true) {\r\n\t\thttpMethod = 'HEAD';\r\n\t\t//__f__('log','at components/supadb/aksupa.uts:914','使用 HEAD 方法进行 count 查询');\r\n\t}\r\n\r\n\tlet reqOptions : AkReqOptions = {\r\n\t\turl,\r\n\t\tmethod: httpMethod,\r\n\t\theaders\r\n\t};\r\n\treturn await this.requestWithAutoRefresh(reqOptions);\r\n}\r\n\r\nasync select_uts(table : string, filter ?: UTSJSONObject | null, options ?: AkSupaSelectOptions) : Promise> {\r\n\tconst filter_str = buildSupabaseFilterQuery(filter)\r\n\treturn this.select(table,filter_str,options)\r\n}\r\n\t/**\r\n\t * 插入表数据\r\n\t * @param table 表名\r\n\t * @param row 插入对象\r\n\t * @returns 插入结果\r\n\t */\r\n\tasync insert(table : string, row : UTSJSONObject | Array) : Promise> {\r\n\t\tconst url = this.baseUrl + '/rest/v1/' + table;\r\n\t\tconst headers = new UTSJSONObject()\r\n\t\theaders.set('apikey', this.apikey)\r\n\t\theaders.set('Content-Type', 'application/json')\r\n\t\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\t\theaders.set('Prefer', 'return=representation')\r\n\r\n\t\tlet reqOptions : AkReqOptions = {\r\n\t\t\turl,\r\n\t\t\tmethod: 'POST',\r\n\t\t\theaders,\r\n\t\t\tdata: row,\r\n\t\t\tcontentType: 'application/json'\r\n\t\t};\r\n\t\treturn await this.requestWithAutoRefresh(reqOptions);\r\n\t}\r\n\r\n\t/**\r\n\t * 更新表数据\r\n\t * @param table 表名\r\n\t * @param filter 过滤条件对象\r\n\t * @param values 更新内容对象\r\n\t * @returns 更新结果\r\n\t */\r\nasync update(table : string, filter : string | null, values : UTSJSONObject) : Promise> {\r\n\tlet url = this.baseUrl + '/rest/v1/' + table;\r\n\tif (filter!=null && filter !== \"\") {\r\n\t\turl += '?' + filter;\r\n\t}\r\n\tconst headers = new UTSJSONObject()\r\n\theaders.set('apikey', this.apikey)\r\n\theaders.set('Content-Type', 'application/json')\r\n\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\theaders.set('Prefer', 'return=representation')\r\n\tlet reqOptions : AkReqOptions = {\r\n\t\turl,\r\n\t\tmethod: 'PATCH',\r\n\t\theaders,\r\n\t\tdata: values,\r\n\t\tcontentType: 'application/json'\r\n\t};\r\n\treturn await this.requestWithAutoRefresh(reqOptions);\r\n}\r\n\r\n\t/**\r\n\t * 删除表数据\r\n\t * @param table 表名\r\n\t * @param filter 过滤条件对象\r\n\t * @returns 删除结果\r\n\t */\r\nasync delete(table : string, filter : string | null) : Promise> {\r\n\tlet url = this.baseUrl + '/rest/v1/' + table;\r\n\tif (filter!=null && filter !== \"\") {\r\n\t\turl += '?' + filter;\r\n\t}\r\n\tconst headers = new UTSJSONObject()\r\n\theaders.set('apikey', this.apikey)\r\n\theaders.set('Content-Type', 'application/json')\r\n\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\theaders.set('Prefer', 'return=representation')\r\n\tlet reqOptions : AkReqOptions = {\r\n\t\turl,\r\n\t\tmethod: 'DELETE',\r\n\t\theaders,\r\n\t\tcontentType: 'application/json'\r\n\t};\r\n\treturn await this.requestWithAutoRefresh(reqOptions);\r\n}\r\n\r\n\t/**\r\n\t * 调用 Supabase/PostgREST RPC (function)\r\n\t * @param functionName 函数名\r\n\t * @param params 参数对象\r\n\t * @returns AkReqResponse\r\n\t */\r\n\tasync rpc(functionName : string, params ?: UTSJSONObject) : Promise> {\r\n\t\tconst url = this.baseUrl + '/rest/v1/rpc/' + functionName;\r\n\t\tconst headers = new UTSJSONObject()\r\n\t\theaders.set('apikey', this.apikey)\r\n\t\theaders.set('Content-Type', 'application/json')\r\n\t\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\t\tlet reqOptions : AkReqOptions = {\r\n\t\t\turl,\r\n\t\t\tmethod: 'POST',\r\n\t\t\theaders,\r\n\t\t\tdata: params ?? new UTSJSONObject(),\r\n\t\t\tcontentType: 'application/json'\r\n\t\t};\r\n\t\treturn await this.requestWithAutoRefresh(reqOptions);\r\n\t}\r\n\t/**\r\n\t * 兼容 supabase-js 风格\r\n\t * @param tableName 表名\r\n\t */\r\n\tfrom(tableName : string) : AkSupaQueryBuilder {\r\n\t\treturn new AkSupaQueryBuilder(this, tableName);\r\n\t}\r\n\r\n /**\r\n * 创建实时订阅通道 (兼容 Supabase Realtime 接口,目前使用轮询模拟)\r\n * @param topic 通道名称,如 public:table\r\n */\r\n channel(topic: string): AkSupaRealtimeChannel {\r\n return new AkSupaRealtimeChannel(this, topic);\r\n }\r\n \r\n /**\r\n * 移除通道\r\n */\r\n removeChannel(channel: AkSupaRealtimeChannel): Promise {\r\n channel.unsubscribe();\r\n return Promise.resolve('ok');\r\n }\r\n\t// AkSupa类内新增:自动刷新session\r\n\tasync refreshSession() : Promise {\r\n\t\tif (this.session == null || this.session?.refresh_token == null) return false;\r\n\t\ttry {\r\n\t\t\tconst headers = new UTSJSONObject()\r\n\t\t\theaders.set('apikey', this.apikey)\r\n\t\t\theaders.set('Content-Type', 'application/json')\r\n\t\t\tconst data = new UTSJSONObject()\r\n\t\t\tdata.set('refresh_token', this.session?.refresh_token)\r\n\t\t\tconst res = await AkReq.request({\r\n\t\t\t\turl: this.baseUrl + '/auth/v1/token?grant_type=refresh_token',\r\n\t\t\t\tmethod: 'POST',\r\n\t\t\t\theaders: headers,\r\n\t\t\t\tdata: data,\r\n\t\t\t\tcontentType: 'application/json'\r\n\t\t\t}, false);\r\n\t\t\tif (res.status == 200 && (res.data != null)) {\r\n\t\t\t\tconst data = res.data as UTSJSONObject;\r\n\t\t\t\tconst access_token = data.getString('access_token') ?? '';\r\n\t\t\t\tconst refresh_token = data.getString('refresh_token') ?? '';\r\n\t\t\t\tconst expires_at = data.getNumber('expires_at') ?? 0;\r\n\t\t\t\tconst user = data.getJSON('user');\r\n\t\t\t\tthis.session = {\r\n\t\t\t\t\taccess_token,\r\n\t\t\t\t\trefresh_token,\r\n\t\t\t\t\texpires_at,\r\n\t\t\t\t\tuser,\r\n\t\t\t\t\ttoken_type: data.getString('token_type') ?? '',\r\n\t\t\t\t\texpires_in: data.getNumber('expires_in') ?? 0,\r\n\t\t\t\t\traw: data\r\n\t\t\t\t};\r\n\t\t\t\tthis.user = user;\r\n\t\t\t\t// 更新本地token\r\n\t\t\t\tAkReq.setToken(access_token, refresh_token, expires_at);\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\treturn false;\r\n\t\t} catch (e) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\tasync updateUserMetadata(metadata: UTSJSONObject): Promise {\r\n\t\tconst headers = new UTSJSONObject()\r\n\t\theaders.set('apikey', this.apikey)\r\n\t\theaders.set('Content-Type', 'application/json')\r\n\t\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\t\tconst data = new UTSJSONObject()\r\n\t\tdata.set('data', metadata)\r\n\t\tconst res = await AkReq.request({\r\n\t\t\turl: this.baseUrl + '/auth/v1/user',\r\n\t\t\tmethod: 'PUT',\r\n\t\t\theaders: headers,\r\n\t\t\tdata: data,\r\n\t\t\tcontentType: 'application/json'\r\n\t\t}, false);\r\n\t\treturn res.data as UTSJSONObject;\r\n\t}\r\n\r\n\t// AkSupa类内新增:自动刷新封装\r\n\tasync requestWithAutoRefresh(reqOptions : AkReqOptions, isRetry = false) : Promise> {\r\n\t\tlet res = await AkReq.request(reqOptions, false);\r\n\t\t// JWT过期:Supabase风格\r\n\t\tconst isJwtExpired = (res.status == 401); //res != null && res.data != null && typeof res.data == 'object' && (res.data as UTSJSONObject)?.getString('code') == 'PGRST301';\r\n\t\t// 401未授权\r\n\t\tconst isUnauthorized = (res.status == 401);\r\n\t\tif ((isJwtExpired || isUnauthorized) && !isRetry) {\r\n\t\t\tconst ok = await this.refreshSession();\r\n\t\t\tif (ok) {\r\n\t\t\t\tlet headers = reqOptions.headers\r\n\t\t\t\tif (headers == null) {\r\n\t\t\t\t\theaders = new UTSJSONObject()\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof headers.set == 'function') {\r\n\t\t\t\t\theaders.set('Authorization', `Bearer ${AkReq.getToken() ?? ''}`)\r\n\t\t\t\t\treqOptions.headers = headers\r\n\t\t\t\t}\r\n\r\n\t\t\t\tres = await AkReq.request(reqOptions, false);\r\n\t\t\t} else {\r\n\t\t\t\tuni.removeStorageSync('user_id');\r\n\t\t\t\tuni.removeStorageSync('token');\r\n\r\n\t\t\t\t//uni.reLaunch({ url: '/pages/user/login' });\r\n __f__('log','at components/supadb/aksupa.uts:1133','登录已过期,请重新登录');\r\n\t\t\t\tthrow toUniError('登录已过期,请重新登录', '用户认证失败');\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn res;\r\n\t}\r\n}\r\n\r\n// 工具函数:将 UTSJSONObject filter 转为 Supabase/PostgREST 查询字符串\r\nfunction buildSupabaseFilterQuery(filter : UTSJSONObject | null) : string {\r\n\t//__f__('log','at components/supadb/aksupa.uts:1143',filter)\r\n\tif (filter == null) return \"\";\r\n\t// 类型保护:如果不是 UTSJSONObject,自动包裹\r\n\tif (typeof filter.get !== 'function') {\r\n\t\ttry {\r\n\t\t\tfilter = new UTSJSONObject(filter as any)\r\n\t\t} catch (e) {\r\n\t\t\t__f__('warn','at components/supadb/aksupa.uts:1150','filter 不是 UTSJSONObject,且无法转换', filter)\r\n\t\t\treturn ''\r\n\t\t}\r\n\t}\r\n\tconst params : string[] = [];\r\n\tconst keys : string[] = UTSJSONObject.keys(filter);\r\n\tfor (let i = 0; i < keys.length; i++) {\r\n\t\tconst k = keys[i];\r\n\t\tconst v = filter.get(k);\r\n\t\tif (k == 'or' && typeof v == 'string') {\r\n\t\t\tparams.push(`or=(${v})`);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (v != null && typeof v == 'object' && typeof (v as UTSJSONObject).get == 'function') {\r\n\t\t\tconst vObj = v as UTSJSONObject;\r\n\t\t\tconst opKeys = UTSJSONObject.keys(vObj);\r\n\t\t\tfor (let j = 0; j < opKeys.length; j++) {\r\n\t\t\t\tconst op = opKeys[j];\r\n\t\t\t\tconst opVal = vObj.get(op);\r\n\t\t\t\tif ((op == 'in' || op == 'not.in') && Array.isArray(opVal)) {\r\n\t\t\t\t\tparams.push(`${k}=${op}.(${opVal.map(x => typeof x == 'object' ? encodeURIComponent(JSON.stringify(x)) : encodeURIComponent(x.toString())).join(',')})`);\r\n\t\t\t\t} else if (op == 'is' && (opVal == null || opVal == 'null')) {\r\n\t\t\t\t\tparams.push(`${k}=is.null`);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst opvalstr : string = (typeof opVal == 'object') ? JSON.stringify(opVal) : (opVal as string);\r\n\t\t\t\t\tparams.push(`${k}=${op}.${encodeURIComponent(opvalstr)}`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (v != null && typeof v == 'object') {\r\n\t\t\tconst vObj = v as UTSJSONObject;\r\n\t\t\tconst opKeys = UTSJSONObject.keys(vObj);\r\n\t\t\tfor (let j = 0; j < opKeys.length; j++) {\r\n\t\t\t\tconst op = opKeys[j];\r\n\t\t\t\tconst opVal = vObj.get(op);\r\n\t\t\t\tparams.push(`${k}=${op}.${encodeURIComponent(!(opVal == null) ? (typeof opVal == 'object' ? JSON.stringify(opVal) : opVal.toString()) : '')}`);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tparams.push(`${k}=eq.${encodeURIComponent(!(v == null) ? v.toString() : '')}`);\r\n\t\t}\r\n\t}\r\n\treturn params.join('&');\r\n}\r\n\r\n/**\r\n * 创建 Supabase 客户端实例\r\n * @param url 项目 URL\r\n * @param key 项目匿名密钥 (Anon Key)\r\n */\r\nexport function createClient(url : string, key : string) : AkSupa {\r\n\treturn new AkSupa(url, key);\r\n}\r\n\r\n// 模拟 Realtime Channel 类 (Polling Fallback)\r\nexport class AkSupaRealtimeChannel {\r\n private _supa: AkSupa;\r\n private _topic: string;\r\n private _timer: number = 0;\r\n private _callback: ((payload: any) => void) | null = null;\r\n private _table: string = '';\r\n private _lastTime: string = new Date().toISOString(); \r\n private _isSubscribed: boolean = false;\r\n\r\n constructor(supa: AkSupa, topic: string) {\r\n this._supa = supa;\r\n this._topic = topic;\r\n }\r\n\r\n // 绑定事件 (仅支持 postgres_changes INSERT)\r\n on(type: string, filter: UTSJSONObject, callback: (payload: any) => void): AkSupaRealtimeChannel {\r\n // 解析 table\r\n const table = filter.getString('table');\r\n if (table != null) {\r\n this._table = table;\r\n }\r\n this._callback = callback;\r\n return this;\r\n }\r\n\r\n // 开始订阅\r\n subscribe(callback?: (status: string, err: any | null) => void): AkSupaRealtimeChannel {\r\n if (this._isSubscribed) return this;\r\n this._isSubscribed = true;\r\n \r\n // 初始回调\r\n if (callback != null) {\r\n callback('SUBSCRIBED', null);\r\n }\r\n\r\n // 如果没有指定 table,无法轮询\r\n if (this._table == '') {\r\n __f__('warn','at components/supadb/aksupa.uts:1240','Realtime check: No table specified for polling.');\r\n return this;\r\n }\r\n\r\n // 开始轮询 (每3秒)\r\n this._timer = setInterval(() => {\r\n this._checkUpdates();\r\n }, 3000);\r\n\r\n return this;\r\n }\r\n\r\n // 停止订阅\r\n unsubscribe() {\r\n if (this._timer > 0) {\r\n clearInterval(this._timer);\r\n this._timer = 0;\r\n }\r\n this._isSubscribed = false;\r\n }\r\n\r\n // 检查更新\r\n private async _checkUpdates() {\r\n if (!this._isSubscribed || this._table == '') return;\r\n \r\n try {\r\n const now = new Date().toISOString();\r\n \r\n const res = await this._supa\r\n .from(this._table)\r\n .select('*')\r\n .gt('created_at', this._lastTime)\r\n .order('created_at', { ascending: true })\r\n .execute();\r\n \r\n if (res.error == null && res.data != null) {\r\n let list: any[] = [];\r\n if (Array.isArray(res.data)) {\r\n list = res.data as any[];\r\n }\r\n \r\n if (list.length > 0) {\r\n // 更新最后时间\r\n const lastItem = list[list.length - 1];\r\n let lastTimeStr: string | null = null;\r\n \r\n if (lastItem instanceof UTSJSONObject) {\r\n lastTimeStr = lastItem.getString('created_at');\r\n } else {\r\n // 尝试转 json\r\n const j = JSON.parse(JSON.stringify(lastItem)) as UTSJSONObject;\r\n lastTimeStr = j.getString('created_at');\r\n }\r\n \r\n if (lastTimeStr != null) {\r\n this._lastTime = lastTimeStr;\r\n } else {\r\n this._lastTime = now;\r\n }\r\n\r\n // 触发回调\r\n if (this._callback != null) {\r\n // 模拟 Realtime payload\r\n list.forEach(item => {\r\n const payload = {\r\n new: item,\r\n eventType: 'INSERT',\r\n old: null\r\n };\r\n this._callback?.(payload);\r\n });\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n __f__('error','at components/supadb/aksupa.uts:1315','Realtime polling error:', e);\r\n }\r\n }\r\n}\r\n\r\nexport default AkSupa;\r\n","// /components/supadb/aksupainstance.uts\r\nimport { createClient } from './aksupa.uts'\r\nimport { SUPA_URL, SUPA_KEY } from '@/ak/config.uts'\r\n\r\n// 创建单一真实的 Supabase 客户端实例 (使用 config.uts 配置)\r\n// Create single source of truth client using config\r\nconst supaInstance = createClient(SUPA_URL, SUPA_KEY)\r\n\r\n// 导出默认实例 (供 login.uvue 等使用)\r\nexport default supaInstance\r\n\r\n// 导出命名实例 'supabase' (供 store.uts 使用)\r\nexport const supabase = supaInstance\r\n\r\n// 导出 isSupabaseReady 状态\r\nexport const isSupabaseReady = true\r\n\r\n// 兼容 ensureSupabaseReady\r\nexport async function ensureSupabaseReady() {\r\n return true\r\n}\r\n\r\n// 检查连接状态的函数\r\nexport function checkConnection() {\r\n return Promise.resolve(true)\r\n}\r\n\r\n// 兼容 supaReady Promise\r\nexport const supaReady = Promise.resolve(true)\r\n\r\n// 如果有其他需要导出的函数,可以这样导出:\r\nexport function initializeSupabase(url: string, key: string) {\r\n return createClient(url, key)\r\n}\r\n","// 电商商城系统类型定义 - UTS Android 兼容\r\n\r\n// 用户类型\r\nexport type UserType = {\r\n\tid: string\r\n\tphone: string\r\n\temail: string | null\r\n\tnickname: string | null\r\n\tavatar_url: string | null\r\n\tgender: number\r\n\tuser_type: number\r\n\tstatus: number\r\n\tcreated_at: string\r\n}\r\n\r\n// 商城用户扩展信息类型\r\nexport type MallUserProfileType = {\r\n\tid: string\r\n\tuser_id: string\r\n\tuser_type: number\r\n\tstatus: number\r\n\treal_name: string | null\r\n\tid_card: string | null\r\n\tcredit_score: number\r\n\tmall_role: string\r\n\tverification_status: number\r\n\tverification_data: UTSJSONObject | null\r\n\tbusiness_license: string | null\r\n\tshop_category: string | null\r\n\tservice_areas: UTSJSONObject | null\r\n\temergency_contact: string | null\r\n\tpreferences: UTSJSONObject | null\r\n\tcreated_at: string\r\n\tupdated_at: string\r\n}\r\n\r\n// 用户地址类型\r\nexport type UserAddressType = {\r\n\tid: string\r\n\tuser_id: string\r\n\treceiver_name: string\r\n\treceiver_phone: string\r\n\tprovince: string\r\n\tcity: string\r\n\tdistrict: string\r\n\taddress_detail: string\r\n\tpostal_code: string | null\r\n\tis_default: boolean\r\n\tlabel: string | null\r\n\tcoordinates: string | null\r\n\tdelivery_instructions: string | null\r\n\tbusiness_hours: string | null\r\n\tstatus: number\r\n\tcreated_at: string\r\n\tupdated_at: string\r\n}\r\n\r\n// 商家类型\r\nexport type MerchantType = {\r\n\tid: string\r\n\tuser_id: string\r\n\tshop_name: string\r\n\tshop_logo: string | null\r\n\tshop_banner: string | null\r\n\tshop_description: string | null\r\n\tcontact_name: string\r\n\tcontact_phone: string\r\n\tshop_status: number\r\n\trating: number\r\n\ttotal_sales: number\r\n\tcreated_at: string\r\n}\r\n\r\n// 商品类型\r\nexport type ProductType = {\r\n\tid: string\r\n\tmerchant_id: string\r\n\tcategory_id: string\r\n\tname: string\r\n\tdescription: string | null\r\n\timages: Array\r\n\tprice: number\r\n\toriginal_price: number | null\r\n\tstock: number\r\n\tsales: number\r\n\tstatus: number\r\n\tcreated_at: string\r\n\t// 药品相关字段\r\n\tspecification?: string | null // 规格说明\r\n\tusage?: string | null // 用法用量\r\n\tside_effects?: string | null // 副作用\r\n\tprecautions?: string | null // 注意事项\r\n\texpiry_date?: string | null // 有效期\r\n\tstorage_conditions?: string | null // 储存条件\r\n\tapproval_number?: string | null // 批准文号\r\n\ttags?: Array | null // 商品标签\r\n}\r\n\r\n// 商品SKU类型\r\nexport type ProductSkuType = {\r\n\tid: string\r\n\tproduct_id: string\r\n\tsku_code: string\r\n\tspecifications: UTSJSONObject | null\r\n\tprice: number\r\n\tstock: number\r\n\timage_url: string | null\r\n\tstatus: number\r\n}\r\n\r\n// 购物车类型\r\nexport type CartItemType = {\r\n\tid: string\r\n\tuser_id: string\r\n\tproduct_id: string\r\n\tsku_id: string\r\n\tquantity: number\r\n\tselected: boolean\r\n\tproduct: ProductType | null\r\n\tsku: ProductSkuType | null\r\n}\r\n\r\n// 订单类型\r\nexport type OrderType = {\r\n\tid: string\r\n\torder_no: string\r\n\tuser_id: string\r\n\tmerchant_id: string\r\n\tstatus: number\r\n\ttotal_amount: number\r\n\tdiscount_amount: number\r\n\tdelivery_fee: number\r\n\tactual_amount: number\r\n\tpayment_method: number | null\r\n\tpayment_status: number\r\n\tdelivery_address: UTSJSONObject\r\n\tcreated_at: string\r\n}\r\n\r\n// 订单商品类型\r\nexport type OrderItemType = {\r\n\tid: string\r\n\torder_id: string\r\n\tproduct_id: string\r\n\tsku_id: string\r\n\tproduct_name: string\r\n\tsku_specifications: UTSJSONObject | null\r\n\tprice: number\r\n\tquantity: number\r\n\ttotal_amount: number\r\n}\r\n\r\n// 配送员类型\r\nexport type DeliveryDriverType = {\r\n\tid: string\r\n\tuser_id: string\r\n\treal_name: string\r\n\tid_card: string\r\n\tdriver_license: string | null\r\n\tvehicle_type: number\r\n\tvehicle_number: string | null\r\n\twork_status: number\r\n\tcurrent_location: UTSJSONObject | null\r\n\tservice_areas: Array\r\n\trating: number\r\n\ttotal_orders: number\r\n\tauth_status: number\r\n\tcreated_at: string\r\n\tupdated_at: string\r\n}\r\n\r\n// 配送任务类型\r\nexport type DeliveryTaskType = {\r\n\tid: string\r\n\torder_id: string\r\n\tdriver_id: string | null\r\n\tpickup_address: UTSJSONObject\r\n\tdelivery_address: UTSJSONObject\r\n\tdistance: number | null\r\n\testimated_time: number | null\r\n\tdelivery_fee: number\r\n\tstatus: number\r\n\tpickup_time: string | null\r\n\tdelivered_time: string | null\r\n\tdelivery_code: string | null\r\n\tremark: string | null\r\n\tcreated_at: string\r\n\tupdated_at: string\r\n}\r\n\r\n// 优惠券模板类型\r\nexport type CouponTemplateType = {\r\n\tid: string\r\n\tname: string\r\n\tdescription: string | null\r\n\tcoupon_type: number\r\n\tdiscount_type: number\r\n\tdiscount_value: number\r\n\tmin_order_amount: number\r\n\tmax_discount_amount: number | null\r\n\ttotal_quantity: number | null\r\n\tper_user_limit: number\r\n\tusage_limit: number\r\n\tmerchant_id: string | null\r\n\tcategory_ids: Array\r\n\tproduct_ids: Array\r\n\tuser_type_limit: number | null\r\n\tstart_time: string\r\n\tend_time: string\r\n\tstatus: number\r\n\tcreated_at: string\r\n}\r\n\r\n// 用户优惠券类型\r\nexport type UserCouponType = {\r\n\tid: string\r\n\tuser_id: string\r\n\ttemplate_id: string\r\n\tcoupon_code: string\r\n\tstatus: number\r\n\tused_at: string | null\r\n\torder_id: string | null\r\n\treceived_at: string\r\n\texpire_at: string\r\n}\r\n\r\n// 分页数据类型\r\nexport type PageDataType = {\r\n\tdata: Array\r\n\ttotal: number\r\n\tpage: number\r\n\tpageSize: number\r\n\thasMore: boolean\r\n}\r\n\r\n// API响应类型\r\nexport type ApiResponseType = {\r\n\tsuccess: boolean\r\n\tdata: T | null\r\n\tmessage: string\r\n\tcode: number\r\n}\r\n\r\n// 订单状态枚举\r\nexport const ORDER_STATUS = {\r\n\tPENDING_PAYMENT: 1,\r\n\tPAID: 2,\r\n\tSHIPPED: 3,\r\n\tDELIVERED: 4,\r\n\tCOMPLETED: 5,\r\n\tCANCELLED: 6,\r\n\tREFUNDING: 7,\r\n\tREFUNDED: 8\r\n}\r\n\r\n// 优惠券类型枚举\r\nexport const COUPON_TYPE = {\r\n\tDISCOUNT_AMOUNT: 1, // 满减券\r\n\tDISCOUNT_PERCENT: 2, // 折扣券\r\n\tFREE_SHIPPING: 3, // 免运费券\r\n\tNEWBIE: 4, // 新人券\r\n\tMEMBER: 5, // 会员券\r\n\tCATEGORY: 6, // 品类券\r\n\tMERCHANT: 7, // 商家券\r\n\tLIMITED_TIME: 8 // 限时券\r\n}\r\n\r\n// 支付方式枚举\r\nexport const PAYMENT_METHOD = {\r\n\tWECHAT: 1,\r\n\tALIPAY: 2,\r\n\tUNIONPAY: 3,\r\n\tBALANCE: 4\r\n}\r\n\r\n// 配送状态枚举\r\nexport const DELIVERY_STATUS = {\r\n\tPENDING: 1,\r\n\tASSIGNED: 2,\r\n\tPICKED_UP: 3,\r\n\tIN_TRANSIT: 4,\r\n\tDELIVERED: 5,\r\n\tFAILED: 6\r\n}\r\n\r\n// 用户类型枚举\r\nexport const MALL_USER_TYPE = {\r\n\tCONSUMER: 1, // 消费者\r\n\tMERCHANT: 2, // 商家\r\n\tDELIVERY: 3, // 配送员\r\n\tSERVICE: 4, // 客服\r\n\tADMIN: 5 // 管理员\r\n}\r\n\r\n// 用户状态枚举\r\nexport const USER_STATUS = {\r\n\tNORMAL: 1, // 正常\r\n\tFROZEN: 2, // 冻结\r\n\tCANCELLED: 3, // 注销\r\n\tPENDING: 4 // 待审核\r\n} as const\r\n\r\n// 认证状态枚举\r\nexport const VERIFICATION_STATUS = {\r\n\tUNVERIFIED: 0, // 未认证\r\n\tVERIFIED: 1, // 已认证\r\n\tFAILED: 2 // 认证失败\r\n}\r\n\r\n// 地址标签枚举\r\nexport const ADDRESS_LABEL = {\r\n\tHOME: 'home', // 家\r\n\tOFFICE: 'office', // 公司\r\n\tSCHOOL: 'school', // 学校\r\n\tOTHER: 'other' // 其他\r\n}\r\n\r\n// 收藏类型枚举\r\nexport const FAVORITE_TYPE = {\r\n\tPRODUCT: 'product', // 商品\r\n\tSHOP: 'shop' // 店铺\r\n}\r\n\r\n// =========================\r\n// 订阅相关类型与枚举\r\n// =========================\r\n\r\n// 订阅周期枚举\r\nexport const SUBSCRIPTION_PERIOD = {\r\n\tMONTHLY: 'monthly',\r\n\tYEARLY: 'yearly'\r\n}\r\n\r\n// 订阅状态枚举\r\nexport const SUBSCRIPTION_STATUS = {\r\n\tTRIAL: 'trial',\r\n\tACTIVE: 'active',\r\n\tPAST_DUE: 'past_due',\r\n\tCANCELED: 'canceled',\r\n\tEXPIRED: 'expired'\r\n}\r\n\r\n// 软件订阅方案类型\r\nexport type SubscriptionPlanType = {\r\n\tid: string\r\n\tplan_code: string\r\n\tname: string\r\n\tdescription: string | null\r\n\tfeatures: UTSJSONObject | null // { featureKey: description }\r\n\tprice: number // 单位:元(或分,取决于后端;前端以显示为准)\r\n\tcurrency: string | null // 'CNY' | 'USD' ...\r\n\tbilling_period: string // 'monthly' | 'yearly'\r\n\ttrial_days: number | null\r\n\tis_active: boolean\r\n\tsort_order?: number | null\r\n\tcreated_at?: string\r\n\tupdated_at?: string\r\n}\r\n\r\n// 用户订阅记录类型\r\nexport type UserSubscriptionType = {\r\n\tid: string\r\n\tuser_id: string\r\n\tplan_id: string\r\n\tstatus: string\r\n\tstart_date: string\r\n\tend_date: string | null\r\n\tnext_billing_date: string | null\r\n\tauto_renew: boolean\r\n\tcancel_at_period_end?: boolean | null\r\n\tmetadata?: UTSJSONObject | null\r\n\tcreated_at?: string\r\n\tupdated_at?: string\r\n}\r\n\r\n// 用户基础信息类型 (兼容 pages/user/types.uts)\r\nexport type UserProfile = {\r\n id?: string;\r\n username: string;\r\n email: string;\r\n gender?: string;\r\n birthday?: string;\r\n height_cm?: number;\r\n weight_kg?: number;\r\n bio?: string;\r\n avatar_url?: string;\r\n preferred_language?: string;\r\n role?: string;\r\n school_id?: string;\r\n grade_id?: string;\r\n class_id?: string;\r\n created_at?: string;\r\n updated_at?: string;\r\n}\r\n\r\nexport type UserStats = {\r\n trainings: number;\r\n points: number;\r\n streak: number;\r\n}\r\n\r\n// 足迹项类型\r\nexport type FootprintItemType = {\r\n id: string\r\n name: string\r\n price: number\r\n original_price: number | null\r\n image: string\r\n sales: number\r\n shopId: string\r\n shopName: string\r\n viewTime: number\r\n}\r\n\r\n// =========================\r\n// 积分相关类型\r\n// =========================\r\n\r\n// 签到记录类型\r\nexport type SigninRecordType = {\r\n id: string\r\n user_id: string\r\n signin_date: string\r\n points_earned: number\r\n bonus_points: number\r\n continuous_days: number\r\n created_at: string\r\n}\r\n\r\n// 签到结果类型\r\nexport type SigninResultType = {\r\n success: boolean\r\n points: number\r\n continuous_days: number\r\n bonus_points: number\r\n total_points: number\r\n message: string\r\n}\r\n\r\n// 积分兑换商品类型\r\nexport type PointProductType = {\r\n id: string\r\n name: string\r\n description: string | null\r\n image_url: string | null\r\n product_type: string\r\n points_required: number\r\n original_price: number | null\r\n stock: number\r\n status: number\r\n sort_order: number\r\n created_at: string\r\n}\r\n\r\n// 积分兑换记录类型\r\nexport type PointExchangeType = {\r\n id: string\r\n user_id: string\r\n product_id: string\r\n quantity: number\r\n points_used: number\r\n status: number\r\n tracking_no: string | null\r\n address_snapshot: UTSJSONObject | null\r\n created_at: string\r\n product: PointProductType | null\r\n}\r\n\r\n// 积分规则类型\r\nexport type PointRuleType = {\r\n id: string\r\n rule_type: string\r\n rule_name: string\r\n points: number\r\n description: string | null\r\n config: UTSJSONObject | null\r\n status: number\r\n}\r\n\r\n// 积分概览类型\r\nexport type PointsOverviewType = {\r\n current_points: number\r\n total_earned: number\r\n total_used: number\r\n expiring_points: number\r\n expiring_date: string | null\r\n}\r\n\r\n// =========================\r\n// 评价相关类型\r\n// =========================\r\n\r\n// 商品评价类型(扩展)\r\nexport type ProductReviewType = {\r\n id: string\r\n user_id: string\r\n product_id: string\r\n order_id: string\r\n order_item_id: string | null\r\n rating: number\r\n content: string | null\r\n images: string[]\r\n videos: string[]\r\n tags: string[]\r\n is_anonymous: boolean\r\n like_count: number\r\n is_edited: boolean\r\n append_content: string | null\r\n append_at: string | null\r\n append_images: string[]\r\n reply: string | null\r\n reply_time: string | null\r\n created_at: string\r\n updated_at: string\r\n user_name: string | null\r\n user_avatar: string | null\r\n is_liked: boolean\r\n}\r\n\r\n// 评价统计类型\r\nexport type ReviewStatsType = {\r\n total_count: number\r\n avg_rating: number\r\n good_rate: number\r\n rating_distribution: Map\r\n tags: ReviewTagType[]\r\n}\r\n\r\n// 评价标签类型\r\nexport type ReviewTagType = {\r\n name: string\r\n count: number\r\n}\r\n\r\n// 评价点赞类型\r\nexport type ReviewLikeType = {\r\n id: string\r\n review_id: string\r\n user_id: string\r\n created_at: string\r\n}\r\n\r\n// 评价举报类型\r\nexport type ReviewReportType = {\r\n id: string\r\n review_id: string\r\n user_id: string\r\n reason: string\r\n description: string | null\r\n status: number\r\n handle_result: string | null\r\n created_at: string\r\n}\r\n\r\n// 配送员评价类型\r\nexport type DeliveryRatingType = {\r\n id: string\r\n order_id: string\r\n delivery_user_id: string\r\n user_id: string\r\n rating: number\r\n content: string | null\r\n created_at: string\r\n}\r\n\r\n// 我的评价列表项类型\r\nexport type MyReviewItemType = {\r\n id: string\r\n product_id: string\r\n product_name: string\r\n product_image: string\r\n rating: number\r\n content: string | null\r\n images: string[]\r\n created_at: string\r\n can_append: boolean\r\n can_edit: boolean\r\n}\r\n\r\n// =========================\r\n// 推销模式相关类型\r\n// =========================\r\n\r\n// 用户余额类型\r\nexport type UserBalanceType = {\r\n id: string\r\n user_id: string\r\n balance: number\r\n frozen_balance: number\r\n total_earned: number\r\n total_withdrawn: number\r\n updated_at: string\r\n}\r\n\r\n// 余额变动记录类型\r\nexport type BalanceRecordType = {\r\n id: string\r\n user_id: string\r\n type: string\r\n amount: number\r\n balance_before: number\r\n balance_after: number\r\n related_id: string | null\r\n description: string | null\r\n operator_id: string | null\r\n created_at: string\r\n}\r\n\r\n// 分享记录类型\r\nexport type ShareRecordType = {\r\n id: string\r\n user_id: string\r\n product_id: string\r\n order_id: string\r\n order_item_id: string | null\r\n share_code: string\r\n product_name: string\r\n product_image: string | null\r\n product_price: number\r\n required_count: number\r\n current_count: number\r\n status: number\r\n reward_amount: number | null\r\n created_at: string\r\n completed_at: string | null\r\n expired_at: string | null\r\n}\r\n\r\n// 二级购买记录类型\r\nexport type SecondaryPurchaseType = {\r\n id: string\r\n share_record_id: string\r\n buyer_id: string\r\n order_id: string\r\n quantity: number\r\n unit_price: number\r\n created_at: string\r\n}\r\n\r\n// 免单奖励记录类型\r\nexport type FreeOrderRewardType = {\r\n id: string\r\n user_id: string\r\n share_record_id: string\r\n amount: number\r\n status: number\r\n balance_record_id: string | null\r\n cleared_at: string | null\r\n cleared_by: string | null\r\n created_at: string\r\n}\r\n\r\n// 会员等级类型\r\nexport type MemberLevelType = {\r\n id: number\r\n name: string\r\n min_amount: number\r\n discount: number\r\n icon: string | null\r\n description: string | null\r\n sort_order: number\r\n status: number\r\n}\r\n\r\n// 用户会员信息类型\r\nexport type UserMemberInfoType = {\r\n member_level: number\r\n level_name: string\r\n discount: number\r\n total_spent: number\r\n next_level: MemberLevelType | null\r\n progress_percent: number\r\n manual_level: boolean\r\n}\r\n\r\n// 会员等级变更记录类型\r\nexport type MemberLevelLogType = {\r\n id: string\r\n user_id: string\r\n old_level: number\r\n new_level: number\r\n reason: string | null\r\n operator_id: string | null\r\n created_at: string\r\n}\r\n","// 设备信息类型\r\nexport type DeviceInfo = {\r\n\tid: string\r\n\tdevice_name?: string\r\n\tstatus?: string // 'online' | 'offline' | 其他状态\r\n\tuser_id?: string\r\n\t// 可根据实际需求添加更多字段\r\n}\r\n\r\n// 设备查询参数类型\r\nexport type DeviceParams = {\r\n\tuser_id: string\r\n\t// 可根据实际需求添加更多查询参数\r\n}\r\n","import supabase, { supaReady } from '@/components/supadb/aksupainstance.uts'\r\nimport type { UserProfile } from '@/types/mall-types.uts'\r\n\r\n/**\r\n * 确保用户资料存在,如果不存在则创建基础资料\r\n * @param sessionUser 会话用户对象 (UTSJSONObject)\r\n * @returns 创建的用户资料,如果创建失败则返回 null\r\n */\r\nexport async function ensureUserProfile(sessionUser: UTSJSONObject): Promise {\r\n\ttry {\r\n\t\tawait supaReady\r\n \r\n\t\t// 从 sessionUser 中获取用户ID和邮箱\r\n\t\tconst userId = sessionUser.getString('id')\r\n\t\tconst email = sessionUser.getString('email') ?? ''\r\n\t\t\r\n\t\tif (userId == null || userId === '') {\r\n\t\t\t__f__('error','at utils/sapi.uts:18','无法获取用户ID')\r\n\t\t\treturn null\r\n\t\t}\r\n\t\t\r\n\t\t// 检查用户是否已存在(ak_users 通过 id 或 auth_id 关联 auth.users.id)\r\n\t\tconst checkRes = await supabase.from('ak_users')\r\n\t\t\t.select('*', {})\r\n\t\t\t.or('id.eq.' + userId + ',auth_id.eq.' + userId)\r\n\t\t\t.execute()\r\n\t\t\r\n\t\t__f__('log','at utils/sapi.uts:28','ensureUserProfile check ak_users:', {\r\n\t\t\tstatus: checkRes.status,\r\n\t\t\thasData: checkRes.data != null\r\n\t\t})\r\n\t\t\r\n\t\tconst dataList = checkRes.data\r\n\t\tif (checkRes.status >= 200 && checkRes.status < 300 && dataList != null && (dataList as any[]).length > 0) {\r\n\t\t\t// 用户已存在,返回现有资料(H5 下 checkRes.data 可能是 plain object,不一定是 UTSJSONObject)\r\n\t\t\tlet existingUser: UTSJSONObject\r\n\t\t\tconst firstItem = (dataList as any[])[0]\r\n\t\t\tif (firstItem instanceof UTSJSONObject) {\r\n\t\t\t\texistingUser = firstItem\r\n\t\t\t} else {\r\n\t\t\t\texistingUser = new UTSJSONObject(firstItem)\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tconst currentRole = existingUser.getString('role')\r\n\t\t\tconst currentAuthId = existingUser.getString('auth_id')\r\n\t\t\t\r\n\t\t\t// 【强力修复逻辑】如果 role 是 student 或者 auth_id 为空,进行 upsert 修复\r\n\t\t\tif (currentRole == 'student' || currentAuthId == null || currentAuthId == '') {\r\n\t\t\t\t__f__('log','at utils/sapi.uts:49','检测到旧数据异常,正在修复角色或关联ID...')\r\n\t\t\t\tconst updateData = new UTSJSONObject()\r\n\t\t\t\t// updateData.set('id', userId) // update 场景不需要传 ID 在 body 里,通常作为 filter\r\n\t\t\t\tupdateData.set('auth_id', userId)\r\n\t\t\t\tupdateData.set('role', 'consumer')\r\n\t\t\t\t\r\n\t\t\t\tawait supabase.from('ak_users')\r\n\t\t\t\t.update(updateData)\r\n\t\t\t\t.eq('id', userId)\r\n\t\t\t\t.execute()\r\n\t\t\t\t\r\n\t\t\t\t// 同步 Auth 元数据\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst meta = new UTSJSONObject()\r\n\t\t\t\t\tmeta.set('user_role', 'consumer')\r\n\t\t\t\t\tawait supabase.updateUserMetadata(meta)\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\t__f__('warn','at utils/sapi.uts:66','同步 Auth 元数据失败:', e)\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t// 返回修复后的对象\r\n\t\t\t\treturn {\r\n\t\t\t\t\tid: userId,\r\n\t\t\t\t\tusername: existingUser.getString('username') ?? email.split('@')[0],\r\n\t\t\t\t\temail: existingUser.getString('email') ?? email,\r\n\t\t\t\t\trole: 'consumer'\r\n\t\t\t\t} as UserProfile\r\n\t\t\t}\r\n\r\n\t\t\treturn {\r\n\t\t\t\tid: userId, // 始终返回 auth.users.id 作为 Profile ID\r\n\t\t\t\tusername: existingUser.getString('username') ?? '',\r\n\t\t\t\temail: existingUser.getString('email') ?? email,\r\n\t\t\t\tgender: existingUser.getString('gender'),\r\n\t\t\t\tbirthday: existingUser.getString('birthday'),\r\n\t\t\t\theight_cm: existingUser.getNumber('height_cm'),\r\n\t\t\t\tweight_kg: existingUser.getNumber('weight_kg'),\r\n\t\t\t\tbio: existingUser.getString('bio'),\r\n\t\t\t\tavatar_url: existingUser.getString('avatar_url'),\r\n\t\t\t\tpreferred_language: existingUser.getString('preferred_language'),\r\n\t\t\t\trole: existingUser.getString('role') ?? 'consumer',\r\n\t\t\t\tcreated_at: existingUser.getString('created_at'),\r\n\t\t\t\tupdated_at: existingUser.getString('updated_at')\r\n\t\t\t} as UserProfile\r\n\t\t}\r\n\t\t\r\n\t\t// 用户不存在,创建新用户资料\r\n\t\tconst newUserData = new UTSJSONObject()\r\n\t\tnewUserData.set('id', userId)\r\n\t\tnewUserData.set('auth_id', userId) // 确保 auth_id 被存储,解决登录查不到 Profile 的问题\r\n\t\tnewUserData.set('email', email)\r\n\t\tnewUserData.set('username', email.split('@')[0] ?? 'user') // 默认用户名为邮箱前缀\r\n\t\tnewUserData.set('role', 'consumer') // 强制设置为消费者角色\r\n\t\tnewUserData.set('created_at', new Date().toISOString()) // 手动设置创建时间\r\n\t\t\r\n\t\t// 尝试同步更新 Auth 元数据,确保以后登录生成的 JWT 中角色也为 consumer\r\n\t\ttry {\r\n\t\t\tconst meta = new UTSJSONObject()\r\n\t\t\tmeta.set('user_role', 'consumer')\r\n\t\t\tawait supabase.updateUserMetadata(meta)\r\n\t\t} catch (e) {\r\n\t\t\t__f__('warn','at utils/sapi.uts:110','同步 Auth 元数据失败 (非致命):', e)\r\n\t\t}\r\n\r\n\t\t__f__('log','at utils/sapi.uts:113','准备插入 ak_users, 目标 ID:', userId)\r\n\t\t__f__('log','at utils/sapi.uts:114','正在执行 insert 资料:', JSON.stringify(newUserData))\r\n\t\tconst insertRes = await supabase.from('ak_users')\r\n\t\t\t.insert(newUserData)\r\n\t\t\t.select('*', {})\r\n\t\t\t.execute()\r\n\t\t\r\n\t\t__f__('log','at utils/sapi.uts:120','ensureUserProfile insert ak_users 完整结果:', JSON.stringify(insertRes))\r\n\t\t\r\n\t\tif (insertRes.status >= 200 && insertRes.status < 300) {\r\n\t\t\tconst dataList = (insertRes.data != null) ? (insertRes.data as any[]) : []\r\n\t\t\tconst rawData = dataList.length > 0 ? dataList[0] : null\r\n\t\t\t\r\n\t\t\tif (rawData == null) {\r\n\t\t\t\t__f__('log','at utils/sapi.uts:127','ensureUserProfile: 资料插入操作已完成(200),但未返回数据(可能是 RLS 限制)');\r\n\t\t\t\treturn {\r\n\t\t\t\t\tid: userId,\r\n\t\t\t\t\tusername: email.split('@')[0] ?? 'user',\r\n\t\t\t\t\temail: email,\r\n\t\t\t\t\trole: 'consumer',\r\n\t\t\t\t\tcreated_at: newUserData.getString('created_at')\r\n\t\t\t\t} as UserProfile\r\n\t\t\t}\r\n\r\n\t\t\tconst newUser = (rawData instanceof UTSJSONObject)\r\n\t\t\t\t? (rawData as UTSJSONObject)\r\n\t\t\t\t: new UTSJSONObject(rawData)\r\n\t\t\treturn {\r\n\t\t\t\tid: newUser.getString('id') ?? userId,\r\n\t\t\t\tusername: newUser.getString('username') ?? email.split('@')[0],\r\n\t\t\t\temail: newUser.getString('email') ?? email,\r\n\t\t\t\tgender: newUser.getString('gender'),\r\n\t\t\t\tbirthday: newUser.getString('birthday'),\r\n\t\t\t\theight_cm: newUser.getNumber('height_cm'),\r\n\t\t\t\tweight_kg: newUser.getNumber('weight_kg'),\r\n\t\t\t\tbio: newUser.getString('bio'),\r\n\t\t\t\tavatar_url: newUser.getString('avatar_url'),\r\n\t\t\t\tpreferred_language: newUser.getString('preferred_language'),\r\n\t\t\t\trole: newUser.getString('role') ?? 'consumer',\r\n\t\t\t\tcreated_at: newUser.getString('created_at'),\r\n\t\t\t\tupdated_at: newUser.getString('updated_at')\r\n\t\t\t} as UserProfile\r\n\t\t} else {\r\n\t\t\t__f__('error','at utils/sapi.uts:156','创建用户资料失败:', insertRes.status)\r\n\t\t\treturn null\r\n\t\t}\r\n\t} catch (error) {\r\n\t\t__f__('error','at utils/sapi.uts:160','ensureUserProfile 异常:', error)\r\n\t\treturn null\r\n\t}\r\n}\r\n","import supa, { supaReady } from '@/components/supadb/aksupainstance.uts'\r\nimport type { UserProfile, UserStats } from '@/types/mall-types.uts'\r\nimport type { DeviceInfo } from '@/pages/sense/types.uts'\r\nimport { SenseDataService, type DeviceParams } from '@/pages/sense/senseDataService.uts'\r\nimport { reactive } from 'vue'\r\nimport { ensureUserProfile } from './sapi.uts'\r\n\r\n// 设备状态类型\r\nexport type DeviceState = {\r\n\tdevices : Array\r\n\tcurrentDevice : DeviceInfo | null\r\n\tisLoading : boolean\r\n\tlastUpdated : number | null\r\n}\r\n\r\n//定义一个大写的State类型\r\nexport type State = {\r\n\tglobalNum : number\r\n\tuserProfile ?: UserProfile\r\n\tisLoggedIn : boolean // 新增字段\r\n\tdeviceState : DeviceState // 新增设备状态\r\n\t// 如有需要,可增加更多属性\r\n}\r\n\r\n// 实例化为state\r\nexport const state = reactive({\r\n\tglobalNum: 0,\r\n\tuserProfile: { username: '', email: '' },\r\n\tisLoggedIn: false,\r\n\tdeviceState: {\r\n\t\tdevices: [],\r\n\t\tcurrentDevice: null,\r\n\t\tisLoading: false,\r\n\t\tlastUpdated: null\r\n\t} as DeviceState\r\n} as State)\r\n// 定义修改属性值的方法\r\nexport const setGlobalNum = (num : number) => {\r\n\tstate.globalNum = num\r\n}\r\n// 新增:设置登录状态的方法\r\nexport const setIsLoggedIn = (val : boolean) => {\r\n\tstate.isLoggedIn = val\r\n}\r\n// 定义全局设置用户信息的方法\r\nexport const setUserProfile = (profile : UserProfile) => {\r\n\tstate.userProfile = profile\r\n}\r\n\r\n// 获取当前用户信息(含补全 profile)\r\nexport async function getCurrentUser() : Promise {\r\n\ttry {\r\n\t\tawait supaReady\r\n\t} catch (_) {}\r\n\r\n\tconst sessionInfo = supa.getSession()\r\n\tif (sessionInfo.user == null) {\r\n\t\tstate.userProfile = { username: '', email: '' } as UserProfile\r\n\t\tstate.isLoggedIn = false // 未登录\r\n\t\treturn null\r\n\t}\r\n\tconst userId = sessionInfo.user?.getString(\"id\")\r\n\tif (userId == null) {\r\n\t\tstate.userProfile = { username: '', email: '' } as UserProfile\r\n\t\tstate.isLoggedIn = false // 未登录\r\n\t\treturn null\r\n\t}\t// 查询 ak_users 表补全 profile\r\n\tconst res = await supa.from('ak_users').select('*', {}).eq('id', userId).execute()\r\n\t__f__('log','at utils/store.uts:69',res)\r\n\tif (res.status >= 200 && res.status < 300 && (res.data != null)) {\r\n\t\tlet user : UTSJSONObject | null = null;\r\n\t\tconst data = res.data as any;\r\n\t\tif (Array.isArray(data)) {\r\n\t\t\tif (data.length > 0) {\r\n\t\t\t\tuser = data[0] as UTSJSONObject;\r\n\t\t\t}\r\n\t\t} else if (data != null) {\r\n\t\t\tuser = data as UTSJSONObject;\r\n\t\t} __f__('log','at utils/store.uts:79',user)\r\n\t\tif (user == null) {\r\n\t\t\t__f__('log','at utils/store.uts:81','用户资料为空,尝试创建基础资料...')\t\t\t// 如果用户资料为空,尝试创建基础用户资料\r\n\t\t\tconst sessionUser = sessionInfo.user\r\n\t\t\tif (sessionUser != null) {\r\n\t\t\t\tconst createdProfile = await ensureUserProfile(sessionUser)\r\n\t\t\t\tif (createdProfile != null) {\r\n\t\t\t\t\tstate.userProfile = createdProfile\r\n\t\t\t\t\tstate.isLoggedIn = true\r\n\t\t\t\t\treturn createdProfile\r\n\t\t\t\t} else {\r\n\t\t\t\t\t__f__('error','at utils/store.uts:90','创建用户资料失败')\r\n\t\t\t\t\tstate.userProfile = { username: '', email: '' } as UserProfile\r\n\t\t\t\t\tstate.isLoggedIn = false\r\n\t\t\t\t\treturn null\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t__f__('error','at utils/store.uts:96','会话用户信息为空')\r\n\t\t\t\tstate.userProfile = { username: '', email: '' } as UserProfile\r\n\t\t\t\tstate.isLoggedIn = false\r\n\t\t\t\treturn null\r\n\t\t\t}\r\n\t\t}\r\n\t\t__f__('log','at utils/store.uts:102',user)\r\n\t\t// 直接用 getString/getNumber,无需兜底属性\t\t\r\n\t\tconst profile : UserProfile = {\r\n\t\t\tid: user.getString('id'),\r\n\t\t\tusername: user.getString('username') ?? \"\",\r\n\t\t\temail: user.getString('email') ?? \"\",\r\n\t\t\tgender: user.getString('gender'),\r\n\t\t\tbirthday: user.getString('birthday'),\r\n\t\t\theight_cm: user.getNumber('height_cm'),\r\n\t\t\tweight_kg: user.getNumber('weight_kg'),\r\n\t\t\tbio: user.getString('bio'),\r\n\t\t\tavatar_url: user.getString('avatar_url'),\r\n\t\t\tpreferred_language: user.getString('preferred_language'),\r\n\t\t\trole: user.getString('role'),\r\n\t\t\tschool_id: user.getString('school_id'),\r\n\t\t\tgrade_id: user.getString('grade_id'),\r\n\t\t\tclass_id: user.getString('class_id')\r\n\t\t}\r\n\t\tstate.userProfile = profile\r\n\t\tstate.isLoggedIn = true // 登录成功\r\n\t\treturn profile\r\n\t} else {\r\n\t\tstate.userProfile = { username: '', email: '' } as UserProfile\r\n\t\tstate.isLoggedIn = false // 未登录\r\n\t\treturn null\r\n\t}\r\n}\r\n\r\n// 登出并清空用户信息\r\nexport function logout() {\r\n\tsupa.signOut()\r\n\tstate.userProfile = { username: '', email: '' } as UserProfile\r\n\tstate.isLoggedIn = false // 登出\r\n}\r\n\r\n// 获取当前用户ID(优先级:state.userProfile.id > session > localStorage)\r\nexport function getCurrentUserId() : string {\r\n\ttry {\r\n\t\tconst profile = state.userProfile\r\n\t\tif (profile != null && profile.id != null) {\r\n\t\t\tconst profileId = profile.id\r\n\t\t\tif (profileId != null) {\r\n\t\t\t\treturn profileId\r\n\t\t\t}\r\n\t\t}\r\n\t} catch (e) { }\r\n\ttry {\r\n\t\tconst session = supa.getSession()\r\n\t\tif (session != null) {\r\n\t\t\tconst curuser = session.user\r\n\t\t\tconst userId = curuser?.getString('id')\r\n\t\t\tif (userId != null) return userId\r\n\t\t}\r\n\t} catch (e) { }\r\n\treturn ''\r\n}\r\n\r\n// 获取当前用户的class_id\r\nexport function getCurrentUserClassId() : string | null {\r\n\ttry {\r\n\t\tconst profile = state.userProfile\r\n\t\tif (profile != null && profile.class_id != null) {\r\n\t\t\treturn profile.class_id\r\n\t\t}\r\n\t} catch (e) {\r\n\t\t__f__('error','at utils/store.uts:167','获取用户class_id失败:', e)\r\n\t}\r\n\treturn null\r\n}\r\n\r\n// User store API for component compatibility\r\nexport function getUserStore() {\r\n\treturn {\r\n\t\tgetUserId() : string | null {\r\n\t\t\tconst sessionInfo = supa.getSession()\r\n\t\t\treturn sessionInfo.user?.getString(\"id\") ?? null\r\n\t\t},\r\n\r\n\t\tgetUserName() : string | null {\r\n\t\t\treturn state.userProfile?.username ?? null\r\n\t\t},\r\n\r\n\t\tgetUserRole() : string | null {\r\n\t\t\t// Default role logic - can be enhanced based on your needs\r\n\t\t\tconst sessionInfo = supa.getSession()\r\n\t\t\tif (sessionInfo.user == null) return null\r\n\r\n\t\t\t// You can add role detection logic here\r\n\t\t\t// For now, return a default role\r\n\t\t\treturn 'teacher' // or determine from user profile/database\r\n\t\t},\r\n\r\n\t\tgetProfile() : UserProfile | null {\r\n\t\t\treturn state.userProfile\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// ========== 设备状态管理方法 ==========\r\n\r\n/**\r\n * 设置设备加载状态\r\n */\r\nexport const setDeviceLoading = (loading : boolean) => {\r\n\tstate.deviceState.isLoading = loading\r\n}\r\n\r\n/**\r\n * 设置设备列表\r\n */\r\nexport const setDevices = (devices : Array) => {\r\n\tstate.deviceState.devices = devices\r\n\tstate.deviceState.lastUpdated = Date.now()\r\n}\r\n\r\n/**\r\n * 添加设备到列表\r\n */\r\nexport const addDevice = (device : DeviceInfo) => {\r\n\tconst existingIndex = state.deviceState.devices.findIndex(d => d.id === device.id)\r\n\tif (existingIndex >= 0) {\r\n\t\t// 更新现有设备\r\n\t\tstate.deviceState.devices[existingIndex] = device\r\n\t} else {\r\n\t\t// 添加新设备\r\n\t\tstate.deviceState.devices.push(device)\r\n\t}\r\n\tstate.deviceState.lastUpdated = Date.now()\r\n}\r\n\r\n/**\r\n * 从列表中移除设备\r\n */\r\nexport const removeDevice = (deviceId : string) => {\r\n\tconst index = state.deviceState.devices.findIndex(d => d.id === deviceId)\r\n\tif (index >= 0) {\r\n\t\tstate.deviceState.devices.splice(index, 1)\r\n\t\t// 如果移除的是当前设备,清空当前设备\r\n\t\tif (state.deviceState.currentDevice?.id === deviceId) {\r\n\t\t\tstate.deviceState.currentDevice = null\r\n\t\t}\r\n\t\tstate.deviceState.lastUpdated = Date.now()\r\n\t}\r\n}\r\n\r\n/**\r\n * 更新设备信息\r\n */\r\nexport const updateDevice = (device : DeviceInfo) => {\r\n\tconst index = state.deviceState.devices.findIndex(d => d.id === device.id)\r\n\tif (index >= 0) {\r\n\t\tstate.deviceState.devices[index] = device\r\n\t\t// 如果更新的是当前设备,也更新当前设备\r\n\t\tif (state.deviceState.currentDevice?.id === device.id) {\r\n\t\t\tstate.deviceState.currentDevice = device\r\n\t\t}\r\n\t\tstate.deviceState.lastUpdated = Date.now()\r\n\t}\r\n}\r\n\r\n/**\r\n * 设置当前选中的设备\r\n */\r\nexport const setCurrentDevice = (device : DeviceInfo | null) => {\r\n\tstate.deviceState.currentDevice = device\r\n}\r\n\r\n/**\r\n * 根据设备ID获取设备信息\r\n */\r\nexport const getDeviceById = (deviceId : string) : DeviceInfo | null => {\r\n\treturn state.deviceState.devices.find(d => d.id === deviceId) ?? null\r\n}\r\n\r\n/**\r\n * 获取在线设备列表\r\n */\r\nexport const getOnlineDevices = () : Array => {\r\n\treturn state.deviceState.devices.filter(d => d.status === 'online')\r\n}\r\n\r\n/**\r\n * 从服务器加载设备列表\r\n */\r\nexport const loadDevices = async (forceRefresh : boolean) : Promise => {\r\n\tconst userId = getCurrentUserId()\r\n\tif (userId == null || userId === '') {\r\n\t\t__f__('log','at utils/store.uts:289','用户未登录,无法加载设备列表')\r\n\t\treturn false\r\n\t}\r\n\r\n\t// 如果不是强制刷新且数据较新(5分钟内),直接返回\r\n\tconst now = Date.now()\r\n\tconst lastUpdated = state.deviceState.lastUpdated\r\n\tif (forceRefresh == false && lastUpdated != null && (now - lastUpdated < 5 * 60 * 1000)) {\r\n\t\t__f__('log','at utils/store.uts:297','设备数据较新,跳过刷新')\r\n\t\treturn true\r\n\t}\r\n\tsetDeviceLoading(true)\r\n\ttry {\r\n\t\tconst result = await SenseDataService.getDevices({ user_id: userId })\r\n\t\tif (result.error === null && result.data != null) {\r\n\t\t\tconst devices = result.data as Array\r\n\t\t\tsetDevices(devices)\r\n\t\t\t__f__('log','at utils/store.uts:306',`加载设备列表成功,共${devices.length}个设备`)\r\n\t\t\treturn true\r\n\t\t} else {\r\n\t\t\t__f__('log','at utils/store.uts:309','加载设备列表失败:', result.error?.message ?? '未知错误')\r\n\t\t\treturn false\r\n\t\t}\r\n\t} catch (error) {\r\n\t\t__f__('log','at utils/store.uts:313','加载设备列表异常:', error)\r\n\t\treturn false\r\n\t} finally {\r\n\t\tsetDeviceLoading(false)\r\n\t}\r\n}\r\n\r\n/**\r\n * 从服务器加载设备列表 - 带默认参数的重载版本\r\n */\r\nexport const loadDevicesWithDefault = async () : Promise => {\r\n\treturn await loadDevices(false)\r\n}\r\n\r\n/**\r\n * 绑定新设备\r\n */\r\nexport const bindNewDevice = async (deviceData : UTSJSONObject) : Promise => {\r\n\tconst userId = getCurrentUserId()\r\n\tif (userId == null) {\r\n\t\t__f__('log','at utils/store.uts:333','用户未登录,无法绑定设备')\r\n\t\treturn false\r\n\t}\r\n\r\n\t// 确保设备数据中包含用户ID\r\n\tdeviceData.set('user_id', userId)\r\n\ttry {\r\n\t\tconst result = await SenseDataService.bindDevice(deviceData)\r\n\t\tif (result.error === null && result.data != null) {\r\n\t\t\t// 添加到本地状态\r\n\t\t\taddDevice(result.data as DeviceInfo)\r\n\t\t\tconst deviceName = (result.data as DeviceInfo).device_name ?? '未知设备'\r\n\t\t\t__f__('log','at utils/store.uts:345','设备绑定成功:', deviceName)\r\n\t\t\treturn true\r\n\t\t} else {\r\n\t\t\t__f__('log','at utils/store.uts:348','设备绑定失败:', result.error?.message ?? '未知错误')\r\n\t\t\treturn false\r\n\t\t}\r\n\t} catch (error) {\r\n\t\t__f__('log','at utils/store.uts:352','设备绑定异常:', error)\r\n\t\treturn false\r\n\t}\r\n}\r\n\r\n/**\r\n * 解绑设备\r\n */\r\nexport const unbindDevice = async (deviceId : string) : Promise => {\r\n\ttry {\r\n\t\tconst result = await SenseDataService.unbindDevice(deviceId)\r\n\t\tif (result.error === null) {\r\n\t\t\t// 从本地状态中移除\r\n\t\t\tremoveDevice(deviceId)\r\n\t\t\t__f__('log','at utils/store.uts:366','设备解绑成功')\r\n\t\t\treturn true\r\n\t\t} else {\r\n\t\t\t__f__('log','at utils/store.uts:369','设备解绑失败:', result.error?.message ?? '未知错误')\r\n\t\t\treturn false\r\n\t\t}\r\n\t} catch (error) {\r\n\t\t__f__('log','at utils/store.uts:373','设备解绑异常:', error)\r\n\t\treturn false\r\n\t}\r\n}\r\n\r\n/**\r\n * 更新设备配置\r\n */\r\nexport const updateDeviceConfig = async (deviceId : string, configData : UTSJSONObject) : Promise => {\r\n\ttry {\r\n\t\tconst result = await SenseDataService.updateDevice(deviceId, configData)\r\n\t\tif (result.error === null && result.data != null) {\r\n\t\t\t// 更新本地状态\r\n\t\t\tupdateDevice(result.data as DeviceInfo)\r\n\t\t\t__f__('log','at utils/store.uts:387','设备配置更新成功')\r\n\t\t\treturn true\r\n\t\t} else {\r\n\t\t\t__f__('log','at utils/store.uts:390','设备配置更新失败:', result.error?.message ?? '未知错误')\r\n\t\t\treturn false\r\n\t\t}\r\n\t} catch (error) {\r\n\t\t__f__('log','at utils/store.uts:394','设备配置更新异常:', error)\r\n\t\treturn false\r\n\t}\r\n}\r\n\r\n// ========== 设备管理 API ==========\r\n\r\n/**\r\n * 获取设备管理相关的API\r\n */\r\nexport function getDeviceStore() {\r\n\treturn {\r\n\t\t// 获取设备状态\r\n\t\tgetDevices() : Array {\r\n\t\t\treturn state.deviceState.devices\r\n\t\t},\r\n\r\n\t\tgetCurrentDevice() : DeviceInfo | null {\r\n\t\t\treturn state.deviceState.currentDevice\r\n\t\t},\r\n\r\n\t\tisLoading() : boolean {\r\n\t\t\treturn state.deviceState.isLoading\r\n\t\t},\r\n\t\tgetLastUpdated() : number | null {\r\n\t\t\treturn state.deviceState.lastUpdated\r\n\t\t},\r\n\r\n\t\t// 设备操作方法\r\n\t\tasync loadDevices(forceRefresh : boolean) : Promise {\r\n\t\t\treturn await loadDevices(forceRefresh)\r\n\t\t},\r\n\r\n\t\tasync refreshDevices() : Promise {\r\n\t\t\treturn await loadDevicesWithDefault()\r\n\t\t},\r\n\r\n\t\tasync bindDevice(deviceData : UTSJSONObject) : Promise {\r\n\t\t\treturn await bindNewDevice(deviceData)\r\n\t\t},\r\n\r\n\t\tasync unbindDevice(deviceId : string) : Promise {\r\n\t\t\treturn await unbindDevice(deviceId)\r\n\t\t},\r\n\r\n\t\tasync updateDevice(deviceId : string, configData : UTSJSONObject) : Promise {\r\n\t\t\treturn await updateDeviceConfig(deviceId, configData)\r\n\t\t},\r\n\r\n\t\t// 设备查询方法\r\n\t\tgetDeviceById(deviceId : string) : DeviceInfo | null {\r\n\t\t\treturn getDeviceById(deviceId)\r\n\t\t},\r\n\r\n\t\tgetOnlineDevices() : Array {\r\n\t\t\treturn getOnlineDevices()\r\n\t\t},\r\n\r\n\t\t// 设备选择\r\n\t\tsetCurrentDevice(device : DeviceInfo | null) {\r\n\t\t\tsetCurrentDevice(device)\r\n\t\t}\r\n\t}\r\n}","import 'D:/HBuilderX/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts';// 简化的main.uts,移除i18n依赖\r\nimport { createSSRApp } from 'vue'\r\nimport App from './App.uvue'\r\nimport i18n from '@/uni_modules/i18n/index.uts'\r\n\r\nexport function createApp() {\r\n const app = createSSRApp(App)\r\n \r\n // 注册 i18n 全局属性,使组件可以使用 $t 方法\r\n\tapp.config.globalProperties.$t = (key: string, values?: any, locale?: string): string => {\r\n\t\tif (i18n.global == null) {\r\n\t\t\t__f__('error','at main.uts:12','i18n is not initialized')\r\n\t\t\treturn key\r\n\t\t}\r\n const params = values as UTSJSONObject | null\r\n\t\tconst res = i18n.global.t(key, params, locale)\r\n if (res.length > 0) {\r\n return res\r\n }\r\n return key\r\n\t}\r\n \r\n return { app }\r\n}\r\n\nexport function main(app: IApp) {\n definePageRoutes();\n defineAppConfig();\n (createApp()['app'] as VueApp).mount(app, GenUniApp());\n}\n\nexport class UniAppConfig extends io.dcloud.uniapp.appframe.AppConfig {\n override name: string = \"mall\"\n override appid: string = \"__UNI__EC68BC3\"\n override versionName: string = \"1.0.0\"\n override versionCode: string = \"100\"\n override uniCompilerVersion: string = \"4.87\"\n \n constructor() { super() }\n}\n\nimport GenPagesUserLoginClass from './pages/user/login.uvue'\nimport GenPagesUserBootClass from './pages/user/boot.uvue'\nimport GenPagesUserRegisterClass from './pages/user/register.uvue'\nimport GenPagesUserForgotPasswordClass from './pages/user/forgot-password.uvue'\nimport GenPagesUserTermsClass from './pages/user/terms.uvue'\nimport GenPagesUserCenterClass from './pages/user/center.uvue'\nimport GenPagesUserProfileClass from './pages/user/profile.uvue'\nimport GenPagesUserChangePasswordClass from './pages/user/change-password.uvue'\nimport GenPagesUserBindPhoneClass from './pages/user/bind-phone.uvue'\nimport GenPagesUserBindEmailClass from './pages/user/bind-email.uvue'\nimport GenPagesMainIndexClass from './pages/main/index.uvue'\nimport GenPagesMainCategoryClass from './pages/main/category.uvue'\nimport GenPagesMainMessagesClass from './pages/main/messages.uvue'\nimport GenPagesMainCartClass from './pages/main/cart.uvue'\nimport GenPagesMainProfileClass from './pages/main/profile.uvue'\nimport GenPagesMallConsumerSettingsClass from './pages/mall/consumer/settings.uvue'\nimport GenPagesMallConsumerWalletClass from './pages/mall/consumer/wallet.uvue'\nimport GenPagesMallConsumerWithdrawClass from './pages/mall/consumer/withdraw.uvue'\nimport GenPagesMallConsumerSearchClass from './pages/mall/consumer/search.uvue'\nimport GenPagesMallConsumerProductDetailClass from './pages/mall/consumer/product-detail.uvue'\nimport GenPagesMallConsumerShopDetailClass from './pages/mall/consumer/shop-detail.uvue'\nimport GenPagesMallConsumerCouponsClass from './pages/mall/consumer/coupons.uvue'\nimport GenPagesMallConsumerFavoritesClass from './pages/mall/consumer/favorites.uvue'\nimport GenPagesMallConsumerFootprintClass from './pages/mall/consumer/footprint.uvue'\nimport GenPagesMallConsumerAddressListClass from './pages/mall/consumer/address-list.uvue'\nimport GenPagesMallConsumerAddressEditClass from './pages/mall/consumer/address-edit.uvue'\nimport GenPagesMallConsumerCheckoutClass from './pages/mall/consumer/checkout.uvue'\nimport GenPagesMallConsumerPaymentClass from './pages/mall/consumer/payment.uvue'\nimport GenPagesMallConsumerPaymentSuccessClass from './pages/mall/consumer/payment-success.uvue'\nimport GenPagesMallConsumerOrdersClass from './pages/mall/consumer/orders.uvue'\nimport GenPagesMallConsumerOrderDetailClass from './pages/mall/consumer/order-detail.uvue'\nimport GenPagesMallConsumerLogisticsClass from './pages/mall/consumer/logistics.uvue'\nimport GenPagesMallConsumerReviewClass from './pages/mall/consumer/review.uvue'\nimport GenPagesMallConsumerRefundClass from './pages/mall/consumer/refund.uvue'\nimport GenPagesMallConsumerApplyRefundClass from './pages/mall/consumer/apply-refund.uvue'\nimport GenPagesMallConsumerRefundReviewClass from './pages/mall/consumer/refund-review.uvue'\nimport GenPagesMallConsumerChatClass from './pages/mall/consumer/chat.uvue'\nimport GenPagesMallConsumerSubscriptionFollowedShopsClass from './pages/mall/consumer/subscription/followed-shops.uvue'\nimport GenPagesMallConsumerPointsIndexClass from './pages/mall/consumer/points/index.uvue'\nimport GenPagesMallConsumerPointsSigninClass from './pages/mall/consumer/points/signin.uvue'\nimport GenPagesMallConsumerPointsExchangeClass from './pages/mall/consumer/points/exchange.uvue'\nimport GenPagesMallConsumerPointsExchangeRecordsClass from './pages/mall/consumer/points/exchange-records.uvue'\nimport GenPagesMallConsumerProductReviewsClass from './pages/mall/consumer/product-reviews.uvue'\nimport GenPagesMallConsumerMyReviewsClass from './pages/mall/consumer/my-reviews.uvue'\nimport GenPagesMallConsumerBalanceIndexClass from './pages/mall/consumer/balance/index.uvue'\nimport GenPagesMallConsumerShareIndexClass from './pages/mall/consumer/share/index.uvue'\nimport GenPagesMallConsumerShareDetailClass from './pages/mall/consumer/share/detail.uvue'\nimport GenPagesMallConsumerMemberIndexClass from './pages/mall/consumer/member/index.uvue'\nimport GenPagesMallConsumerMessageDetailClass from './pages/mall/consumer/message-detail.uvue'\nimport GenPagesMallConsumerRedPacketsIndexClass from './pages/mall/consumer/red-packets/index.uvue'\nimport GenPagesMallConsumerBankCardsIndexClass from './pages/mall/consumer/bank-cards/index.uvue'\nimport GenPagesMallConsumerBankCardsAddClass from './pages/mall/consumer/bank-cards/add.uvue'\nfunction definePageRoutes() {\n__uniRoutes.push({ path: \"pages/user/login\", component: GenPagesUserLoginClass, meta: { isQuit: true } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"用户登录\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/boot\", component: GenPagesUserBootClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/register\", component: GenPagesUserRegisterClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"注册\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/forgot-password\", component: GenPagesUserForgotPasswordClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"忘记密码\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/terms\", component: GenPagesUserTermsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"用户协议与隐私政策\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/center\", component: GenPagesUserCenterClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"用户中心\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/profile\", component: GenPagesUserProfileClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"个人资料\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/change-password\", component: GenPagesUserChangePasswordClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"修改密码\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/bind-phone\", component: GenPagesUserBindPhoneClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"绑定手机\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/user/bind-email\", component: GenPagesUserBindEmailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"绑定邮箱\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/main/index\", component: GenPagesMainIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"首页\"],[\"navigationStyle\",\"custom\"],[\"enablePullDownRefresh\",false]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/main/category\", component: GenPagesMainCategoryClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"分类\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/main/messages\", component: GenPagesMainMessagesClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"消息\"],[\"navigationStyle\",\"custom\"],[\"enablePullDownRefresh\",true]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/main/cart\", component: GenPagesMainCartClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"购物车\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/main/profile\", component: GenPagesMainProfileClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/settings\", component: GenPagesMallConsumerSettingsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"设置\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/wallet\", component: GenPagesMallConsumerWalletClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的钱包\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/withdraw\", component: GenPagesMallConsumerWithdrawClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"余额提现\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/search\", component: GenPagesMallConsumerSearchClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"搜索\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/product-detail\", component: GenPagesMallConsumerProductDetailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"商品详情\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/shop-detail\", component: GenPagesMallConsumerShopDetailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"店铺详情\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/coupons\", component: GenPagesMallConsumerCouponsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的优惠券\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/favorites\", component: GenPagesMallConsumerFavoritesClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的收藏\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/footprint\", component: GenPagesMallConsumerFootprintClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的足迹\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/address-list\", component: GenPagesMallConsumerAddressListClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"收货地址\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/address-edit\", component: GenPagesMallConsumerAddressEditClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"编辑地址\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/checkout\", component: GenPagesMallConsumerCheckoutClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"确认订单\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/payment\", component: GenPagesMallConsumerPaymentClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"收银台\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/payment-success\", component: GenPagesMallConsumerPaymentSuccessClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"支付成功\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/orders\", component: GenPagesMallConsumerOrdersClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的订单\"],[\"enablePullDownRefresh\",true]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/order-detail\", component: GenPagesMallConsumerOrderDetailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"订单详情\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/logistics\", component: GenPagesMallConsumerLogisticsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"物流详情\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/review\", component: GenPagesMallConsumerReviewClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"评价晒单\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/refund\", component: GenPagesMallConsumerRefundClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"退款/售后\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/apply-refund\", component: GenPagesMallConsumerApplyRefundClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"申请售后\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/refund-review\", component: GenPagesMallConsumerRefundReviewClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"服务评价\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/chat\", component: GenPagesMallConsumerChatClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"客服聊天\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/subscription/followed-shops\", component: GenPagesMallConsumerSubscriptionFollowedShopsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"关注店铺\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/points/index\", component: GenPagesMallConsumerPointsIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"积分管理\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/points/signin\", component: GenPagesMallConsumerPointsSigninClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"每日签到\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/points/exchange\", component: GenPagesMallConsumerPointsExchangeClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"积分兑换\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/points/exchange-records\", component: GenPagesMallConsumerPointsExchangeRecordsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"兑换记录\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/product-reviews\", component: GenPagesMallConsumerProductReviewsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"商品评价\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/my-reviews\", component: GenPagesMallConsumerMyReviewsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的评价\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/balance/index\", component: GenPagesMallConsumerBalanceIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的余额\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/share/index\", component: GenPagesMallConsumerShareIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的分享\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/share/detail\", component: GenPagesMallConsumerShareDetailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"分享详情\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/member/index\", component: GenPagesMallConsumerMemberIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"会员中心\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/message-detail\", component: GenPagesMallConsumerMessageDetailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"消息详情\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/red-packets/index\", component: GenPagesMallConsumerRedPacketsIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的红包\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/bank-cards/index\", component: GenPagesMallConsumerBankCardsIndexClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"银行卡管理\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/mall/consumer/bank-cards/add\", component: GenPagesMallConsumerBankCardsAddClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"添加银行卡\"]]) } as UniPageRoute)\n}\nconst __uniTabBar: Map | null = _uM([[\"color\",\"#999999\"],[\"selectedColor\",\"#ff5000\"],[\"backgroundColor\",\"#ffffff\"],[\"borderStyle\",\"black\"],[\"list\",[_uM([[\"pagePath\",\"pages/main/index\"],[\"text\",\"首页\"],[\"iconPath\",\"static/tabbar/home.png\"],[\"selectedIconPath\",\"static/tabbar/home.png\"]]),_uM([[\"pagePath\",\"pages/main/category\"],[\"text\",\"分类\"],[\"iconPath\",\"static/tabbar/category.png\"],[\"selectedIconPath\",\"static/tabbar/category.png\"]]),_uM([[\"pagePath\",\"pages/main/messages\"],[\"text\",\"消息\"],[\"iconPath\",\"static/tabbar/message.png\"],[\"selectedIconPath\",\"static/tabbar/message.png\"]]),_uM([[\"pagePath\",\"pages/main/cart\"],[\"text\",\"购物车\"],[\"iconPath\",\"static/tabbar/cart.png\"],[\"selectedIconPath\",\"static/tabbar/cart.png\"]]),_uM([[\"pagePath\",\"pages/main/profile\"],[\"text\",\"我的\"],[\"iconPath\",\"static/tabbar/user.png\"],[\"selectedIconPath\",\"static/tabbar/user.png\"]])]]])\nconst __uniLaunchPage: Map = _uM([[\"url\",\"pages/user/login\"],[\"style\",_uM([[\"navigationBarTitleText\",\"用户登录\"],[\"navigationStyle\",\"custom\"]])]])\nfunction defineAppConfig(){\n __uniConfig.entryPagePath = '/pages/user/login'\n __uniConfig.globalStyle = _uM([[\"navigationBarTextStyle\",\"black\"],[\"navigationBarTitleText\",\"mall\"],[\"navigationBarBackgroundColor\",\"#FFFFFF\"],[\"backgroundColor\",\"#F8F8F8\"]])\n __uniConfig.getTabBarConfig = ():Map | null => _uM([[\"color\",\"#999999\"],[\"selectedColor\",\"#ff5000\"],[\"backgroundColor\",\"#ffffff\"],[\"borderStyle\",\"black\"],[\"list\",[_uM([[\"pagePath\",\"pages/main/index\"],[\"text\",\"首页\"],[\"iconPath\",\"static/tabbar/home.png\"],[\"selectedIconPath\",\"static/tabbar/home.png\"]]),_uM([[\"pagePath\",\"pages/main/category\"],[\"text\",\"分类\"],[\"iconPath\",\"static/tabbar/category.png\"],[\"selectedIconPath\",\"static/tabbar/category.png\"]]),_uM([[\"pagePath\",\"pages/main/messages\"],[\"text\",\"消息\"],[\"iconPath\",\"static/tabbar/message.png\"],[\"selectedIconPath\",\"static/tabbar/message.png\"]]),_uM([[\"pagePath\",\"pages/main/cart\"],[\"text\",\"购物车\"],[\"iconPath\",\"static/tabbar/cart.png\"],[\"selectedIconPath\",\"static/tabbar/cart.png\"]]),_uM([[\"pagePath\",\"pages/main/profile\"],[\"text\",\"我的\"],[\"iconPath\",\"static/tabbar/user.png\"],[\"selectedIconPath\",\"static/tabbar/user.png\"]])]]])\n __uniConfig.tabBar = __uniConfig.getTabBarConfig()\n __uniConfig.conditionUrl = ''\n __uniConfig.uniIdRouter = new Map()\n \n __uniConfig.ready = true\n}\n","import supa from '@/components/supadb/aksupainstance.uts'\r\nimport type { AkReqResponse } from '@/uni_modules/ak-req/index.uts'\r\n\r\nconst OLD_URL = '192.168.1.61:18000'\r\nconst NEW_URL = '119.146.131.237:9126'\r\n\r\nfunction fixImageUrl(url: string | null): string {\r\n if (url == null) return ''\r\n if (url.indexOf(OLD_URL) >= 0) {\r\n return url.replace(OLD_URL, NEW_URL)\r\n }\r\n return url\r\n}\r\n\r\nfunction fixImageUrls(urls: any): string[] {\r\n if (urls == null) return []\r\n if (Array.isArray(urls)) {\r\n const result: string[] = []\r\n const arr = urls as any[]\r\n for (let i = 0; i < arr.length; i++) {\r\n try {\r\n const urlStr = JSON.stringify(arr[i])\r\n if (urlStr != null && urlStr.startsWith('\"') && urlStr.endsWith('\"')) {\r\n const fixed = fixImageUrl(urlStr.substring(1, urlStr.length - 1))\r\n if (fixed !== '') result.push(fixed)\r\n }\r\n } catch (e) {}\r\n }\r\n return result\r\n }\r\n return []\r\n}\r\n\r\n// 使用单例 Supabase 客户端\r\n// const supa = createClient(SUPA_URL, SUPA_KEY)\r\n\r\n// 辅助函数:安全获取字符串值\r\nfunction safeGetString(obj: UTSJSONObject, key: string): string {\r\n try {\r\n const rawVal = obj.get(key)\r\n if (rawVal == null) return ''\r\n const strVal = JSON.stringify(rawVal)\r\n if (strVal == null) return ''\r\n if (strVal.startsWith('\"') && strVal.endsWith('\"')) {\r\n return strVal.substring(1, strVal.length - 1)\r\n }\r\n return strVal\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:49','safeGetString error for key:', key, e)\r\n return ''\r\n }\r\n}\r\n\r\n// 辅助函数:安全获取数值\r\nfunction safeGetNumber(obj: UTSJSONObject, key: string): number {\r\n try {\r\n const rawVal = obj.get(key)\r\n if (rawVal == null) return 0\r\n try {\r\n const numVal = rawVal as number\r\n if (!isNaN(numVal)) return numVal\r\n } catch (e) {}\r\n return 0\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:65','safeGetNumber error for key:', key, e)\r\n return 0\r\n }\r\n}\r\n\r\n// 辅助函数:安全获取布尔值\r\nfunction safeGetBoolean(obj: UTSJSONObject, key: string): boolean {\r\n try {\r\n const rawVal = obj.get(key)\r\n if (rawVal == null) return false\r\n try {\r\n const boolVal = rawVal as boolean\r\n return boolVal\r\n } catch (e) {}\r\n return false\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:81','safeGetBoolean error for key:', key, e)\r\n return false\r\n }\r\n}\r\n\r\n// 辅助函数:安全获取字符串数组\r\nfunction safeGetStringArray(obj: UTSJSONObject, key: string): string[] {\r\n try {\r\n const rawVal = obj.get(key)\r\n if (rawVal != null && Array.isArray(rawVal)) {\r\n return rawVal as string[]\r\n }\r\n return [] as string[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:95','safeGetStringArray error for key:', key, e)\r\n return [] as string[]\r\n }\r\n}\r\n\r\n// 辅助函数:从原始数据解析商品\r\nfunction parseProductFromRaw(item: any): Product {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:103','[parseProductFromRaw] 开始解析商品')\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n __f__('log','at utils/supabaseService.uts:105','[parseProductFromRaw] JSON转换成功')\r\n \r\n const mainImageUrl = fixImageUrl(safeGetString(itemObj, 'main_image_url'))\r\n const imageUrls = fixImageUrls(safeGetStringArray(itemObj, 'image_urls'))\r\n __f__('log','at utils/supabaseService.uts:109','[parseProductFromRaw] 图片处理完成')\r\n \r\n const result: Product = {\r\n id: safeGetString(itemObj, 'id'),\r\n name: safeGetString(itemObj, 'name'),\r\n description: safeGetString(itemObj, 'description'),\r\n base_price: safeGetNumber(itemObj, 'base_price'),\r\n price: safeGetNumber(itemObj, 'base_price'),\r\n original_price: safeGetNumber(itemObj, 'market_price'),\r\n market_price: safeGetNumber(itemObj, 'market_price'),\r\n main_image_url: mainImageUrl,\r\n image_url: mainImageUrl,\r\n images: imageUrls,\r\n category_id: safeGetString(itemObj, 'category_id'),\r\n brand_id: safeGetString(itemObj, 'brand_id'),\r\n merchant_id: safeGetString(itemObj, 'merchant_id'),\r\n total_stock: safeGetNumber(itemObj, 'total_stock'),\r\n stock: safeGetNumber(itemObj, 'total_stock'),\r\n sale_count: safeGetNumber(itemObj, 'sale_count'),\r\n status: safeGetNumber(itemObj, 'status'),\r\n is_featured: safeGetBoolean(itemObj, 'is_featured'),\r\n is_new: safeGetBoolean(itemObj, 'is_new'),\r\n is_hot: safeGetBoolean(itemObj, 'is_hot'),\r\n specification: safeGetString(itemObj, 'specification'),\r\n usage: safeGetString(itemObj, 'usage'),\r\n side_effects: safeGetString(itemObj, 'side_effects'),\r\n precautions: safeGetString(itemObj, 'precautions'),\r\n expiry_date: safeGetString(itemObj, 'expiry_date'),\r\n storage_conditions: safeGetString(itemObj, 'storage_conditions'),\r\n approval_number: safeGetString(itemObj, 'approval_number'),\r\n created_at: safeGetString(itemObj, 'created_at')\r\n }\r\n __f__('log','at utils/supabaseService.uts:141','[parseProductFromRaw] 商品解析成功:', result.name)\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:144','parseProductFromRaw error:', e)\r\n return {\r\n id: '',\r\n name: '',\r\n description: '',\r\n base_price: 0,\r\n price: 0,\r\n original_price: 0,\r\n market_price: 0,\r\n main_image_url: '',\r\n image_url: '',\r\n images: [] as string[],\r\n category_id: '',\r\n brand_id: '',\r\n merchant_id: '',\r\n total_stock: 0,\r\n stock: 0,\r\n sale_count: 0,\r\n status: 0,\r\n is_featured: false,\r\n is_new: false,\r\n is_hot: false,\r\n specification: '',\r\n usage: '',\r\n side_effects: '',\r\n precautions: '',\r\n expiry_date: '',\r\n storage_conditions: '',\r\n approval_number: '',\r\n created_at: ''\r\n } as Product\r\n }\r\n}\r\n\r\n// 类型定义\r\nexport type Brand = {\r\n id: string\r\n name: string\r\n logo_url: string\r\n description: string\r\n}\r\n\r\nexport type Category = {\r\n id: string\r\n name: string\r\n icon: string\r\n description: string\r\n color: string\r\n parent_id?: string\r\n level?: number\r\n slug?: string\r\n created_at?: string\r\n}\r\n\r\nexport type Product = {\r\n id: string\r\n category_id: string\r\n merchant_id: string\r\n name: string\r\n subtitle?: string\r\n description?: string\r\n base_price?: number\r\n market_price?: number\r\n cost_price?: number\r\n main_image_url?: string\r\n image_url?: string\r\n image_urls?: string\r\n video_urls?: string\r\n images?: string[]\r\n sale_count?: number\r\n view_count?: number\r\n total_stock?: number\r\n available_stock?: number\r\n is_hot?: boolean\r\n is_new?: boolean\r\n is_featured?: boolean\r\n status?: number\r\n rating_avg?: number\r\n rating_count?: number\r\n rating?: number\r\n review_count?: number\r\n brand_id?: string\r\n shop_id?: string\r\n tags?: string\r\n attributes?: string\r\n specification?: string\r\n usage?: string\r\n side_effects?: string\r\n precautions?: string\r\n expiry_date?: string\r\n storage_conditions?: string\r\n approval_number?: string\r\n created_at?: string\r\n updated_at?: string\r\n price?: number\r\n original_price?: number\r\n stock?: number\r\n sales?: number\r\n cover?: string\r\n brand_name?: string\r\n category_name?: string\r\n shop_name?: string\r\n merchant_name?: string\r\n}\r\n\r\nexport type Shop = {\r\n id: string\r\n merchant_id: string\r\n shop_name: string\r\n shop_logo?: string\r\n shop_banner?: string\r\n description?: string\r\n contact_name?: string\r\n contact_phone?: string\r\n rating_avg?: number\r\n total_sales?: number\r\n product_count?: number\r\n total_sales_count?: number\r\n created_at?: string\r\n}\r\n\r\nexport type CartItem = {\r\n id: string\r\n user_id: string\r\n product_id: string\r\n sku_id?: string\r\n merchant_id?: string\r\n quantity: number\r\n selected: boolean\r\n product_name?: string\r\n product_image?: string\r\n product_price?: number\r\n product_specification?: string\r\n shop_id?: string\r\n shop_name?: string\r\n created_at?: string\r\n updated_at?: string\r\n}\r\n\r\nexport type UserAddress = {\r\n id: string\r\n user_id: string\r\n recipient_name: string\r\n phone: string\r\n province: string\r\n city: string\r\n district: string\r\n detail_address: string\r\n postal_code?: string\r\n is_default: boolean\r\n label?: string\r\n created_at?: string\r\n updated_at?: string\r\n}\r\n\r\nexport type UserCoupon = {\r\n id: string\r\n user_id: string\r\n template_id: string\r\n coupon_code: string\r\n status: number // 1: unused, 2: used, 3: expired\r\n received_at: string\r\n expire_at: string\r\n used_at?: string\r\n // join fields from template or view\r\n template_name?: string\r\n amount?: number\r\n min_spend?: number\r\n name?: string\r\n title?: string\r\n}\r\n\r\nexport type ChatRoom = {\r\n id: string\r\n user_id: string\r\n merchant_id: string\r\n shop_name: string\r\n shop_logo?: string\r\n last_message?: string\r\n last_message_at?: string\r\n unread_count: number\r\n is_top: boolean\r\n created_at?: string\r\n updated_at?: string\r\n}\r\n\r\nexport type Notification = {\r\n id: string\r\n user_id: string\r\n type: string\r\n title: string\r\n content: string\r\n icon_url?: string\r\n link_url?: string\r\n is_read: boolean\r\n extra_data?: string\r\n created_at?: string\r\n}\r\n\r\nexport type ChatMessage = {\r\n id: string\r\n session_id?: string\r\n sender_id?: string\r\n receiver_id?: string\r\n content: string\r\n msg_type: string\r\n is_read: boolean\r\n is_from_user: boolean\r\n extra_data?: string\r\n created_at?: string\r\n}\r\n\r\nexport type PaginatedResponse = {\r\n data: T[]\r\n total: number\r\n page: number\r\n limit: number\r\n hasmore: boolean\r\n}\r\n\r\nexport type ProductSku = {\r\n id: string\r\n product_id: string\r\n sku_code: string\r\n specifications: string // JSON string\r\n price: number\r\n market_price?: number\r\n cost_price?: number\r\n stock?: number\r\n warning_stock?: number\r\n image_url?: string\r\n weight?: number\r\n status?: number\r\n created_at?: string\r\n}\r\n\r\nexport type AddAddressParams = {\r\n recipient_name: string\r\n phone: string\r\n province: string\r\n city: string\r\n district: string\r\n detail_address: string\r\n postal_code?: string\r\n is_default?: boolean\r\n label?: string\r\n}\r\n\r\nexport type UpdateAddressParams = {\r\n recipient_name?: string\r\n phone?: string\r\n province?: string\r\n city?: string\r\n district?: string\r\n detail_address?: string\r\n postal_code?: string\r\n is_default?: boolean\r\n label?: string\r\n}\r\n\r\nexport type CreateOrderParams = {\r\n merchant_id: string\r\n product_amount: number\r\n shipping_fee: number\r\n total_amount: number\r\n shipping_address: any\r\n items: any[]\r\n}\r\n\r\nexport type ShopOrderParams = {\r\n shipping_address: any\r\n shopGroups: any[]\r\n deliveryFee: number\r\n discountAmount: number\r\n}\r\n\r\nexport type ShopOrderResponse = {\r\n success: boolean\r\n orderIds: string[]\r\n error?: string\r\n}\r\n\r\nexport type RefundResponse = {\r\n success: boolean\r\n message: string\r\n}\r\n\r\nexport type ConfirmReceiptResponse = {\r\n success: boolean\r\n error?: string\r\n}\r\n\r\nclass SupabaseService {\r\n // 获取当前用户ID\r\n public getCurrentUserId(): string | null {\r\n try {\r\n // 1. 优先从 Supabase 会话获取\r\n const session = supa.getSession()\r\n if (session != null && session.user != null) {\r\n return session.user.getString('id')\r\n }\r\n \r\n // 2. 尝试从 Storage 恢复 Session (针对 App 重启后内存丢失的情况)\r\n // 注意:这里无法异步调用 hydrate,所以只能依赖 UI 层或 init 层的预加载\r\n // 但我们可以返回本地存储 ID 作为 fallback,前提是 Token 有效\r\n \r\n // 后备:尝试从本地存储获取\r\n const userId = uni.getStorageSync('user_id')\r\n return userId != null ? userId as string : null\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:454','获取用户ID失败:', e)\r\n return null\r\n }\r\n }\r\n\r\n // 确保会话有效 (异步)\r\n async ensureSession(): Promise {\r\n let session = supa.getSession()\r\n if (session.user == null) {\r\n __f__('log','at utils/supabaseService.uts:463','Session user is null, attempting to hydrate from storage...')\r\n await supa.hydrateSessionFromStorage()\r\n session = supa.getSession()\r\n }\r\n \r\n if (session.user != null) {\r\n // 同步 user_id 到 storage 保持一致\r\n const uid = session.user!!.getString('id')\r\n if (uid != null) {\r\n uni.setStorageSync('user_id', uid)\r\n return uid\r\n }\r\n }\r\n return this.getCurrentUserId()\r\n }\r\n\r\n // 获取所有分类\r\n async getCategories(): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_categories')\r\n .select('*')\r\n .order('name', { ascending: true })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:489','获取分类失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return []\r\n }\r\n \r\n const categories: Category[] = []\r\n const rawList = rawData as any[]\r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const catObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const idVal = catObj.get('id')\r\n const nameVal = catObj.get('name')\r\n const iconVal = catObj.get('icon')\r\n const iconUrlVal = catObj.get('icon_url')\r\n const descVal = catObj.get('description')\r\n const colorVal = catObj.get('color')\r\n const parentIdVal = catObj.get('parent_id')\r\n const levelVal = catObj.get('level')\r\n \r\n const cat: Category = {\r\n id: (typeof idVal == 'string') ? (idVal as string) : '',\r\n name: (typeof nameVal == 'string') ? (nameVal as string) : '',\r\n icon: (typeof iconVal == 'string') ? (iconVal as string) : ((typeof iconUrlVal == 'string') ? (iconUrlVal as string) : ''),\r\n description: (typeof descVal == 'string') ? (descVal as string) : '',\r\n color: (typeof colorVal == 'string') ? (colorVal as string) : '#4CAF50',\r\n parent_id: (typeof parentIdVal == 'string') ? (parentIdVal as string) : null,\r\n level: (typeof levelVal == 'number') ? (levelVal as number) : 0\r\n } as Category\r\n categories.push(cat)\r\n }\r\n return categories\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:525','获取分类异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 根据ID获取单个分类\r\n async getCategoryById(categoryId: string): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_categories')\r\n .select('*')\r\n .eq('id', categoryId)\r\n .limit(1)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:541','获取分类失败:', response.error)\r\n return null\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return null\r\n }\r\n \r\n // 处理数组返回值\r\n const rawList = rawData as any[]\r\n if (rawList.length == 0) {\r\n return null\r\n }\r\n \r\n const item = rawList[0]\r\n const catObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const idVal = catObj.get('id')\r\n const nameVal = catObj.get('name')\r\n const iconVal = catObj.get('icon')\r\n const iconUrlVal = catObj.get('icon_url')\r\n const descVal = catObj.get('description')\r\n const colorVal = catObj.get('color')\r\n const parentIdVal = catObj.get('parent_id')\r\n const levelVal = catObj.get('level')\r\n \r\n const cat: Category = {\r\n id: (typeof idVal == 'string') ? (idVal as string) : '',\r\n name: (typeof nameVal == 'string') ? (nameVal as string) : '',\r\n icon: (typeof iconVal == 'string') ? (iconVal as string) : ((typeof iconUrlVal == 'string') ? (iconUrlVal as string) : ''),\r\n description: (typeof descVal == 'string') ? (descVal as string) : '',\r\n color: (typeof colorVal == 'string') ? (colorVal as string) : '#4CAF50',\r\n parent_id: (typeof parentIdVal == 'string') ? (parentIdVal as string) : null,\r\n level: (typeof levelVal == 'number') ? (levelVal as number) : 0\r\n } as Category\r\n return cat\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:578','获取分类异常:', error)\r\n return null\r\n }\r\n }\r\n\r\n // 获取一级分类\r\n async getParentCategories(): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_categories')\r\n .select('*')\r\n .is('parent_id', null)\r\n .order('sort_order', { ascending: true })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:594','获取一级分类失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return []\r\n }\r\n\r\n const categories: Category[] = []\r\n const rawList = rawData as Array\r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const icon = this.getCategoryIcon(item)\r\n \r\n // 安全获取属性\r\n const idVal = item['id']\r\n const nameVal = item['name']\r\n const descVal = item['description']\r\n const colorVal = item['color']\r\n const slugVal = item['slug']\r\n \r\n const cat: Category = {\r\n id: (typeof idVal == 'string') ? (idVal as string) : '',\r\n name: (typeof nameVal == 'string') ? (nameVal as string) : '',\r\n icon: icon,\r\n description: (typeof descVal == 'string') ? (descVal as string) : '',\r\n color: (typeof colorVal == 'string') ? (colorVal as string) : '#ff5000',\r\n level: 1,\r\n slug: (typeof slugVal == 'string') ? (slugVal as string) : ''\r\n }\r\n categories.push(cat)\r\n }\r\n return categories\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:629','获取一级分类异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取子分类\r\n async getSubCategories(parentId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:637','[getSubCategories] 开始获取子分类, parentId:', parentId)\r\n const response = await supa\r\n .from('ml_categories')\r\n .select('*')\r\n .order('sort_order', { ascending: true })\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:644','[getSubCategories] 查询完成')\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:647','获取子分类失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n __f__('log','at utils/supabaseService.uts:653','[getSubCategories] 数据为空')\r\n return []\r\n }\r\n\r\n const categories: Category[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:659','[getSubCategories] 原始数据条数:', rawList.length)\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 parent_id\r\n const itemParentId = safeGetString(itemObj, 'parent_id')\r\n const isMatch = (itemParentId.length > 0 && itemParentId == parentId)\r\n if (!isMatch) {\r\n continue\r\n }\r\n \r\n const icon = this.getCategoryIcon(itemObj)\r\n const cat: Category = {\r\n id: safeGetString(itemObj, 'id'),\r\n name: safeGetString(itemObj, 'name'),\r\n icon: icon,\r\n description: safeGetString(itemObj, 'description'),\r\n color: safeGetString(itemObj, 'color').length > 0 ? safeGetString(itemObj, 'color') : '#ff5000',\r\n level: 2,\r\n parent_id: safeGetString(itemObj, 'parent_id'),\r\n slug: safeGetString(itemObj, 'slug')\r\n }\r\n categories.push(cat)\r\n }\r\n __f__('log','at utils/supabaseService.uts:685','[getSubCategories] 返回分类数量:', categories.length)\r\n return categories\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:688','获取子分类异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取分类图标的辅助方法\r\n getCategoryIcon(item: UTSJSONObject): string {\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const icon = safeGetString(itemObj, 'icon')\r\n if (icon.length > 0) {\r\n return icon\r\n }\r\n const iconUrl = safeGetString(itemObj, 'icon_url')\r\n if (iconUrl.length > 0) {\r\n return iconUrl\r\n }\r\n const name = safeGetString(itemObj, 'name')\r\n if (name.includes('数码') || name.includes('电器') || name.includes('手机')) return '📱'\r\n if (name.includes('服装') || name.includes('衣服') || name.includes('鞋')) return '👕'\r\n if (name.includes('食品') || name.includes('水果') || name.includes('零食')) return '🍎'\r\n if (name.includes('美妆') || name.includes('护肤') || name.includes('化妆')) return '💄'\r\n if (name.includes('母婴') || name.includes('婴儿') || name.includes('儿童')) return '👶'\r\n if (name.includes('家居') || name.includes('家具') || name.includes('装饰')) return '🏠'\r\n if (name.includes('图书') || name.includes('文具')) return '📚'\r\n if (name.includes('运动') || name.includes('户外') || name.includes('健身')) return '⚽'\r\n if (name.includes('医药') || name.includes('保健') || name.includes('健康')) return '💊'\r\n return '📦'\r\n }\r\n\r\n // 获取所有品牌\r\n async getBrands(): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:720','[getBrands] 开始获取品牌数据...')\r\n const response = await supa\r\n .from('ml_brands')\r\n .select('id, name, logo_url, description, is_active')\r\n .order('name', { ascending: true })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:728','获取品牌失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n __f__('log','at utils/supabaseService.uts:734','[getBrands] 数据为空')\r\n return []\r\n }\r\n \r\n const brands: Brand[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:740','[getBrands] 数据条数:', rawList.length)\r\n \r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const brandObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const idVal = brandObj.get('id')\r\n const nameVal = brandObj.get('name')\r\n const logoVal = brandObj.get('logo_url')\r\n const descVal = brandObj.get('description')\r\n const isActiveVal = brandObj.get('is_active')\r\n \r\n let isActiveBool: boolean = true\r\n if (isActiveVal != null) {\r\n if (typeof isActiveVal == 'boolean') {\r\n isActiveBool = isActiveVal as boolean\r\n } else if (typeof isActiveVal == 'number') {\r\n isActiveBool = (isActiveVal as number) === 1\r\n }\r\n }\r\n if (!isActiveBool) {\r\n continue\r\n }\r\n \r\n const brand: Brand = {\r\n id: (typeof idVal == 'string') ? (idVal as string) : '',\r\n name: (typeof nameVal == 'string') ? (nameVal as string) : '',\r\n logo_url: (typeof logoVal == 'string') ? (logoVal as string) : '',\r\n description: (typeof descVal == 'string') ? (descVal as string) : ''\r\n } as Brand\r\n brands.push(brand)\r\n }\r\n __f__('log','at utils/supabaseService.uts:771','[getBrands] 返回品牌数量:', brands.length)\r\n return brands\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:774','获取品牌异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取指定分类的商品\r\n async getProductsByCategory(\r\n categoryId: string, \r\n page: number = 1, \r\n limit: number = 20\r\n ): Promise> {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:786','[getProductsByCategory] 开始查询,分类ID:', categoryId, '页码:', page)\r\n \r\n // 在数据库层面进行分类过滤\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('*', { count: 'exact' })\r\n .eq('category_id', categoryId)\r\n .eq('status', '1') // 使用字符串 '1' 而不是整数 1\r\n .order('sale_count', { ascending: false })\r\n .page(page)\r\n .limit(limit)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:799','[getProductsByCategory] 查询完成,total:', response.total)\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:802','获取商品失败:', response.error)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:825','[getProductsByCategory] 返回数据条数:', rawList.length)\r\n \r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n products.push(parseProductFromRaw(item))\r\n }\r\n \r\n return {\r\n data: products,\r\n total: response.total ?? products.length,\r\n page,\r\n limit,\r\n hasmore: response.hasmore ?? false\r\n }\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:840','获取商品异常:', error)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n }\r\n\r\n // 根据商品ID获取SKU列表\r\n async getProductSkus(productId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:854','[getProductSkus] 开始获取SKU,商品ID:', productId)\r\n const response = await supa\r\n .from('ml_product_skus')\r\n .select('*')\r\n .eq('product_id', productId)\r\n .eq('status', '1')\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:863','获取商品SKU失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) return []\r\n \r\n const skus: ProductSku[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:872','[getProductSkus] 获取到SKU数量:', rawList.length)\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const skuObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n const rawId = skuObj.get('id')\r\n const rawSkuCode = skuObj.get('sku_code')\r\n const rawProdId = skuObj.get('product_id')\r\n const rawPrice = skuObj.get('price')\r\n const rawStock = skuObj.get('stock')\r\n const rawImageUrl = skuObj.get('image_url')\r\n const rawSpecs = skuObj.get('specifications')\r\n \r\n let specsStr = ''\r\n if (rawSpecs != null) {\r\n try {\r\n if (typeof rawSpecs == 'string') {\r\n specsStr = rawSpecs as string\r\n } else {\r\n specsStr = JSON.stringify(rawSpecs)\r\n }\r\n } catch(e) {\r\n __f__('error','at utils/supabaseService.uts:895','解析SKU规格失败', e)\r\n }\r\n }\r\n \r\n const sku: ProductSku = {\r\n id: (typeof rawId == 'string') ? (rawId as string) : '',\r\n product_id: (typeof rawProdId == 'string') ? (rawProdId as string) : '',\r\n sku_code: (typeof rawSkuCode == 'string') ? (rawSkuCode as string) : '',\r\n specifications: specsStr,\r\n price: (typeof rawPrice == 'number') ? (rawPrice as number) : 0,\r\n stock: (typeof rawStock == 'number') ? (rawStock as number) : 0,\r\n image_url: (typeof rawImageUrl == 'string') ? (rawImageUrl as string) : '',\r\n status: 1\r\n }\r\n skus.push(sku)\r\n }\r\n return skus\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:913','获取商品SKU异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 搜索商品\r\n async searchProducts(\r\n keyword: string, \r\n page: number = 1, \r\n limit: number = 20,\r\n sortBy: string = 'sales',\r\n ascending: boolean = false\r\n ): Promise> {\r\n try {\r\n const keywordLower = keyword.toLowerCase()\r\n const encodedKeyword = encodeURIComponent(keywordLower)\r\n const orString = `name.ilike.%${encodedKeyword}%,description.ilike.%${encodedKeyword}%,subtitle.ilike.%${encodedKeyword}%,brand_name.ilike.%${encodedKeyword}%`\r\n __f__('log','at utils/supabaseService.uts:930','[searchProducts] 搜索关键词:', keyword, '编码后:', encodedKeyword)\r\n __f__('log','at utils/supabaseService.uts:931','[searchProducts] or条件:', orString)\r\n \r\n let query = supa\r\n .from('ml_products_detail_view')\r\n .select('*', { count: 'exact' })\r\n .eq('status', 1)\r\n .or(orString)\r\n \r\n if (sortBy === 'price') {\r\n query = query.order('base_price', { ascending })\r\n } else if (sortBy === 'sales' || sortBy === 'sale_count') {\r\n query = query.order('sale_count', { ascending: false })\r\n } else {\r\n query = query.order('sale_count', { ascending: false })\r\n }\r\n \r\n const response = await query\r\n .page(page)\r\n .limit(limit)\r\n .execute()\r\n \r\n let dataLength = 0\r\n try {\r\n const respData = response.data\r\n if (respData != null && Array.isArray(respData)) {\r\n dataLength = (respData as any[]).length\r\n }\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:959','[searchProducts] 获取数据长度失败:', e)\r\n }\r\n let statusNum = 0\r\n try {\r\n statusNum = response.status as number\r\n } catch (e) {}\r\n __f__('log','at utils/supabaseService.uts:965','[searchProducts] 响应状态:', statusNum, '数据条数:', dataLength)\r\n \r\n let hasError = false\r\n try {\r\n hasError = response.error != null\r\n } catch (e) {}\r\n if (hasError) {\r\n __f__('error','at utils/supabaseService.uts:972','[searchProducts] 搜索商品失败:', response.error)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n \r\n const rawData = response.data\r\n __f__('log','at utils/supabaseService.uts:983','[searchProducts] rawData:', rawData != null ? 'not null' : 'null')\r\n if (rawData == null) {\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n \r\n const products: Product[] = []\r\n let rawList: any[] = []\r\n try {\r\n rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:998','[searchProducts] rawList长度:', rawList.length)\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:1000','[searchProducts] 转换rawList失败:', e)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n __f__('log','at utils/supabaseService.uts:1012','[searchProducts] 处理第', i + 1, '个商品')\r\n products.push(parseProductFromRaw(item))\r\n }\r\n \r\n let totalNum = 0\r\n try {\r\n totalNum = response.total as number\r\n } catch (e) {}\r\n let hasmoreVal = false\r\n try {\r\n hasmoreVal = response.hasmore as boolean\r\n } catch (e) {}\r\n \r\n return {\r\n data: products,\r\n total: totalNum > 0 ? totalNum : products.length,\r\n page,\r\n limit,\r\n hasmore: hasmoreVal\r\n }\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1033','搜索商品异常:', error)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n }\r\n\r\n // 搜索店铺\r\n async searchShops(\r\n keyword: string,\r\n page: number = 1,\r\n limit: number = 20\r\n ): Promise> {\r\n try {\r\n const encodedKeyword = encodeURIComponent(keyword)\r\n const response = await supa\r\n .from('ml_shops')\r\n .select('*', { count: 'exact' })\r\n .ilike('shop_name', `%${encodedKeyword}%`)\r\n .order('product_count', { ascending: false })\r\n .page(page)\r\n .limit(limit)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1062','搜索店铺失败:', response.error)\r\n return { data: [] as Shop[], total: 0, page, limit, hasmore: false }\r\n }\r\n\r\n const rawData = response.data\r\n if (rawData == null) {\r\n return { data: [] as Shop[], total: 0, page, limit, hasmore: false }\r\n }\r\n\r\n const shops: Shop[] = []\r\n const dataList = rawData as any[]\r\n for (let i = 0; i < dataList.length; i++) {\r\n const item = dataList[i]\r\n const shopObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 status\r\n const rawStatus = shopObj.get('status')\r\n let statusNum: number = 0\r\n if (typeof rawStatus == 'number') {\r\n statusNum = rawStatus as number\r\n }\r\n if (statusNum !== 1) continue\r\n \r\n // 手动创建 Shop 对象,避免安卓端类型转换错误\r\n const shop: Shop = {\r\n id: shopObj.getString('id') ?? '',\r\n merchant_id: shopObj.getString('merchant_id') ?? '',\r\n shop_name: shopObj.getString('shop_name') ?? '',\r\n shop_logo: shopObj.getString('shop_logo'),\r\n shop_banner: shopObj.getString('shop_banner'),\r\n description: shopObj.getString('description'),\r\n contact_name: shopObj.getString('contact_name'),\r\n contact_phone: shopObj.getString('contact_phone'),\r\n rating_avg: shopObj.getNumber('rating_avg'),\r\n total_sales: shopObj.getNumber('total_sales'),\r\n product_count: shopObj.getNumber('product_count'),\r\n total_sales_count: shopObj.getNumber('total_sales_count'),\r\n created_at: shopObj.getString('created_at')\r\n }\r\n shops.push(shop)\r\n }\r\n\r\n return {\r\n data: shops,\r\n total: response.total ?? shops.length,\r\n page,\r\n limit,\r\n hasmore: response.hasmore ?? false\r\n }\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1112','搜索店铺异常:', error)\r\n return { data: [] as Shop[], total: 0, page, limit, hasmore: false }\r\n }\r\n }\r\n\r\n // 获取单个商品详情\r\n async getProductById(productId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1120','[getProductById] 开始获取商品详情,ID:', productId)\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('*')\r\n .eq('id', productId)\r\n .limit(1)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1129','获取商品详情失败:', response.error)\r\n return null\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n __f__('log','at utils/supabaseService.uts:1135','[getProductById] 数据为空')\r\n return null\r\n }\r\n \r\n const rawList = rawData as any[]\r\n if (rawList.length == 0) {\r\n __f__('log','at utils/supabaseService.uts:1141','[getProductById] 未找到商品')\r\n return null\r\n }\r\n \r\n const item = rawList[0]\r\n const product = parseProductFromRaw(item)\r\n __f__('log','at utils/supabaseService.uts:1147','[getProductById] 成功获取商品:', product.name)\r\n return product\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1150','获取商品详情异常:', error)\r\n return null\r\n }\r\n }\r\n\r\n // --- 关注店铺相关 ---\r\n\r\n // 检查是否已关注店铺\r\n async isShopFollowed(shopId: string, userId: string): Promise {\r\n try {\r\n const res = await supa\r\n .from('ml_shop_follows')\r\n .select('id', { count: 'exact' })\r\n .eq('shop_id', shopId)\r\n .eq('user_id', userId)\r\n .limit(1)\r\n .execute()\r\n \r\n return (res.total != null && res.total! > 0)\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:1170','Check follow error:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 关注店铺\r\n async followShop(shopId: string, userId: string): Promise {\r\n try {\r\n const res = await supa\r\n .from('ml_shop_follows')\r\n .insert({\r\n user_id: userId,\r\n shop_id: shopId\r\n })\r\n .execute()\r\n \r\n return res.error == null\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:1188','Follow shop error:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 取消关注\r\n async unfollowShop(shopId: string, userId: string): Promise {\r\n try {\r\n const res = await supa\r\n .from('ml_shop_follows')\r\n .eq('shop_id', shopId)\r\n .eq('user_id', userId)\r\n .delete()\r\n .execute()\r\n \r\n return res.error == null\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:1205','Unfollow shop error:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 获取我关注的店铺列表\r\n async getFollowedShops(userId: string): Promise {\r\n try {\r\n // 关联查询店铺信息\r\n const res = await supa\r\n .from('ml_shop_follows')\r\n .select('*, ml_shops(*)') \r\n .eq('user_id', userId)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n \r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1222','getFollowedShops error:', res.error)\r\n return []\r\n }\r\n \r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:1228','getFollowedShops exception:', e)\r\n return []\r\n }\r\n }\r\n\r\n // 根据商户ID获取店铺信息\r\n async getShopByMerchantId(merchantId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1236','[getShopByMerchantId] 开始获取店铺信息,merchantId:', merchantId)\r\n // 1. Try querying by merchant_id\r\n let response = await supa\r\n .from('ml_shops')\r\n .select('*')\r\n .eq('merchant_id', merchantId)\r\n .limit(1)\r\n .execute()\r\n \r\n if (response.error == null && response.data != null && (response.data as any[]).length > 0) {\r\n const shopData = (response.data as any[])[0]\r\n const shop = this.parseShopFromRaw(shopData)\r\n __f__('log','at utils/supabaseService.uts:1248','[getShopByMerchantId] 通过 merchant_id 找到店铺:', shop.shop_name)\r\n return shop\r\n }\r\n\r\n // 2. Fallback: Try querying by id (Maybe the passed ID is the Shop ID?)\r\n __f__('log','at utils/supabaseService.uts:1253','getShopByMerchantId: merchant_id not found, trying id...', merchantId)\r\n response = await supa\r\n .from('ml_shops')\r\n .select('*')\r\n .eq('id', merchantId)\r\n .limit(1)\r\n .execute()\r\n\r\n if (response.error == null && response.data != null && (response.data as any[]).length > 0) {\r\n __f__('log','at utils/supabaseService.uts:1262','Found shop by ID instead of MerchantID')\r\n const shopData = (response.data as any[])[0]\r\n const shop = this.parseShopFromRaw(shopData)\r\n return shop\r\n }\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1269','获取店铺信息失败:', response.error)\r\n }\r\n return null\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1273','获取店铺信息异常:', error)\r\n return null\r\n }\r\n }\r\n \r\n // 解析店铺数据\r\n parseShopFromRaw(item: any): Shop {\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n const getSafeString = (key: string): string => {\r\n const val = itemObj.get(key)\r\n if (val == null) return ''\r\n if (typeof val == 'string') return val\r\n return ''\r\n }\r\n \r\n const getSafeNumber = (key: string): number => {\r\n const val = itemObj.get(key)\r\n if (val == null) return 0\r\n if (typeof val == 'number') return val\r\n return 0\r\n }\r\n \r\n return {\r\n id: getSafeString('id'),\r\n merchant_id: getSafeString('merchant_id'),\r\n shop_name: getSafeString('shop_name'),\r\n shop_logo: getSafeString('shop_logo'),\r\n shop_banner: getSafeString('shop_banner'),\r\n description: getSafeString('description'),\r\n contact_name: getSafeString('contact_name'),\r\n contact_phone: getSafeString('contact_phone'),\r\n rating_avg: getSafeNumber('rating_avg'),\r\n total_sales: getSafeNumber('total_sales'),\r\n product_count: getSafeNumber('product_count'),\r\n total_sales_count: getSafeNumber('total_sales_count'),\r\n created_at: getSafeString('created_at')\r\n } as Shop\r\n }\r\n\r\n // 根据商户ID获取商品列表\r\n async getProductsByMerchantId(merchantId: string, page: number = 1, limit: number = 20): Promise> {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1316','getProductsByMerchantId querying for:', merchantId)\r\n \r\n // 1. Try fetching from view strictly first\r\n let query = supa\r\n .from('ml_products_detail_view')\r\n .select('*', { count: 'exact' })\r\n .eq('merchant_id', merchantId)\r\n // .eq('status', 1) // Temporarily disabled status check to see if products exist at all\r\n .order('created_at', { ascending: false })\r\n .page(page)\r\n .limit(limit)\r\n \r\n const response = await query.execute()\r\n \r\n // 检查视图结果:如果有错误 OR 数据为空,都尝试去查原始表\r\n if (response.error != null || (response.data != null && (response.data as any[]).length === 0)) {\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1333','获取商户商品失败 (View):', response.error)\r\n } else {\r\n __f__('log','at utils/supabaseService.uts:1335','View returned 0 products, trying raw table fallback...')\r\n }\r\n \r\n // Fallback: Try raw table\r\n __f__('log','at utils/supabaseService.uts:1339','Falling back to raw ml_products table...')\r\n const query2 = supa\r\n .from('ml_products')\r\n .select('*', { count: 'exact' })\r\n .eq('merchant_id', merchantId)\r\n // .eq('status', 1) // Also disabled here\r\n .order('created_at', { ascending: false })\r\n .page(page)\r\n .limit(limit)\r\n \r\n const res2 = await query2.execute()\r\n if (res2.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1351','获取商户商品失败 (Raw):', res2.error)\r\n return {data:[] as Product[], total:0, page, limit, hasmore:false}\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:1355',`Fallback (Raw) found: ${(res2.data as any[]).length} products`)\r\n \r\n const mappedData: Product[] = []\r\n const rawData = res2.data as any[]\r\n for(let i = 0; i < rawData.length; i++) {\r\n const item = JSON.parse(JSON.stringify(rawData[i])) as UTSJSONObject\r\n const images: string[] = []\r\n \r\n const mainImageUrl = fixImageUrl(item.getString('main_image_url'))\r\n if (mainImageUrl != null && mainImageUrl !== '') {\r\n images.push(mainImageUrl)\r\n }\r\n\r\n const imageUrlsRaw = item.get('image_urls')\r\n if (imageUrlsRaw != null) {\r\n try {\r\n if (Array.isArray(imageUrlsRaw)) {\r\n const arr = imageUrlsRaw as string[]\r\n if (arr.length > 0 && images.length === 0) {\r\n for (let j = 0; j < arr.length; j++) {\r\n const fixedUrl = fixImageUrl(arr[j])\r\n if (fixedUrl !== '') images.push(fixedUrl)\r\n }\r\n }\r\n } else {\r\n const rawUrlStr = imageUrlsRaw as string\r\n if (rawUrlStr.startsWith('[')) {\r\n const parsed = JSON.parse(rawUrlStr)\r\n if (Array.isArray(parsed) && images.length === 0) {\r\n for (let j = 0; j < parsed.length; j++) {\r\n const fixedUrl = fixImageUrl(parsed[j] as string)\r\n if (fixedUrl !== '') images.push(fixedUrl)\r\n }\r\n }\r\n } else {\r\n const fixedUrl = fixImageUrl(rawUrlStr)\r\n if (fixedUrl !== '' && images.indexOf(fixedUrl) === -1) images.push(fixedUrl)\r\n }\r\n }\r\n } catch(e) {\r\n __f__('error','at utils/supabaseService.uts:1395','解析图片数组失败:', e)\r\n }\r\n }\r\n \r\n if (images.length === 0) {\r\n images.push('/static/default-product.png')\r\n }\r\n \r\n let safePrice = item.getNumber('base_price')\r\n if (safePrice == null) {\r\n const p = item.getNumber('price')\r\n safePrice = p != null ? p : 0\r\n }\r\n \r\n let safeOriginalPrice = item.getNumber('market_price')\r\n if (safeOriginalPrice == null) {\r\n const op = item.getNumber('original_price')\r\n safeOriginalPrice = op != null ? op : safePrice\r\n }\r\n \r\n let safeStock = item.getNumber('total_stock')\r\n if (safeStock == null) {\r\n let as_ = item.getNumber('available_stock')\r\n if (as_ == null) {\r\n const s = item.getNumber('stock')\r\n safeStock = s != null ? s : 0\r\n } else {\r\n safeStock = as_\r\n }\r\n }\r\n \r\n let safeSales = item.getNumber('sale_count')\r\n if (safeSales == null) {\r\n const s = item.getNumber('sales')\r\n safeSales = s != null ? s : 0\r\n }\r\n \r\n const product: Product = {\r\n id: item.getString('id') ?? '',\r\n category_id: item.getString('category_id') ?? '',\r\n merchant_id: item.getString('merchant_id') ?? '',\r\n name: item.getString('name') ?? '',\r\n description: item.getString('description') ?? '',\r\n images: images,\r\n price: safePrice,\r\n original_price: safeOriginalPrice,\r\n stock: safeStock,\r\n sales: safeSales,\r\n status: item.getNumber('status') ?? 1,\r\n created_at: item.getString('created_at') ?? '',\r\n base_price: safePrice,\r\n market_price: safeOriginalPrice,\r\n main_image_url: images.length > 0 ? images[0] : '',\r\n sale_count: safeSales,\r\n total_stock: safeStock\r\n } as Product\r\n mappedData.push(product)\r\n }\r\n\r\n return {\r\n data: mappedData,\r\n total: res2.total ?? 0,\r\n page,\r\n limit,\r\n hasmore: res2.hasmore ?? false\r\n }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:1463',`Merchant products found: ${(response.data as any[]).length}`)\r\n \r\n const viewData = response.data as any[]\r\n const parsedProducts: Product[] = []\r\n for (let i = 0; i < viewData.length; i++) {\r\n parsedProducts.push(parseProductFromRaw(viewData[i]))\r\n }\r\n \r\n return {\r\n data: parsedProducts,\r\n total: response.total ?? 0,\r\n page,\r\n limit,\r\n hasmore: response.hasmore ?? false\r\n }\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1479','获取商户商品异常:', error)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n }\r\n\r\n // 根据店铺ID获取商品列表(新增)\r\n async getProductsByShopId(shopId: string, page: number = 1, limit: number = 20): Promise> {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1493','getProductsByShopId querying for:', shopId)\r\n \r\n // 1. Try fetching from view with shop_id\r\n let query = supa\r\n .from('ml_products_detail_view')\r\n .select('*', { count: 'exact' })\r\n .eq('shop_id', shopId)\r\n .order('created_at', { ascending: false })\r\n .page(page)\r\n .limit(limit)\r\n \r\n const response = await query.execute()\r\n \r\n // 检查视图结果:如果有错误 OR 数据为空,都尝试去查原始表\r\n if (response.error != null || (response.data != null && (response.data as any[]).length === 0)) {\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1509','获取店铺商品失败 (View):', response.error)\r\n } else {\r\n __f__('log','at utils/supabaseService.uts:1511','View returned 0 products, trying raw table fallback...')\r\n }\r\n \r\n // Fallback: Try raw table with shop_id\r\n __f__('log','at utils/supabaseService.uts:1515','Falling back to raw ml_products table with shop_id...')\r\n const query2 = supa\r\n .from('ml_products')\r\n .select('*', { count: 'exact' })\r\n .eq('shop_id', shopId)\r\n .order('created_at', { ascending: false })\r\n .page(page)\r\n .limit(limit)\r\n \r\n const res2 = await query2.execute()\r\n if (res2.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1526','获取店铺商品失败 (Raw):', res2.error)\r\n return {data:[] as Product[], total:0, page, limit, hasmore:false}\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:1530',`Fallback (Raw) found: ${(res2.data as any[]).length} products`)\r\n \r\n const mappedData: Product[] = []\r\n const rawData = res2.data as any[]\r\n for(let i = 0; i < rawData.length; i++) {\r\n const item = JSON.parse(JSON.stringify(rawData[i])) as UTSJSONObject\r\n const images: string[] = []\r\n \r\n const mainImageUrl = fixImageUrl(item.getString('main_image_url'))\r\n if (mainImageUrl != null && mainImageUrl !== '') {\r\n images.push(mainImageUrl)\r\n }\r\n\r\n const imageUrlsRaw = item.get('image_urls')\r\n if (imageUrlsRaw != null) {\r\n try {\r\n if (Array.isArray(imageUrlsRaw)) {\r\n const arr = imageUrlsRaw as string[]\r\n if (arr.length > 0 && images.length === 0) {\r\n for (let j = 0; j < arr.length; j++) {\r\n const fixedUrl = fixImageUrl(arr[j])\r\n if (fixedUrl !== '') images.push(fixedUrl)\r\n }\r\n }\r\n } else {\r\n const rawUrlStr = imageUrlsRaw as string\r\n if (rawUrlStr.startsWith('[')) {\r\n const parsed = JSON.parse(rawUrlStr)\r\n if (Array.isArray(parsed) && images.length === 0) {\r\n for (let j = 0; j < parsed.length; j++) {\r\n const fixedUrl = fixImageUrl(parsed[j] as string)\r\n if (fixedUrl !== '') images.push(fixedUrl)\r\n }\r\n }\r\n } else {\r\n const fixedUrl = fixImageUrl(rawUrlStr)\r\n if (fixedUrl !== '' && images.indexOf(fixedUrl) === -1) images.push(fixedUrl)\r\n }\r\n }\r\n } catch(e) {\r\n __f__('error','at utils/supabaseService.uts:1570','解析图片数组失败:', e)\r\n }\r\n }\r\n \r\n if (images.length === 0) {\r\n images.push('/static/default-product.png')\r\n }\r\n \r\n let safePrice = item.getNumber('base_price')\r\n if (safePrice == null) {\r\n const p = item.getNumber('price')\r\n safePrice = p != null ? p : 0\r\n }\r\n \r\n let safeOriginalPrice = item.getNumber('market_price')\r\n if (safeOriginalPrice == null) {\r\n const op = item.getNumber('original_price')\r\n safeOriginalPrice = op != null ? op : safePrice\r\n }\r\n \r\n let safeStock = item.getNumber('total_stock')\r\n if (safeStock == null) {\r\n let as_ = item.getNumber('available_stock')\r\n if (as_ == null) {\r\n const s = item.getNumber('stock')\r\n safeStock = s != null ? s : 0\r\n } else {\r\n safeStock = as_\r\n }\r\n }\r\n \r\n let safeSales = item.getNumber('sale_count')\r\n if (safeSales == null) {\r\n const s = item.getNumber('sales')\r\n safeSales = s != null ? s : 0\r\n }\r\n \r\n const product: Product = {\r\n id: item.getString('id') ?? '',\r\n category_id: item.getString('category_id') ?? '',\r\n merchant_id: item.getString('merchant_id') ?? '',\r\n name: item.getString('name') ?? '',\r\n description: item.getString('description') ?? '',\r\n images: images,\r\n price: safePrice,\r\n original_price: safeOriginalPrice,\r\n stock: safeStock,\r\n sales: safeSales,\r\n status: item.getNumber('status') ?? 1,\r\n created_at: item.getString('created_at') ?? '',\r\n base_price: safePrice,\r\n market_price: safeOriginalPrice,\r\n main_image_url: images.length > 0 ? images[0] : '',\r\n sale_count: safeSales,\r\n total_stock: safeStock\r\n } as Product\r\n mappedData.push(product)\r\n }\r\n\r\n return {\r\n data: mappedData,\r\n total: res2.total ?? 0,\r\n page,\r\n limit,\r\n hasmore: res2.hasmore ?? false\r\n }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:1638',`Shop products found: ${(response.data as any[]).length}`)\r\n \r\n const viewData = response.data as any[]\r\n const parsedProducts: Product[] = []\r\n for (let i = 0; i < viewData.length; i++) {\r\n parsedProducts.push(parseProductFromRaw(viewData[i]))\r\n }\r\n \r\n return {\r\n data: parsedProducts,\r\n total: response.total ?? 0,\r\n page,\r\n limit,\r\n hasmore: response.hasmore ?? false\r\n }\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1654','获取店铺商品异常:', error)\r\n return {\r\n data: [] as Product[],\r\n total: 0,\r\n page,\r\n limit,\r\n hasmore: false\r\n }\r\n }\r\n }\r\n\r\n // 获取热销商品(按销量排序)\r\n async getHotProducts(limit: number = 10): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1668','[getHotProducts] 开始获取热销商品...')\r\n \r\n // 在数据库层面过滤 status,获取更多数据以便手动过滤 is_hot\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .eq('status', '1') // 使用字符串 '1'\r\n .order('sale_count', { ascending: false })\r\n .limit(limit * 5) // 获取更多数据以便过滤\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1680','获取热销商品失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n __f__('log','at utils/supabaseService.uts:1685','[getHotProducts] 原始数据条数:', rawData != null ? (rawData as any[]).length : 0)\r\n if (rawData == null) {\r\n __f__('log','at utils/supabaseService.uts:1687','[getHotProducts] 数据为空')\r\n return []\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = rawData as any[]\r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 is_hot\r\n const rawIsHot = prodObj.get('is_hot')\r\n let isHotBool: boolean = false\r\n if (typeof rawIsHot == 'boolean') {\r\n isHotBool = rawIsHot as boolean\r\n } else if (typeof rawIsHot == 'number') {\r\n isHotBool = (rawIsHot as number) == 1\r\n }\r\n if (!isHotBool) continue\r\n \r\n products.push(parseProductFromRaw(item))\r\n \r\n // 达到目标数量就停止\r\n if (products.length >= limit) break\r\n }\r\n __f__('log','at utils/supabaseService.uts:1712','[getHotProducts] 最终返回商品数:', products.length)\r\n return products\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1715','获取热销商品异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取按销量排序的商品(所有商品,不限制 is_hot)\r\n async getProductsBySales(limit: number = 10): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1723','[getProductsBySales] 开始获取销量排序商品...')\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .eq('status', '1')\r\n .order('sale_count', { ascending: false })\r\n .limit(limit)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1733','获取销量排序商品失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return []\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = rawData as any[]\r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n products.push(parseProductFromRaw(item))\r\n }\r\n __f__('log','at utils/supabaseService.uts:1748','[getProductsBySales] 返回商品数:', products.length)\r\n return products\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1751','获取销量排序商品异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取按价格排序的商品(升序:从低到高)\r\n async getProductsByPrice(limit: number = 10, ascending: boolean = true): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .eq('status', '1') // 在数据库层面过滤\r\n .order('base_price', { ascending })\r\n .limit(limit)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1768','获取价格排序商品失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return []\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = rawData as any[]\r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n products.push(parseProductFromRaw(item))\r\n }\r\n return products\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1785','获取价格排序商品异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取新品(按创建时间排序,最新的在前)\r\n async getProductsByNewest(limit: number = 10): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1793','[getProductsByNewest] 开始获取新品...')\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .eq('status', '1')\r\n .order('created_at', { ascending: false })\r\n .limit(limit * 5)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1803','获取新品失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n return []\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = rawData as any[]\r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 is_new\r\n const rawIsNew = prodObj.get('is_new')\r\n let isNewBool: boolean = false\r\n if (typeof rawIsNew == 'boolean') {\r\n isNewBool = rawIsNew as boolean\r\n } else if (typeof rawIsNew == 'number') {\r\n isNewBool = (rawIsNew as number) == 1\r\n }\r\n if (!isNewBool) continue\r\n \r\n products.push(parseProductFromRaw(item))\r\n if (products.length >= limit) break\r\n }\r\n \r\n // 如果 is_new 商品不足,补充普通商品\r\n if (products.length < limit) {\r\n __f__('log','at utils/supabaseService.uts:1834','[getProductsByNewest] is_new商品不足,补充普通商品')\r\n const addedIds = new Set()\r\n for (let i = 0; i < products.length; i++) {\r\n addedIds.add(products[i].id)\r\n }\r\n \r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const rawId = prodObj.get('id')\r\n const itemId = (typeof rawId == 'string') ? (rawId as string) : ''\r\n \r\n if (!addedIds.has(itemId)) {\r\n products.push(parseProductFromRaw(item))\r\n addedIds.add(itemId)\r\n if (products.length >= limit) break\r\n }\r\n }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:1854','[getProductsByNewest] 返回商品数:', products.length)\r\n return products\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1857','获取新品异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取推荐商品(is_featured=true)\r\n async getRecommendedProducts(limit: number = 10): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:1865','[getRecommendedProducts] 开始获取推荐商品...')\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .eq('status', '1') // 在数据库层面过滤\r\n .order('sale_count', { ascending: false })\r\n .limit(limit * 5) // 获取更多数据以便过滤 is_featured\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:1874','[getRecommendedProducts] 查询完成')\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1877','获取推荐商品失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n __f__('log','at utils/supabaseService.uts:1883','[getRecommendedProducts] 数据为空')\r\n return []\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:1889','[getRecommendedProducts] 数据条数:', rawList.length)\r\n \r\n for (let i: number = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const rawFeatured = prodObj.get('is_featured')\r\n \r\n let isFeaturedBool: boolean = false\r\n if (typeof rawFeatured == 'boolean') {\r\n isFeaturedBool = rawFeatured as boolean\r\n } else if (typeof rawFeatured == 'number') {\r\n isFeaturedBool = (rawFeatured as number) == 1\r\n }\r\n if (!isFeaturedBool) {\r\n continue\r\n }\r\n \r\n products.push(parseProductFromRaw(item))\r\n if (products.length >= limit) break\r\n }\r\n return products\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:1911','获取推荐商品异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取特价商品(这里假设没有specific flag, just use logic or tag if exists, defaulting to hot for now or just skip)\r\n // Modify to use compatible logic if badge column doesn't exist\r\n async getDiscountProducts(limit: number = 10): Promise {\r\n return [] as Product[] // 暂无特价字段\r\n }\r\n\r\n // 获取当前用户的购物车商品(关联商品和店铺信息)\r\n async getCartItems(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('warn','at utils/supabaseService.uts:1927','用户未登录,无法获取购物车')\r\n return []\r\n }\r\n\r\n // 查询购物车表,并关联商品表(使用内联关联)\r\n // 注意:使用 !inner 进行内连接,或者 left join (默认)\r\n // 修改查询语法以符合 PostgREST 规范\r\n // 尝试简化查询,先只查购物车,再查商品,避免复杂的嵌套查询导致 400 错误\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .select('*')\r\n .eq('user_id', userId)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:1943','获取购物车失败:', response.error)\r\n return []\r\n }\r\n \r\n const cartData = response.data as any[]\r\n // __f__('log','at utils/supabaseService.uts:1948','Raw Cart Data:', JSON.stringify(cartData))\r\n \r\n if (cartData == null || cartData.length === 0) {\r\n return []\r\n }\r\n\r\n // 收集所有 product_id 和 sku_id\r\n const productIds: string[] = []\r\n const skuIds: string[] = []\r\n for (let i = 0; i < cartData.length; i++) {\r\n let item = cartData[i]\r\n let pid: string = ''\r\n let sid: string = ''\r\n if (item instanceof UTSJSONObject) {\r\n pid = item.getString('product_id') ?? ''\r\n sid = item.getString('sku_id') ?? ''\r\n } else {\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n pid = itemObj.getString('product_id') ?? ''\r\n sid = itemObj.getString('sku_id') ?? ''\r\n }\r\n if (pid !== '' && !productIds.includes(pid)) {\r\n productIds.push(pid)\r\n }\r\n if (sid !== '' && !skuIds.includes(sid)) {\r\n skuIds.push(sid)\r\n }\r\n }\r\n\r\n // 批量查询商品详情 (使用视图关联店铺信息,修复字段名 specification -> attributes)\r\n const productMap = new Map()\r\n \r\n if (productIds.length > 0) {\r\n // Convert string array to any array for .in()\r\n const productIdsAny: any[] = []\r\n for(let i=0; i()\r\n const merchantIds: string[] = []\r\n // 遍历 productMap 获取 merchant_id\r\n productMap.forEach((p: any, pid: string) => {\r\n let mid: string = ''\r\n if (p instanceof UTSJSONObject) {\r\n mid = p.getString('merchant_id') ?? ''\r\n } else {\r\n const pObj = JSON.parse(JSON.stringify(p)) as UTSJSONObject\r\n mid = pObj.getString('merchant_id') ?? ''\r\n }\r\n if (mid !== '' && !merchantIds.includes(mid)) {\r\n merchantIds.push(mid)\r\n }\r\n })\r\n \r\n if (merchantIds.length > 0) {\r\n const merchantIdsAny: any[] = []\r\n for(let i=0; i()\r\n if (skuIds.length > 0) {\r\n const skuIdsAny: any[] = []\r\n for(let i=0; i 0) {\r\n productPrice = skuPrice\r\n }\r\n const skuImg = sku.getString('image_url')\r\n if (skuImg != null && skuImg !== '') {\r\n productImage = skuImg\r\n }\r\n \r\n const specRaw = sku.get('specifications')\r\n if (specRaw != null) {\r\n if (typeof specRaw === 'string') {\r\n productSpec = specRaw\r\n } else if (specRaw instanceof UTSJSONObject) {\r\n const keys = ['规格', '颜色', '尺码', '容量', '版本', '型号']\r\n const result: string[] = []\r\n for (let k = 0; k < keys.length; k++) {\r\n const key = keys[k]\r\n const val = specRaw.get(key)\r\n if (val != null && val !== '') {\r\n result.push(`${val}`)\r\n }\r\n }\r\n if (result.length > 0) {\r\n productSpec = result.join(' ')\r\n } else {\r\n const allKeys = UTSJSONObject.keys(specRaw)\r\n const parts: string[] = []\r\n for(let k = 0; k < allKeys.length; k++) {\r\n let val = specRaw.get(allKeys[k])\r\n if (val != null) {\r\n parts.push(`${val}`)\r\n }\r\n }\r\n productSpec = parts.join(' ')\r\n }\r\n } else {\r\n try {\r\n let jsonStr = JSON.stringify(specRaw)\r\n productSpec = jsonStr.replace(/[\"{}]/g, '').replace(/,/g, ' ').replace(/:/g, ' ')\r\n } catch (e) {}\r\n }\r\n }\r\n } else {\r\n const sObj = JSON.parse(JSON.stringify(sku)) as UTSJSONObject\r\n const skuPrice = sObj.getNumber('price') ?? 0\r\n if (skuPrice > 0) productPrice = skuPrice\r\n\r\n const skuImg = sObj.getString('image_url') ?? ''\r\n if (skuImg !== '') productImage = skuImg\r\n\r\n const specRaw = sObj.get('specifications')\r\n if (specRaw != null) {\r\n if (typeof specRaw === 'string') {\r\n productSpec = specRaw\r\n } else if (specRaw instanceof UTSJSONObject) {\r\n const keys = ['规格', '颜色', '尺码', '容量', '版本', '型号']\r\n const result: string[] = []\r\n for (let k = 0; k < keys.length; k++) {\r\n const key = keys[k]\r\n const val = specRaw.get(key)\r\n if (val != null && val !== '') {\r\n result.push(`${val}`)\r\n }\r\n }\r\n if (result.length > 0) {\r\n productSpec = result.join(' ')\r\n } else {\r\n const allKeys = UTSJSONObject.keys(specRaw)\r\n const parts: string[] = []\r\n for(let k = 0; k < allKeys.length; k++) {\r\n let val = specRaw.get(allKeys[k])\r\n if (val != null) {\r\n parts.push(`${val}`)\r\n }\r\n }\r\n productSpec = parts.join(' ')\r\n }\r\n } else {\r\n try {\r\n let jsonStr = JSON.stringify(specRaw)\r\n productSpec = jsonStr.replace(/[\"{}]/g, '').replace(/,/g, ' ').replace(/:/g, ' ')\r\n } catch (e) {}\r\n }\r\n }\r\n }\r\n }\r\n\r\n let shopIdStr = merchantId != '' ? merchantId : 'unknown_shop'\r\n\r\n \r\n cartItems.push({\r\n id: itemId,\r\n user_id: userIdVal,\r\n product_id: productId,\r\n sku_id: skuId,\r\n merchant_id: merchantId,\r\n quantity: quantity,\r\n selected: selected,\r\n product_name: productName,\r\n product_image: productImage,\r\n product_price: productPrice,\r\n product_specification: productSpec,\r\n shop_id: shopIdStr,\r\n shop_name: shopNameStr,\r\n created_at: createdAt,\r\n updated_at: updatedAt\r\n } as CartItem)\r\n }\r\n }\r\n \r\n return cartItems\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2295','获取购物车异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 获取用户通知 (系统、活动、订单)\r\n async getUserNotifications(type: string | null = null): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2303','[getUserNotifications] 开始获取通知')\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return []\r\n\r\n let query = supa\r\n .from('ml_notifications')\r\n .select('*')\r\n .eq('user_id', userId)\r\n \r\n if (type != null) {\r\n query = query.eq('type', type)\r\n }\r\n \r\n const response = await query.order('created_at', { ascending: false }).execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2319','获取通知失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) return []\r\n \r\n const notifications: Notification[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:2328','[getUserNotifications] 获取到通知数量:', rawList.length)\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const noteObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n const getSafeString = (key: string): string => {\r\n const val = noteObj.get(key)\r\n if (val == null) return ''\r\n if (typeof val == 'string') return val\r\n return ''\r\n }\r\n \r\n const getSafeNumber = (key: string): number => {\r\n const val = noteObj.get(key)\r\n if (val == null) return 0\r\n if (typeof val == 'number') return val\r\n return 0\r\n }\r\n \r\n const getSafeBoolean = (key: string): boolean => {\r\n const val = noteObj.get(key)\r\n if (val == null) return false\r\n if (typeof val == 'boolean') return val\r\n if (typeof val == 'number') return (val as number) == 1\r\n return false\r\n }\r\n \r\n const note: Notification = {\r\n id: getSafeString('id'),\r\n user_id: getSafeString('user_id'),\r\n type: getSafeString('type'),\r\n title: getSafeString('title'),\r\n content: getSafeString('content'),\r\n is_read: getSafeBoolean('is_read'),\r\n icon_url: getSafeString('icon_url'),\r\n link_url: getSafeString('link_url'),\r\n extra_data: getSafeString('extra_data'),\r\n created_at: getSafeString('created_at')\r\n }\r\n notifications.push(note)\r\n }\r\n return notifications\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:2372','获取通知异常:', e)\r\n return []\r\n }\r\n }\r\n\r\n // 获取聊天会话列表\r\n async getChatRooms(): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2380','[getChatRooms] 开始获取聊天会话')\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return []\r\n\r\n const response = await supa\r\n .from('ml_chat_rooms')\r\n .select('*')\r\n .eq('user_id', userId)\r\n .order('updated_at', { ascending: false })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2392','获取聊天会话失败:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) return []\r\n \r\n const rooms: ChatRoom[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:2401','[getChatRooms] 获取到会话数量:', rawList.length)\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const roomObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n const getSafeString = (key: string): string => {\r\n const val = roomObj.get(key)\r\n if (val == null) return ''\r\n if (typeof val == 'string') return val\r\n return ''\r\n }\r\n \r\n const getSafeNumber = (key: string): number => {\r\n const val = roomObj.get(key)\r\n if (val == null) return 0\r\n if (typeof val == 'number') return val\r\n return 0\r\n }\r\n \r\n const getSafeBoolean = (key: string): boolean => {\r\n const val = roomObj.get(key)\r\n if (val == null) return false\r\n if (typeof val == 'boolean') return val\r\n if (typeof val == 'number') return (val as number) == 1\r\n return false\r\n }\r\n \r\n const room: ChatRoom = {\r\n id: getSafeString('id'),\r\n user_id: getSafeString('user_id'),\r\n merchant_id: getSafeString('merchant_id'),\r\n shop_name: getSafeString('shop_name'),\r\n shop_logo: getSafeString('shop_logo'),\r\n last_message: getSafeString('last_message'),\r\n last_message_at: getSafeString('last_message_at'),\r\n unread_count: getSafeNumber('unread_count'),\r\n is_top: getSafeBoolean('is_top'),\r\n created_at: getSafeString('created_at'),\r\n updated_at: getSafeString('updated_at')\r\n }\r\n rooms.push(room)\r\n }\r\n return rooms\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:2446','获取聊天会话异常:', e)\r\n return []\r\n }\r\n }\r\n\r\n // 获取用户聊天消息\r\n async getUserChatMessages(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return []\r\n\r\n const response = await supa\r\n .from('ml_chat_messages')\r\n .select('*')\r\n .or(`sender_id.eq.${userId},receiver_id.eq.${userId}`)\r\n .order('created_at', { ascending: false })\r\n .limit(50)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2466','获取聊天记录失败:', response.error)\r\n return []\r\n }\r\n return response.data as ChatMessage[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:2471','获取聊天记录异常:', e)\r\n return []\r\n }\r\n }\r\n\r\n // 获取与特定商家的聊天记录 (合并版本)\r\n async getChatMessages(merchantId: string, page: number = 1, pageSize: number = 20): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2479','[getChatMessages] 开始获取聊天记录,merchantId:', merchantId, 'page:', page)\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return []\r\n\r\n const fromIndex = (page - 1) * pageSize\r\n const toIndex = fromIndex + pageSize - 1\r\n\r\n // 使用 or 组合精确条件查询:(我发给商家) OR (商家发给我)\r\n const queryStr = `and(sender_id.eq.${userId},receiver_id.eq.${merchantId}),and(sender_id.eq.${merchantId},receiver_id.eq.${userId})`\r\n \r\n const response = await supa\r\n .from('ml_chat_messages')\r\n .select('*')\r\n .or(queryStr)\r\n .order('created_at', { ascending: false }) // 最新在前\r\n .range(fromIndex, toIndex)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2498','getChatMessages error:', response.error)\r\n return []\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) return []\r\n \r\n const messages: ChatMessage[] = []\r\n const rawList = rawData as any[]\r\n __f__('log','at utils/supabaseService.uts:2507','[getChatMessages] 获取到消息数量:', rawList.length)\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const msgObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n const getSafeString = (key: string): string => {\r\n const val = msgObj.get(key)\r\n if (val == null) return ''\r\n return val.toString()\r\n }\r\n \r\n const getSafeBoolean = (key: string): boolean => {\r\n const val = msgObj.get(key)\r\n if (val == null) return false\r\n if (typeof val == 'boolean') return val as boolean\r\n return (val.toString() == '1' || val.toString() == 'true')\r\n }\r\n \r\n const msg: ChatMessage = {\r\n id: getSafeString('id'),\r\n session_id: getSafeString('session_id'),\r\n sender_id: getSafeString('sender_id'),\r\n receiver_id: getSafeString('receiver_id'),\r\n content: getSafeString('content'),\r\n msg_type: getSafeString('msg_type'),\r\n is_read: getSafeBoolean('is_read'),\r\n is_from_user: getSafeBoolean('is_from_user'),\r\n extra_data: getSafeString('extra_data'),\r\n created_at: getSafeString('created_at')\r\n }\r\n messages.push(msg)\r\n }\r\n return messages\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:2542','获取聊天记录异常:', e)\r\n return []\r\n }\r\n }\r\n\r\n // 发送聊天消息\r\n async sendChatMessage(content: string, toId: string | null = null, type: string = 'text'): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n \r\n const payload = {\r\n sender_id: userId,\r\n content: content,\r\n msg_type: type,\r\n is_from_user: true,\r\n created_at: new Date().toISOString()\r\n } as UTSJSONObject\r\n if (toId != null) {\r\n payload.set('receiver_id', toId)\r\n }\r\n\r\n const response = await supa\r\n .from('ml_chat_messages')\r\n .insert(payload)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2570','发送消息失败:', response.error)\r\n return false\r\n }\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:2575','发送消息异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 模拟客服回复\r\n async simulateServiceReply(content: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n\r\n const response = await supa\r\n .from('ml_chat_messages')\r\n .insert({\r\n receiver_id: userId,\r\n content: content,\r\n msg_type: 'text',\r\n is_from_user: false,\r\n created_at: new Date().toISOString()\r\n })\r\n .execute()\r\n return response.error == null\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n\r\n // 添加商品到购物车\r\n async addToCart(productId: string, quantity: number = 1, skuId: string = '', merchantId: string = ''): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2607','用户未登录,无法添加商品到购物车')\r\n return false\r\n }\r\n \r\n const realSkuId = (skuId != null && skuId.length > 0) ? skuId : null\r\n const realMerchantId = (merchantId != null && merchantId.length > 0) ? merchantId : null\r\n\r\n // 检查商品是否已在购物车中\r\n // 注意:必须处理 sku_id 为空的情况,使用 is.null 过滤器\r\n let query = supa\r\n .from('ml_shopping_cart')\r\n .select('*')\r\n .eq('user_id', userId)\r\n .eq('product_id', productId)\r\n \r\n if (realSkuId != null) {\r\n query = query.eq('sku_id', realSkuId)\r\n } else {\r\n query = query.is('sku_id', null)\r\n }\r\n\r\n const existingResponse = await query.single().execute()\r\n\r\n let existingItem: any | null = null\r\n \r\n if (existingResponse.data != null) {\r\n const rawData = existingResponse.data as any\r\n if (Array.isArray(rawData)) {\r\n if (rawData.length > 0) {\r\n existingItem = rawData[0]\r\n }\r\n } else {\r\n existingItem = rawData\r\n }\r\n }\r\n\r\n let response: AkReqResponse\r\n if (existingItem != null) {\r\n // 商品已存在,更新数量\r\n __f__('log','at utils/supabaseService.uts:2646','Found existing cart item:', JSON.stringify(existingItem))\r\n\r\n // 确保 existingItem.id 存在\r\n let itemId: string | null = null\r\n let itemQty: any | null = null\r\n\r\n if (existingItem instanceof UTSJSONObject) {\r\n itemId = existingItem.getString('id')\r\n itemQty = existingItem.getNumber('quantity')\r\n } else {\r\n const obj = JSON.parse(JSON.stringify(existingItem)) as UTSJSONObject\r\n itemId = obj.getString('id')\r\n itemQty = obj.getNumber('quantity')\r\n }\r\n\r\n if (itemId != null) {\r\n let currentQty = 0\r\n if (typeof itemQty === 'number') {\r\n currentQty = itemQty as number\r\n } else {\r\n const qStr = `${itemQty ?? 0}`\r\n currentQty = parseInt(qStr)\r\n }\r\n const newQty = currentQty + quantity\r\n\r\n response = await supa\r\n .from('ml_shopping_cart')\r\n .update({\r\n quantity: newQty,\r\n merchant_id: realMerchantId,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', itemId)\r\n .execute()\r\n } else {\r\n __f__('error','at utils/supabaseService.uts:2681','购物车已有商品但缺少ID,无法更新. Data:', JSON.stringify(existingItem))\r\n return false\r\n }\r\n } else {\r\n // 商品不存在,添加新记录\r\n const cartPayload = new UTSJSONObject()\r\n cartPayload.set('user_id', userId)\r\n cartPayload.set('product_id', productId)\r\n cartPayload.set('sku_id', realSkuId)\r\n cartPayload.set('quantity', quantity)\r\n cartPayload.set('selected', true)\r\n cartPayload.set('created_at', new Date().toISOString())\r\n cartPayload.set('updated_at', new Date().toISOString())\r\n if (realMerchantId != null) {\r\n cartPayload.set('merchant_id', realMerchantId)\r\n }\r\n \r\n response = await supa\r\n .from('ml_shopping_cart')\r\n .insert(cartPayload)\r\n .execute()\r\n }\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2705','添加商品到购物车失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2711','添加商品到购物车异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 更新购物车商品数量\r\n async updateCartItemQuantity(cartItemId: string, quantity: number): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2721','用户未登录,无法更新购物车')\r\n return false\r\n }\r\n\r\n if (quantity < 1) {\r\n // 数量小于1时删除商品\r\n return await this.deleteCartItem(cartItemId)\r\n }\r\n\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .update({\r\n quantity: quantity,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', cartItemId)\r\n .eq('user_id', userId)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2741','更新购物车商品数量失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2747','更新购物车商品数量异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 更新购物车商品选中状态\r\n async updateCartItemSelection(cartItemId: string, selected: boolean): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2757','用户未登录,无法更新购物车')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .update({\r\n selected: selected,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', cartItemId)\r\n .eq('user_id', userId)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2772','更新购物车商品选中状态失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2778','更新购物车商品选中状态异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 批量更新购物车商品选中状态\r\n async batchUpdateCartItemSelection(cartItemIds: string[], selected: boolean): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2786','[batchUpdateCartItemSelection] 开始批量更新')\r\n __f__('log','at utils/supabaseService.uts:2787','[batchUpdateCartItemSelection] cartItemIds:', JSON.stringify(cartItemIds))\r\n __f__('log','at utils/supabaseService.uts:2788','[batchUpdateCartItemSelection] cartItemIds length:', cartItemIds.length)\r\n __f__('log','at utils/supabaseService.uts:2789','[batchUpdateCartItemSelection] selected:', selected)\r\n \r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2793','用户未登录,无法更新购物车')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .update({\r\n selected: selected,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('user_id', userId)\r\n .in('id', cartItemIds as any[])\r\n .execute()\r\n\r\n __f__('log','at utils/supabaseService.uts:2807','[batchUpdateCartItemSelection] response.error:', response.error)\r\n __f__('log','at utils/supabaseService.uts:2808','[batchUpdateCartItemSelection] response.data:', JSON.stringify(response.data))\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2811','批量更新购物车商品选中状态失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2817','批量更新购物车商品选中状态异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 删除购物车商品\r\n async deleteCartItem(cartItemId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2825','正在执行删除购物车商品,ID:', cartItemId)\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2828','用户未登录,无法删除购物车商品')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .eq('id', cartItemId)\r\n .eq('user_id', userId)\r\n .delete()\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2840','删除购物车商品失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2846','删除购物车商品异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 批量删除购物车商品\r\n async batchDeleteCartItems(cartItemIds: string[]): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2854','[batchDeleteCartItems] 开始删除, ids:', cartItemIds.length)\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2857','用户未登录,无法删除购物车商品')\r\n return false\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:2861','[batchDeleteCartItems] userId:', userId)\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .eq('user_id', userId)\r\n .in('id', cartItemIds as any[])\r\n .delete()\r\n .execute()\r\n\r\n __f__('log','at utils/supabaseService.uts:2869','[batchDeleteCartItems] response.error:', response.error)\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2871','批量删除购物车商品失败:', response.error)\r\n return false\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:2875','[batchDeleteCartItems] 删除成功')\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2878','批量删除购物车商品异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 清空购物车\r\n async clearCart(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:2888','用户未登录,无法清空购物车')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_shopping_cart')\r\n .eq('user_id', userId)\r\n .delete()\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2899','清空购物车失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2905','清空购物车异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 获取当前用户的所有地址\r\n async getAddresses(): Promise {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('warn','at utils/supabaseService.uts:2914','[getAddresses] 用户未登录,无法获取地址')\r\n return []\r\n }\r\n\r\n try {\r\n __f__('log','at utils/supabaseService.uts:2919','[getAddresses] 查询地址, userId:', userId)\r\n \r\n const response = await supa\r\n .from('ml_user_addresses')\r\n .select('*')\r\n .eq('user_id', userId)\r\n .order('is_default', { ascending: false })\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:2929','[getAddresses] response.error:', response.error)\r\n __f__('log','at utils/supabaseService.uts:2930','[getAddresses] response.data:', JSON.stringify(response.data))\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2933','[getAddresses] 获取地址失败:', response.error)\r\n return []\r\n }\r\n \r\n const data = response.data\r\n if (data == null) {\r\n return []\r\n }\r\n \r\n const result: UserAddress[] = []\r\n const rawData = data as any[]\r\n for (let i = 0; i < rawData.length; i++) {\r\n const item = rawData[i]\r\n let itemObj: UTSJSONObject\r\n if (item instanceof UTSJSONObject) {\r\n itemObj = item as UTSJSONObject\r\n } else {\r\n itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n }\r\n \r\n const addr: UserAddress = {\r\n id: itemObj.getString('id') ?? '',\r\n user_id: itemObj.getString('user_id') ?? '',\r\n recipient_name: itemObj.getString('receiver_name') ?? itemObj.getString('recipient_name') ?? '',\r\n phone: itemObj.getString('receiver_phone') ?? itemObj.getString('phone') ?? '',\r\n province: itemObj.getString('province') ?? '',\r\n city: itemObj.getString('city') ?? '',\r\n district: itemObj.getString('district') ?? '',\r\n detail_address: itemObj.getString('address_detail') ?? itemObj.getString('detail_address') ?? '',\r\n is_default: itemObj.getBoolean('is_default') ?? false,\r\n label: itemObj.getString('label') ?? '',\r\n created_at: itemObj.getString('created_at') ?? '',\r\n updated_at: itemObj.getString('updated_at') ?? ''\r\n }\r\n result.push(addr)\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:2970','[getAddresses] 返回地址数量:', result.length)\r\n return result\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:2973','[getAddresses] 获取地址异常:', error)\r\n return []\r\n }\r\n }\r\n\r\n // 根据ID获取地址详情\r\n async getAddressById(addressId: string): Promise {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('warn','at utils/supabaseService.uts:2982','用户未登录,无法获取地址')\r\n return null\r\n }\r\n\r\n try {\r\n const query = supa\r\n .from('ml_user_addresses')\r\n .select('*, recipient_name:receiver_name, phone:receiver_phone, detail_address:address_detail')\r\n .eq('id', addressId)\r\n .eq('user_id', userId)\r\n .single()\r\n \r\n const response = await query.execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:2997','获取地址详情失败:', response.error)\r\n return null\r\n }\r\n \r\n return response.data as UserAddress\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3003','获取地址详情异常:', error)\r\n return null\r\n }\r\n }\r\n\r\n // 添加新地址\r\n async addAddress(address: AddAddressParams): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:3013','用户未登录,无法添加地址')\r\n return false\r\n }\r\n\r\n // 如果设置为默认地址,需要先取消其他默认地址\r\n if (address.is_default == true) {\r\n await this.clearDefaultAddress(userId)\r\n }\r\n\r\n const response = await supa\r\n .from('ml_user_addresses')\r\n .insert({\r\n user_id: userId,\r\n receiver_name: address.recipient_name,\r\n receiver_phone: address.phone,\r\n province: address.province,\r\n city: address.city,\r\n district: address.district,\r\n address_detail: address.detail_address,\r\n postal_code: address.postal_code ?? null,\r\n is_default: address.is_default ?? false,\r\n created_at: new Date().toISOString(),\r\n updated_at: new Date().toISOString()\r\n })\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3040','添加地址失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3046','添加地址异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 更新地址\r\n async updateAddress(addressId: string, address: UpdateAddressParams): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:3056','用户未登录,无法更新地址')\r\n return false\r\n }\r\n\r\n // 如果设置为默认地址,需要先取消其他默认地址\r\n if (address.is_default == true) {\r\n await this.clearDefaultAddress(userId)\r\n }\r\n \r\n // 构造更新数据,映射字段名到数据库列名\r\n const updateData = {}\r\n if (address.recipient_name != null) updateData['receiver_name'] = address.recipient_name\r\n if (address.phone != null) updateData['receiver_phone'] = address.phone\r\n if (address.province != null) updateData['province'] = address.province\r\n if (address.city != null) updateData['city'] = address.city\r\n if (address.district != null) updateData['district'] = address.district\r\n if (address.detail_address != null) updateData['address_detail'] = address.detail_address\r\n if (address.postal_code != null) updateData['postal_code'] = address.postal_code\r\n if (address.is_default != null) updateData['is_default'] = address.is_default\r\n if (address.label != null) updateData['label'] = address.label\r\n updateData['updated_at'] = new Date().toISOString()\r\n\r\n const response = await supa\r\n .from('ml_user_addresses')\r\n .update(updateData)\r\n .eq('id', addressId)\r\n .eq('user_id', userId)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3086','更新地址失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3092','更新地址异常:', error)\r\n return false\r\n }\r\n }\r\n \r\n // 确认收货\r\n async confirmReceipt(orderId: string): Promise {\r\n __f__('log','at utils/supabaseService.uts:3099','[confirmReceipt] 开始确认收货, orderId:', orderId)\r\n try {\r\n const userId = this.getCurrentUserId()\r\n __f__('log','at utils/supabaseService.uts:3102','[confirmReceipt] userId:', userId)\r\n if (userId == null) {\r\n return { success: false, error: '用户未登录' }\r\n }\r\n\r\n const updateData = new UTSJSONObject()\r\n updateData.set('order_status', 4)\r\n updateData.set('delivered_at', new Date().toISOString())\r\n updateData.set('completed_at', new Date().toISOString())\r\n updateData.set('updated_at', new Date().toISOString())\r\n \r\n __f__('log','at utils/supabaseService.uts:3113','[confirmReceipt] 准备更新订单状态, updateData:', JSON.stringify(updateData))\r\n\r\n const response = await supa\r\n .from('ml_orders')\r\n .update(updateData)\r\n .eq('id', orderId)\r\n .eq('user_id', userId)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3122','[confirmReceipt] response.status:', response.status)\r\n __f__('log','at utils/supabaseService.uts:3123','[confirmReceipt] response.error:', response.error)\r\n __f__('log','at utils/supabaseService.uts:3124','[confirmReceipt] response.data:', JSON.stringify(response.data))\r\n \r\n // 检查 HTTP 状态码\r\n if (response.status != null && response.status >= 400) {\r\n // 尝试从 response.data 中提取错误信息\r\n let errorMsg = '请求失败'\r\n if (response.data != null) {\r\n try {\r\n const errorData = response.data as UTSJSONObject\r\n const msg = errorData.getString('message')\r\n if (msg != null) {\r\n errorMsg = msg\r\n }\r\n } catch (e) {\r\n // ignore\r\n }\r\n }\r\n __f__('log','at utils/supabaseService.uts:3141','[confirmReceipt] HTTP错误:', response.status, errorMsg)\r\n return { success: false, error: errorMsg }\r\n }\r\n \r\n if (response.error != null) {\r\n return { success: false, error: response.error.message }\r\n }\r\n \r\n // 检查 response.data 是否包含错误代码\r\n if (response.data != null) {\r\n try {\r\n const respData = response.data as UTSJSONObject\r\n const errorCode = respData.getString('code')\r\n if (errorCode != null) {\r\n const errorMsg = respData.getString('message') ?? '数据库错误'\r\n __f__('log','at utils/supabaseService.uts:3156','[confirmReceipt] 数据库错误:', errorCode, errorMsg)\r\n return { success: false, error: errorMsg }\r\n }\r\n } catch (e) {\r\n // ignore\r\n }\r\n }\r\n \r\n // 检查是否有数据被更新\r\n if (response.data == null || (Array.isArray(response.data) && response.data.length === 0)) {\r\n __f__('log','at utils/supabaseService.uts:3166','[confirmReceipt] 没有数据被更新,可能订单不存在或无权限')\r\n return { success: false, error: '订单不存在或无权限更新' }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3170','[confirmReceipt] 确认收货成功')\r\n return { success: true }\r\n } catch (e: any) {\r\n __f__('error','at utils/supabaseService.uts:3173','[confirmReceipt] 异常:', e)\r\n return { success: false, error: e.message }\r\n }\r\n }\r\n\r\n // 取消订单\r\n async cancelOrder(orderId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_orders')\r\n .update({\r\n order_status: 5,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', orderId)\r\n .eq('user_id', userId)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3197','取消订单失败:', response.error)\r\n return false\r\n }\r\n \r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3203','取消订单异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 删除订单\r\n async deleteOrder(orderId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_orders')\r\n .delete()\r\n .eq('id', orderId)\r\n .eq('user_id', userId)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3224','删除订单失败:', response.error)\r\n return false\r\n }\r\n \r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3230','删除订单异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 确认收货\r\n async confirmOrderReceived(orderId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_orders')\r\n .update({\r\n order_status: 4,\r\n shipping_status: 3,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', orderId)\r\n .eq('user_id', userId)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3255','确认收货失败:', response.error)\r\n return false\r\n }\r\n \r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3261','确认收货异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 删除地址\r\n async deleteAddress(addressId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:3269','正在执行删除地址,ID:', addressId)\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:3272','用户未登录,无法删除地址')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_user_addresses')\r\n .eq('id', addressId)\r\n .eq('user_id', userId)\r\n .delete()\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3284','删除地址失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3290','删除地址异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 清除默认地址(内部使用)\r\n private async clearDefaultAddress(userId: string): Promise {\r\n try {\r\n await supa\r\n .from('ml_user_addresses')\r\n .update({\r\n is_default: false,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('user_id', userId)\r\n .eq('is_default', true)\r\n .execute()\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3308','清除默认地址异常:', error)\r\n }\r\n }\r\n\r\n // 获取用户资料\r\n async getUserProfile(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return null\r\n \r\n // 联合查询 auth user 和 profile\r\n // 由于 Supabase auth table 不可直接访问,这里查询 ml_user_profiles\r\n // 注意:使用 limit(1) 替代 single() 以避免 Android 端类型转换错误\r\n const response = await supa\r\n .from('ml_user_profiles')\r\n .select('*')\r\n .eq('user_id', userId)\r\n .limit(1)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n // 如果不存在 profile,可能只有 auth user,这里暂时返回空或创建默认\r\n return null\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) return null\r\n \r\n // 作为数组处理\r\n const rawList = rawData as any[]\r\n if (rawList.length == 0) return null\r\n \r\n return rawList[0]\r\n } catch (e) {\r\n return null\r\n }\r\n }\r\n \r\n // 创建订单\r\n async createOrder(orderData: CreateOrderParams): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:3351','CreateOrder: User not logged in')\r\n return null\r\n }\r\n \r\n const orderNo = 'ML' + Date.now() + Math.floor(Math.random() * 1000)\r\n \r\n let merchantId = orderData.merchant_id\r\n __f__('log','at utils/supabaseService.uts:3358','[CreateOrder] 原始 merchant_id:', merchantId)\r\n if (merchantId == null || merchantId == '' || merchantId == 'unknown') {\r\n __f__('warn','at utils/supabaseService.uts:3360','[CreateOrder] merchant_id 为空或无效,将使用 userId 作为 fallback')\r\n merchantId = userId\r\n }\r\n __f__('log','at utils/supabaseService.uts:3363','[CreateOrder] 最终使用的 merchant_id:', merchantId)\r\n \r\n let shippingAddrStr = '{}'\r\n if (orderData.shipping_address != null) {\r\n if (typeof orderData.shipping_address === 'string') {\r\n shippingAddrStr = orderData.shipping_address\r\n } else {\r\n shippingAddrStr = JSON.stringify(orderData.shipping_address)\r\n }\r\n }\r\n \r\n const orderPayload = new UTSJSONObject()\r\n orderPayload.set('user_id', userId)\r\n orderPayload.set('merchant_id', merchantId)\r\n orderPayload.set('order_no', orderNo)\r\n orderPayload.set('product_amount', orderData.product_amount)\r\n orderPayload.set('shipping_fee', orderData.shipping_fee)\r\n orderPayload.set('total_amount', orderData.total_amount)\r\n orderPayload.set('paid_amount', 0)\r\n orderPayload.set('shipping_address', shippingAddrStr)\r\n orderPayload.set('order_status', 1)\r\n orderPayload.set('payment_status', 1)\r\n orderPayload.set('shipping_status', 1)\r\n orderPayload.set('created_at', new Date().toISOString())\r\n orderPayload.set('updated_at', new Date().toISOString())\r\n \r\n __f__('log','at utils/supabaseService.uts:3389','[CreateOrder] 插入订单数据:', JSON.stringify(orderPayload))\r\n __f__('log','at utils/supabaseService.uts:3390','[CreateOrder] 期望的订单号:', orderNo)\r\n \r\n const orderResponse = await supa\r\n .from('ml_orders')\r\n .insert(orderPayload)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3397','[CreateOrder] insert 完成')\r\n __f__('log','at utils/supabaseService.uts:3398','[CreateOrder] orderResponse.error:', orderResponse.error)\r\n \r\n if (orderResponse.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3401','[CreateOrder] 创建订单失败:', orderResponse.error)\r\n return null\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3405','[CreateOrder] 开始查询新创建的订单, order_no:', orderNo)\r\n \r\n const queryResponse = await supa\r\n .from('ml_orders')\r\n .select('id, order_no')\r\n .eq('order_no', orderNo)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3413','[CreateOrder] queryResponse.error:', queryResponse.error)\r\n __f__('log','at utils/supabaseService.uts:3414','[CreateOrder] queryResponse.data:', JSON.stringify(queryResponse.data))\r\n \r\n if (queryResponse.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3417','[CreateOrder] 查询订单失败:', queryResponse.error)\r\n return null\r\n }\r\n \r\n const queryData = queryResponse.data as any\r\n let orderId = ''\r\n \r\n __f__('log','at utils/supabaseService.uts:3424','[CreateOrder] queryData 类型:', typeof queryData, '是否数组:', Array.isArray(queryData))\r\n \r\n if (Array.isArray(queryData) && queryData.length > 0) {\r\n __f__('log','at utils/supabaseService.uts:3427','[CreateOrder] queryData 长度:', queryData.length)\r\n const firstItemRaw = queryData[0]\r\n __f__('log','at utils/supabaseService.uts:3429','[CreateOrder] firstItemRaw 类型:', typeof firstItemRaw)\r\n \r\n // 将 firstItemRaw 转换为可访问的对象\r\n const firstItemStr = JSON.stringify(firstItemRaw)\r\n const firstItemParsed = JSON.parse(firstItemStr)\r\n if (firstItemParsed == null) {\r\n __f__('error','at utils/supabaseService.uts:3435','[CreateOrder] 解析订单数据失败')\r\n return null\r\n }\r\n const firstItem = firstItemParsed as UTSJSONObject\r\n orderId = (firstItem.getString('id') ?? '') as string\r\n __f__('log','at utils/supabaseService.uts:3440','[CreateOrder] 找到新创建的订单, id:', orderId)\r\n } else {\r\n __f__('error','at utils/supabaseService.uts:3442','[CreateOrder] 未找到新创建的订单,插入可能失败')\r\n return null\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3446','[CreateOrder] 订单创建成功, orderId:', orderId)\r\n \r\n const orderItems: UTSJSONObject[] = []\r\n __f__('log','at utils/supabaseService.uts:3449','[CreateOrder] orderData.items 类型:', typeof orderData.items, '是否数组:', Array.isArray(orderData.items))\r\n \r\n if (orderData.items == null) {\r\n __f__('error','at utils/supabaseService.uts:3452','[CreateOrder] orderData.items 为 null!')\r\n return orderId\r\n }\r\n \r\n const rawItems = orderData.items as any[]\r\n __f__('log','at utils/supabaseService.uts:3457','[CreateOrder] rawItems 长度:', rawItems.length)\r\n \r\n if (rawItems.length === 0) {\r\n __f__('warn','at utils/supabaseService.uts:3460','[CreateOrder] rawItems 为空数组,没有商品项需要插入')\r\n return orderId\r\n }\r\n \r\n for(let i = 0; i < rawItems.length; i++) {\r\n const rawItem = rawItems[i]\r\n const itemStr = JSON.stringify(rawItem)\r\n const itemParsed = JSON.parse(itemStr)\r\n if (itemParsed == null) {\r\n __f__('error','at utils/supabaseService.uts:3469','[CreateOrder] 商品项解析失败')\r\n continue\r\n }\r\n const item = itemParsed as UTSJSONObject\r\n\r\n const itemJson = new UTSJSONObject()\r\n \r\n let pId = item.get('product_id')\r\n if (pId == null) {\r\n pId = item.get('id')\r\n }\r\n const productId = (pId ?? '') as string\r\n \r\n itemJson.set('order_id', orderId)\r\n itemJson.set('product_id', productId)\r\n \r\n const skuIdVal = item.get('sku_id')\r\n if (skuIdVal != null && skuIdVal !== '') {\r\n itemJson.set('sku_id', skuIdVal as string)\r\n }\r\n \r\n const productName = (item.get('product_name') ?? '') as string\r\n itemJson.set('product_name', productName)\r\n \r\n const sName = item.get('sku_name')\r\n itemJson.set('sku_name', (sName ?? '') as string)\r\n \r\n const specVal = item.get('specifications')\r\n let skuSnapshot = '{}'\r\n if (specVal != null) {\r\n if (typeof specVal === 'string') {\r\n skuSnapshot = specVal as string\r\n } else {\r\n skuSnapshot = JSON.stringify(specVal)\r\n }\r\n }\r\n itemJson.set('sku_snapshot', skuSnapshot)\r\n itemJson.set('specifications', skuSnapshot)\r\n \r\n const img1 = item.get('product_image')\r\n const img2 = item.get('image_url')\r\n let imgUrl = ((img1 ?? img2 ?? '') as string)\r\n while (imgUrl.indexOf('`') >= 0) {\r\n imgUrl = imgUrl.replace('`', '')\r\n }\r\n itemJson.set('image_url', imgUrl)\r\n\r\n const iPrice = item.getNumber('price') ?? 0\r\n const iQty = item.getNumber('quantity') ?? 1\r\n itemJson.set('price', iPrice)\r\n itemJson.set('quantity', iQty)\r\n itemJson.set('total_amount', iPrice * iQty)\r\n itemJson.set('created_at', new Date().toISOString())\r\n \r\n orderItems.push(itemJson)\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3526','[CreateOrder] 插入订单项数量:', orderItems.length)\r\n \r\n for (let j: number = 0; j < orderItems.length; j++) {\r\n __f__('log','at utils/supabaseService.uts:3529','[CreateOrder] 开始插入订单项', j)\r\n const itemJson = orderItems[j]\r\n // 将 UTSJSONObject 转换为普通对象\r\n __f__('log','at utils/supabaseService.uts:3532','[CreateOrder] 序列化订单项...')\r\n const itemObjStr = JSON.stringify(itemJson)\r\n __f__('log','at utils/supabaseService.uts:3534','[CreateOrder] 订单项 JSON:', itemObjStr)\r\n const itemObjParsed = JSON.parse(itemObjStr)\r\n __f__('log','at utils/supabaseService.uts:3536','[CreateOrder] itemObjParsed 类型:', typeof itemObjParsed)\r\n if (itemObjParsed == null) {\r\n __f__('error','at utils/supabaseService.uts:3538','[CreateOrder] 订单项转换失败')\r\n continue\r\n }\r\n \r\n // 使用 UTSJSONObject 而不是 Record\r\n const itemObj = itemObjParsed as UTSJSONObject\r\n __f__('log','at utils/supabaseService.uts:3544','[CreateOrder] 执行 insert...')\r\n \r\n const itemsResponse = await supa\r\n .from('ml_order_items')\r\n .insert(itemObj)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3551','[CreateOrder] insert 完成, error:', itemsResponse.error) \r\n if (itemsResponse.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3553','[CreateOrder] 创建订单项失败:', itemsResponse.error)\r\n }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3557','[CreateOrder] 订单项创建成功')\r\n \r\n const cartItemIds: string[] = []\r\n for(let i = 0; i < rawItems.length; i++) {\r\n const rawItem = rawItems[i]\r\n const itemParsed = JSON.parse(JSON.stringify(rawItem))\r\n if (itemParsed == null) continue\r\n const item = itemParsed as UTSJSONObject\r\n const iid = item.getString('id')\r\n if (iid != null && iid.length > 10) {\r\n cartItemIds.push(iid)\r\n }\r\n }\r\n \r\n if (cartItemIds.length > 0) {\r\n await this.batchDeleteCartItems(cartItemIds)\r\n }\r\n \r\n return orderId\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3577','[CreateOrder] 创建订单异常:', error)\r\n return null\r\n }\r\n }\r\n\r\n // 批量通过店铺创建订单\r\n async createOrdersByShop(params: ShopOrderParams): Promise {\r\n try {\r\n const orderIds: string[] = []\r\n const groups = params.shopGroups as any[]\r\n \r\n let grandTotal = 0.0\r\n for(let k = 0; k < groups.length; k++) {\r\n const g = JSON.parse(JSON.stringify(groups[k])) as UTSJSONObject\r\n const gItemsRaw = g.get('items')\r\n if (gItemsRaw == null) continue\r\n const gItems = gItemsRaw as any[]\r\n \r\n for(let gi = 0; gi < gItems.length; gi++) {\r\n const it = JSON.parse(JSON.stringify(gItems[gi])) as UTSJSONObject\r\n const itPrice = it.getNumber('price') ?? 0\r\n const itQty = it.getNumber('quantity') ?? 1\r\n grandTotal += itPrice * itQty\r\n }\r\n }\r\n \r\n // 为每个店铺创建一个订单\r\n for (let i = 0; i < groups.length; i++) {\r\n const group = JSON.parse(JSON.stringify(groups[i])) as UTSJSONObject\r\n const shopItemsRaw = group.get('items')\r\n if (shopItemsRaw == null) continue\r\n const shopItems = shopItemsRaw as any[]\r\n \r\n let productAmount = 0.0\r\n for(let j = 0; j < shopItems.length; j++) {\r\n const sItem = JSON.parse(JSON.stringify(shopItems[j])) as UTSJSONObject\r\n const siPrice = sItem.getNumber('price') ?? 0\r\n const siQty = sItem.getNumber('quantity') ?? 1\r\n productAmount += siPrice * siQty\r\n }\r\n \r\n // 简单平摊运费和优惠 (实际逻辑可能更复杂)\r\n const ratio = grandTotal > 0 ? (productAmount / grandTotal) : 0\r\n const shopShippingFee = params.deliveryFee * ratio\r\n const shopDiscount = params.discountAmount * ratio\r\n const shopTotal = productAmount + shopShippingFee - shopDiscount\r\n \r\n const mId = group.getString('merchant_id')\r\n const sId = group.getString('shopId')\r\n const shopName = group.getString('shopName')\r\n\r\n __f__('log','at utils/supabaseService.uts:3628','[createOrdersByShop] 店铺组信息:', {\r\n merchant_id: mId,\r\n shopId: sId,\r\n shopName: shopName\r\n })\r\n\r\n const finalMerchantId = (mId != null && mId != '') ? mId : (sId ?? '')\r\n __f__('log','at utils/supabaseService.uts:3635','[createOrdersByShop] 最终使用的 merchant_id:', finalMerchantId)\r\n \r\n // 将 shopItems 转换为普通对象数组\r\n const plainItems: any[] = []\r\n for(let k = 0; k < shopItems.length; k++) {\r\n const plainItemRaw = JSON.parse(JSON.stringify(shopItems[k]))\r\n if (plainItemRaw != null) {\r\n plainItems.push(plainItemRaw as any)\r\n }\r\n }\r\n __f__('log','at utils/supabaseService.uts:3645','[createOrdersByShop] plainItems 数量:', plainItems.length)\r\n\r\n const orderId = await this.createOrder({\r\n merchant_id: finalMerchantId,\r\n product_amount: productAmount,\r\n shipping_fee: shopShippingFee,\r\n total_amount: shopTotal,\r\n shipping_address: params.shipping_address,\r\n items: plainItems\r\n })\r\n \r\n if (orderId != null) {\r\n orderIds.push(orderId)\r\n } else {\r\n return { success: false, orderIds, error: `店铺 ${shopName} 订单创建失败` }\r\n }\r\n }\r\n \r\n return { success: true, orderIds }\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3665','批量创建订单异常:', e)\r\n return { success: false, orderIds: [], error: '系统异常' }\r\n }\r\n }\r\n\r\n // 获取订单列表\r\n async getOrders(status: number = 0): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n // 关联查询店铺表获取店铺名称\r\n let query = supa\r\n .from('ml_orders')\r\n .select('*, ml_order_items(*), ml_shops(shop_name)')\r\n .eq('user_id', userId)\r\n .order('created_at', { ascending: false })\r\n \r\n if (status > 0) {\r\n query = query.eq('order_status', status)\r\n }\r\n \r\n const response = await query.execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3692','[getOrders] response.error:', response.error)\r\n if (response.data != null && Array.isArray(response.data)) {\r\n __f__('log','at utils/supabaseService.uts:3694','[getOrders] 订单数量:', response.data.length)\r\n }\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3698','获取订单列表失败:', response.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n const data = response.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n // 修复订单项中的图片URL\r\n const orders = data as any[]\r\n for (let i = 0; i < orders.length; i++) {\r\n const order = orders[i]\r\n const orderStr = JSON.stringify(order)\r\n const orderObj = JSON.parse(orderStr) as UTSJSONObject\r\n const itemsRaw = orderObj.get('ml_order_items')\r\n if (itemsRaw != null && Array.isArray(itemsRaw)) {\r\n const items = itemsRaw as any[]\r\n for (let j = 0; j < items.length; j++) {\r\n const item = items[j]\r\n const itemStr = JSON.stringify(item)\r\n const itemObj = JSON.parse(itemStr) as UTSJSONObject\r\n const imgUrl = itemObj.getString('image_url')\r\n if (imgUrl != null) {\r\n itemObj['image_url'] = fixImageUrl(imgUrl)\r\n }\r\n const prodImg = itemObj.getString('product_image')\r\n if (prodImg != null) {\r\n itemObj['product_image'] = fixImageUrl(prodImg)\r\n }\r\n items[j] = itemObj\r\n }\r\n orderObj['ml_order_items'] = items\r\n orders[i] = orderObj\r\n }\r\n }\r\n \r\n return orders\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:3739','获取订单列表异常:', error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n \r\n // 获取订单详情\r\n async getOrderDetail(orderId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:3748','[getOrderDetail] 开始获取订单详情,orderId:', orderId)\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return null\r\n \r\n const response = await supa\r\n .from('ml_orders')\r\n .select('*, ml_order_items(*)')\r\n .eq('id', orderId)\r\n .eq('user_id', userId!)\r\n .limit(1)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3760','[getOrderDetail] response.error:', response.error)\r\n __f__('log','at utils/supabaseService.uts:3761','[getOrderDetail] response.data:', JSON.stringify(response.data))\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3764','[getOrderDetail] 获取订单详情失败:', response.error)\r\n return null\r\n }\r\n \r\n const rawData = response.data\r\n if (rawData == null) {\r\n __f__('log','at utils/supabaseService.uts:3770','[getOrderDetail] 数据为空')\r\n return null\r\n }\r\n \r\n const rawList = rawData as any[]\r\n if (rawList.length == 0) {\r\n __f__('log','at utils/supabaseService.uts:3776','[getOrderDetail] 未找到订单')\r\n return null\r\n }\r\n \r\n const orderData = rawList[0]\r\n __f__('log','at utils/supabaseService.uts:3781','[getOrderDetail] 成功获取订单')\r\n \r\n const orderObj = JSON.parse(JSON.stringify(orderData)) as UTSJSONObject\r\n \r\n const result = new UTSJSONObject()\r\n result.set('id', orderObj.get('id') ?? '')\r\n result.set('order_no', orderObj.get('order_no') ?? '')\r\n result.set('order_status', orderObj.get('order_status') ?? 1)\r\n result.set('user_id', orderObj.get('user_id') ?? '')\r\n result.set('merchant_id', orderObj.get('merchant_id') ?? '')\r\n result.set('product_amount', orderObj.get('product_amount') ?? 0)\r\n result.set('shipping_fee', orderObj.get('shipping_fee') ?? 0)\r\n result.set('total_amount', orderObj.get('total_amount') ?? 0)\r\n result.set('paid_amount', orderObj.get('paid_amount') ?? 0)\r\n result.set('discount_amount', orderObj.get('discount_amount') ?? 0)\r\n result.set('payment_method', orderObj.get('payment_method') ?? '')\r\n result.set('payment_status', orderObj.get('payment_status') ?? 1)\r\n result.set('shipping_status', orderObj.get('shipping_status') ?? 1)\r\n result.set('created_at', orderObj.get('created_at') ?? '')\r\n result.set('paid_at', orderObj.get('paid_at') ?? '')\r\n result.set('shipped_at', orderObj.get('shipped_at') ?? '')\r\n result.set('completed_at', orderObj.get('completed_at') ?? '')\r\n result.set('shipping_address', orderObj.get('shipping_address'))\r\n result.set('ml_order_items', orderObj.get('ml_order_items'))\r\n // 添加物流信息\r\n result.set('tracking_no', orderObj.get('tracking_no') ?? '')\r\n result.set('carrier_name', orderObj.get('carrier_name') ?? '')\r\n result.set('delivered_at', orderObj.get('delivered_at') ?? '')\r\n \r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3812','[getOrderDetail] 获取订单详情异常:', e)\r\n return null\r\n }\r\n }\r\n\r\n // 支付订单\r\n async payOrder(orderId: string, paymentMethod: string, amount: number): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:3822','[payOrder] 用户未登录')\r\n return false\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3826','[payOrder] 开始更新订单状态, orderId:', orderId, 'userId:', userId)\r\n \r\n const updatePayload = new UTSJSONObject()\r\n updatePayload.set('order_status', 2)\r\n updatePayload.set('payment_status', 1)\r\n updatePayload.set('payment_method', paymentMethod)\r\n updatePayload.set('payment_time', new Date().toISOString())\r\n updatePayload.set('paid_amount', amount)\r\n updatePayload.set('updated_at', new Date().toISOString())\r\n \r\n __f__('log','at utils/supabaseService.uts:3836','[payOrder] 更新数据:', JSON.stringify(updatePayload))\r\n \r\n const response = await supa\r\n .from('ml_orders')\r\n .update(updatePayload)\r\n .eq('id', orderId)\r\n .eq('user_id', userId)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3846','[payOrder] 更新订单失败:', response.error)\r\n return false\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3850','[payOrder] 订单状态更新成功')\r\n\r\n if (paymentMethod === 'balance') {\r\n __f__('log','at utils/supabaseService.uts:3853','[payOrder] 余额支付,暂不扣减余额')\r\n }\r\n\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3858','[payOrder] 支付异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 根据ID获取订单信息\r\n async getOrderById(orderId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:3868','[getOrderById] 用户未登录')\r\n return null\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3872','[getOrderById] 查询订单, orderId:', orderId)\r\n \r\n const response = await supa\r\n .from('ml_orders')\r\n .select('*')\r\n .eq('id', orderId)\r\n .eq('user_id', userId)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3882','[getOrderById] 查询订单失败:', response.error)\r\n return null\r\n }\r\n \r\n const data = response.data as any[]\r\n if (data == null || data.length === 0) {\r\n __f__('log','at utils/supabaseService.uts:3888','[getOrderById] 未找到订单')\r\n return null\r\n }\r\n \r\n const orderRaw = data[0]\r\n let orderObj: UTSJSONObject\r\n if (orderRaw instanceof UTSJSONObject) {\r\n orderObj = orderRaw as UTSJSONObject\r\n } else {\r\n orderObj = JSON.parse(JSON.stringify(orderRaw)) as UTSJSONObject\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3900','[getOrderById] 订单数据:', JSON.stringify(orderObj))\r\n return orderObj\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3903','[getOrderById] 查询异常:', e)\r\n return null\r\n }\r\n }\r\n\r\n // 提交售后申请\r\n async createRefund(data: any): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:3911','[createRefund] 开始处理退款申请')\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('log','at utils/supabaseService.uts:3914','[createRefund] 用户未登录')\r\n return { success: false, message: '请先登录' }\r\n }\r\n \r\n const d = JSON.parse(JSON.stringify(data)) as UTSJSONObject\r\n const orderId = d.getString('order_id') ?? ''\r\n const refundType = d.getNumber('refund_type')\r\n const refundReason = d.getString('refund_reason')\r\n const refundAmount = d.getNumber('refund_amount')\r\n const description = d.getString('description')\r\n const images = d.getArray('images')\r\n \r\n __f__('log','at utils/supabaseService.uts:3926','[createRefund] orderId:', orderId)\r\n __f__('log','at utils/supabaseService.uts:3927','[createRefund] refundType:', refundType)\r\n __f__('log','at utils/supabaseService.uts:3928','[createRefund] refundReason:', refundReason)\r\n __f__('log','at utils/supabaseService.uts:3929','[createRefund] refundAmount:', refundAmount)\r\n\r\n const payload = {\r\n user_id: userId,\r\n order_id: orderId,\r\n refund_no: 'REF' + Date.now() + Math.floor(Math.random() * 1000),\r\n refund_type: refundType,\r\n refund_reason: refundReason,\r\n refund_amount: refundAmount,\r\n description: description ?? '',\r\n images: images ?? ([] as any[]),\r\n status: 1 // Pending\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3943','[createRefund] 准备插入 ml_refunds')\r\n const response = await supa\r\n .from('ml_refunds')\r\n .insert(payload)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3949','[createRefund] insert response.error:', response.error)\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3952','提交售后失败:', response.error)\r\n return { success: false, message: '提交失败: ' + (response.error.message ?? '未知错误') }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3956','[createRefund] 插入成功,更新订单状态')\r\n // 更新订单状态为退款中\r\n const updateResponse = await supa\r\n .from('ml_orders')\r\n .update({\r\n order_status: 6, // 退款中\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', orderId)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:3967','[createRefund] update response.error:', updateResponse.error)\r\n \r\n if (updateResponse.error != null) {\r\n __f__('error','at utils/supabaseService.uts:3970','更新订单状态失败:', updateResponse.error)\r\n // 不影响退款申请结果,只记录错误\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:3974','[createRefund] 完成,返回成功')\r\n return { success: true, message: '申请提交成功' }\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:3977','提交售后异常:', e)\r\n return { success: false, message: '系统异常' }\r\n }\r\n }\r\n\r\n // 取消退款申请\r\n async cancelRefund(orderId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:3985','[cancelRefund] 开始取消退款申请, orderId:', orderId)\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return { success: false, message: '请先登录' }\r\n }\r\n \r\n // 更新退款记录状态为已取消\r\n const refundUpdateResponse = await supa\r\n .from('ml_refunds')\r\n .update({\r\n status: 4, // 已取消\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('order_id', orderId)\r\n .eq('user_id', userId)\r\n .eq('status', 1) // 只能取消待处理的退款\r\n .execute()\r\n \r\n if (refundUpdateResponse.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4004','取消退款记录失败:', refundUpdateResponse.error)\r\n return { success: false, message: '取消失败: ' + (refundUpdateResponse.error.message ?? '未知错误') }\r\n }\r\n \r\n // 恢复订单状态为已完成(假设之前是已完成状态)\r\n const orderUpdateResponse = await supa\r\n .from('ml_orders')\r\n .update({\r\n order_status: 4, // 已完成\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', orderId)\r\n .execute()\r\n \r\n if (orderUpdateResponse.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4019','恢复订单状态失败:', orderUpdateResponse.error)\r\n // 不影响取消退款结果,只记录错误\r\n }\r\n \r\n return { success: true, message: '已取消退款申请' }\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4025','取消退款异常:', e)\r\n return { success: false, message: '系统异常' }\r\n }\r\n }\r\n\r\n // 再次购买\r\n async rePurchase(order: any): Promise {\r\n try {\r\n // 将 order 转换为 UTSJSONObject 以安全访问属性\r\n const orderObj = JSON.parse(JSON.stringify(order)) as UTSJSONObject\r\n // 尝试获取 ml_order_items 或 items\r\n let itemsKey = 'ml_order_items'\r\n let itemsRaw = orderObj.get(itemsKey)\r\n \r\n if (itemsRaw == null) {\r\n itemsKey = 'items'\r\n itemsRaw = orderObj.get(itemsKey)\r\n }\r\n \r\n if (itemsRaw == null) return false\r\n \r\n // 断言为数组\r\n const items = itemsRaw as any[]\r\n if (items.length === 0) return false\r\n\r\n // 简单的循环添加,实际项目中可以优化为批量插入\r\n for (let i = 0; i < items.length; i++) {\r\n // 同样,item 也是 UTSJSONObject 或支持访问的对象\r\n const item = JSON.parse(JSON.stringify(items[i])) as UTSJSONObject\r\n const productId = item.getString('product_id') \r\n const skuId = item.getString('sku_id')\r\n // 数量可能是数字或字符串\r\n const quantity = item.getNumber('quantity') ?? 1\r\n \r\n if (productId != null) {\r\n await this.addToCart(productId, quantity, skuId ?? '', '')\r\n }\r\n }\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4065','rePurchase error', e)\r\n return false\r\n }\r\n }\r\n\r\n // 申请售后 (Legacy/Simple update)\r\n async applyRefund(orderId: string, reason: string): Promise {\r\n try {\r\n // 更新订单状态为 退款中 (6)\r\n const response = await supa\r\n .from('ml_orders')\r\n .update({\r\n order_status: 6,\r\n cancel_reason: reason,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', orderId)\r\n .execute()\r\n \r\n return response.error === null\r\n } catch (e) {\r\n return false\r\n }\r\n }\r\n\r\n // 获取售后记录列表\r\n async getRefunds(statusList: number[] = [], page: number = 1, pageSize: number = 10): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n let query = supa\r\n .from('ml_refunds')\r\n .select(`\r\n *,\r\n order:ml_orders!inner (\r\n order_no,\r\n created_at,\r\n ml_order_items (\r\n product_id,\r\n product_name,\r\n image_url\r\n )\r\n )\r\n `)\r\n .eq('user_id', userId)\r\n .order('created_at', { ascending: false })\r\n\r\n if (statusList.length > 0) {\r\n // 显式转换为 any[] 以匹配 .in 方法的参数要求\r\n const anyList = statusList as any[]\r\n query = query.in('status', anyList)\r\n }\r\n\r\n query = query.range((page - 1) * pageSize, page * pageSize - 1)\r\n\r\n const response = await query.execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4127','获取售后列表失败:', response.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const data = response.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return data\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4140','获取售后列表异常:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n async deleteRefund(refundId: string): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_refunds')\r\n .delete()\r\n .eq('id', refundId)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4155','删除退款记录失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4161','删除退款记录异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n async getUserBalanceNumber(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n __f__('log','at utils/supabaseService.uts:4169','[Supabase] getUserBalance userId:', userId)\r\n if (userId == null) return 0\r\n \r\n // 优先查 ml_user_wallets\r\n const walletRes = await supa\r\n .from('ml_user_wallets')\r\n .select('balance')\r\n .eq('user_id', userId!)\r\n .single()\r\n .execute()\r\n \r\n if (walletRes.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4181','[Supabase] getUserBalance error:', walletRes.error)\r\n } else {\r\n __f__('log','at utils/supabaseService.uts:4183','[Supabase] getUserBalance data:', walletRes.data)\r\n }\r\n\r\n if (walletRes.error == null && walletRes.data != null) {\r\n let data = walletRes.data\r\n // 如果是数组,取第一项\r\n if (Array.isArray(data)) {\r\n const arr = data as any[]\r\n if (arr.length > 0) {\r\n data = arr[0]\r\n }\r\n }\r\n\r\n let val:number = 0\r\n if (data instanceof UTSJSONObject) {\r\n val = data.getNumber('balance') ?? 0\r\n // 尝试字符串转换,防止精度丢失导致转为string\r\n if (val === 0 && data.getString('balance') != null) {\r\n val = parseFloat(data.getString('balance')!)\r\n }\r\n return val\r\n } else {\r\n // 对于 Map 或 loose object\r\n const jsonObj = JSON.parse(JSON.stringify(data)) as UTSJSONObject\r\n val = jsonObj.getNumber('balance') ?? 0\r\n if (val === 0 && jsonObj.getString('balance') != null) {\r\n val = parseFloat(jsonObj.getString('balance')!)\r\n }\r\n return val\r\n }\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:4215','[Supabase] Wallet table empty, checking profile...')\r\n\r\n // Fallback to profile\r\n const profile = await this.getUserProfile()\r\n if (profile != null) {\r\n if (profile instanceof UTSJSONObject) {\r\n return profile.getNumber('balance') ?? 0\r\n } else {\r\n const pObj = JSON.parse(JSON.stringify(profile)) as UTSJSONObject\r\n return pObj.getNumber('balance') ?? 0\r\n }\r\n }\r\n return 0\r\n } catch(e) {\r\n __f__('error','at utils/supabaseService.uts:4229','[Supabase] getUserBalance exception:', e)\r\n return 0\r\n }\r\n }\r\n \r\n // 获取用户积分\r\n async getUserPoints(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n __f__('log','at utils/supabaseService.uts:4238','[Supabase] getUserPoints userId:', userId)\r\n if (userId == null) return 0\r\n \r\n // 查 ml_user_points\r\n const res = await supa\r\n .from('ml_user_points')\r\n .select('points')\r\n .eq('user_id', userId!)\r\n .single()\r\n .execute()\r\n \r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4250','[Supabase] getUserPoints error:', res.error)\r\n } else {\r\n __f__('log','at utils/supabaseService.uts:4252','[Supabase] getUserPoints data:', res.data)\r\n }\r\n\r\n if (res.error == null && res.data != null) {\r\n let data = res.data\r\n // 如果是数组,取第一项\r\n if (Array.isArray(data)) {\r\n const arr = data as any[]\r\n if (arr.length > 0) {\r\n data = arr[0]\r\n }\r\n }\r\n\r\n if (data instanceof UTSJSONObject) {\r\n return data.getNumber('points') ?? 0\r\n } else {\r\n // 尝试转为 UTSJSONObject\r\n const jsonObj = JSON.parse(JSON.stringify(data)) as UTSJSONObject\r\n const val = jsonObj.getNumber('points')\r\n if (val != null) return val\r\n\r\n return 0\r\n }\r\n }\r\n \r\n // Fallback check profile if needed\r\n const profile = await this.getUserProfile()\r\n if (profile != null) {\r\n if (profile instanceof UTSJSONObject) {\r\n return profile.getNumber('points') ?? 0\r\n } else {\r\n const pObj = JSON.parse(JSON.stringify(profile)) as UTSJSONObject\r\n return pObj.getNumber('points') ?? 0\r\n }\r\n }\r\n \r\n return 0\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4290','[Supabase] getUserPoints exception:', e)\r\n return 0\r\n }\r\n }\r\n\r\n // 获取钱包交易记录\r\n async getTransactions(page: number = 1, limit: number = 20): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const from = (page - 1) * limit\r\n const to = from + limit - 1\r\n\r\n const response = await supa\r\n .from('ml_wallet_transactions')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .range(from, to)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4316','获取交易记录失败:', response.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n const data = response.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4329','获取交易记录异常:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n \r\n // 获取积分记录\r\n async getPointRecords(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n const res = await supa\r\n .from('ml_point_records')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n \r\n if (res.error != null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n const data = res.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n return data as any[]\r\n } catch (e) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 获取用户红包\r\n async getUserRedPackets(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const res = await supa\r\n .from('ml_user_red_packets')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4384','获取红包失败:', res.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n const data = res.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n return data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4395','获取红包异常:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 获取用户银行卡\r\n async getUserBankCards(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const res = await supa\r\n .from('ml_user_bank_cards')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4418','获取银行卡失败:', res.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n const data = res.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n return data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4429','获取银行卡异常:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 余额充值 (调用 RPC)\r\n async rechargeBalance(amount: number): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n \r\n const res = await supa.rpc('recharge_wallet', { \r\n p_user_id: userId,\r\n p_amount: amount \r\n })\r\n \r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4447','充值失败RPC:', res.error)\r\n return false\r\n }\r\n \r\n // 简单判断: 如果没有error且data里success为true\r\n const data = res.data\r\n if (data instanceof UTSJSONObject) {\r\n return data.getBoolean('success') ?? false\r\n }\r\n // 如果返回不是对象,作为失败处理\r\n return false\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4459','充值异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 余额提现 (调用 RPC)\r\n async withdrawBalance(amount: number): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n \r\n const res = await supa.rpc('withdraw_wallet', { \r\n p_user_id: userId,\r\n p_amount: amount \r\n })\r\n \r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4476','提现失败RPC:', res.error)\r\n return false\r\n }\r\n \r\n const data = res.data\r\n if (data instanceof UTSJSONObject) {\r\n return data.getBoolean('success') ?? false\r\n }\r\n return false\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4486','提现异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 添加银行卡\r\n async addBankCard(card: UTSJSONObject): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n \r\n // 补全 user_id\r\n card.set('user_id', userId)\r\n \r\n const res = await supa\r\n .from('ml_user_bank_cards')\r\n .insert(card)\r\n .execute()\r\n \r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4506','添加银行卡失败:', res.error)\r\n return false\r\n }\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4511','添加银行卡异常:', e)\r\n return false\r\n }\r\n }\r\n \r\n // 删除银行卡\r\n async deleteBankCard(cardId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n \r\n const res = await supa\r\n .from('ml_user_bank_cards')\r\n .eq('id', cardId)\r\n .eq('user_id', userId!)\r\n .delete()\r\n .execute()\r\n \r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4530','删除银行卡失败:', res.error)\r\n return false\r\n }\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4535','删除银行卡异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 收藏相关\r\n async checkFavorite(productId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n __f__('log','at utils/supabaseService.uts:4544',`[CheckFav] Checking for User: ${userId}, Product: ${productId}`)\r\n \r\n if (userId == null) return false\r\n \r\n const response = await supa\r\n .from('ml_user_favorites')\r\n .select('*') // Select all to verify data\r\n .eq('user_id', userId!)\r\n .eq('target_id', productId)\r\n .eq('target_type', '1') // 使用字符串 '1'\r\n .limit(1)\r\n .execute()\r\n \r\n // __f__('log','at utils/supabaseService.uts:4557',`[CheckFav] Response: ${JSON.stringify(response)}`)\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4560',`[CheckFav] Error: ${JSON.stringify(response.error)}`)\r\n return false\r\n }\r\n \r\n const data = response.data\r\n if (Array.isArray(data)) {\r\n if ((data as any[]).length > 0) {\r\n // Double check: ensure the returned item actually matches the product ID\r\n // This guards against potential query filter failures\r\n const item = data[0]\r\n let targetId = ''\r\n if (item instanceof UTSJSONObject) {\r\n targetId = item.getString('target_id') ?? ''\r\n } else {\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n targetId = itemObj.getString('target_id') ?? ''\r\n }\r\n \r\n if (targetId != '' && targetId != productId) {\r\n __f__('error','at utils/supabaseService.uts:4579',`[CheckFav] ID Mismatch! Query ${productId}, Got ${targetId}`)\r\n return false\r\n }\r\n \r\n return true\r\n }\r\n } else if (data instanceof UTSJSONObject) {\r\n // Handle single object return case (though limit(1) usually returns array)\r\n let targetId = data.getString('target_id') ?? ''\r\n if (targetId !== '' && targetId !== productId) {\r\n return false\r\n }\r\n return true\r\n }\r\n \r\n return false\r\n } catch(e) {\r\n __f__('error','at utils/supabaseService.uts:4596',`[CheckFav] Exception: ${e}`)\r\n return false\r\n }\r\n }\r\n \r\n async toggleFavorite(productId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n \r\n __f__('log','at utils/supabaseService.uts:4606',`[ToggleFav] Toggling for ${productId}`)\r\n \r\n // Check if exists\r\n const exists = await this.checkFavorite(productId)\r\n __f__('log','at utils/supabaseService.uts:4610',`[ToggleFav] Current status: ${exists}`)\r\n \r\n if (exists) {\r\n const response = await supa\r\n .from('ml_user_favorites')\r\n .eq('user_id', userId!)\r\n .eq('target_id', productId)\r\n .eq('target_type', '1')\r\n .delete()\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4622','取消收藏失败:', response.error)\r\n return true // 仍然是收藏状态\r\n }\r\n return false // 已取消收藏\r\n } else {\r\n const response = await supa\r\n .from('ml_user_favorites')\r\n .insert({\r\n user_id: userId,\r\n target_id: productId,\r\n target_type: '1',\r\n created_at: new Date().toISOString()\r\n })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4638','添加收藏失败:', response.error)\r\n return false // 添加失败,仍未收藏\r\n }\r\n return true // 已收藏\r\n }\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4644','切换收藏状态异常:', e)\r\n // 发生异常时,尝试查询当前状态返回\r\n return await this.checkFavorite(productId)\r\n }\r\n }\r\n \r\n async getFavorites(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n // 第一步:查询收藏列表\r\n const response = await supa\r\n .from('ml_user_favorites')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .eq('target_type', '1')\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n const favorites = response.data as any[]\r\n if (favorites == null || favorites.length === 0) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n // 第二步:收集商品ID\r\n const productIds: string[] = []\r\n for (let i = 0; i < favorites.length; i++) {\r\n let item: any = favorites[i]\r\n let itemObj: UTSJSONObject\r\n if (item instanceof UTSJSONObject) {\r\n itemObj = item as UTSJSONObject\r\n } else {\r\n itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n }\r\n \r\n // target_id 可能是 Integer 或 String 类型,需要安全转换\r\n const targetIdRaw = itemObj.get('target_id')\r\n let pid = ''\r\n if (targetIdRaw != null) {\r\n if (typeof targetIdRaw === 'string') {\r\n pid = targetIdRaw as string\r\n } else if (typeof targetIdRaw === 'number') {\r\n pid = (targetIdRaw as number).toString()\r\n }\r\n }\r\n if (pid !== '') productIds.push(pid)\r\n }\r\n \r\n if (productIds.length === 0) return []\r\n \r\n // 第三步:批量查询商品详情\r\n const anyProductIds = productIds as any[]\r\n const productRes = await supa\r\n .from('ml_products')\r\n .select('id, name, main_image_url, base_price, sale_count')\r\n .in('id', anyProductIds)\r\n .execute()\r\n \r\n if (productRes.error != null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n const products = productRes.data as any[]\r\n const productMap = new Map()\r\n \r\n for (let i = 0; i < products.length; i++) {\r\n // 显式声明类型为 any\r\n let p: any = products[i]\r\n let pid = ''\r\n if (p instanceof UTSJSONObject) {\r\n pid = p.getString('id') ?? ''\r\n } else {\r\n const pObj = JSON.parse(JSON.stringify(p)) as UTSJSONObject\r\n pid = pObj.getString('id') ?? ''\r\n }\r\n if (pid !== '') productMap.set(pid, p)\r\n }\r\n \r\n // 第四步:组合数据\r\n const result: any[] = []\r\n for (let i = 0; i < favorites.length; i++) {\r\n let item: any = favorites[i]\r\n let newItem: UTSJSONObject\r\n \r\n if (item instanceof UTSJSONObject) {\r\n newItem = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n } else {\r\n newItem = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n }\r\n \r\n // target_id 可能是 Integer 或 String 类型,需要安全转换\r\n const targetIdRaw = newItem.get('target_id')\r\n let targetId = ''\r\n if (targetIdRaw != null) {\r\n if (typeof targetIdRaw === 'string') {\r\n targetId = targetIdRaw as string\r\n } else if (typeof targetIdRaw === 'number') {\r\n targetId = (targetIdRaw as number).toString()\r\n }\r\n }\r\n \r\n if (targetId !== '') {\r\n const product = productMap.get(targetId)\r\n if (product != null) {\r\n newItem.set('ml_products', product)\r\n result.push(newItem)\r\n }\r\n }\r\n }\r\n \r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4765','获取收藏列表异常:', e)\r\n return []\r\n }\r\n }\r\n\r\n // 获取足迹列表\r\n async getFootprints(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('log','at utils/supabaseService.uts:4775','[getFootprints] 用户未登录')\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:4780','[getFootprints] 查询足迹, userId:', userId)\r\n\r\n // 1. 获取足迹记录\r\n const response = await supa\r\n .from('ml_user_footprints')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('updated_at', { ascending: false })\r\n .limit(50)\r\n .execute()\r\n\r\n __f__('log','at utils/supabaseService.uts:4791','[getFootprints] 足迹查询 error:', response.error)\r\n __f__('log','at utils/supabaseService.uts:4792','[getFootprints] 足迹查询 data:', JSON.stringify(response.data))\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:4795','[getFootprints] 获取足迹失败:', response.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const footprints = response.data as any[]\r\n if (footprints == null || footprints.length === 0) {\r\n __f__('log','at utils/supabaseService.uts:4802','[getFootprints] 没有足迹记录')\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:4807','[getFootprints] 足迹记录数量:', footprints.length)\r\n\r\n // 2. 收集商品ID\r\n const productIds: string[] = []\r\n for (let i = 0; i < footprints.length; i++) {\r\n let item = footprints[i]\r\n let pid = ''\r\n if (item instanceof UTSJSONObject) {\r\n pid = item.getString('product_id') ?? ''\r\n } else {\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n pid = itemObj.getString('product_id') ?? ''\r\n }\r\n if (pid !== '' && !productIds.includes(pid)) productIds.push(pid)\r\n }\r\n\r\n if (productIds.length === 0) return []\r\n \r\n const productIdsAny: any[] = []\r\n for(let i=0; i()\r\n for(let i=0; i {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('log','at utils/supabaseService.uts:4940','[addFootprint] 用户未登录')\r\n return false\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:4944','[addFootprint] 添加足迹, userId:', userId, 'productId:', productId)\r\n \r\n // 检查是否已存在\r\n const checkRes = await supa\r\n .from('ml_user_footprints')\r\n .select('id')\r\n .eq('user_id', userId!)\r\n .eq('product_id', productId)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:4954','[addFootprint] 检查结果 error:', checkRes.error)\r\n __f__('log','at utils/supabaseService.uts:4955','[addFootprint] 检查结果 data:', JSON.stringify(checkRes.data))\r\n\r\n const checkData = checkRes.data as any[]\r\n const exists = checkData != null && Array.isArray(checkData) && checkData.length > 0\r\n \r\n if (checkRes.error == null && exists) {\r\n __f__('log','at utils/supabaseService.uts:4961','[addFootprint] 足迹已存在,更新时间')\r\n // 更新时间\r\n const updateRes = await supa\r\n .from('ml_user_footprints')\r\n .update({ updated_at: new Date().toISOString() })\r\n .eq('user_id', userId!)\r\n .eq('product_id', productId)\r\n .execute()\r\n __f__('log','at utils/supabaseService.uts:4969','[addFootprint] 更新结果 error:', updateRes.error)\r\n } else {\r\n __f__('log','at utils/supabaseService.uts:4971','[addFootprint] 足迹不存在,插入新记录')\r\n // 插入新记录\r\n const insertPayload = new UTSJSONObject()\r\n insertPayload.set('user_id', userId!)\r\n insertPayload.set('product_id', productId)\r\n insertPayload.set('created_at', new Date().toISOString())\r\n insertPayload.set('updated_at', new Date().toISOString())\r\n \r\n const insertRes = await supa\r\n .from('ml_user_footprints')\r\n .insert(insertPayload)\r\n .execute()\r\n __f__('log','at utils/supabaseService.uts:4983','[addFootprint] 插入结果 error:', insertRes.error)\r\n }\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:4987','[addFootprint] 添加足迹异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 删除单个足迹\r\n async deleteFootprint(productId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('log','at utils/supabaseService.uts:4997','[deleteFootprint] 用户未登录')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_user_footprints')\r\n .eq('user_id', userId)\r\n .eq('product_id', productId)\r\n .delete()\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5009','[deleteFootprint] 删除足迹失败:', response.error)\r\n return false\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:5013','[deleteFootprint] 删除足迹成功')\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5016','[deleteFootprint] 删除足迹异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 批量删除足迹\r\n async deleteFootprints(productIds: string[]): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('log','at utils/supabaseService.uts:5026','[deleteFootprints] 用户未登录')\r\n return false\r\n }\r\n\r\n const idsAny: any[] = []\r\n for (let i = 0; i < productIds.length; i++) {\r\n idsAny.push(productIds[i])\r\n }\r\n\r\n const response = await supa\r\n .from('ml_user_footprints')\r\n .eq('user_id', userId)\r\n .in('product_id', idsAny)\r\n .delete()\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5043','[deleteFootprints] 批量删除足迹失败:', response.error)\r\n return false\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:5047','[deleteFootprints] 批量删除足迹成功')\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5050','[deleteFootprints] 批量删除足迹异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 清空所有足迹\r\n async clearFootprints(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('log','at utils/supabaseService.uts:5060','[clearFootprints] 用户未登录')\r\n return false\r\n }\r\n\r\n const response = await supa\r\n .from('ml_user_footprints')\r\n .eq('user_id', userId)\r\n .delete()\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5071','[clearFootprints] 清空足迹失败:', response.error)\r\n return false\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:5075','[clearFootprints] 清空足迹成功')\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5078','[clearFootprints] 清空足迹异常:', e)\r\n return false\r\n }\r\n }\r\n\r\n async getAddressList(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: UserAddress[] = []\r\n return empty\r\n }\r\n\r\n const response = await supa\r\n .from('ml_user_addresses')\r\n .select('*, recipient_name:receiver_name, phone:receiver_phone, detail_address:address_detail')\r\n .eq('user_id', userId!)\r\n .order('is_default', { ascending: false })\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5100','获取地址列表失败:', response.error)\r\n const empty: UserAddress[] = []\r\n return empty\r\n }\r\n return response.data as UserAddress[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5106','获取地址列表异常:', e)\r\n const empty: UserAddress[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 设置默认地址\r\n async setDefaultAddress(addressId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:5117','用户未登录,无法设置默认地址')\r\n return false\r\n }\r\n\r\n // 先取消所有默认地址\r\n await this.clearDefaultAddress(userId!)\r\n\r\n // 设置新的默认地址\r\n const response = await supa\r\n .from('ml_user_addresses')\r\n .update({\r\n is_default: true,\r\n updated_at: new Date().toISOString()\r\n })\r\n .eq('id', addressId)\r\n .eq('user_id', userId!)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5136','设置默认地址失败:', response.error)\r\n return false\r\n }\r\n\r\n return true\r\n } catch (error) {\r\n __f__('error','at utils/supabaseService.uts:5142','设置默认地址异常:', error)\r\n return false\r\n }\r\n }\r\n\r\n // 获取用户优惠券列表\r\n async getUserCoupons(status: number = 1): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: UserCoupon[] = []\r\n return empty\r\n }\r\n\r\n // 假设有一个视图或者直接关联 ml_user_coupons 和 ml_coupon_templates\r\n // 这里简化处理,尝试直接从 ml_user_coupons 读取,并且加入 template 信息\r\n // 如果没有 view,可能需要改为两个查询或者使用 left join\r\n const response = await supa\r\n .from('ml_user_coupons')\r\n .select('*, template:ml_coupon_templates(name, amount, min_spend)')\r\n .eq('user_id', userId!)\r\n .eq('status', status.toString())\r\n .order('expire_at', { ascending: true })\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5168','获取优惠券失败:', response.error)\r\n const empty: UserCoupon[] = []\r\n return empty\r\n }\r\n\r\n // 安全处理返回数据 - 安卓端可能是 UTSJSONObject 或 UTSArray\r\n const rawData: any[] = []\r\n const respData = response.data\r\n __f__('log','at utils/supabaseService.uts:5176','[getUserCoupons] 原始数据类型:', typeof respData, '是否数组:', Array.isArray(respData))\r\n if (respData != null) {\r\n if (Array.isArray(respData)) {\r\n const arr = respData as any[]\r\n __f__('log','at utils/supabaseService.uts:5180','[getUserCoupons] 数组长度:', arr.length)\r\n for (let i = 0; i < arr.length; i++) {\r\n rawData.push(arr[i])\r\n }\r\n } else if (respData instanceof UTSJSONObject) {\r\n // 单个对象情况,包装成数组\r\n __f__('log','at utils/supabaseService.uts:5186','[getUserCoupons] 单个对象,包装成数组')\r\n rawData.push(respData)\r\n } else {\r\n // 尝试 JSON 转换\r\n try {\r\n const parsed = JSON.parse(JSON.stringify(respData))\r\n __f__('log','at utils/supabaseService.uts:5192','[getUserCoupons] JSON转换后是否数组:', Array.isArray(parsed))\r\n if (Array.isArray(parsed)) {\r\n __f__('log','at utils/supabaseService.uts:5194','[getUserCoupons] 转换后数组长度:', parsed.length)\r\n for (let i = 0; i < parsed.length; i++) {\r\n rawData.push(parsed[i])\r\n }\r\n }\r\n } catch (parseErr) {\r\n __f__('error','at utils/supabaseService.uts:5200','解析优惠券数据异常:', parseErr)\r\n }\r\n }\r\n }\r\n __f__('log','at utils/supabaseService.uts:5204','[getUserCoupons] 最终rawData长度:', rawData.length)\r\n\r\n // 映射数据,将 template 的字段展平\r\n const coupons: UserCoupon[] = []\r\n for (let i = 0; i < rawData.length; i++) {\r\n const item = rawData[i]\r\n let template: any | null = null\r\n let itemId = ''\r\n let itemUserId = ''\r\n let itemTmplId = ''\r\n let itemCode = ''\r\n let itemStatus = 0\r\n let itemRecv = ''\r\n let itemExpire = ''\r\n \r\n if (item instanceof UTSJSONObject) {\r\n template = item.get('template') as any | null\r\n itemId = item.getString('id') ?? ''\r\n itemUserId = item.getString('user_id') ?? ''\r\n itemTmplId = item.getString('template_id') ?? ''\r\n itemCode = item.getString('coupon_code') ?? ''\r\n itemStatus = item.getNumber('status') ?? 0\r\n itemRecv = item.getString('received_at') ?? ''\r\n itemExpire = item.getString('expire_at') ?? ''\r\n } else {\r\n const iObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n template = iObj.get('template') as any | null\r\n itemId = iObj.getString('id') ?? ''\r\n itemUserId = iObj.getString('user_id') ?? ''\r\n itemTmplId = iObj.getString('template_id') ?? ''\r\n itemCode = iObj.getString('coupon_code') ?? ''\r\n itemStatus = iObj.getNumber('status') ?? 0\r\n itemRecv = iObj.getString('received_at') ?? ''\r\n itemExpire = iObj.getString('expire_at') ?? ''\r\n }\r\n \r\n if (template == null) template = new UTSJSONObject()\r\n \r\n let tName = ''\r\n let tAmount = 0\r\n let tMin = 0\r\n \r\n if (template instanceof UTSJSONObject) {\r\n tName = template.getString('name') ?? '优惠券'\r\n tAmount = template.getNumber('amount') ?? 0\r\n tMin = template.getNumber('min_spend') ?? 0\r\n } else {\r\n const tObj = JSON.parse(JSON.stringify(template)) as UTSJSONObject\r\n tName = tObj.getString('name') ?? '优惠券'\r\n tAmount = tObj.getNumber('amount') ?? 0\r\n tMin = tObj.getNumber('min_spend') ?? 0\r\n }\r\n\r\n // 创建真正的 UserCoupon 对象,而不是 UTSJSONObject\r\n const couponItem: UserCoupon = {\r\n id: itemId,\r\n user_id: itemUserId,\r\n template_id: itemTmplId,\r\n coupon_code: itemCode,\r\n status: itemStatus,\r\n received_at: itemRecv,\r\n expire_at: itemExpire,\r\n template_name: tName,\r\n amount: tAmount,\r\n min_spend: tMin\r\n }\r\n \r\n coupons.push(couponItem)\r\n }\r\n\r\n return coupons\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5276','获取优惠券异常:', e)\r\n const empty: UserCoupon[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 获取可用优惠券数量\r\n async getUserCouponCount(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return 0\r\n\r\n const response = await supa\r\n .from('ml_user_coupons')\r\n .select('id', { count: 'exact' })\r\n .eq('user_id', userId!)\r\n .eq('status', '1')\r\n .gt('expire_at', new Date().toISOString())\r\n .limit(1)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n return 0\r\n }\r\n return response.total ?? 0\r\n } catch (e) {\r\n return 0\r\n }\r\n }\r\n\r\n // 获取店铺/商品可用优惠券\r\n async getAvailableCoupons(merchantId: string): Promise {\r\n return this.fetchShopCoupons(merchantId)\r\n }\r\n\r\n // ALIAS for Cache busting: 获取店铺优惠券\r\n async fetchShopCoupons(merchantId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:5314','[fetchShopCoupons] 开始获取优惠券,merchantId:', merchantId)\r\n // 查询该商家的优惠券 + 平台通用券 (merchant_id is null)\r\n // 注意:这里简化逻辑,实际可能需要联合查询用户是否已领取\r\n const response = await supa\r\n .from('ml_coupon_templates')\r\n .select('*')\r\n .or(`merchant_id.eq.${merchantId},merchant_id.is.null`)\r\n .eq('status', '1') // 使用字符串 '1'\r\n .gt('end_time', new Date().toISOString())\r\n .order('discount_value', { ascending: false })\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5327','Fetch coupons failed:', response.error)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n \r\n const data = response.data\r\n if (data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n __f__('log','at utils/supabaseService.uts:5337','[fetchShopCoupons] 获取到优惠券数量:', (data as any[]).length)\r\n return data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5340','Fetch coupons error:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 领取优惠券\r\n async claimCoupon(templateId: string, userId: string): Promise {\r\n return this.claimShopCoupon(templateId, userId)\r\n }\r\n\r\n // ALIAS for Cache busting\r\n async claimShopCoupon(templateId: string, userId: string): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:5354','Claiming coupon templateId:', templateId, 'userId:', userId)\r\n\r\n // 1. Fetch template details to get merchant_id and validity\r\n const tmplRes = await supa\r\n .from('ml_coupon_templates')\r\n .select('*')\r\n .eq('id', templateId)\r\n .limit(1)\r\n .execute()\r\n \r\n if (tmplRes.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5365','Claim Coupon: Template query error', tmplRes.error)\r\n return false\r\n }\r\n\r\n // Null check for data\r\n if (tmplRes.data == null) {\r\n __f__('error','at utils/supabaseService.uts:5371','Claim Coupon: Template data response is null')\r\n return false\r\n }\r\n \r\n const dataList = tmplRes.data as any[]\r\n if (dataList.length === 0) {\r\n __f__('error','at utils/supabaseService.uts:5377','Claim Coupon: Template not found (empty list)')\r\n return false\r\n }\r\n\r\n const template = dataList[0]\r\n \r\n // Safe property access\r\n let validDays = 0\r\n let endTimeStr: string | null = null\r\n let merchantId: string | null = null\r\n \r\n if (template instanceof UTSJSONObject) {\r\n validDays = template.getNumber('valid_days') ?? 0\r\n endTimeStr = template.getString('end_time')\r\n merchantId = template.getString('merchant_id')\r\n } else {\r\n const tJson = JSON.parse(JSON.stringify(template)) as UTSJSONObject\r\n validDays = tJson.getNumber('valid_days') ?? 0\r\n endTimeStr = tJson.getString('end_time')\r\n merchantId = tJson.getString('merchant_id')\r\n }\r\n \r\n // Calculate expire_at\r\n let expireAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()\r\n if (validDays > 0) {\r\n expireAt = new Date(Date.now() + (validDays * 24 * 60 * 60 * 1000)).toISOString()\r\n } else if (endTimeStr != null && endTimeStr !== '') {\r\n expireAt = endTimeStr\r\n }\r\n \r\n // Handle UUID fields: Empty string is not valid UUID, must be null\r\n if (merchantId != null && merchantId.length === 0) {\r\n merchantId = null\r\n }\r\n\r\n // 2. Insert into user coupons with merchant_id\r\n const insertData = {\r\n user_id: userId,\r\n template_id: templateId,\r\n merchant_id: merchantId, // Important for shop filtering: null for platform coupons\r\n coupon_code: 'C' + Date.now() + Math.floor(Math.random() * 1000), \r\n status: 1, \r\n expire_at: expireAt,\r\n received_at: new Date().toISOString()\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:5423','Claim Coupon Insert Payload:', JSON.stringify(insertData))\r\n\r\n const response = await supa\r\n .from('ml_user_coupons')\r\n .insert(insertData)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5431','Claim Coupon: Insert failed:', JSON.stringify(response.error))\r\n // 尝试降级:如果 merchant_id 报错,尝试不带 merchant_id (仅调试用,或兼容旧表结构)\r\n if (JSON.stringify(response.error).includes('merchant_id')) {\r\n __f__('log','at utils/supabaseService.uts:5434','Retrying without merchant_id...')\r\n const fallbackData = {\r\n user_id: userId,\r\n template_id: templateId,\r\n coupon_code: 'C' + Date.now() + Math.random().toString().substring(2,6),\r\n status: 1,\r\n expire_at: expireAt,\r\n received_at: new Date().toISOString()\r\n }\r\n const res2 = await supa.from('ml_user_coupons').insert(fallbackData).execute()\r\n if (res2.error == null) return true\r\n }\r\n return false\r\n }\r\n return true\r\n } catch(e) {\r\n __f__('error','at utils/supabaseService.uts:5450','Claim coupon error:', e)\r\n return false\r\n }\r\n }\r\n\r\n // ==========================================\r\n // 聊天相关方法\r\n // ==========================================\r\n\r\n // 发送消息\r\n async sendMessage(merchantId: string, content: string, msgType: string = 'text'): Promise {\r\n // 确保 session 有效\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n __f__('error','at utils/supabaseService.uts:5464',\"sendMessage failed: user not logged in or session lost\")\r\n return false\r\n }\r\n\r\n try {\r\n // Debug check\r\n // const session = supa.getSession()\r\n // __f__('log','at utils/supabaseService.uts:5471',\"Sending check: UserID\", userId, \"AuthID:\", session.user?.getString('id'))\r\n \r\n const msg = {\r\n sender_id: userId!,\r\n receiver_id: merchantId,\r\n content: content,\r\n msg_type: msgType,\r\n is_read: false,\r\n is_from_user: true\r\n }\r\n \r\n const response = await supa\r\n .from('ml_chat_messages')\r\n .insert(msg)\r\n .execute()\r\n \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5488','sendMessage error:', response.error)\r\n return false\r\n }\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5493','sendMessage exception:', e)\r\n return false\r\n }\r\n }\r\n \r\n // 标记会话已读\r\n async markRead(merchantId: string): Promise {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n try {\r\n const response = await supa\r\n .from('ml_chat_messages')\r\n .update({ is_read: true })\r\n .eq('sender_id', merchantId)\r\n .eq('receiver_id', userId)\r\n .eq('is_read', false)\r\n .execute() \r\n\r\n if (response.error != null) return false\r\n } catch (e) { return false }\r\n return true\r\n }\r\n\r\n // 提交商品评价\r\n async submitProductReviews(reviews: Array): Promise {\r\n try {\r\n for (let i: number = 0; i < reviews.length; i++) {\r\n const review = reviews[i]\r\n const response = await supa\r\n .from('ml_product_reviews')\r\n .insert(review)\r\n .execute() \r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:5526','提交商品评价失败:', response.error)\r\n return false\r\n }\r\n }\r\n return true\r\n } catch (e) { \r\n __f__('error','at utils/supabaseService.uts:5532','提交商品评价失败:', e)\r\n return false \r\n }\r\n }\r\n\r\n // 提交店铺评价\r\n async submitShopReview(review: UTSJSONObject): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_shop_reviews')\r\n .insert(review)\r\n .execute() \r\n return response.error == null\r\n } catch (e) { \r\n __f__('error','at utils/supabaseService.uts:5546','提交店铺评价失败:', e)\r\n return false \r\n }\r\n }\r\n\r\n // 更新订单状态\r\n async updateOrderStatus(orderId: string, status: number): Promise {\r\n try {\r\n const updateData = new UTSJSONObject()\r\n updateData.set('order_status', status)\r\n const response = await supa\r\n .from('ml_orders')\r\n .update(updateData) \r\n .eq('id', orderId)\r\n .execute() \r\n return response.error == null\r\n } catch (e) { \r\n __f__('error','at utils/supabaseService.uts:5563','更新订单状态失败:', e)\r\n return false \r\n }\r\n }\r\n\r\n // ==================== 智能推荐相关API ====================\r\n\r\n // 获取热搜词(全站搜索频率最高的关键词)\r\n async getHotKeywords(limit: number = 10): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_search_history')\r\n .select('keyword')\r\n .order('created_at', { ascending: false })\r\n .limit(100)\r\n .execute()\r\n \r\n if (response.error != null || response.data == null) {\r\n return [] as string[]\r\n }\r\n \r\n // 统计关键词频率\r\n const keywordCount = new Map()\r\n const rawList = response.data as any[]\r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const keyword = safeGetString(itemObj, 'keyword').toLowerCase().trim()\r\n if (keyword.length > 0) {\r\n const count = keywordCount.get(keyword) ?? 0\r\n keywordCount.set(keyword, count + 1)\r\n }\r\n }\r\n \r\n // 按频率排序并返回前N个 - UTS兼容方式\r\n // 将Map转换为数组进行排序\r\n type KeywordEntry = {\r\n keyword: string\r\n count: number\r\n }\r\n const entryArray: KeywordEntry[] = []\r\n \r\n // 使用forEach遍历Map(UTS支持)\r\n keywordCount.forEach((value: number, key: string) => {\r\n entryArray.push({\r\n keyword: key,\r\n count: value\r\n })\r\n })\r\n \r\n // 按count降序排序\r\n entryArray.sort((a: KeywordEntry, b: KeywordEntry): number => {\r\n return b.count - a.count\r\n })\r\n \r\n // 取前limit个并提取关键词\r\n const sortedKeywords: string[] = []\r\n const maxCount = Math.min(entryArray.length, limit)\r\n for (let i = 0; i < maxCount; i++) {\r\n sortedKeywords.push(entryArray[i].keyword)\r\n }\r\n \r\n return sortedKeywords\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5627','获取热搜词失败:', e)\r\n return [] as string[]\r\n }\r\n }\r\n\r\n // 获取用户搜索历史\r\n async getUserSearchHistory(limit: number = 10): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return [] as string[]\r\n }\r\n \r\n const response = await supa\r\n .from('ml_search_history')\r\n .select('keyword')\r\n .order('created_at', { ascending: false })\r\n .limit(limit * 2)\r\n .execute()\r\n \r\n if (response.error != null || response.data == null) {\r\n return [] as string[]\r\n }\r\n \r\n const keywords: string[] = []\r\n const rawList = response.data as any[]\r\n const seen = new Set()\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n const rawUserId = itemObj.get('user_id')\r\n const itemUserId = (typeof rawUserId == 'string') ? (rawUserId as string) : ''\r\n \r\n // 只获取当前用户的搜索历史\r\n if (itemUserId !== userId) continue\r\n \r\n const keyword = safeGetString(itemObj, 'keyword').trim()\r\n if (keyword.length > 0 && !seen.has(keyword)) {\r\n keywords.push(keyword)\r\n seen.add(keyword)\r\n if (keywords.length >= limit) break\r\n }\r\n }\r\n \r\n return keywords\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5674','获取用户搜索历史失败:', e)\r\n return [] as string[]\r\n }\r\n }\r\n\r\n // 获取用户浏览历史中的商品分类\r\n async getUserBrowseCategories(limit: number = 5): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return [] as string[]\r\n }\r\n \r\n const response = await supa\r\n .from('ml_browse_history')\r\n .select('product_id')\r\n .order('created_at', { ascending: false })\r\n .limit(20)\r\n .execute()\r\n \r\n if (response.error != null || response.data == null) {\r\n return [] as string[]\r\n }\r\n \r\n // 获取浏览过的商品ID\r\n const productIds: string[] = []\r\n const rawList = response.data as any[]\r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 user_id\r\n const rawUserId = itemObj.get('user_id')\r\n const itemUserId = (typeof rawUserId == 'string') ? (rawUserId as string) : ''\r\n if (itemUserId !== userId) continue\r\n \r\n const productId = safeGetString(itemObj, 'product_id')\r\n if (productId.length > 0) {\r\n productIds.push(productId)\r\n }\r\n }\r\n \r\n if (productIds.length === 0) {\r\n return [] as string[]\r\n }\r\n \r\n // 查询这些商品的分类\r\n const prodResponse = await supa\r\n .from('ml_products')\r\n .select('category_id')\r\n .limit(50)\r\n .execute()\r\n \r\n if (prodResponse.error != null || prodResponse.data == null) {\r\n return [] as string[]\r\n }\r\n \r\n const categoryIds: string[] = []\r\n const prodList = prodResponse.data as any[]\r\n for (let i = 0; i < prodList.length; i++) {\r\n const prodItem = prodList[i]\r\n const prodObj = JSON.parse(JSON.stringify(prodItem)) as UTSJSONObject\r\n const prodId = safeGetString(prodObj, 'id')\r\n \r\n // 只统计浏览过的商品\r\n let found = false\r\n for (let j = 0; j < productIds.length; j++) {\r\n if (productIds[j] == prodId) {\r\n found = true\r\n break\r\n }\r\n }\r\n if (!found) continue\r\n \r\n const catId = safeGetString(prodObj, 'category_id')\r\n if (catId.length > 0 && categoryIds.indexOf(catId) < 0) {\r\n categoryIds.push(catId)\r\n if (categoryIds.length >= limit) break\r\n }\r\n }\r\n \r\n return categoryIds\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5757','获取用户浏览分类失败:', e)\r\n return [] as string[]\r\n }\r\n }\r\n\r\n // 智能推荐:综合用户搜索历史、浏览历史、热销商品\r\n async getSmartRecommendations(limit: number = 10): Promise {\r\n try {\r\n __f__('log','at utils/supabaseService.uts:5765','[getSmartRecommendations] 开始获取智能推荐...')\r\n \r\n const products: Product[] = []\r\n const addedIds = new Set()\r\n \r\n // 1. 根据用户搜索历史推荐商品(权重最高)\r\n const searchHistory = await this.getUserSearchHistory(5)\r\n __f__('log','at utils/supabaseService.uts:5772','[getSmartRecommendations] 用户搜索历史:', searchHistory)\r\n \r\n if (searchHistory.length > 0) {\r\n // 根据搜索关键词查找商品\r\n const keywordProducts = await this.searchProductsByKeywords(searchHistory, limit)\r\n for (let i = 0; i < keywordProducts.length; i++) {\r\n const prod = keywordProducts[i]\r\n if (!addedIds.has(prod.id)) {\r\n products.push(prod)\r\n addedIds.add(prod.id)\r\n }\r\n }\r\n }\r\n \r\n // 2. 根据用户浏览历史推荐相似分类商品\r\n if (products.length < limit) {\r\n const browseCategories = await this.getUserBrowseCategories(3)\r\n __f__('log','at utils/supabaseService.uts:5789','[getSmartRecommendations] 用户浏览分类:', browseCategories)\r\n \r\n if (browseCategories.length > 0) {\r\n const categoryProducts = await this.getProductsByCategories(browseCategories, limit - products.length)\r\n for (let i = 0; i < categoryProducts.length; i++) {\r\n const prod = categoryProducts[i]\r\n if (!addedIds.has(prod.id)) {\r\n products.push(prod)\r\n addedIds.add(prod.id)\r\n }\r\n }\r\n }\r\n }\r\n \r\n // 3. 补充热销商品\r\n if (products.length < limit) {\r\n const hotProducts = await this.getHotProducts(limit - products.length + 5)\r\n for (let i = 0; i < hotProducts.length; i++) {\r\n const prod = hotProducts[i]\r\n if (!addedIds.has(prod.id)) {\r\n products.push(prod)\r\n addedIds.add(prod.id)\r\n if (products.length >= limit) break\r\n }\r\n }\r\n }\r\n \r\n // 4. 如果还不够,用普通商品补充\r\n if (products.length < limit) {\r\n const moreProducts = await this.getProductsByPrice(limit - products.length + 5, false)\r\n for (let i = 0; i < moreProducts.length; i++) {\r\n const prod = moreProducts[i]\r\n if (!addedIds.has(prod.id)) {\r\n products.push(prod)\r\n addedIds.add(prod.id)\r\n if (products.length >= limit) break\r\n }\r\n }\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:5829','[getSmartRecommendations] 返回商品数量:', products.length)\r\n return products.slice(0, limit)\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5832','获取智能推荐失败:', e)\r\n return [] as Product[]\r\n }\r\n }\r\n\r\n // 根据关键词列表搜索商品\r\n async searchProductsByKeywords(keywords: string[], limit: number): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .order('sale_count', { ascending: false })\r\n .limit(limit * 2)\r\n .execute()\r\n \r\n if (response.error != null || response.data == null) {\r\n return [] as Product[]\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = response.data as any[]\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 status\r\n const rawStatus = prodObj.get('status')\r\n let statusNum: number = 0\r\n if (typeof rawStatus == 'number') {\r\n statusNum = rawStatus as number\r\n }\r\n if (statusNum !== 1) continue\r\n \r\n // 检查是否匹配任何关键词\r\n const name = safeGetString(prodObj, 'name').toLowerCase()\r\n const desc = safeGetString(prodObj, 'description').toLowerCase()\r\n \r\n let matched = false\r\n for (let j = 0; j < keywords.length; j++) {\r\n const keyword = keywords[j].toLowerCase()\r\n if (name.indexOf(keyword) >= 0 || desc.indexOf(keyword) >= 0) {\r\n matched = true\r\n break\r\n }\r\n }\r\n \r\n if (!matched) continue\r\n \r\n products.push(parseProductFromRaw(item))\r\n if (products.length >= limit) break\r\n }\r\n \r\n return products\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5887','根据关键词搜索商品失败:', e)\r\n return [] as Product[]\r\n }\r\n }\r\n\r\n // 根据分类列表获取商品\r\n async getProductsByCategories(categoryIds: string[], limit: number): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_products_detail_view')\r\n .select('id, name, description, base_price, market_price, main_image_url, image_urls, category_id, brand_id, merchant_id, total_stock, sale_count, status, is_featured, is_new, is_hot')\r\n .order('sale_count', { ascending: false })\r\n .limit(limit * 2)\r\n .execute()\r\n \r\n if (response.error != null || response.data == null) {\r\n return [] as Product[]\r\n }\r\n \r\n const products: Product[] = []\r\n const rawList = response.data as any[]\r\n \r\n for (let i = 0; i < rawList.length; i++) {\r\n const item = rawList[i]\r\n const prodObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject\r\n \r\n // 手动过滤 status\r\n const rawStatus = prodObj.get('status')\r\n let statusNum: number = 0\r\n if (typeof rawStatus == 'number') {\r\n statusNum = rawStatus as number\r\n }\r\n if (statusNum !== 1) continue\r\n \r\n // 手动过滤 category_id\r\n const rawCatId = prodObj.get('category_id')\r\n const itemCatId = (typeof rawCatId == 'string') ? (rawCatId as string) : ''\r\n \r\n let matched = false\r\n for (let j = 0; j < categoryIds.length; j++) {\r\n if (itemCatId == categoryIds[j]) {\r\n matched = true\r\n break\r\n }\r\n }\r\n \r\n if (!matched) continue\r\n \r\n products.push(parseProductFromRaw(item))\r\n if (products.length >= limit) break\r\n }\r\n \r\n return products\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5941','根据分类获取商品失败:', e)\r\n return [] as Product[]\r\n }\r\n }\r\n\r\n // 记录用户搜索行为\r\n async recordSearch(keyword: string, resultCount: number): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n const searchRecord = new UTSJSONObject()\r\n searchRecord.set('keyword', keyword)\r\n searchRecord.set('result_count', resultCount)\r\n if (userId != null) {\r\n searchRecord.set('user_id', userId)\r\n }\r\n \r\n await supa\r\n .from('ml_search_history')\r\n .insert(searchRecord)\r\n .execute()\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5962','记录搜索失败:', e)\r\n }\r\n }\r\n\r\n // 记录用户浏览行为\r\n async recordBrowse(productId: string, duration: number = 0): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return\r\n \r\n const browseRecord = new UTSJSONObject()\r\n browseRecord.set('user_id', userId)\r\n browseRecord.set('product_id', productId)\r\n browseRecord.set('browse_duration', duration)\r\n browseRecord.set('created_at', new Date().toISOString())\r\n \r\n // UTS Android不支持upsert,使用insert\r\n await supa\r\n .from('ml_browse_history')\r\n .insert(browseRecord)\r\n .execute()\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:5984','记录浏览失败:', e)\r\n }\r\n }\r\n\r\n // ==================== 签到相关API ====================\r\n\r\n // 用户签到\r\n async signin(): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('success', false)\r\n result.set('points', 0)\r\n result.set('continuous_days', 0)\r\n result.set('bonus_points', 0)\r\n result.set('total_points', 0)\r\n result.set('message', '')\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n result.set('message', '请先登录')\r\n return result\r\n }\r\n\r\n const today = new Date()\r\n const todayStr = today.toISOString().split('T')[0]\r\n const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000)\r\n const yesterdayStr = yesterday.toISOString().split('T')[0]\r\n\r\n // 检查今天是否已签到\r\n const checkRes = await supa\r\n .from('ml_signin_records')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .eq('signin_date', todayStr)\r\n .execute()\r\n\r\n if (checkRes.error != null) {\r\n result.set('message', '查询签到状态失败')\r\n return result\r\n }\r\n\r\n const checkData = checkRes.data as any[]\r\n if (checkData != null && checkData.length > 0) {\r\n result.set('message', '今天已签到')\r\n return result\r\n }\r\n\r\n // 查询昨天是否签到,计算连续天数\r\n const yesterdayRes = await supa\r\n .from('ml_signin_records')\r\n .select('continuous_days')\r\n .eq('user_id', userId!)\r\n .eq('signin_date', yesterdayStr)\r\n .execute()\r\n\r\n let continuousDays = 1\r\n if (yesterdayRes.error == null && yesterdayRes.data != null) {\r\n const yData = yesterdayRes.data as any[]\r\n if (yData.length > 0) {\r\n const yItem = yData[0]\r\n let yDays = 0\r\n if (yItem instanceof UTSJSONObject) {\r\n yDays = yItem.getNumber('continuous_days') ?? 0\r\n } else {\r\n const yObj = JSON.parse(JSON.stringify(yItem)) as UTSJSONObject\r\n yDays = yObj.getNumber('continuous_days') ?? 0\r\n }\r\n continuousDays = yDays + 1\r\n }\r\n }\r\n\r\n // 计算积分\r\n let pointsEarned = 5 // 每日签到基础积分\r\n let bonusPoints = 0\r\n\r\n if (continuousDays >= 30) {\r\n bonusPoints = 100\r\n } else if (continuousDays >= 7) {\r\n bonusPoints = 20\r\n }\r\n\r\n const totalPointsEarned = pointsEarned + bonusPoints\r\n\r\n // 插入签到记录\r\n const signinRecord = new UTSJSONObject()\r\n signinRecord.set('user_id', userId!)\r\n signinRecord.set('signin_date', todayStr)\r\n signinRecord.set('points_earned', pointsEarned)\r\n signinRecord.set('bonus_points', bonusPoints)\r\n signinRecord.set('continuous_days', continuousDays)\r\n\r\n const insertRes = await supa\r\n .from('ml_signin_records')\r\n .insert(signinRecord)\r\n .execute()\r\n\r\n if (insertRes.error != null) {\r\n result.set('message', '签到失败')\r\n return result\r\n }\r\n\r\n // 更新用户积分\r\n await this.addPoints(userId!, totalPointsEarned, 'signin', '每日签到')\r\n\r\n // 获取最新积分\r\n const newPoints = await this.getUserPoints()\r\n\r\n result.set('success', true)\r\n result.set('points', pointsEarned)\r\n result.set('continuous_days', continuousDays)\r\n result.set('bonus_points', bonusPoints)\r\n result.set('total_points', newPoints)\r\n result.set('message', '签到成功')\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6100','签到异常:', e)\r\n result.set('message', '签到异常')\r\n return result\r\n }\r\n }\r\n\r\n // 获取签到记录(当月)\r\n async getSigninRecords(year: number, month: number): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const startDate = `${year}-${month.toString().padStart(2, '0')}-01`\r\n const endDate = month === 12 \r\n ? `${year + 1}-01-01` \r\n : `${year}-${(month + 1).toString().padStart(2, '0')}-01`\r\n\r\n const response = await supa\r\n .from('ml_signin_records')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .gte('signin_date', startDate)\r\n .lt('signin_date', endDate)\r\n .order('signin_date', { ascending: true })\r\n .execute()\r\n\r\n if (response.error != null || response.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return response.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6136','获取签到记录失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 获取今日签到状态\r\n async getTodaySigninStatus(): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('signed', false)\r\n result.set('continuous_days', 0)\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return result\r\n\r\n const today = new Date().toISOString().split('T')[0]\r\n\r\n // 检查今天是否签到\r\n const todayRes = await supa\r\n .from('ml_signin_records')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .eq('signin_date', today)\r\n .execute()\r\n\r\n if (todayRes.error == null && todayRes.data != null) {\r\n const tData = todayRes.data as any[]\r\n if (tData.length > 0) {\r\n const tItem = tData[0]\r\n let cDays = 0\r\n if (tItem instanceof UTSJSONObject) {\r\n cDays = tItem.getNumber('continuous_days') ?? 0\r\n } else {\r\n const tObj = JSON.parse(JSON.stringify(tItem)) as UTSJSONObject\r\n cDays = tObj.getNumber('continuous_days') ?? 0\r\n }\r\n result.set('signed', true)\r\n result.set('continuous_days', cDays)\r\n return result\r\n }\r\n }\r\n\r\n // 今天未签到,获取最近的连续签到天数\r\n const lastRes = await supa\r\n .from('ml_signin_records')\r\n .select('continuous_days, signin_date')\r\n .eq('user_id', userId!)\r\n .order('signin_date', { ascending: false })\r\n .limit(1)\r\n .execute()\r\n\r\n if (lastRes.error == null && lastRes.data != null) {\r\n const lData = lastRes.data as any[]\r\n if (lData.length > 0) {\r\n const lItem = lData[0]\r\n let lastDate = ''\r\n let lastDays = 0\r\n if (lItem instanceof UTSJSONObject) {\r\n lastDate = lItem.getString('signin_date') ?? ''\r\n lastDays = lItem.getNumber('continuous_days') ?? 0\r\n } else {\r\n const lObj = JSON.parse(JSON.stringify(lItem)) as UTSJSONObject\r\n lastDate = lObj.getString('signin_date') ?? ''\r\n lastDays = lObj.getNumber('continuous_days') ?? 0\r\n }\r\n\r\n const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split('T')[0]\r\n if (lastDate === yesterday) {\r\n result.set('continuous_days', lastDays)\r\n }\r\n }\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6212','获取签到状态失败:', e)\r\n return result\r\n }\r\n }\r\n\r\n // ==================== 积分兑换相关API ====================\r\n\r\n // 获取积分兑换商品列表\r\n async getPointProducts(): Promise {\r\n try {\r\n const response = await supa\r\n .from('ml_point_products')\r\n .select('*')\r\n .eq('status', 1)\r\n .gt('stock', 0)\r\n .order('sort_order', { ascending: true })\r\n .execute()\r\n\r\n if (response.error != null || response.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return response.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6237','获取积分商品失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 积分兑换\r\n async exchangeProduct(productId: string, quantity: number, addressSnapshot: UTSJSONObject | null): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('success', false)\r\n result.set('message', '')\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n result.set('message', '请先登录')\r\n return result\r\n }\r\n\r\n // 获取商品信息\r\n const productRes = await supa\r\n .from('ml_point_products')\r\n .select('*')\r\n .eq('id', productId)\r\n .single()\r\n .execute()\r\n\r\n if (productRes.error != null || productRes.data == null) {\r\n result.set('message', '商品不存在')\r\n return result\r\n }\r\n\r\n const productRaw = productRes.data\r\n let pointsRequired = 0\r\n let stock = 0\r\n let productType = ''\r\n \r\n // 检查是否是数组,如果是则取第一个元素\r\n let productObj: UTSJSONObject | null = null\r\n if (Array.isArray(productRaw)) {\r\n const arr = productRaw as any[]\r\n if (arr.length > 0) {\r\n const firstItem = arr[0]\r\n if (firstItem instanceof UTSJSONObject) {\r\n productObj = firstItem\r\n } else {\r\n productObj = JSON.parse(JSON.stringify(firstItem)) as UTSJSONObject\r\n }\r\n }\r\n } else {\r\n if (productRaw instanceof UTSJSONObject) {\r\n productObj = productRaw\r\n } else {\r\n productObj = JSON.parse(JSON.stringify(productRaw)) as UTSJSONObject\r\n }\r\n }\r\n \r\n // 使用 UTSJSONObject 方法访问属性\r\n if (productObj != null) {\r\n pointsRequired = productObj.getNumber('points_required') ?? 0\r\n stock = productObj.getNumber('stock') ?? 0\r\n productType = productObj.getString('product_type') ?? ''\r\n }\r\n\r\n const totalPoints = pointsRequired * quantity\r\n\r\n // 检查库存\r\n if (stock < quantity) {\r\n result.set('message', '库存不足')\r\n return result\r\n }\r\n\r\n // 检查积分\r\n const userPoints = await this.getUserPoints()\r\n if (userPoints < totalPoints) {\r\n result.set('message', '积分不足')\r\n return result\r\n }\r\n\r\n // 创建兑换记录\r\n const exchangeRecord = new UTSJSONObject()\r\n exchangeRecord.set('user_id', userId!)\r\n exchangeRecord.set('product_id', productId)\r\n exchangeRecord.set('quantity', quantity)\r\n exchangeRecord.set('points_used', totalPoints)\r\n exchangeRecord.set('status', 0)\r\n if (addressSnapshot != null && productType === 'physical') {\r\n exchangeRecord.set('address_snapshot', JSON.stringify(addressSnapshot))\r\n }\r\n\r\n const insertRes = await supa\r\n .from('ml_point_exchanges')\r\n .insert(exchangeRecord)\r\n .execute()\r\n\r\n if (insertRes.error != null) {\r\n __f__('error','at utils/supabaseService.uts:6333','[exchangeProduct] 创建兑换记录失败:', insertRes.error)\r\n result.set('message', '兑换失败')\r\n return result\r\n }\r\n \r\n __f__('log','at utils/supabaseService.uts:6338','[exchangeProduct] 兑换记录创建成功')\r\n\r\n // 扣减库存\r\n __f__('log','at utils/supabaseService.uts:6341','[exchangeProduct] 准备扣减库存')\r\n __f__('log','at utils/supabaseService.uts:6342','[exchangeProduct] productId 类型:', typeof productId)\r\n __f__('log','at utils/supabaseService.uts:6343','[exchangeProduct] productId 值:', productId)\r\n __f__('log','at utils/supabaseService.uts:6344','[exchangeProduct] 当前库存:', stock, ', 扣减数量:', quantity)\r\n \r\n // 使用 UTSJSONObject 替代 Record\r\n const stockUpdateData = new UTSJSONObject()\r\n stockUpdateData.set('stock', stock - quantity)\r\n \r\n __f__('log','at utils/supabaseService.uts:6350','[exchangeProduct] stockUpdateData:', stockUpdateData)\r\n __f__('log','at utils/supabaseService.uts:6351','[exchangeProduct] stockUpdateData 类型:', typeof stockUpdateData)\r\n \r\n // 先查询确认商品存在\r\n const checkProduct = await supa\r\n .from('ml_point_products')\r\n .select('id, stock')\r\n .eq('id', productId)\r\n .execute()\r\n __f__('log','at utils/supabaseService.uts:6359','[exchangeProduct] 查询商品结果:', checkProduct.data, 'error:', checkProduct.error)\r\n \r\n const stockUpdateRes = await supa\r\n .from('ml_point_products')\r\n .update(stockUpdateData)\r\n .eq('id', productId)\r\n .execute()\r\n \r\n __f__('log','at utils/supabaseService.uts:6367','[exchangeProduct] 库存更新结果 error:', stockUpdateRes.error)\r\n __f__('log','at utils/supabaseService.uts:6368','[exchangeProduct] 库存更新结果 data:', stockUpdateRes.data)\r\n \r\n if (stockUpdateRes.error != null) {\r\n __f__('error','at utils/supabaseService.uts:6371','[exchangeProduct] 扣减库存失败:', stockUpdateRes.error)\r\n }\r\n\r\n // 扣减积分\r\n __f__('log','at utils/supabaseService.uts:6375','[exchangeProduct] 准备扣减积分, userId:', userId, ', 积分:', totalPoints)\r\n const deductResult = await this.deductPoints(userId!, totalPoints, 'redeem', '积分兑换商品')\r\n __f__('log','at utils/supabaseService.uts:6377','[exchangeProduct] 积分扣减结果:', deductResult)\r\n \r\n if (!deductResult) {\r\n __f__('error','at utils/supabaseService.uts:6380','[exchangeProduct] 扣减积分失败')\r\n }\r\n\r\n __f__('log','at utils/supabaseService.uts:6383','[exchangeProduct] 兑换流程完成')\r\n result.set('success', true)\r\n result.set('message', '兑换成功')\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6388','积分兑换异常:', e)\r\n result.set('message', '兑换异常')\r\n return result\r\n }\r\n }\r\n\r\n // 获取兑换记录\r\n async getExchangeRecords(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const response = await supa\r\n .from('ml_point_exchanges')\r\n .select('*, product:ml_point_products(name, image_url, product_type)')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (response.error != null || response.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return response.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6417','获取兑换记录失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // ==================== 评价相关API ====================\r\n\r\n // 获取商品评价列表\r\n async getProductReviews(productId: string, page: number = 1, limit: number = 10, rating: number = 0, hasImage: boolean = false): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('total', 0)\r\n result.set('page', page)\r\n result.set('limit', limit)\r\n result.set('data', [] as any[])\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n \r\n let query = supa\r\n .from('ml_product_reviews')\r\n .select('*, user:auth.users!ml_product_reviews_user_id_fkey(raw_user_meta_data)', { count: 'exact' })\r\n .eq('product_id', productId)\r\n\r\n if (rating > 0) {\r\n query = query.eq('rating', rating)\r\n }\r\n\r\n if (hasImage) {\r\n query = query.neq('images', '[]')\r\n }\r\n\r\n const offset = (page - 1) * limit\r\n const response = await query\r\n .order('created_at', { ascending: false })\r\n .range(offset, offset + limit - 1)\r\n .execute()\r\n\r\n if (response.error != null) {\r\n __f__('error','at utils/supabaseService.uts:6456','获取评价列表失败:', response.error)\r\n return result\r\n }\r\n\r\n const total = response.total ?? 0\r\n const reviews = response.data as any[]\r\n\r\n // 处理评价数据\r\n const processedReviews: any[] = []\r\n for (let i = 0; i < reviews.length; i++) {\r\n const review = reviews[i]\r\n const processed = JSON.parse(JSON.stringify(review)) as UTSJSONObject\r\n\r\n // 处理用户信息\r\n const userRaw = processed.get('user')\r\n let userName = '匿名用户'\r\n let userAvatar = ''\r\n\r\n if (userRaw != null) {\r\n let userData: UTSJSONObject\r\n if (userRaw instanceof UTSJSONObject) {\r\n userData = userRaw as UTSJSONObject\r\n } else {\r\n userData = JSON.parse(JSON.stringify(userRaw)) as UTSJSONObject\r\n }\r\n const metaData = userData.get('raw_user_meta_data')\r\n if (metaData != null) {\r\n let metaObj: UTSJSONObject\r\n if (metaData instanceof UTSJSONObject) {\r\n metaObj = metaData as UTSJSONObject\r\n } else {\r\n metaObj = JSON.parse(JSON.stringify(metaData)) as UTSJSONObject\r\n }\r\n userName = metaObj.getString('nickname') ?? metaObj.getString('name') ?? '匿名用户'\r\n userAvatar = metaObj.getString('avatar_url') ?? ''\r\n }\r\n }\r\n\r\n // 检查是否匿名\r\n const isAnonymous = processed.getBoolean('is_anonymous') ?? false\r\n if (isAnonymous) {\r\n userName = '匿名用户'\r\n userAvatar = ''\r\n }\r\n\r\n processed.set('user_name', userName)\r\n processed.set('user_avatar', userAvatar)\r\n\r\n // 检查当前用户是否点赞\r\n let isLiked = false\r\n if (userId != null) {\r\n const likeRes = await supa\r\n .from('ml_review_likes')\r\n .select('id')\r\n .eq('review_id', processed.getString('id') ?? '')\r\n .eq('user_id', userId!)\r\n .limit(1)\r\n .execute()\r\n if (likeRes.error == null && likeRes.data != null) {\r\n const likeData = likeRes.data as any[]\r\n isLiked = likeData.length > 0\r\n }\r\n }\r\n processed.set('is_liked', isLiked)\r\n\r\n processedReviews.push(processed)\r\n }\r\n\r\n result.set('total', total)\r\n result.set('data', processedReviews)\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6528','获取评价列表异常:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取商品评价统计\r\n async getReviewStats(productId: string): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('total_count', 0)\r\n result.set('avg_rating', 0)\r\n result.set('good_rate', 0)\r\n result.set('rating_distribution', new UTSJSONObject())\r\n result.set('tags', [] as any[])\r\n\r\n try {\r\n const response = await supa\r\n .from('ml_product_reviews')\r\n .select('rating')\r\n .eq('product_id', productId)\r\n .execute()\r\n\r\n if (response.error != null || response.data == null) {\r\n return result\r\n }\r\n\r\n const reviews = response.data as any[]\r\n const totalCount = reviews.length\r\n\r\n if (totalCount === 0) return result\r\n\r\n let totalRating = 0\r\n let goodCount = 0\r\n const distribution: Map = new Map()\r\n distribution.set(1, 0)\r\n distribution.set(2, 0)\r\n distribution.set(3, 0)\r\n distribution.set(4, 0)\r\n distribution.set(5, 0)\r\n\r\n for (let i = 0; i < reviews.length; i++) {\r\n const review = reviews[i]\r\n let rating = 0\r\n if (review instanceof UTSJSONObject) {\r\n rating = review.getNumber('rating') ?? 0\r\n } else {\r\n const rObj = JSON.parse(JSON.stringify(review)) as UTSJSONObject\r\n rating = rObj.getNumber('rating') ?? 0\r\n }\r\n\r\n totalRating += rating\r\n if (rating >= 4) goodCount++\r\n\r\n const currentCount = distribution.get(rating) ?? 0\r\n distribution.set(rating, currentCount + 1)\r\n }\r\n\r\n const avgRating = Math.round((totalRating / totalCount) * 10) / 10\r\n const goodRate = Math.round((goodCount / totalCount) * 100)\r\n\r\n const distObj = new UTSJSONObject()\r\n distribution.forEach((value: number, key: number) => {\r\n distObj.set(key.toString(), value)\r\n })\r\n\r\n result.set('total_count', totalCount)\r\n result.set('avg_rating', avgRating)\r\n result.set('good_rate', goodRate)\r\n result.set('rating_distribution', distObj)\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6599','获取评价统计异常:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 评价点赞\r\n async toggleReviewLike(reviewId: string): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('success', false)\r\n result.set('is_liked', false)\r\n result.set('like_count', 0)\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n return result\r\n }\r\n\r\n // 检查是否已点赞\r\n const checkRes = await supa\r\n .from('ml_review_likes')\r\n .select('id')\r\n .eq('review_id', reviewId)\r\n .eq('user_id', userId!)\r\n .limit(1)\r\n .execute()\r\n\r\n let isLiked = false\r\n if (checkRes.error == null && checkRes.data != null) {\r\n const checkData = checkRes.data as any[]\r\n isLiked = checkData.length > 0\r\n }\r\n\r\n if (isLiked) {\r\n // 取消点赞\r\n await supa\r\n .from('ml_review_likes')\r\n .eq('review_id', reviewId)\r\n .eq('user_id', userId!)\r\n .delete()\r\n .execute()\r\n\r\n // 更新点赞数 - 直接查询并更新\r\n const currentCountRes = await supa\r\n .from('ml_product_reviews')\r\n .select('like_count')\r\n .eq('id', reviewId)\r\n .single()\r\n .execute()\r\n \r\n if (currentCountRes.error == null && currentCountRes.data != null) {\r\n let currentCount = 0\r\n if (currentCountRes.data instanceof UTSJSONObject) {\r\n currentCount = currentCountRes.data.getNumber('like_count') ?? 0\r\n } else {\r\n const countObj = JSON.parse(JSON.stringify(currentCountRes.data)) as UTSJSONObject\r\n currentCount = countObj.getNumber('like_count') ?? 0\r\n }\r\n \r\n const updateData = new UTSJSONObject()\r\n updateData.set('like_count', Math.max(0, currentCount - 1))\r\n await supa\r\n .from('ml_product_reviews')\r\n .update(updateData)\r\n .eq('id', reviewId)\r\n .execute()\r\n }\r\n\r\n result.set('is_liked', false)\r\n } else {\r\n // 添加点赞\r\n const likeRecord = new UTSJSONObject()\r\n likeRecord.set('review_id', reviewId)\r\n likeRecord.set('user_id', userId!)\r\n\r\n await supa\r\n .from('ml_review_likes')\r\n .insert(likeRecord)\r\n .execute()\r\n\r\n // 更新点赞数 - 直接查询并更新\r\n const currentCountRes = await supa\r\n .from('ml_product_reviews')\r\n .select('like_count')\r\n .eq('id', reviewId)\r\n .single()\r\n .execute()\r\n \r\n if (currentCountRes.error == null && currentCountRes.data != null) {\r\n let currentCount = 0\r\n if (currentCountRes.data instanceof UTSJSONObject) {\r\n currentCount = currentCountRes.data.getNumber('like_count') ?? 0\r\n } else {\r\n const countObj = JSON.parse(JSON.stringify(currentCountRes.data)) as UTSJSONObject\r\n currentCount = countObj.getNumber('like_count') ?? 0\r\n }\r\n \r\n const updateData = new UTSJSONObject()\r\n updateData.set('like_count', currentCount + 1)\r\n await supa\r\n .from('ml_product_reviews')\r\n .update(updateData)\r\n .eq('id', reviewId)\r\n .execute()\r\n }\r\n\r\n result.set('is_liked', true)\r\n }\r\n\r\n // 获取最新点赞数\r\n const reviewRes = await supa\r\n .from('ml_product_reviews')\r\n .select('like_count')\r\n .eq('id', reviewId)\r\n .single()\r\n .execute()\r\n\r\n if (reviewRes.error == null && reviewRes.data != null) {\r\n let likeCount = 0\r\n if (reviewRes.data instanceof UTSJSONObject) {\r\n likeCount = reviewRes.data.getNumber('like_count') ?? 0\r\n } else {\r\n const rObj = JSON.parse(JSON.stringify(reviewRes.data)) as UTSJSONObject\r\n likeCount = rObj.getNumber('like_count') ?? 0\r\n }\r\n result.set('like_count', likeCount)\r\n }\r\n\r\n result.set('success', true)\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6730','评价点赞异常:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取我的评价列表\r\n async getMyReviews(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const response = await supa\r\n .from('ml_product_reviews')\r\n .select(`\r\n *,\r\n product:ml_products!ml_product_reviews_product_id_fkey(name, main_image_url)\r\n `)\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (response.error != null || response.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const reviews = response.data as any[]\r\n const result: any[] = []\r\n\r\n for (let i = 0; i < reviews.length; i++) {\r\n const review = reviews[i]\r\n const processed = JSON.parse(JSON.stringify(review)) as UTSJSONObject\r\n\r\n // 处理商品信息\r\n const productRaw = processed.get('product')\r\n let productName = ''\r\n let productImage = ''\r\n if (productRaw != null) {\r\n let productObj: UTSJSONObject\r\n if (productRaw instanceof UTSJSONObject) {\r\n productObj = productRaw as UTSJSONObject\r\n } else {\r\n productObj = JSON.parse(JSON.stringify(productRaw)) as UTSJSONObject\r\n }\r\n productName = productObj.getString('name') ?? ''\r\n productImage = productObj.getString('main_image_url') ?? ''\r\n }\r\n processed.set('product_name', productName)\r\n processed.set('product_image', productImage)\r\n\r\n // 计算是否可追加评价(7天内)\r\n const createdAt = processed.getString('created_at') ?? ''\r\n const createdTime = new Date(createdAt).getTime()\r\n const now = Date.now()\r\n const sevenDays = 7 * 24 * 60 * 60 * 1000\r\n const canAppend = (now - createdTime) < sevenDays && (processed.getString('append_content') ?? '') === ''\r\n processed.set('can_append', canAppend)\r\n\r\n // 计算是否可编辑(24小时内)\r\n const oneDay = 24 * 60 * 60 * 1000\r\n const canEdit = (now - createdTime) < oneDay\r\n processed.set('can_edit', canEdit)\r\n\r\n result.push(processed)\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6801','获取我的评价失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 追加评价\r\n async appendReview(reviewId: string, content: string, images: string[]): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n\r\n const updateData = new UTSJSONObject()\r\n updateData.set('append_content', content)\r\n updateData.set('append_images', JSON.stringify(images))\r\n updateData.set('append_at', new Date().toISOString())\r\n\r\n const response = await supa\r\n .from('ml_product_reviews')\r\n .update(updateData)\r\n .eq('id', reviewId)\r\n .eq('user_id', userId!)\r\n .execute()\r\n\r\n return response.error == null\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6827','追加评价失败:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 删除评价\r\n async deleteReview(reviewId: string): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return false\r\n\r\n const response = await supa\r\n .from('ml_product_reviews')\r\n .delete()\r\n .eq('id', reviewId)\r\n .eq('user_id', userId!)\r\n .execute()\r\n\r\n return response.error == null\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6847','删除评价失败:', e)\r\n return false\r\n }\r\n }\r\n\r\n // ==================== 积分辅助方法 ====================\r\n\r\n // 增加积分\r\n private async addPoints(userId: string, points: number, type: string, description: string): Promise {\r\n try {\r\n // 获取当前积分\r\n const currentPoints = await this.getUserPoints()\r\n const newPoints = currentPoints + points\r\n const totalEarned = await this.getTotalEarned()\r\n\r\n // 检查用户积分记录是否存在\r\n const checkRes = await supa\r\n .from('ml_user_points')\r\n .select('user_id')\r\n .eq('user_id', userId)\r\n .limit(1)\r\n .execute()\r\n\r\n const exists = checkRes.error == null && checkRes.data != null && (checkRes.data as any[]).length > 0\r\n\r\n if (exists) {\r\n // 更新现有记录\r\n const updateData = new UTSJSONObject()\r\n updateData.set('points', newPoints)\r\n updateData.set('total_earned', totalEarned + points)\r\n updateData.set('updated_at', new Date().toISOString())\r\n\r\n await supa\r\n .from('ml_user_points')\r\n .update(updateData)\r\n .eq('user_id', userId)\r\n .execute()\r\n } else {\r\n // 插入新记录\r\n const insertData = new UTSJSONObject()\r\n insertData.set('user_id', userId)\r\n insertData.set('points', newPoints)\r\n insertData.set('total_earned', points)\r\n insertData.set('updated_at', new Date().toISOString())\r\n\r\n await supa\r\n .from('ml_user_points')\r\n .insert(insertData)\r\n .execute()\r\n }\r\n\r\n // 记录积分变动\r\n const record = new UTSJSONObject()\r\n record.set('user_id', userId)\r\n record.set('points', points)\r\n record.set('type', type)\r\n record.set('description', description)\r\n\r\n await supa\r\n .from('ml_point_records')\r\n .insert(record)\r\n .execute()\r\n\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6912','增加积分失败:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 扣减积分\r\n private async deductPoints(userId: string, points: number, type: string, description: string): Promise {\r\n try {\r\n const currentPoints = await this.getUserPoints()\r\n const newPoints = currentPoints - points\r\n\r\n if (newPoints < 0) return false\r\n\r\n const updateData = new UTSJSONObject()\r\n updateData.set('points', newPoints)\r\n updateData.set('updated_at', new Date().toISOString())\r\n\r\n await supa\r\n .from('ml_user_points')\r\n .update(updateData)\r\n .eq('user_id', userId)\r\n .execute()\r\n\r\n const record = new UTSJSONObject()\r\n record.set('user_id', userId)\r\n record.set('points', -points)\r\n record.set('type', type)\r\n record.set('description', description)\r\n\r\n await supa\r\n .from('ml_point_records')\r\n .insert(record)\r\n .execute()\r\n\r\n return true\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:6948','扣减积分失败:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 获取历史累计积分\r\n private async getTotalEarned(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return 0\r\n\r\n const res = await supa\r\n .from('ml_user_points')\r\n .select('total_earned')\r\n .eq('user_id', userId!)\r\n .single()\r\n .execute()\r\n\r\n if (res.error == null && res.data != null) {\r\n if (res.data instanceof UTSJSONObject) {\r\n return res.data.getNumber('total_earned') ?? 0\r\n } else {\r\n const obj = JSON.parse(JSON.stringify(res.data)) as UTSJSONObject\r\n return obj.getNumber('total_earned') ?? 0\r\n }\r\n }\r\n return 0\r\n } catch (e) {\r\n return 0\r\n }\r\n }\r\n\r\n // ==================== 积分过期相关API ====================\r\n\r\n // 获取即将过期积分\r\n async getExpiringPoints(): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('expiring_points', 0)\r\n result.set('expiring_date', null)\r\n result.set('details', [] as any[])\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return result\r\n\r\n // 查询30天内即将过期的积分记录\r\n const now = new Date()\r\n const thirtyDaysLater = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)\r\n const nowStr = now.toISOString()\r\n const laterStr = thirtyDaysLater.toISOString()\r\n\r\n const res = await supa\r\n .from('ml_point_records')\r\n .select('points, description, expires_at, created_at')\r\n .eq('user_id', userId!)\r\n .gt('points', 0)\r\n .eq('is_expired', false)\r\n .not('expires_at', 'is', null)\r\n .gte('expires_at', nowStr)\r\n .lte('expires_at', laterStr)\r\n .order('expires_at', { ascending: true })\r\n .execute()\r\n\r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:7012','获取即将过期积分失败:', res.error)\r\n return result\r\n }\r\n\r\n if (res.data != null && Array.isArray(res.data)) {\r\n const records = res.data as any[]\r\n let totalExpiring = 0\r\n let earliestDate: string | null = null\r\n const details: any[] = []\r\n\r\n for (let i = 0; i < records.length; i++) {\r\n const record = records[i]\r\n let recordObj: UTSJSONObject\r\n if (record instanceof UTSJSONObject) {\r\n recordObj = record\r\n } else {\r\n recordObj = JSON.parse(JSON.stringify(record)) as UTSJSONObject\r\n }\r\n\r\n const points = recordObj.getNumber('points') ?? 0\r\n const expiresAt = recordObj.getString('expires_at') ?? ''\r\n\r\n totalExpiring += points\r\n\r\n if (earliestDate == null || expiresAt < earliestDate) {\r\n earliestDate = expiresAt\r\n }\r\n\r\n details.push({\r\n points: points,\r\n description: recordObj.getString('description'),\r\n expires_at: expiresAt,\r\n created_at: recordObj.getString('created_at') ?? ''\r\n })\r\n }\r\n\r\n result.set('expiring_points', totalExpiring)\r\n result.set('expiring_date', earliestDate != null ? earliestDate.split('T')[0] : null)\r\n result.set('details', details)\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7055','获取即将过期积分异常:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取积分概览(包含即将过期积分)\r\n async getPointsOverview(): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('current_points', 0)\r\n result.set('total_earned', 0)\r\n result.set('expiring_points', 0)\r\n result.set('expiring_date', null)\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return result\r\n\r\n const res = await supa\r\n .from('ml_user_points')\r\n .select('points, total_earned, expiring_points, expiring_date')\r\n .eq('user_id', userId!)\r\n .single()\r\n .execute()\r\n\r\n if (res.error == null && res.data != null) {\r\n let data: UTSJSONObject\r\n if (res.data instanceof UTSJSONObject) {\r\n data = res.data as UTSJSONObject\r\n } else {\r\n data = JSON.parse(JSON.stringify(res.data)) as UTSJSONObject\r\n }\r\n\r\n result.set('current_points', data.getNumber('points') ?? 0)\r\n result.set('total_earned', data.getNumber('total_earned') ?? 0)\r\n result.set('expiring_points', data.getNumber('expiring_points') ?? 0)\r\n result.set('expiring_date', data.getString('expiring_date'))\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7095','获取积分概览异常:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取过期提醒通知列表\r\n async getExpiryNotifications(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const res = await supa\r\n .from('ml_point_expiry_notifications')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .eq('is_sent', false)\r\n .order('expiry_date', { ascending: true })\r\n .execute()\r\n\r\n if (res.error != null || res.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7124','获取过期提醒失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 标记过期提醒为已读\r\n async markNotificationRead(notificationId: string): Promise {\r\n try {\r\n const res = await supa\r\n .from('ml_point_expiry_notifications')\r\n .update({ is_sent: true, sent_at: new Date().toISOString() })\r\n .eq('id', notificationId)\r\n .execute()\r\n\r\n return res.error == null\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7141','标记通知失败:', e)\r\n return false\r\n }\r\n }\r\n\r\n // 手动触发积分维护任务(管理员功能)\r\n // 注意:UTS不支持rpc,此功能需要在Supabase后台手动执行或通过其他方式触发\r\n async triggerPointsMaintenance(): Promise {\r\n __f__('warn','at utils/supabaseService.uts:7149','triggerPointsMaintenance: UTS不支持rpc调用,请在Supabase后台手动执行 daily_points_maintenance()')\r\n return false\r\n }\r\n\r\n // ==================== 推销模式 - 商家配置API ====================\r\n\r\n // 获取商家推销配置\r\n async getMerchantPromotionConfig(merchantId: string): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('promotion_enabled', false)\r\n result.set('share_free_enabled', false)\r\n result.set('distribution_enabled', false)\r\n result.set('required_count', 4)\r\n result.set('reward_type', 'product_price')\r\n result.set('fixed_reward_amount', 0)\r\n\r\n try {\r\n const res = await supa\r\n .from('ml_merchant_promotion_config')\r\n .select('*')\r\n .eq('merchant_id', merchantId)\r\n .limit(1)\r\n .execute()\r\n\r\n if (res.error == null && res.data != null && Array.isArray(res.data)) {\r\n const arr = res.data as any[]\r\n if (arr.length > 0) {\r\n const item = arr[0]\r\n const itemAny = item as any\r\n \r\n if (itemAny instanceof UTSJSONObject) {\r\n result.set('promotion_enabled', itemAny.getBoolean('promotion_enabled') ?? false)\r\n result.set('share_free_enabled', itemAny.getBoolean('share_free_enabled') ?? false)\r\n result.set('distribution_enabled', itemAny.getBoolean('distribution_enabled') ?? false)\r\n result.set('required_count', itemAny.getNumber('required_count') ?? 4)\r\n result.set('reward_type', itemAny.getString('reward_type') ?? 'product_price')\r\n result.set('fixed_reward_amount', itemAny.getNumber('fixed_reward_amount') ?? 0)\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7190','获取商家推销配置失败:', e)\r\n }\r\n\r\n return result\r\n }\r\n\r\n // 检查商家是否开启分享免单\r\n async isShareFreeEnabled(merchantId: string): Promise {\r\n try {\r\n const config = await this.getMerchantPromotionConfig(merchantId)\r\n const promotionEnabled = config.get('promotion_enabled')\r\n const shareFreeEnabled = config.get('share_free_enabled')\r\n return (promotionEnabled === true || promotionEnabled === 'true') && \r\n (shareFreeEnabled === true || shareFreeEnabled === 'true')\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7205','检查分享免单状态失败:', e)\r\n return false\r\n }\r\n }\r\n\r\n // ==================== 推销模式 - 余额相关API ====================\r\n\r\n // 获取用户余额\r\n async getUserBalance(): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('balance', 0)\r\n result.set('frozen_balance', 0)\r\n result.set('total_earned', 0)\r\n result.set('total_withdrawn', 0)\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return result\r\n\r\n const res = await supa\r\n .from('ml_user_balance')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .limit(1)\r\n .execute()\r\n\r\n if (res.error == null && res.data != null && Array.isArray(res.data)) {\r\n const arr = res.data as any[]\r\n if (arr.length > 0) {\r\n const item = arr[0]\r\n const itemAny = item as any\r\n if (itemAny instanceof UTSJSONObject) {\r\n result.set('balance', itemAny.getNumber('balance') ?? 0)\r\n result.set('frozen_balance', itemAny.getNumber('frozen_balance') ?? 0)\r\n result.set('total_earned', itemAny.getNumber('total_earned') ?? 0)\r\n result.set('total_withdrawn', itemAny.getNumber('total_withdrawn') ?? 0)\r\n }\r\n }\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7247','获取用户余额失败:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取余额变动记录\r\n async getBalanceRecords(page: number = 1, limit: number = 20): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const offset = (page - 1) * limit\r\n const res = await supa\r\n .from('ml_balance_records')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .range(offset, offset + limit - 1)\r\n .execute()\r\n\r\n if (res.error != null || res.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7277','获取余额记录失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // ==================== 推销模式 - 分享免单相关API ====================\r\n\r\n // 创建分享记录\r\n async createShareRecord(productId: string, orderId: string, orderItemId: string | null, productName: string, productImage: string | null, productPrice: number): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('success', false)\r\n result.set('share_code', '')\r\n result.set('message', '')\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n result.set('message', '请先登录')\r\n return result\r\n }\r\n\r\n // 生成分享码\r\n const shareCode = this.generateShareCode()\r\n\r\n const insertData = new UTSJSONObject()\r\n insertData.set('user_id', userId)\r\n insertData.set('product_id', productId)\r\n insertData.set('order_id', orderId)\r\n insertData.set('order_item_id', orderItemId)\r\n insertData.set('share_code', shareCode)\r\n insertData.set('product_name', productName)\r\n insertData.set('product_image', productImage)\r\n insertData.set('product_price', productPrice)\r\n insertData.set('required_count', 4)\r\n insertData.set('current_count', 0)\r\n insertData.set('status', 0)\r\n\r\n const res = await supa\r\n .from('ml_share_records')\r\n .insert(insertData)\r\n .execute()\r\n\r\n if (res.error != null) {\r\n __f__('error','at utils/supabaseService.uts:7321','[createShareRecord] 插入失败:', res.error)\r\n __f__('error','at utils/supabaseService.uts:7322','[createShareRecord] 插入数据:', JSON.stringify(insertData))\r\n result.set('message', '创建分享记录失败: ' + (res.error.message ?? '未知错误'))\r\n return result\r\n }\r\n\r\n // 获取插入记录的id\r\n let insertedId = ''\r\n if (res.data != null && Array.isArray(res.data) && res.data.length > 0) {\r\n const inserted = res.data[0]\r\n let insertedObj: UTSJSONObject | null = null\r\n if (inserted instanceof UTSJSONObject) {\r\n insertedObj = inserted\r\n } else {\r\n insertedObj = JSON.parse(JSON.stringify(inserted)) as UTSJSONObject\r\n }\r\n insertedId = insertedObj.getString('id') ?? ''\r\n }\r\n\r\n result.set('success', true)\r\n result.set('id', insertedId)\r\n result.set('share_code', shareCode)\r\n result.set('message', '分享创建成功')\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7346','创建分享记录失败:', e)\r\n result.set('message', '创建分享记录异常')\r\n return result\r\n }\r\n }\r\n\r\n // 生成分享码\r\n private generateShareCode(): string {\r\n const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'\r\n let result = ''\r\n for (let i = 0; i < 8; i++) {\r\n const randomIndex = Math.floor(Math.random() * chars.length)\r\n result += chars.charAt(randomIndex)\r\n }\r\n return result\r\n }\r\n\r\n // 验证分享码\r\n async validateShareCode(shareCode: string): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('valid', false)\r\n result.set('share_record', null)\r\n\r\n try {\r\n const res = await supa\r\n .from('ml_share_records')\r\n .select('*')\r\n .eq('share_code', shareCode)\r\n .eq('status', 0)\r\n .limit(1)\r\n .execute()\r\n\r\n if (res.error == null && res.data != null && Array.isArray(res.data)) {\r\n const arr = res.data as any[]\r\n if (arr.length > 0) {\r\n result.set('valid', true)\r\n result.set('share_record', arr[0])\r\n }\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7388','验证分享码失败:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取我的分享记录\r\n async getMyShareRecords(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const res = await supa\r\n .from('ml_share_records')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (res.error != null || res.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7416','获取分享记录失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 获取分享详情\r\n async getShareDetail(shareId: string): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('share_record', null)\r\n result.set('secondary_purchases', [] as any[])\r\n\r\n try {\r\n const res = await supa\r\n .from('ml_share_records')\r\n .select('*')\r\n .eq('id', shareId)\r\n .limit(1)\r\n .execute()\r\n\r\n if (res.error == null && res.data != null && Array.isArray(res.data)) {\r\n const arr = res.data as any[]\r\n if (arr.length > 0) {\r\n result.set('share_record', arr[0])\r\n }\r\n }\r\n\r\n // 获取二级购买记录\r\n const purchasesRes = await supa\r\n .from('ml_secondary_purchases')\r\n .select('*')\r\n .eq('share_record_id', shareId)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (purchasesRes.error == null && purchasesRes.data != null) {\r\n result.set('secondary_purchases', purchasesRes.data)\r\n }\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7457','获取分享详情失败:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取免单奖励记录\r\n async getFreeOrderRewards(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const res = await supa\r\n .from('ml_free_order_rewards')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (res.error != null || res.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7485','获取免单奖励记录失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // ==================== 推销模式 - 会员等级相关API ====================\r\n\r\n // 获取会员等级列表\r\n async getMemberLevels(): Promise {\r\n try {\r\n const res = await supa\r\n .from('ml_member_levels')\r\n .select('*')\r\n .eq('status', 1)\r\n .order('sort_order', { ascending: true })\r\n .execute()\r\n\r\n if (res.error != null || res.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7510','获取会员等级列表失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n\r\n // 获取用户会员信息\r\n async getUserMemberInfo(): Promise {\r\n const result = new UTSJSONObject()\r\n result.set('member_level', 0)\r\n result.set('level_name', '普通会员')\r\n result.set('discount', 1.0)\r\n result.set('total_spent', 0)\r\n result.set('next_level', null)\r\n result.set('progress_percent', 0)\r\n result.set('manual_level', false)\r\n\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) return result\r\n\r\n // 获取用户信息\r\n const userRes = await supa\r\n .from('ml_user_profiles')\r\n .select('member_level, total_spent, manual_level')\r\n .eq('user_id', userId!)\r\n .limit(1)\r\n .execute()\r\n\r\n let memberLevel = 0\r\n let totalSpent = 0\r\n let manualLevel = false\r\n\r\n if (userRes.error == null && userRes.data != null && Array.isArray(userRes.data)) {\r\n const arr = userRes.data as any[]\r\n if (arr.length > 0) {\r\n const item = arr[0]\r\n const itemAny = item as any\r\n if (itemAny instanceof UTSJSONObject) {\r\n memberLevel = itemAny.getNumber('member_level') ?? 0\r\n totalSpent = itemAny.getNumber('total_spent') ?? 0\r\n manualLevel = itemAny.getBoolean('manual_level') ?? false\r\n }\r\n }\r\n }\r\n\r\n // 获取等级信息\r\n const levels = await this.getMemberLevels()\r\n let levelName = '普通会员'\r\n let discount = 1.0\r\n let nextLevel: UTSJSONObject | null = null\r\n let progressPercent = 0\r\n\r\n for (let i = 0; i < levels.length; i++) {\r\n const level = levels[i]\r\n const levelAny = level as any\r\n let levelId = 0\r\n let levelNameStr = ''\r\n let levelDiscount = 1.0\r\n let levelMinAmount = 0\r\n\r\n if (levelAny instanceof UTSJSONObject) {\r\n levelId = levelAny.getNumber('id') ?? 0\r\n levelNameStr = levelAny.getString('name') ?? ''\r\n levelDiscount = levelAny.getNumber('discount') ?? 1.0\r\n levelMinAmount = levelAny.getNumber('min_amount') ?? 0\r\n }\r\n\r\n if (levelId === memberLevel) {\r\n levelName = levelNameStr\r\n discount = levelDiscount\r\n }\r\n\r\n // 找下一等级\r\n if (levelId > memberLevel && nextLevel == null) {\r\n const nextLevelObj = new UTSJSONObject()\r\n nextLevelObj.set('id', levelId)\r\n nextLevelObj.set('name', levelNameStr)\r\n nextLevelObj.set('min_amount', levelMinAmount)\r\n nextLevel = nextLevelObj\r\n\r\n // 计算进度\r\n if (levelMinAmount > 0) {\r\n const currentLevelMinAmount = this.getCurrentLevelMinAmount(levels, memberLevel)\r\n const progressRange = levelMinAmount - currentLevelMinAmount\r\n const currentProgress = totalSpent - currentLevelMinAmount\r\n progressPercent = Math.min(100, Math.round((currentProgress / progressRange) * 100))\r\n }\r\n }\r\n }\r\n\r\n result.set('member_level', memberLevel)\r\n result.set('level_name', levelName)\r\n result.set('discount', discount)\r\n result.set('total_spent', totalSpent)\r\n result.set('next_level', nextLevel)\r\n result.set('progress_percent', progressPercent)\r\n result.set('manual_level', manualLevel)\r\n\r\n return result\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7611','获取用户会员信息失败:', e)\r\n return result\r\n }\r\n }\r\n\r\n // 获取当前等级的最低消费金额\r\n private getCurrentLevelMinAmount(levels: any[], currentLevel: number): number {\r\n for (let i = 0; i < levels.length; i++) {\r\n const level = levels[i]\r\n const levelAny = level as any\r\n if (levelAny instanceof UTSJSONObject) {\r\n const levelId = levelAny.getNumber('id') ?? 0\r\n if (levelId === currentLevel) {\r\n return levelAny.getNumber('min_amount') ?? 0\r\n }\r\n }\r\n }\r\n return 0\r\n }\r\n\r\n // 获取会员等级变更记录\r\n async getMemberLevelLogs(): Promise {\r\n try {\r\n const userId = this.getCurrentUserId()\r\n if (userId == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n const res = await supa\r\n .from('ml_member_level_logs')\r\n .select('*')\r\n .eq('user_id', userId!)\r\n .order('created_at', { ascending: false })\r\n .execute()\r\n\r\n if (res.error != null || res.data == null) {\r\n const empty: any[] = []\r\n return empty\r\n }\r\n\r\n return res.data as any[]\r\n } catch (e) {\r\n __f__('error','at utils/supabaseService.uts:7654','获取会员等级变更记录失败:', e)\r\n const empty: any[] = []\r\n return empty\r\n }\r\n }\r\n}\r\n\r\n// 导出单例实例\r\nexport const supabaseService = new SupabaseService()\r\n\r\n// 默认导出\r\nexport default supabaseService\r\n","\r\n \r\n \r\n