完善登录逻辑和个人资料完善

This commit is contained in:
2026-05-26 11:29:06 +08:00
parent cecb51a8e2
commit 9680276b3f
27 changed files with 3934 additions and 1572 deletions

View File

@@ -0,0 +1,425 @@
{
"pages": [
{
"path": "pages/user/register",
"style": {
"navigationBarTitleText": "服务人员注册",
"navigationStyle": "custom"
}
},
{
"path": "pages/user/terms",
"style": {
"navigationBarTitleText": "用户协议与隐私政策",
"navigationStyle": "custom"
}
},
{
"path": "pages/user/login",
"style": {
"navigationBarTitleText": "服务人员登录",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/home/index",
"style": {
"navigationBarTitleText": "工作台",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/orders/index",
"style": {
"navigationBarTitleText": "工单列表",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/orders/detail",
"style": {
"navigationBarTitleText": "订单详情",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/service-record/index",
"style": {
"navigationBarTitleText": "服务记录",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/orders/exception",
"style": {
"navigationBarTitleText": "异常上报",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/profile/index",
"style": {
"navigationBarTitleText": "我的",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/profile/settings",
"style": {
"navigationBarTitleText": "设置",
"navigationStyle": "custom"
}
}
],
"subPackages": [
{
"root": "pages/mall/consumer",
"pages": [
{
"path": "settings",
"style": {
"navigationBarTitleText": "设置"
}
},
{
"path": "edit-profile",
"style": {
"navigationBarTitleText": "编辑资料"
}
},
{
"path": "wallet",
"style": {
"navigationBarTitleText": "我的钱包"
}
},
{
"path": "withdraw",
"style": {
"navigationBarTitleText": "余额提现"
}
},
{
"path": "search",
"style": {
"navigationBarTitleText": "搜索",
"navigationStyle": "custom"
}
},
{
"path": "product-detail",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "channel-detail",
"style": {
"navigationBarTitleText": "频道详情",
"navigationStyle": "custom"
}
},
{
"path": "shop-detail",
"style": {
"navigationBarTitleText": "店铺详情"
}
},
{
"path": "coupons",
"style": {
"navigationBarTitleText": "我的优惠券"
}
},
{
"path": "favorites",
"style": {
"navigationBarTitleText": "我的收藏"
}
},
{
"path": "footprint",
"style": {
"navigationBarTitleText": "我的足迹"
}
},
{
"path": "address",
"style": {
"navigationBarTitleText": "地址"
}
},
{
"path": "address-list",
"style": {
"navigationBarTitleText": "收货地址"
}
},
{
"path": "address-edit",
"style": {
"navigationBarTitleText": "编辑地址"
}
},
{
"path": "checkout",
"style": {
"navigationBarTitleText": "确认订单"
}
},
{
"path": "payment",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "payment-success",
"style": {
"navigationBarTitleText": "支付成功",
"navigationStyle": "custom"
}
},
{
"path": "orders",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": true,
"backgroundColor": "#f5f5f5"
}
},
{
"path": "order-detail",
"style": {
"navigationBarTitleText": "订单详情"
}
},
{
"path": "logistics",
"style": {
"navigationBarTitleText": "物流详情"
}
},
{
"path": "review",
"style": {
"navigationBarTitleText": "评价晒单"
}
},
{
"path": "refund",
"style": {
"navigationBarTitleText": "退款/售后"
}
},
{
"path": "apply-refund",
"style": {
"navigationBarTitleText": "申请售后"
}
},
{
"path": "refund-review",
"style": {
"navigationBarTitleText": "服务评价"
}
},
{
"path": "chat",
"style": {
"navigationBarTitleText": "客服聊天",
"navigationStyle": "custom"
}
},
{
"path": "chat_new",
"style": {
"navigationBarTitleText": "客服聊天(新版)"
}
},
{
"path": "subscription/plan-list",
"style": {
"navigationBarTitleText": "软件订阅"
}
},
{
"path": "subscription/plan-detail",
"style": {
"navigationBarTitleText": "订阅详情"
}
},
{
"path": "subscription/subscribe-checkout",
"style": {
"navigationBarTitleText": "确认订阅"
}
},
{
"path": "subscription/my-subscriptions",
"style": {
"navigationBarTitleText": "我的订阅"
}
},
{
"path": "subscription/followed-shops",
"style": {
"navigationBarTitleText": "关注店铺"
}
},
{
"path": "points/index",
"style": {
"navigationBarTitleText": "积分管理"
}
},
{
"path": "points/signin",
"style": {
"navigationBarTitleText": "签到"
}
},
{
"path": "points/exchange",
"style": {
"navigationBarTitleText": "积分兑换"
}
},
{
"path": "points/exchange-records",
"style": {
"navigationBarTitleText": "兑换记录"
}
},
{
"path": "red-packets/index",
"style": {
"navigationBarTitleText": "我的红包"
}
},
{
"path": "bank-cards/index",
"style": {
"navigationBarTitleText": "银行卡管理"
}
},
{
"path": "bank-cards/add",
"style": {
"navigationBarTitleText": "添加银行卡"
}
},
{
"path": "home-service/index",
"style": {
"navigationBarTitleText": "居家上门服务",
"navigationStyle": "custom"
}
},
{
"path": "home-service/apply",
"style": {
"navigationBarTitleText": "提交服务申请",
"navigationStyle": "custom"
}
},
{
"path": "home-service/service-detail",
"style": {
"navigationBarTitleText": "预约服务",
"navigationStyle": "custom"
}
},
{
"path": "home-service/order-detail",
"style": {
"navigationBarTitleText": "服务单详情",
"navigationStyle": "custom"
}
},
{
"path": "home-service/feedback",
"style": {
"navigationBarTitleText": "验收反馈",
"navigationStyle": "custom"
}
},
{
"path": "bank-cards/verify",
"style": {
"navigationBarTitleText": "银行卡验证"
}
},
{
"path": "balance/index",
"style": {
"navigationBarTitleText": "余额"
}
},
{
"path": "my-reviews",
"style": {
"navigationBarTitleText": "我的评价"
}
},
{
"path": "message-detail",
"style": {
"navigationBarTitleText": "消息详情"
}
},
{
"path": "member/index",
"style": {
"navigationBarTitleText": "会员中心"
}
},
{
"path": "product-reviews",
"style": {
"navigationBarTitleText": "商品评价"
}
}
]
}
],
"tabBar": {
"color": "#6B7280",
"selectedColor": "#0F766E",
"backgroundColor": "#FFFFFF",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/mall/delivery/home/index",
"text": "工作台",
"iconPath": "static/tabbar/home.png",
"selectedIconPath": "static/tabbar/home-active.png"
},
{
"pagePath": "pages/mall/delivery/orders/index",
"text": "订单",
"iconPath": "static/tabbar/cart.png",
"selectedIconPath": "static/tabbar/cart.png"
},
{
"pagePath": "pages/mall/delivery/profile/index",
"text": "我的",
"iconPath": "static/tabbar/user.png",
"selectedIconPath": "static/tabbar/user.png"
}
]
},
"condition": {
"current": 0,
"list": [
{
"name": "delivery端",
"path": "pages/user/login",
"query": "mode=delivery&role=delivery"
}
]
}
}

View File

@@ -1 +1 @@
export const CURRENT_CLIENT: string = 'delivery'
export const CURRENT_CLIENT: string = 'consumer'

View File

@@ -0,0 +1,12 @@
ALTER TABLE public.ak_users
ADD COLUMN IF NOT EXISTS health_goal text,
ADD COLUMN IF NOT EXISTS service_address text,
ADD COLUMN IF NOT EXISTS emergency_contact text,
ADD COLUMN IF NOT EXISTS chronic_notes text,
ADD COLUMN IF NOT EXISTS care_preference text;
COMMENT ON COLUMN public.ak_users.health_goal IS '健康目标';
COMMENT ON COLUMN public.ak_users.service_address IS '常住服务地址';
COMMENT ON COLUMN public.ak_users.emergency_contact IS '紧急联系人';
COMMENT ON COLUMN public.ak_users.chronic_notes IS '慢病或过敏备注';
COMMENT ON COLUMN public.ak_users.care_preference IS '护理偏好';

View File

@@ -1,72 +1,100 @@
{
"pages": [
{
"path": "pages/user/register",
"path": "pages/main/index",
"style": {
"navigationBarTitleText": "服务人员注册",
"navigationStyle": "custom"
"navigationBarTitleText": "首页",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/user/terms",
"path": "pages/user/boot",
"style": {
"navigationBarTitleText": "用户协议与隐私政策",
"navigationStyle": "custom"
"navigationBarTitleText": ""
}
},
{
"path": "pages/user/login",
"style": {
"navigationBarTitleText": "服务人员登录",
"navigationStyle": "custom"
"navigationBarTitleText": "登录",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/mall/delivery/home/index",
"path": "pages/user/register",
"style": {
"navigationBarTitleText": "工作台",
"navigationStyle": "custom"
"navigationBarTitleText": "注册"
}
},
{
"path": "pages/mall/delivery/orders/index",
"path": "pages/user/forgot-password",
"style": {
"navigationBarTitleText": "工单列表",
"navigationStyle": "custom"
"navigationBarTitleText": "忘记密码"
}
},
{
"path": "pages/mall/delivery/orders/detail",
"path": "pages/user/terms",
"style": {
"navigationBarTitleText": "订单详情",
"navigationStyle": "custom"
"navigationBarTitleText": "用户协议与隐私政策"
}
},
{
"path": "pages/mall/delivery/service-record/index",
"path": "pages/user/center",
"style": {
"navigationBarTitleText": "服务记录",
"navigationStyle": "custom"
"navigationBarTitleText": "用户中心"
}
},
{
"path": "pages/mall/delivery/orders/exception",
"path": "pages/user/profile",
"style": {
"navigationBarTitleText": "异常上报",
"navigationBarTitleText": "个人资料"
}
},
{
"path": "pages/user/change-password",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "pages/user/bind-phone",
"style": {
"navigationBarTitleText": "绑定手机"
}
},
{
"path": "pages/user/bind-email",
"style": {
"navigationBarTitleText": "绑定邮箱"
}
},
{
"path": "pages/main/messages",
"style": {
"navigationBarTitleText": "消息",
"enablePullDownRefresh": true
}
},
{
"path": "pages/main/cart",
"style": {
"navigationBarTitleText": "购物车",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/profile/index",
"path": "pages/main/profile",
"style": {
"navigationBarTitleText": "我的",
"navigationStyle": "custom"
}
},
{
"path": "pages/mall/delivery/profile/settings",
"path": "pages/main/category",
"style": {
"navigationBarTitleText": "设置",
"navigationBarTitleText": "分类",
"navigationStyle": "custom"
}
}
@@ -387,38 +415,50 @@
}
],
"tabBar": {
"color": "#6B7280",
"selectedColor": "#0F766E",
"backgroundColor": "#FFFFFF",
"color": "#999999",
"selectedColor": "#ff5000",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/mall/delivery/home/index",
"text": "工作台",
"pagePath": "pages/main/index",
"text": "首页",
"iconPath": "static/tabbar/home.png",
"selectedIconPath": "static/tabbar/home-active.png"
},
{
"pagePath": "pages/mall/delivery/orders/index",
"text": "订单",
"pagePath": "pages/main/messages",
"text": "消息",
"iconPath": "static/tabbar/message.png",
"selectedIconPath": "static/tabbar/message.png"
},
{
"pagePath": "pages/main/cart",
"text": "购物车",
"iconPath": "static/tabbar/cart.png",
"selectedIconPath": "static/tabbar/cart.png"
},
{
"pagePath": "pages/mall/delivery/profile/index",
"pagePath": "pages/main/profile",
"text": "我的",
"iconPath": "static/tabbar/user.png",
"selectedIconPath": "static/tabbar/user.png"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "mall",
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#F8F8F8"
},
"condition": {
"current": 0,
"list": [
{
"name": "delivery端",
"path": "pages/user/login",
"query": "mode=delivery&role=delivery"
"name": "consumer端",
"path": "pages/main/index",
"query": "role=consumer"
}
]
}

View File

@@ -185,7 +185,15 @@
<view class="tabbar-safe-area"></view>
</scroll-view>
<view v-if="currentCartType == 'goods' && cartItems.length > 0" class="fixed-cart-settlement-bar">
<view v-if="!isLoggedIn" class="guest-login-bar cart-guest-login-bar">
<view class="guest-login-left">
<image class="guest-login-avatar" src="/static/images/default.png" mode="aspectFit" />
<text class="guest-login-text">登录后可同步购物车中的商品</text>
</view>
<button class="guest-login-btn" @click.stop="goCartLogin">立即登录</button>
</view>
<view v-if="isLoggedIn && currentCartType == 'goods' && cartItems.length > 0" class="fixed-cart-settlement-bar">
<view class="settlement-inner">
<view class="settlement-left">
<view class="select-all" @click="toggleSelectAll">
@@ -337,6 +345,7 @@ const recommendPageSize = ref<number>(8)
const recommendHasMore = ref<boolean>(true)
const recommendInitialized = ref<boolean>(false)
const loading = ref<boolean>(false)
const isLoggedIn = ref<boolean>(false)
const statusBarHeight = ref(0)
const isManageMode = ref(false)
const updatingItems = ref<Set<string>>(new Set()) // Track items being updated to prevent race conditions
@@ -540,6 +549,9 @@ const emptyTitle = computed((): string => {
})
const emptyDesc = computed((): string => {
if (!isLoggedIn.value && currentCartType.value == 'goods') {
return '登录后可同步购物车中的商品,换设备也能继续查看'
}
if (currentCartType.value == 'service') {
return '可切换筛选条件,或等待服务购物车正式接入'
}
@@ -552,6 +564,15 @@ const emptyDesc = computed((): string => {
return '快去挑选喜欢的商品吧'
})
function refreshLoginState(): void {
const userId = supabaseService.getCurrentUserId()
isLoggedIn.value = userId != null && userId !== ''
}
function goCartLogin(): void {
goToLogin('/pages/main/cart')
}
const showEmptyShoppingBtn = computed((): boolean => {
return currentCartType.value == 'goods'
})
@@ -829,6 +850,15 @@ function onRecommendScroll(event: any): void {
// 加载数据
const loadCartData = async () => {
loading.value = true
const userId = supabaseService.getCurrentUserId()
if (userId == null || userId === '') {
isLoggedIn.value = false
cartItems.value = []
loading.value = false
return
}
isLoggedIn.value = true
try {
// 获取会员折扣信息
@@ -892,6 +922,7 @@ const loadCartData = async () => {
}
onShow(() => {
refreshLoginState()
loadCartData()
})
@@ -1692,6 +1723,68 @@ const goToCheckout = () => {
font-size: 16px;
}
.guest-login-bar {
position: fixed;
left: 12px;
right: 12px;
bottom: calc(var(--window-bottom) + 12px);
height: 48px;
padding: 0 8px 0 10px;
border-radius: 24px;
background-color: rgba(45, 38, 42, 0.72);
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
backdrop-filter: blur(10px);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
z-index: 998;
}
.cart-guest-login-bar {
background-color: rgba(55, 41, 43, 0.76);
}
.guest-login-left {
flex: 1;
min-width: 0;
display: flex;
flex-direction: row;
align-items: center;
}
.guest-login-avatar {
width: 32px;
height: 32px;
border-radius: 16px;
margin-right: 8px;
background-color: rgba(255, 255, 255, 0.85);
}
.guest-login-text {
flex: 1;
min-width: 0;
font-size: 12px;
color: #ffffff;
lines: 1;
}
.guest-login-btn {
height: 32px;
line-height: 32px;
padding: 0 14px;
border-radius: 16px;
background-color: #ff4d31;
color: #ffffff;
font-size: 12px;
font-weight: 600;
margin-left: 8px;
}
.guest-login-btn::after {
border: none;
}
/* 购物车商品列表 */
.cart-list {
background-color: transparent; /* 背景透明,因为每个店铺有自己的卡片 */
@@ -2491,7 +2584,7 @@ const goToCheckout = () => {
}
.tabbar-safe-area {
height: 150px;
height: 166px;
width: 100%;
background-color: transparent;
}

View File

@@ -205,6 +205,14 @@
<view class="profile-bottom-safe"></view>
</view>
</scroll-view>
<view v-if="!isLoggedIn" class="guest-login-bar">
<view class="guest-login-left">
<image class="guest-login-avatar" src="/static/images/default.png" mode="aspectFit" />
<text class="guest-login-text">登录一下,康养权益和订单记录同步保存~</text>
</view>
<button class="guest-login-btn" @click.stop="goProfileLogin">立即登录</button>
</view>
</view>
</template>
@@ -332,6 +340,7 @@ export default {
recommendBottomLocked: false,
recommendViewportHeight: 0,
pageWindowHeight: 0,
isLoggedIn: false,
guessLoadMoreKey: 0,
statusBarHeight: 0,
isAndroidApp: false,
@@ -362,6 +371,7 @@ export default {
},
onLoad() {
this.initPage()
this.refreshLoginState()
this.loadUserProfile()
this.loadOrders()
@@ -370,6 +380,7 @@ export default {
uni.$on('authChanged', this.handleAuthChanged)
},
onShow() {
this.refreshLoginState()
this.refreshData()
},
onUnload() {
@@ -413,6 +424,11 @@ export default {
}
},
methods: {
refreshLoginState() {
const userId = supabaseService.getCurrentUserId()
this.isLoggedIn = userId != null && userId !== ''
},
toRecommendScrollJson(value: any | null): UTSJSONObject | null {
if (value == null) {
return null
@@ -851,6 +867,7 @@ export default {
return 'height:' + this.pageWindowHeight + 'px;min-height:' + this.pageWindowHeight + 'px;'
},
async loadUserProfile() {
this.refreshLoginState()
const userId = supabaseService.getCurrentUserId()
if (userId == null || userId === '') {
this.resetGuestProfileState()
@@ -969,6 +986,7 @@ export default {
},
refreshData() {
this.refreshLoginState()
const userId = supabaseService.getCurrentUserId()
if (userId == null || userId === '') {
this.resetGuestProfileState()
@@ -1391,13 +1409,17 @@ export default {
editProfile() {
const userId = supabaseService.getCurrentUserId()
if (userId == null || userId === '') {
goToLogin('/pages/user/profile')
this.goProfileLogin()
return
}
uni.navigateTo({
url: '/pages/user/profile'
})
},
goProfileLogin() {
goToLogin('/pages/main/profile')
},
// 跳转设置
goToSettings() {
@@ -1667,6 +1689,7 @@ export default {
},
handleAuthChanged(data: any) {
this.refreshLoginState()
let payload: UTSJSONObject | null = null
if (data instanceof UTSJSONObject) {
@@ -1687,6 +1710,11 @@ export default {
}
const loggedIn = payload.getBoolean('loggedIn')
if (loggedIn === true) {
this.refreshData()
return
}
if (loggedIn === false) {
this.resetGuestProfileState()
}
@@ -2492,7 +2520,65 @@ export default {
}
.profile-bottom-safe {
height: 90px;
height: 156px;
}
.guest-login-bar {
position: fixed;
left: 12px;
right: 12px;
bottom: calc(var(--window-bottom) + 12px);
height: 48px;
padding: 0 8px 0 10px;
border-radius: 24px;
background-color: rgba(45, 38, 42, 0.72);
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
backdrop-filter: blur(10px);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
z-index: 998;
}
.guest-login-left {
flex: 1;
min-width: 0;
display: flex;
flex-direction: row;
align-items: center;
}
.guest-login-avatar {
width: 32px;
height: 32px;
border-radius: 16px;
margin-right: 8px;
background-color: rgba(255, 255, 255, 0.85);
}
.guest-login-text {
flex: 1;
min-width: 0;
font-size: 12px;
color: #ffffff;
lines: 1;
}
.guest-login-btn {
height: 32px;
line-height: 32px;
padding: 0 14px;
border-radius: 16px;
background-color: #ff6a4d;
color: #ffffff;
font-size: 12px;
font-weight: 600;
margin-left: 8px;
}
.guest-login-btn::after {
border: none;
}
.pending {

View File

@@ -4,7 +4,7 @@
<text class="empty-text">未找到评估信息</text>
</view>
<view v-else>
<ServicePanel title="上门评估" subtitle="先用 mock 表单承接风险等级、护理等级和评估结论。">
<ServicePanel title="上门评估" subtitle="基于真实服务单补充风险等级、护理等级和评估结论。">
<ServiceInfoList
:items="[
{ label: '服务单号:', value: detail.caseNo },

View File

@@ -4,7 +4,7 @@
<text class="empty-text">未找到服务方案</text>
</view>
<view v-else>
<ServicePanel title="服务方案" subtitle="先用 mock 数据完成计划频次、周期和执行说明。">
<ServicePanel title="服务方案" subtitle="基于真实服务单补充频次、周期和执行说明。">
<ServiceInfoList
:items="[
{ label: '服务单号:', value: detail.caseNo },

View File

@@ -83,7 +83,7 @@
<script setup lang="uts">
import { computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { onLoad, onShow } from '@dcloudio/uni-app'
import ServicePageScaffold from '@/components/homeService/ServicePageScaffold.uvue'
import ServicePanel from '@/components/homeService/ServicePanel.uvue'
import ServiceStatusTag from '@/components/homeService/ServiceStatusTag.uvue'
@@ -193,6 +193,10 @@ onLoad((options) => {
}
loadData()
})
onShow(() => {
loadData()
})
</script>
<style scoped>

View File

@@ -1,6 +1,6 @@
<template>
<ServicePageScaffold title="到岗签到" fallback-url="/pages/mall/merchant/home-service/tasks">
<ServicePanel title="到岗签到" subtitle="先用 mock 方式记录签到结果、到岗说明和留痕提示。">
<ServicePanel title="到岗签到" subtitle="记录真实签到结果、到岗说明和执行留痕提示。">
<text class="info">任务编号:{{ taskNo }}</text>
<text class="info">当前状态:{{ taskStatus }}</text>
<view class="block">

View File

@@ -1,6 +1,6 @@
<template>
<ServicePageScaffold title="异常上报" fallback-url="/pages/mall/merchant/home-service/tasks">
<ServicePanel title="异常上报" subtitle="先完成异常类型、说明和调度通知的 mock 处理。">
<ServicePanel title="异常上报" subtitle="提交真实异常类型、说明和调度协同信息。">
<text class="info">任务编号:{{ taskNo }}</text>
<view class="block">
<text class="label">异常类型</text>

View File

@@ -70,6 +70,10 @@ async function handleAdvance() {
goCheckIn()
return
}
if (detail.value != null && detail.value.status != 'serving') {
uni.showToast({ title: '当前任务无需更新', icon: 'none' })
return
}
const result = await advanceWorkerTask(taskId.value)
if (result != null) {
detail.value = result

View File

@@ -237,7 +237,7 @@ onLoad((opts) => {
uni.setNavigationBarTitle({ title: '服务人员登录' })
} else {
loginMode.value = 'consumer'
uni.setNavigationBarTitle({ title: '用户登录' })
uni.setNavigationBarTitle({ title: '登录' })
}
}
})
@@ -499,6 +499,7 @@ const handleLogin = async () => {
clearDeliveryAuth()
throw new Error(authResult.message != '' ? authResult.message : '服务人员登录失败')
}
uni.$emit('authChanged', { loggedIn: true })
uni.showToast({ title: '登录成功', icon: 'success' })
setTimeout(() => {
const redirect = redirectPath.value
@@ -543,6 +544,7 @@ const handleLogin = async () => {
setUserProfile(adminProfile)
// uni.setStorageSync('merchant_id', 'admin') // mock removed
uni.$emit('authChanged', { loggedIn: true })
uni.showToast({ title: '管理员登录成功', icon: 'success' })
setTimeout(() => {
goTargetHome()
@@ -649,6 +651,7 @@ const handleLogin = async () => {
// 已移除对 shared storage user_id 的依赖
const currentSession = supa.getSession()
uni.$emit('authChanged', { loggedIn: true })
uni.showToast({ title: '登录成功', icon: 'success' })
// 获取并上报推送 CID若可用

File diff suppressed because it is too large Load Diff

View File

@@ -24,6 +24,11 @@ CREATE TABLE IF NOT EXISTS public.ak_users (
bio text,
avatar_url text,
preferred_language text,
health_goal text,
service_address text,
emergency_contact text,
chronic_notes text,
care_preference text,
role text,
school_id text,
grade_id text,
@@ -44,6 +49,11 @@ COMMENT ON COLUMN public.ak_users.weight_kg IS '体重(公斤)';
COMMENT ON COLUMN public.ak_users.bio IS '个人简介';
COMMENT ON COLUMN public.ak_users.avatar_url IS '头像地址';
COMMENT ON COLUMN public.ak_users.preferred_language IS '偏好语言';
COMMENT ON COLUMN public.ak_users.health_goal IS '健康目标';
COMMENT ON COLUMN public.ak_users.service_address IS '常住服务地址';
COMMENT ON COLUMN public.ak_users.emergency_contact IS '紧急联系人';
COMMENT ON COLUMN public.ak_users.chronic_notes IS '慢病或过敏备注';
COMMENT ON COLUMN public.ak_users.care_preference IS '护理偏好';
COMMENT ON COLUMN public.ak_users.role IS '角色(如 customer/merchant/admin 等)';
COMMENT ON COLUMN public.ak_users.school_id IS '学校ID可选';
COMMENT ON COLUMN public.ak_users.grade_id IS '年级ID可选';

View File

@@ -10,10 +10,17 @@ export type UserProfile ={
bio?: string;
avatar_url?: string;
preferred_language?: string;
health_goal?: string;
service_address?: string;
emergency_contact?: string;
chronic_notes?: string;
care_preference?: string;
role?:string;
school_id?: string; // 所属学校ID
grade_id?: string; // 所属年级ID
class_id?: string; // 所属班级ID
created_at?: string;
updated_at?: string;
}
// 语言选项类型 - 对应 ak_languages 表

View File

@@ -1,16 +1,18 @@
import { getDeliveryProfileByUserId, loginDelivery as loginDeliveryApi } from '@/api/delivery.uts'
import {
acceptOrder as acceptRealServiceOrder,
arriveOrder as arriveRealServiceOrder,
checkinOrder as checkinRealServiceOrder,
departOrder as departRealServiceOrder,
finishOrder as finishRealServiceOrder,
getDashboard as getRealDashboard,
getOrderDetail as getRealServiceOrderDetail,
getOrdersByTab as getRealOrdersByTab,
saveServiceRecord as saveRealServiceRecord,
startService as startRealService
} from '@/services/serviceOrderService.uts'
acceptDeliveryOrderById,
arriveOrderById,
checkinOrderById,
finishServiceById,
getDeliveryDashboardByStaffId,
getDeliveryOrderDetailById,
getDeliveryOrdersByStaffId,
getDeliveryProfileByUserId,
loginDelivery as loginDeliveryApi,
saveServiceProgressById,
startDepartById,
startServiceById
} from '@/api/delivery.uts'
import { saveServiceRecord as saveRealServiceRecord } from '@/services/serviceOrderService.uts'
import {
acceptCareOrder,
checkInCareOrder,
@@ -31,12 +33,13 @@ import {
updateCareOrderStatus,
updateDeliveryCareOnlineStatus
} from '@/mock/delivery-care.mock.uts'
import { getUserInfo, requireDeliveryAuth } from '@/utils/deliveryAuth.uts'
import { requireDeliveryAuth } from '@/utils/deliveryAuth.uts'
import type {
DeliveryAbnormalReportType,
DeliveryCheckinPayloadType,
DeliveryDashboardType,
DeliveryExceptionPayloadType,
DeliveryFinishPayloadType,
DeliveryInfoType,
DeliveryLocationType,
DeliveryLoginPayloadType,
@@ -79,26 +82,51 @@ export async function checkDeliveryAuth(): Promise<boolean> {
return result.ok
}
async function getCurrentStaffId(): Promise<string> {
const profile = await getDeliveryProfile()
if (profile == null) {
return ''
}
return profile.id
}
function createEmptyLocation(): DeliveryLocationType {
return {
latitude: 0,
longitude: 0,
address: '',
time: new Date().toISOString().replace('T', ' ').substring(0, 19)
}
}
export async function getDeliveryDashboard(): Promise<DeliveryDashboardType> {
const staffId = await getCurrentStaffId()
if (staffId != '') {
return await getDeliveryDashboardByStaffId(staffId)
}
return getDeliveryCareDashboard()
}
export async function getDeliveryOrders(params: DeliveryOrderQueryType): Promise<Array<DeliveryOrderType>> {
const staffId = await getCurrentStaffId()
if (staffId != '') {
return await getDeliveryOrdersByStaffId(staffId, params)
}
if (params.tab == 'pending' || params.tab == 'pending_assignment') {
return await getRealOrdersByTab('pending')
return getPendingCareOrders()
}
if (params.tab == 'history' || params.tab == 'completed' || params.tab == 'archive') {
return await getRealOrdersByTab('history')
return getHistoryCareOrders()
}
return await getRealOrdersByTab('today')
return getTodayCareOrders()
}
export async function getDeliveryOrderDetail(id: string): Promise<DeliveryOrderType | null> {
return await getRealServiceOrderDetail(id)
return await getDeliveryOrderDetailById(id)
}
export async function acceptDeliveryOrder(id: string): Promise<DeliveryOrderType | null> {
return await acceptRealServiceOrder(id)
return await acceptDeliveryOrderById(id)
}
export async function rejectDeliveryOrder(id: string, reason: string): Promise<DeliveryOrderType | null> {
@@ -106,30 +134,23 @@ export async function rejectDeliveryOrder(id: string, reason: string): Promise<D
}
export async function startDepart(id: string, location: DeliveryLocationType): Promise<DeliveryOrderType | null> {
return await departRealServiceOrder(id, location)
return await startDepartById(id, location)
}
export async function arriveOrder(id: string, location: DeliveryLocationType): Promise<DeliveryOrderType | null> {
return await arriveRealServiceOrder(id, location)
return await arriveOrderById(id, location)
}
export async function checkinOrder(id: string, payload: DeliveryCheckinPayloadType): Promise<DeliveryOrderType | null> {
return await checkinRealServiceOrder(id, payload)
return await checkinOrderById(id, payload)
}
export async function startService(id: string): Promise<DeliveryOrderType | null> {
return await startRealService(id)
return await startServiceById(id)
}
export async function saveServiceProgress(id: string, payload: DeliveryProgressPayloadType): Promise<DeliveryOrderType | null> {
const current = getCareOrderDetail(id)
if (current == null) {
return null
}
current.serviceItems = payload.items
current.progressNote = payload.progressNote
current.serviceSummary = payload.serviceSummary
return current
return await saveServiceProgressById(id, payload)
}
export async function uploadEvidence(id: string, phase: string, files: Array<string>): Promise<Array<any>> {
@@ -168,8 +189,13 @@ export async function submitException(id: string, payload: DeliveryExceptionPayl
return submitCareAbnormalReport(id, payload)
}
export async function finishService(id: string): Promise<DeliveryOrderType | null> {
return completeCareOrder(id)
export async function finishService(id: string, payload: DeliveryFinishPayloadType | null = null): Promise<DeliveryOrderType | null> {
const finishPayload = payload != null ? payload : {
serviceSummary: '',
signatureName: '',
confirmByFamily: false
} as DeliveryFinishPayloadType
return await finishServiceById(id, finishPayload)
}
export async function getDeliveryRecords(): Promise<Array<DeliveryRecordType>> {
@@ -198,27 +224,27 @@ export async function updateDeliveryOnlineStatus(status: string): Promise<Delive
}
export async function getDeliveryDashboardStats(): Promise<DeliveryDashboardType> {
return await getRealDashboard()
return await getDeliveryDashboard()
}
export async function getPendingServiceOrders(): Promise<Array<DeliveryOrderType>> {
return await getRealOrdersByTab('pending')
return await getDeliveryOrders({ tab: 'pending', keyword: '' } as DeliveryOrderQueryType)
}
export async function getTodayServiceOrders(): Promise<Array<DeliveryOrderType>> {
return await getRealOrdersByTab('today')
return await getDeliveryOrders({ tab: 'today', keyword: '' } as DeliveryOrderQueryType)
}
export async function getHistoryServiceOrders(): Promise<Array<DeliveryOrderType>> {
return await getRealOrdersByTab('history')
return await getDeliveryOrders({ tab: 'history', keyword: '' } as DeliveryOrderQueryType)
}
export async function getServiceOrderDetail(orderId: string): Promise<DeliveryOrderType | null> {
return await getRealServiceOrderDetail(orderId)
return await getDeliveryOrderDetail(orderId)
}
export async function acceptServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
return await acceptRealServiceOrder(orderId)
return await acceptDeliveryOrder(orderId)
}
export async function rejectServiceOrder(orderId: string, reason: string): Promise<DeliveryOrderType | null> {
@@ -226,18 +252,18 @@ export async function rejectServiceOrder(orderId: string, reason: string): Promi
}
export async function markDeparted(orderId: string): Promise<DeliveryOrderType | null> {
return await departRealServiceOrder(orderId, null)
return await startDepartById(orderId, createEmptyLocation())
}
export async function markArrived(orderId: string): Promise<DeliveryOrderType | null> {
return await arriveRealServiceOrder(orderId, null)
return await arriveOrderById(orderId, createEmptyLocation())
}
export async function checkInServiceOrder(orderId: string, note: string, location: DeliveryLocationType | null = null): Promise<DeliveryOrderType | null> {
if (location == null) {
return null
}
return await checkinRealServiceOrder(orderId, {
return await checkinOrderById(orderId, {
location,
note,
photos: [] as Array<string>,
@@ -246,7 +272,7 @@ export async function checkInServiceOrder(orderId: string, note: string, locatio
}
export async function startServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
return await startRealService(orderId)
return await startServiceById(orderId)
}
export async function submitServiceRecord(orderId: string, record: DeliveryServiceRecordType): Promise<DeliveryOrderType | null> {
@@ -254,7 +280,7 @@ export async function submitServiceRecord(orderId: string, record: DeliveryServi
}
export async function completeServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
return await finishRealServiceOrder(orderId)
return await finishService(orderId)
}
export async function submitAbnormalReport(orderId: string, report: DeliveryExceptionPayloadType): Promise<DeliveryOrderType | null> {

View File

@@ -20,6 +20,7 @@ import {
rejectServiceOrderAcceptance
} from '@/services/serviceOrderService.uts'
import supa from '@/components/supadb/aksupainstance.uts'
import { getCurrentUserId } from '@/utils/store.uts'
import {
getServiceOrderStatusText,
type ServiceOrderStatus,
@@ -27,6 +28,14 @@ import {
type ServiceOrderType
} from '@/types/service-order.uts'
function nowIso(): string {
return new Date().toISOString()
}
function buildId(prefix: string): string {
return prefix + '-' + String(Date.now()) + '-' + String(Math.floor(Math.random() * 100000)).padStart(5, '0')
}
function plainObject(source: any): any {
return JSON.parse(JSON.stringify(source)) as any
}
@@ -576,259 +585,500 @@ function mapOrderToCase(order: ServiceOrderType): HomeServiceCaseType {
}
}
function mapOrderToWorkerTask(order: ServiceOrderType): HomeServiceTaskType {
let taskStatus = 'pending_visit'
let taskStatusText = '待上门'
let taskStatusTone = 'warning'
let actionText = '签到开始'
if (order.status == 'arrived' || order.status == 'in_service') {
taskStatus = 'serving'
taskStatusText = '服务中'
taskStatusTone = 'primary'
actionText = '完成提交'
} else if (order.status == 'pending_acceptance' || order.status == 'accepted_by_user' || order.status == 'reviewed' || order.status == 'settled') {
taskStatus = 'completed'
taskStatusText = '待验收'
taskStatusTone = 'success'
actionText = '已提交'
} else if (order.status == 'exception' || order.status == 'rejected' || order.status == 'cancelled') {
taskStatus = 'exception'
taskStatusText = getServiceOrderStatusText(order.status)
taskStatusTone = 'warning'
actionText = '已上报'
}
return {
id: order.id,
caseId: order.id,
caseNo: order.orderNo,
status: taskStatus,
statusText: taskStatusText,
statusTone: taskStatusTone,
serviceName: order.serviceName,
elderName: order.recipientName,
address: order.addressSnapshot.fullAddress,
appointmentTime: formatServiceAppointmentText(order.appointmentTime),
checkInStatus: order.executionRecord != null && order.executionRecord.checkinTime != '' ? '已签到' : '未签到',
recordSummary: order.executionRecord != null ? (order.executionRecord.summary != '' ? order.executionRecord.summary : order.executionRecord.remark) : '待填写服务记录',
staffName: order.staffName == '' ? '待分配' : order.staffName,
staffPhone: order.staffPhone == '' ? '待分配' : order.staffPhone,
actionText,
timeline: mapLogsToTimeline(order.logs)
}
}
async function listWorkerTaskIds(): Promise<Array<string>> {
const userId = getCurrentUserId()
if (userId == '') {
return [] as Array<string>
}
const careTaskResponse = await supa.from('ec_care_tasks').select('id').eq('assigned_to', userId).order('created_at', { ascending: false }).execute()
if (careTaskResponse.error == null && careTaskResponse.data != null) {
const result = [] as Array<string>
const rows = careTaskResponse.data as Array<any>
for (let i = 0; i < rows.length; i++) {
const id = readString(rows[i], 'id')
if (id != '') {
result.push(id)
}
}
if (result.length > 0) {
return result
}
}
const legacyResponse = await supa.from('hss_service_orders').select('id').eq('current_staff_id', userId).order('created_at', { ascending: false }).execute()
if (legacyResponse.error != null || legacyResponse.data == null) {
return [] as Array<string>
}
const legacyIds = [] as Array<string>
const legacyRows = legacyResponse.data as Array<any>
for (let i = 0; i < legacyRows.length; i++) {
const id = readString(legacyRows[i], 'id')
if (id != '') {
legacyIds.push(id)
}
}
return legacyIds
}
async function isCareTask(taskId: string): Promise<boolean> {
const response = await supa.from('ec_care_tasks').select('id').eq('id', taskId).limit(1).execute()
return response.error == null && response.data != null && (response.data as Array<any>).length > 0
}
async function completeWorkerTask(taskId: string): Promise<HomeServiceTaskType | null> {
const completedAt = nowIso()
if (await isCareTask(taskId)) {
await supa.from('ec_care_tasks').update({
status: 'ACCEPTANCE_PENDING',
service_completed_at: completedAt,
acceptance_pending_at: completedAt,
updated_at: completedAt
}).eq('id', taskId).execute()
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: taskId,
from_status: 'ORDER_IN_SERVICE',
to_status: 'ACCEPTANCE_PENDING',
actor_id: getCurrentUserId(),
actor_role: 'merchant',
action: 'finish_service',
remark: '服务记录和凭证已经提交。',
created_at: completedAt
}).execute()
} else {
await supa.from('hss_service_orders').update({
status: 'pending_acceptance',
completed_at: completedAt,
pending_acceptance_at: completedAt,
updated_at: completedAt
}).eq('id', taskId).execute()
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: taskId,
from_status: 'in_service',
to_status: 'pending_acceptance',
operator_id: getCurrentUserId(),
operator_role: 'merchant',
remark: '服务记录和凭证已经提交。',
created_at: completedAt
}).execute()
}
return await fetchWorkerTaskDetail(taskId)
}
const ADMIN_ASSESSMENT_PREFIX = '[admin_assessment]'
const ADMIN_PLAN_PREFIX = '[admin_plan]'
const ADMIN_RECTIFICATION_PREFIX = '[admin_rectification]'
function encodeAdminRemark(prefix: string, payload: any): string {
return prefix + JSON.stringify(payload)
}
function parseAdminRemark(remark: string, prefix: string): any | null {
if (remark == '' || remark.indexOf(prefix) != 0) {
return null
}
const body = remark.substring(prefix.length)
if (body == '') {
return null
}
try {
return JSON.parse(body) as any
} catch (error) {
return null
}
}
function getDefaultCareLevel(order: ServiceOrderType): string {
if (order.serviceName.indexOf('随访') >= 0) {
return '随访管理'
}
if (order.serviceName.indexOf('护理') >= 0) {
return '护理二级'
}
return '护理一级'
}
function getOrderLatestRemark(order: ServiceOrderType): string {
for (let i = 0; i < order.logs.length; i++) {
if (order.logs[i].remark != '') {
return order.logs[i].remark
}
}
return ''
}
async function listAdminEventRows(caseId: string): Promise<Array<any>> {
if (await isCareTask(caseId)) {
const response = await supa.from('hc_work_order_events').select('*').eq('task_id', caseId).order('created_at', { ascending: false }).execute()
return response.data != null ? response.data as Array<any> : [] as Array<any>
}
const response = await supa.from('hss_service_order_status_logs').select('*').eq('order_id', caseId).order('created_at', { ascending: false }).execute()
return response.data != null ? response.data as Array<any> : [] as Array<any>
}
async function readAdminPayload(caseId: string, prefix: string): Promise<any | null> {
const rows = await listAdminEventRows(caseId)
for (let i = 0; i < rows.length; i++) {
const payload = parseAdminRemark(readString(rows[i], 'remark'), prefix)
if (payload != null) {
return payload
}
}
return null
}
async function readLatestExceptionSummary(caseId: string, order: ServiceOrderType): Promise<string> {
if (await isCareTask(caseId)) {
const response = await supa.from('hc_work_order_exceptions').select('description').eq('task_id', caseId).order('created_at', { ascending: false }).limit(1).execute()
if (response.data != null && (response.data as Array<any>).length > 0) {
const rows = response.data as Array<any>
const text = readString(rows[0], 'description')
if (text != '') {
return text
}
}
}
const latestRemark = getOrderLatestRemark(order)
if (latestRemark != '') {
return latestRemark
}
if (order.review != null && order.review.content != '') {
return order.review.content
}
return '待补充整改说明。'
}
function buildAssessmentDetail(order: ServiceOrderType, payload: any | null): HomeServiceAssessmentType {
const requirementTags = payload != null ? readStringArray(payload, 'requirementTags') : [] as Array<string>
return {
caseId: order.id,
caseNo: order.orderNo,
elderName: order.recipientName,
serviceName: order.serviceName,
riskLevel: payload != null && readString(payload, 'riskLevel') != '' ? readString(payload, 'riskLevel') : '中风险',
careLevel: payload != null && readString(payload, 'careLevel') != '' ? readString(payload, 'careLevel') : getDefaultCareLevel(order),
visitTime: formatServiceAppointmentText(order.appointmentTime),
assessmentSummary: payload != null && readString(payload, 'assessmentSummary') != '' ? readString(payload, 'assessmentSummary') : (order.remark != '' ? order.remark : '待补充上门评估结论。'),
requirementTags: requirementTags.length > 0 ? requirementTags : order.serviceSnapshot.tags
}
}
function buildPlanDetail(order: ServiceOrderType, payload: any | null): HomeServicePlanType {
const serviceCycle = payload != null && readString(payload, 'serviceCycle') != '' ? readString(payload, 'serviceCycle') : formatServiceAppointmentText(order.appointmentTime)
const amountText = '¥' + String(order.serviceSnapshot.price)
return {
caseId: order.id,
caseNo: order.orderNo,
elderName: order.recipientName,
serviceName: order.serviceName,
planTitle: payload != null && readString(payload, 'planTitle') != '' ? readString(payload, 'planTitle') : (order.serviceName + '执行方案'),
serviceFrequency: payload != null && readString(payload, 'serviceFrequency') != '' ? readString(payload, 'serviceFrequency') : '按预约执行',
serviceCycle: serviceCycle,
executorAdvice: payload != null && readString(payload, 'executorAdvice') != '' ? readString(payload, 'executorAdvice') : (order.staffName != '' ? ('优先由' + order.staffName + '承接本次服务并补全留痕。') : '优先安排熟悉该服务类型的执行人员。'),
billingSummary: payload != null && readString(payload, 'billingSummary') != '' ? readString(payload, 'billingSummary') : ('本次服务金额 ' + amountText),
planSummary: payload != null && readString(payload, 'planSummary') != '' ? readString(payload, 'planSummary') : (order.remark != '' ? order.remark : '待补充服务目标、执行重点和验收口径。')
}
}
function buildRectificationDetail(order: ServiceOrderType, payload: any | null, issueSummary: string): HomeServiceRectificationType {
const status = payload != null && readString(payload, 'status') != '' ? readString(payload, 'status') : (order.status == 'exception' ? 'pending' : 'closed')
return {
caseId: order.id,
caseNo: order.orderNo,
elderName: order.recipientName,
serviceName: order.serviceName,
issueSummary: payload != null && readString(payload, 'issueSummary') != '' ? readString(payload, 'issueSummary') : issueSummary,
deadline: payload != null && readString(payload, 'deadline') != '' ? readString(payload, 'deadline') : (order.pendingAcceptanceAt != '' ? order.pendingAcceptanceAt : formatServiceAppointmentText(order.appointmentTime)),
ownerName: payload != null && readString(payload, 'ownerName') != '' ? readString(payload, 'ownerName') : (order.staffName != '' ? order.staffName : '待分配'),
status: status,
statusText: status == 'closed' ? '已关闭' : '待整改'
}
}
export async function fetchWorkerTasks(): Promise<Array<HomeServiceTaskType>> {
await delay()
return TASK_STORE.map((item) => cloneTask(item))
const taskIds = await listWorkerTaskIds()
const result = [] as Array<HomeServiceTaskType>
for (let i = 0; i < taskIds.length; i++) {
const detail = await getServiceOrderDetail(taskIds[i])
if (detail != null) {
result.push(mapOrderToWorkerTask(detail))
}
}
return result
}
export async function fetchWorkerTaskDetail(taskId: string): Promise<HomeServiceTaskType | null> {
await delay()
const target = TASK_STORE.find((item) => item.id == taskId)
return target == null ? null : cloneTask(target)
const detail = await getServiceOrderDetail(taskId)
return detail == null ? null : mapOrderToWorkerTask(detail)
}
export async function advanceWorkerTask(taskId: string): Promise<HomeServiceTaskType | null> {
await delay()
const target = TASK_STORE.find((item) => item.id == taskId)
if (target == null) {
const detail = await fetchWorkerTaskDetail(taskId)
if (detail == null) {
return null
}
if (target.status == 'pending_visit') {
target.status = 'serving'
target.statusText = '服务中'
target.statusTone = 'primary'
target.checkInStatus = '已签到'
target.recordSummary = '已完成签到,请按步骤填写服务记录。'
target.actionText = '完成提交'
target.timeline.unshift({
id: 'tl-' + String(target.timeline.length + 1),
title: '已到岗签到',
time: '2026-05-13 14:55',
description: '护理员已在服务地址完成签到。'
})
} else if (target.status == 'serving') {
target.status = 'completed'
target.statusText = '待验收'
target.statusTone = 'success'
target.recordSummary = '已提交执行记录与服务凭证,等待家属验收。'
target.actionText = '已提交'
target.timeline.unshift({
id: 'tl-' + String(target.timeline.length + 1),
title: '服务完成待验收',
time: '2026-05-13 16:20',
description: '服务记录和凭证已经提交。'
})
if (detail.status == 'serving') {
return await completeWorkerTask(taskId)
}
const relatedCase = CASE_STORE.find((item) => item.id == target.caseId)
if (relatedCase != null) {
if (target.status == 'serving') {
relatedCase.status = 'in_service'
relatedCase.statusText = '服务中'
relatedCase.statusTone = 'primary'
relatedCase.currentStep = 6
relatedCase.staffName = target.staffName
relatedCase.staffPhone = target.staffPhone
relatedCase.timeline.unshift({
id: 'case-log-' + String(relatedCase.timeline.length + 1),
title: '护理员已签到',
time: '2026-05-13 14:55',
description: '执行端已开始上门服务。'
})
} else if (target.status == 'completed') {
relatedCase.status = 'pending_acceptance'
relatedCase.statusText = '待验收'
relatedCase.statusTone = 'success'
relatedCase.currentStep = 7
relatedCase.timeline.unshift({
id: 'case-log-' + String(relatedCase.timeline.length + 1),
title: '执行完成待验收',
time: '2026-05-13 16:20',
description: '家属可查看记录并进行验收反馈。'
})
}
}
const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == target.caseId)
if (relatedAdmin != null) {
if (target.status == 'serving') {
relatedAdmin.status = 'in_service'
relatedAdmin.statusText = '服务中'
relatedAdmin.statusTone = 'primary'
relatedAdmin.staffName = target.staffName
} else if (target.status == 'completed') {
relatedAdmin.status = 'pending_acceptance'
relatedAdmin.statusText = '待验收'
relatedAdmin.statusTone = 'success'
}
}
return cloneTask(target)
return detail
}
export async function submitWorkerCheckIn(taskId: string, note: string): Promise<HomeServiceTaskType | null> {
await delay()
const target = TASK_STORE.find((item) => item.id == taskId)
if (target == null) {
return null
const checkedInAt = nowIso()
if (await isCareTask(taskId)) {
const recordId = buildId('care-checkin')
await supa.from('ec_care_records').insert({
id: recordId,
task_id: taskId,
record_type: 'checkin',
started_at: checkedInAt,
checked_in_at: checkedInAt,
location_text: note,
remark: note,
created_at: checkedInAt,
updated_at: checkedInAt
}).execute()
await supa.from('ec_care_tasks').update({
status: 'ORDER_IN_SERVICE',
checked_in_at: checkedInAt,
service_started_at: checkedInAt,
updated_at: checkedInAt
}).eq('id', taskId).execute()
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: taskId,
from_status: 'ORDER_ACCEPTED',
to_status: 'ORDER_IN_SERVICE',
actor_id: getCurrentUserId(),
actor_role: 'merchant',
action: 'checkin_task',
remark: note == '' ? '已完成签到,开始执行服务。' : note,
created_at: checkedInAt
}).execute()
} else {
const recordId = buildId('ser')
await supa.from('hss_service_execution_records').upsert({
id: recordId,
order_id: taskId,
assignment_id: '',
checkin_time: checkedInAt,
checkin_address: note,
service_started_at: checkedInAt,
remark: note,
created_at: checkedInAt,
updated_at: checkedInAt
}).execute()
await supa.from('hss_service_orders').update({
status: 'in_service',
arrived_at: checkedInAt,
service_started_at: checkedInAt,
updated_at: checkedInAt
}).eq('id', taskId).execute()
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: taskId,
from_status: 'accepted',
to_status: 'in_service',
operator_id: getCurrentUserId(),
operator_role: 'merchant',
remark: note == '' ? '已完成签到,开始执行服务。' : note,
created_at: checkedInAt
}).execute()
}
if (target.status == 'pending_visit') {
target.status = 'serving'
target.statusText = '服务中'
target.statusTone = 'primary'
target.checkInStatus = '已签到'
target.recordSummary = note == '' ? '已完成签到,请继续填写服务记录。' : note
target.actionText = '完成提交'
target.timeline.unshift({
id: 'checkin-' + String(target.timeline.length + 1),
title: '到岗签到完成',
time: '2026-05-13 14:40',
description: note == '' ? '护理员已完成签到。' : note
})
}
const relatedCase = CASE_STORE.find((item) => item.id == target.caseId)
if (relatedCase != null) {
relatedCase.status = 'in_service'
relatedCase.statusText = '服务中'
relatedCase.statusTone = 'primary'
relatedCase.currentStep = 6
relatedCase.staffName = target.staffName
relatedCase.staffPhone = target.staffPhone
relatedCase.timeline.unshift({
id: 'case-checkin-' + String(relatedCase.timeline.length + 1),
title: '执行人员已到岗',
time: '2026-05-13 14:40',
description: note == '' ? '已完成签到,开始执行服务。' : note
})
}
const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == target.caseId)
if (relatedAdmin != null) {
relatedAdmin.status = 'in_service'
relatedAdmin.statusText = '服务中'
relatedAdmin.statusTone = 'primary'
relatedAdmin.staffName = target.staffName
}
return cloneTask(target)
return await fetchWorkerTaskDetail(taskId)
}
export async function submitWorkerServiceRecord(taskId: string, summary: string): Promise<HomeServiceTaskType | null> {
await delay()
const target = TASK_STORE.find((item) => item.id == taskId)
if (target == null) {
const detail = await getServiceOrderDetail(taskId)
if (detail == null) {
return null
}
target.recordSummary = summary == '' ? target.recordSummary : summary
target.timeline.unshift({
id: 'record-' + String(target.timeline.length + 1),
title: '服务记录已更新',
time: '2026-05-13 15:30',
description: summary == '' ? '已保存服务记录。' : summary
})
const relatedCase = CASE_STORE.find((item) => item.id == target.caseId)
if (relatedCase != null) {
relatedCase.summary = summary == '' ? relatedCase.summary : summary
relatedCase.timeline.unshift({
id: 'case-record-' + String(relatedCase.timeline.length + 1),
title: '执行记录已回传',
time: '2026-05-13 15:30',
description: summary == '' ? '执行端已保存记录。' : summary
})
const now = nowIso()
const recordId = detail.executionRecord != null && detail.executionRecord.id != '' ? detail.executionRecord.id : buildId('worker-rec')
if (await isCareTask(taskId)) {
await supa.from('ec_care_records').upsert({
id: recordId,
task_id: taskId,
record_type: 'service',
started_at: detail.executionRecord != null ? detail.executionRecord.serviceStartedAt : detail.serviceStartedAt,
summary: summary,
remark: summary,
created_at: detail.executionRecord != null && detail.executionRecord.createdAt != '' ? detail.executionRecord.createdAt : now,
updated_at: now
}).execute()
await supa.from('ec_care_tasks').update({
status: 'ORDER_IN_SERVICE',
updated_at: now
}).eq('id', taskId).execute()
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: taskId,
from_status: 'ORDER_IN_SERVICE',
to_status: 'ORDER_IN_SERVICE',
actor_id: getCurrentUserId(),
actor_role: 'merchant',
action: 'save_record',
remark: summary == '' ? '已保存服务记录。' : summary,
created_at: now
}).execute()
} else {
await supa.from('hss_service_execution_records').upsert({
id: recordId,
order_id: taskId,
assignment_id: detail.currentAssignmentId,
service_started_at: detail.executionRecord != null ? detail.executionRecord.serviceStartedAt : detail.serviceStartedAt,
summary: summary,
remark: summary,
created_at: detail.executionRecord != null && detail.executionRecord.createdAt != '' ? detail.executionRecord.createdAt : now,
updated_at: now
}).execute()
}
return cloneTask(target)
return await fetchWorkerTaskDetail(taskId)
}
export async function submitWorkerException(taskId: string, exceptionType: string, description: string): Promise<HomeServiceTaskType | null> {
await delay()
const target = TASK_STORE.find((item) => item.id == taskId)
if (target == null) {
return null
const now = nowIso()
if (await isCareTask(taskId)) {
await supa.from('hc_work_order_exceptions').insert({
id: buildId('hc-ex'),
task_id: taskId,
exception_type: exceptionType,
description: description,
occurred_at: now,
created_by: getCurrentUserId(),
created_at: now,
updated_at: now
}).execute()
await supa.from('ec_care_tasks').update({
status: 'ORDER_EXCEPTION',
updated_at: now
}).eq('id', taskId).execute()
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: taskId,
from_status: '',
to_status: 'ORDER_EXCEPTION',
actor_id: getCurrentUserId(),
actor_role: 'merchant',
action: 'report_exception',
remark: exceptionType + '' + description,
created_at: now
}).execute()
} else {
await supa.from('hss_service_orders').update({
status: 'exception',
updated_at: now
}).eq('id', taskId).execute()
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: taskId,
from_status: 'in_service',
to_status: 'exception',
operator_id: getCurrentUserId(),
operator_role: 'merchant',
remark: exceptionType + '' + description,
created_at: now
}).execute()
}
target.status = 'exception'
target.statusText = '异常上报'
target.statusTone = 'warning'
target.actionText = '已上报'
target.timeline.unshift({
id: 'exception-' + String(target.timeline.length + 1),
title: '异常已上报',
time: '2026-05-13 15:45',
description: exceptionType + '' + description
})
const relatedCase = CASE_STORE.find((item) => item.id == target.caseId)
if (relatedCase != null) {
relatedCase.status = 'exception'
relatedCase.statusText = '异常处理中'
relatedCase.statusTone = 'warning'
relatedCase.timeline.unshift({
id: 'case-exception-' + String(relatedCase.timeline.length + 1),
title: '服务异常待处理',
time: '2026-05-13 15:45',
description: exceptionType + '' + description
})
}
const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == target.caseId)
if (relatedAdmin != null) {
relatedAdmin.status = 'exception'
relatedAdmin.statusText = '异常处理中'
relatedAdmin.statusTone = 'warning'
}
return cloneTask(target)
return await fetchWorkerTaskDetail(taskId)
}
export async function fetchAdminAssessmentDetail(caseId: string): Promise<HomeServiceAssessmentType | null> {
await delay()
const target = ADMIN_ASSESSMENTS.find((item) => item.caseId == caseId)
return target == null ? null : cloneAssessment(target)
const order = await getServiceOrderDetail(caseId)
if (order == null) {
return null
}
const payload = await readAdminPayload(caseId, ADMIN_ASSESSMENT_PREFIX)
return buildAssessmentDetail(order, payload)
}
export async function submitAdminAssessment(caseId: string, riskLevel: string, careLevel: string, assessmentSummary: string): Promise<HomeServiceAssessmentType | null> {
await delay()
const target = ADMIN_ASSESSMENTS.find((item) => item.caseId == caseId)
if (target == null) {
const order = await getServiceOrderDetail(caseId)
if (order == null) {
return null
}
target.riskLevel = riskLevel
target.careLevel = careLevel
target.assessmentSummary = assessmentSummary
const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == caseId)
if (relatedAdmin != null) {
relatedAdmin.status = 'pending_plan'
relatedAdmin.statusText = '待方案'
relatedAdmin.statusTone = 'primary'
relatedAdmin.assessmentResult = careLevel + ' · ' + riskLevel
const payload = {
riskLevel,
careLevel,
assessmentSummary,
requirementTags: order.serviceSnapshot.tags,
updatedAt: nowIso()
}
const relatedCase = CASE_STORE.find((item) => item.id == caseId)
if (relatedCase != null) {
relatedCase.currentStep = 2
relatedCase.timeline.unshift({
id: 'case-assessment-' + String(relatedCase.timeline.length + 1),
title: '上门评估完成',
time: '2026-05-13 13:20',
description: assessmentSummary
})
if (await isCareTask(caseId)) {
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: caseId,
from_status: order.status,
to_status: order.status,
actor_id: getCurrentUserId(),
actor_role: 'admin',
action: 'submit_assessment',
remark: encodeAdminRemark(ADMIN_ASSESSMENT_PREFIX, payload),
created_at: nowIso()
}).execute()
} else {
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: caseId,
from_status: order.status,
to_status: order.status,
operator_id: getCurrentUserId(),
operator_role: 'admin',
remark: encodeAdminRemark(ADMIN_ASSESSMENT_PREFIX, payload),
created_at: nowIso()
}).execute()
}
return cloneAssessment(target)
return buildAssessmentDetail(order, payload)
}
export async function fetchAdminServicePlanDetail(caseId: string): Promise<HomeServicePlanType | null> {
await delay()
const target = ADMIN_PLANS.find((item) => item.caseId == caseId)
return target == null ? null : clonePlan(target)
const order = await getServiceOrderDetail(caseId)
if (order == null) {
return null
}
const payload = await readAdminPayload(caseId, ADMIN_PLAN_PREFIX)
return buildPlanDetail(order, payload)
}
export async function submitAdminServicePlan(
@@ -838,40 +1088,44 @@ export async function submitAdminServicePlan(
serviceCycle: string,
planSummary: string
): Promise<HomeServicePlanType | null> {
await delay()
const target = ADMIN_PLANS.find((item) => item.caseId == caseId)
if (target == null) {
const order = await getServiceOrderDetail(caseId)
if (order == null) {
return null
}
target.planTitle = planTitle
target.serviceFrequency = serviceFrequency
target.serviceCycle = serviceCycle
target.planSummary = planSummary
const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == caseId)
if (relatedAdmin != null) {
relatedAdmin.status = 'pending_dispatch'
relatedAdmin.statusText = '待派单'
relatedAdmin.statusTone = 'warning'
relatedAdmin.assessmentResult = target.planTitle + ' · ' + target.serviceFrequency
const payload = {
planTitle,
serviceFrequency,
serviceCycle,
executorAdvice: order.staffName != '' ? ('优先由' + order.staffName + '承接本次服务并补全留痕。') : '优先安排熟悉该服务类型的执行人员。',
billingSummary: '本次服务金额 ¥' + String(order.serviceSnapshot.price),
planSummary,
updatedAt: nowIso()
}
const relatedCase = CASE_STORE.find((item) => item.id == caseId)
if (relatedCase != null) {
relatedCase.currentStep = 3
relatedCase.status = 'pending_dispatch'
relatedCase.statusText = '待派单'
relatedCase.statusTone = 'warning'
relatedCase.timeline.unshift({
id: 'case-plan-' + String(relatedCase.timeline.length + 1),
title: '服务方案已生成',
time: '2026-05-13 14:10',
description: planSummary
})
if (await isCareTask(caseId)) {
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: caseId,
from_status: order.status,
to_status: order.status,
actor_id: getCurrentUserId(),
actor_role: 'admin',
action: 'submit_plan',
remark: encodeAdminRemark(ADMIN_PLAN_PREFIX, payload),
created_at: nowIso()
}).execute()
} else {
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: caseId,
from_status: order.status,
to_status: order.status,
operator_id: getCurrentUserId(),
operator_role: 'admin',
remark: encodeAdminRemark(ADMIN_PLAN_PREFIX, payload),
created_at: nowIso()
}).execute()
}
return clonePlan(target)
return buildPlanDetail(order, payload)
}
export async function fetchConsumerAcceptanceDetail(caseId: string): Promise<HomeServiceAcceptanceType | null> {
@@ -914,43 +1168,68 @@ export async function submitConsumerAcceptance(
}
export async function fetchAdminRectificationDetail(caseId: string): Promise<HomeServiceRectificationType | null> {
await delay()
const target = ADMIN_RECTIFICATIONS.find((item) => item.caseId == caseId)
return target == null ? null : cloneRectification(target)
const order = await getServiceOrderDetail(caseId)
if (order == null) {
return null
}
const payload = await readAdminPayload(caseId, ADMIN_RECTIFICATION_PREFIX)
const issueSummary = await readLatestExceptionSummary(caseId, order)
return buildRectificationDetail(order, payload, issueSummary)
}
export async function submitAdminRectification(caseId: string, issueSummary: string): Promise<HomeServiceRectificationType | null> {
await delay()
const target = ADMIN_RECTIFICATIONS.find((item) => item.caseId == caseId)
if (target == null) {
const order = await getServiceOrderDetail(caseId)
if (order == null) {
return null
}
target.issueSummary = issueSummary
target.status = 'closed'
target.statusText = '已关闭'
const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == caseId)
if (relatedAdmin != null) {
relatedAdmin.status = 'pending_acceptance'
relatedAdmin.statusText = '待复验收'
relatedAdmin.statusTone = 'primary'
const payload = {
issueSummary,
deadline: order.pendingAcceptanceAt != '' ? order.pendingAcceptanceAt : formatServiceAppointmentText(order.appointmentTime),
ownerName: order.staffName != '' ? order.staffName : '待分配',
status: 'closed',
updatedAt: nowIso()
}
const relatedCase = CASE_STORE.find((item) => item.id == caseId)
if (relatedCase != null) {
relatedCase.status = 'pending_acceptance'
relatedCase.statusText = '待复验收'
relatedCase.statusTone = 'primary'
relatedCase.timeline.unshift({
id: 'case-rectification-' + String(relatedCase.timeline.length + 1),
title: '整改处理完成',
time: '2026-05-13 18:10',
description: issueSummary
})
if (await isCareTask(caseId)) {
const reopenedAt = nowIso()
await supa.from('ec_care_tasks').update({
status: 'ACCEPTANCE_PENDING',
acceptance_pending_at: reopenedAt,
updated_at: reopenedAt
}).eq('id', caseId).execute()
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: caseId,
from_status: 'ACCEPTANCE_REJECTED',
to_status: 'ACCEPTANCE_PENDING',
actor_id: getCurrentUserId(),
actor_role: 'admin',
action: 'submit_rectification',
remark: encodeAdminRemark(ADMIN_RECTIFICATION_PREFIX, payload),
created_at: reopenedAt
}).execute()
} else {
const reopenedAt = nowIso()
await supa.from('hss_service_orders').update({
status: 'pending_acceptance',
pending_acceptance_at: reopenedAt,
updated_at: reopenedAt
}).eq('id', caseId).execute()
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: caseId,
from_status: order.status,
to_status: 'pending_acceptance',
operator_id: getCurrentUserId(),
operator_role: 'admin',
remark: encodeAdminRemark(ADMIN_RECTIFICATION_PREFIX, payload),
created_at: reopenedAt
}).execute()
}
return cloneRectification(target)
const latest = await getServiceOrderDetail(caseId)
if (latest == null) {
return buildRectificationDetail(order, payload, issueSummary)
}
return buildRectificationDetail(latest, payload, issueSummary)
}
export async function fetchAdminSettlementDetail(caseId: string): Promise<HomeServiceSettlementType | null> {

View File

@@ -30,6 +30,10 @@ function nowText(): string {
return new Date().toISOString().replace('T', ' ').substring(0, 19)
}
function nowIso(): string {
return new Date().toISOString()
}
function buildId(prefix: string): string {
return prefix + '-' + String(Date.now()) + '-' + String(Math.floor(Math.random() * 100000)).padStart(5, '0')
}
@@ -290,7 +294,7 @@ function parseServiceOrder(item: any, logs: Array<ServiceOrderTimelineItemType>,
}
}
async function insertStatusLog(orderId: string, fromStatus: string, toStatus: ServiceOrderStatus, operatorId: string, operatorRole: string, remark: string): Promise<void> {
async function insertLegacyStatusLog(orderId: string, fromStatus: string, toStatus: ServiceOrderStatus, operatorId: string, operatorRole: string, remark: string): Promise<void> {
await supa.from('hss_service_order_status_logs').insert({
id: buildId('slog'),
order_id: orderId,
@@ -303,110 +307,318 @@ async function insertStatusLog(orderId: string, fromStatus: string, toStatus: Se
}).execute()
}
export function buildAddressSnapshot(address: UserAddress, latitude: number, longitude: number): ServiceOrderAddressSnapshotType {
async function insertWorkOrderEvent(taskId: string, fromStatus: string, toStatus: string, actorId: string, actorRole: string, action: string, remark: string): Promise<void> {
await supa.from('hc_work_order_events').insert({
id: buildId('hc-event'),
task_id: taskId,
from_status: fromStatus == '' ? null : fromStatus,
to_status: toStatus,
actor_id: actorId == '' ? null : actorId,
actor_role: actorRole,
action,
remark,
created_at: nowIso()
}).execute()
}
function readFirstString(source: any, keys: Array<string>): string {
for (let i = 0; i < keys.length; i++) {
const value = readString(source, keys[i])
if (value != '') {
return value
}
}
return ''
}
function readFirstNumber(source: any, keys: Array<string>): number {
for (let i = 0; i < keys.length; i++) {
const value = readNumber(source, keys[i])
if (value != 0) {
return value
}
}
return 0
}
function readJsonObjectField(source: any, keys: Array<string>): any {
const plain = plainObject(source)
for (let i = 0; i < keys.length; i++) {
const value = plain[keys[i]]
if (value != null) {
return value
}
}
return null
}
function mapCareTaskRowToLegacyOrderRow(item: any): any {
const serviceSnapshotValue = readJsonObjectField(item, ['service_snapshot_json'])
const addressSnapshotValue = readJsonObjectField(item, ['address_snapshot_json'])
let derivedStatus = readString(item, 'status')
if (readFirstString(item, ['accepted_by_family_at']) != '') {
derivedStatus = 'ACCEPTED'
} else if (readFirstString(item, ['acceptance_pending_at']) != '') {
derivedStatus = 'ACCEPTANCE_PENDING'
} else if (readString(item, 'service_started_at') != '') {
derivedStatus = 'ORDER_IN_SERVICE'
} else if (readFirstString(item, ['checked_in_at']) != '') {
derivedStatus = 'ORDER_CHECKED_IN'
} else if (readString(item, 'departed_at') != '') {
derivedStatus = 'departed'
} else if (readString(item, 'accepted_at') != '') {
derivedStatus = 'ORDER_ACCEPTED'
} else if (readFirstString(item, ['assigned_to']) != '') {
derivedStatus = 'ORDER_ASSIGNED'
}
const serviceSnapshot = serviceSnapshotValue != null ? serviceSnapshotValue : {
serviceId: readFirstString(item, ['service_catalog_id', 'service_id']),
serviceName: readString(item, 'service_name'),
category: readFirstString(item, ['service_category', 'category']),
price: readFirstNumber(item, ['service_price', 'price']),
durationText: readFirstString(item, ['service_duration_text', 'duration_text']),
summary: readFirstString(item, ['service_summary', 'summary']),
tags: [] as Array<string>,
suitableFor: readFirstString(item, ['suitable_for'])
}
return {
addressId: address.id,
contactName: address.recipient_name,
contactPhone: address.phone,
province: address.province,
city: address.city,
district: address.district,
detailAddress: address.detail_address,
fullAddress: address.province + address.city + address.district + ' ' + address.detail_address,
latitude,
longitude,
coordinateType: 'gcj02',
remark: address.label ?? ''
id: readString(item, 'id'),
order_no: readFirstString(item, ['task_no', 'order_no']),
user_id: readFirstString(item, ['user_id', 'requester_user_id']),
service_id: readFirstString(item, ['service_catalog_id', 'service_id']),
service_name: readString(item, 'service_name'),
service_snapshot_json: serviceSnapshot,
service_address_id: readFirstString(item, ['service_address_id', 'address_id']),
address_snapshot_json: addressSnapshotValue != null ? addressSnapshotValue : JSON.parse('{}'),
recipient_name: readFirstString(item, ['elder_name', 'recipient_name']),
recipient_phone: readFirstString(item, ['elder_phone', 'recipient_phone']),
contact_name: readString(item, 'contact_name'),
contact_phone: readString(item, 'contact_phone'),
appointment_time: readFirstString(item, ['scheduled_at', 'appointment_time']),
remark: readString(item, 'remark'),
status: derivedStatus,
current_assignment_id: readFirstString(item, ['assignment_id', 'current_assignment_id']),
current_staff_id: readFirstString(item, ['assigned_to', 'current_staff_id']),
accepted_at: readString(item, 'accepted_at'),
departed_at: readString(item, 'departed_at'),
arrived_at: readFirstString(item, ['checked_in_at', 'arrived_at']),
service_started_at: readString(item, 'service_started_at'),
completed_at: readFirstString(item, ['service_completed_at', 'completed_at']),
pending_acceptance_at: readFirstString(item, ['acceptance_pending_at', 'pending_acceptance_at']),
accepted_by_user_at: readFirstString(item, ['accepted_by_family_at', 'accepted_by_user_at']),
reviewed_at: readString(item, 'reviewed_at'),
created_at: readString(item, 'created_at'),
updated_at: readString(item, 'updated_at')
}
}
export async function createServiceOrder(params: CreateServiceOrderParams): Promise<ServiceOrderType | null> {
function mapWorkOrderEventToLegacyLog(item: any): any {
return {
id: readString(item, 'id'),
order_id: readFirstString(item, ['task_id', 'order_id']),
from_status: readString(item, 'from_status'),
to_status: readFirstString(item, ['to_status', 'status']),
operator_id: readFirstString(item, ['actor_id', 'operator_id']),
operator_role: readFirstString(item, ['actor_role', 'operator_role']),
remark: readString(item, 'remark'),
created_at: readString(item, 'created_at')
}
}
function mapCareReviewRecordToLegacyReview(item: any): any {
return {
id: readString(item, 'id'),
order_id: readFirstString(item, ['task_id', 'order_id']),
user_id: readFirstString(item, ['created_by', 'user_id']),
rating: readFirstNumber(item, ['rating']),
tags_json: readJsonObjectField(item, ['tags_json']) != null ? readJsonObjectField(item, ['tags_json']) : [] as Array<string>,
content: readFirstString(item, ['content', 'summary', 'remark']),
created_at: readString(item, 'created_at')
}
}
function buildLegacyExecutionRecord(taskId: string, records: Array<any>): ServiceExecutionRecordType | null {
if (records.length == 0) {
return null
}
let checkinRecord: any = null
let serviceRecord: any = null
for (let i = 0; i < records.length; i++) {
const recordType = readFirstString(records[i], ['record_type', 'care_record_type'])
if (recordType == 'review') {
continue
}
if (recordType == 'checkin') {
checkinRecord = records[i]
continue
}
if (serviceRecord == null) {
serviceRecord = records[i]
}
}
const target = serviceRecord != null ? serviceRecord : (checkinRecord != null ? checkinRecord : records[0])
return parseExecutionRecord({
id: readString(target, 'id'),
order_id: taskId,
assignment_id: readFirstString(target, ['assignment_id']),
checkin_time: checkinRecord != null ? readFirstString(checkinRecord, ['checked_in_at', 'checkin_time', 'started_at']) : readFirstString(target, ['checked_in_at', 'checkin_time']),
checkin_latitude: checkinRecord != null ? readFirstNumber(checkinRecord, ['latitude', 'checkin_latitude']) : readFirstNumber(target, ['latitude', 'checkin_latitude']),
checkin_longitude: checkinRecord != null ? readFirstNumber(checkinRecord, ['longitude', 'checkin_longitude']) : readFirstNumber(target, ['longitude', 'checkin_longitude']),
checkin_address: checkinRecord != null ? readFirstString(checkinRecord, ['location_text', 'checkin_address', 'remark']) : readFirstString(target, ['location_text', 'checkin_address']),
service_started_at: readFirstString(target, ['started_at', 'service_started_at']),
service_finished_at: readFirstString(target, ['finished_at', 'service_finished_at']),
actual_duration_minutes: readFirstNumber(target, ['duration_minutes', 'actual_duration_minutes']),
service_items_json: readJsonObjectField(target, ['service_items_json']) != null ? readJsonObjectField(target, ['service_items_json']) : [] as Array<any>,
summary: readFirstString(target, ['summary', 'content']),
remark: readString(target, 'remark'),
track_points_json: readJsonObjectField(target, ['track_points_json']) != null ? readJsonObjectField(target, ['track_points_json']) : [] as Array<any>,
created_at: readString(target, 'created_at'),
updated_at: readString(target, 'updated_at')
})
}
async function getCareTaskDetail(taskId: string): Promise<ServiceOrderType | null> {
const taskResponse = await supa.from('ec_care_tasks').select('*').eq('id', taskId).limit(1).execute()
if (taskResponse.error != null || taskResponse.data == null) {
return null
}
const taskRows = taskResponse.data as Array<any>
if (taskRows.length == 0) {
return null
}
const eventsResponse = await supa.from('hc_work_order_events').select('*').eq('task_id', taskId).order('created_at', { ascending: false }).execute()
const recordsResponse = await supa.from('ec_care_records').select('*').eq('task_id', taskId).order('created_at', { ascending: false }).execute()
const evidenceResponse = await supa.from('hc_evidence_files').select('*').eq('task_id', taskId).order('created_at', { ascending: false }).execute()
const logs = [] as Array<ServiceOrderTimelineItemType>
if (eventsResponse.data != null) {
const rawEvents = eventsResponse.data as Array<any>
for (let i = 0; i < rawEvents.length; i++) {
logs.push(parseTimeline(mapWorkOrderEventToLegacyLog(rawEvents[i])))
}
}
let review: ServiceReviewType | null = null
const recordRows = recordsResponse.data != null ? recordsResponse.data as Array<any> : [] as Array<any>
for (let i = 0; i < recordRows.length; i++) {
const recordType = readFirstString(recordRows[i], ['record_type', 'care_record_type'])
if (recordType == 'review') {
review = parseReview(mapCareReviewRecordToLegacyReview(recordRows[i]))
break
}
}
const parsed = parseServiceOrder(mapCareTaskRowToLegacyOrderRow(taskRows[0]), logs, review)
parsed.executionRecord = buildLegacyExecutionRecord(taskId, recordRows)
if (evidenceResponse.data != null) {
const rawEvidence = evidenceResponse.data as Array<any>
const evidenceFiles = [] as Array<ServiceEvidenceFileType>
for (let i = 0; i < rawEvidence.length; i++) {
evidenceFiles.push(parseEvidenceFile({
id: readString(rawEvidence[i], 'id'),
order_id: taskId,
execution_record_id: readFirstString(rawEvidence[i], ['care_record_id', 'execution_record_id']),
phase: readString(rawEvidence[i], 'phase'),
file_type: readString(rawEvidence[i], 'file_type'),
storage_path: readString(rawEvidence[i], 'storage_path'),
file_url: readString(rawEvidence[i], 'file_url'),
latitude: readFirstNumber(rawEvidence[i], ['latitude']),
longitude: readFirstNumber(rawEvidence[i], ['longitude']),
captured_at: readString(rawEvidence[i], 'captured_at'),
created_at: readString(rawEvidence[i], 'created_at')
}))
}
parsed.evidenceFiles = evidenceFiles
}
if (parsed.currentStaffId != '') {
const staffResponse = await supa.from('ml_delivery_staff').select('nickname, phone').eq('uid', parsed.currentStaffId).limit(1).execute()
if (staffResponse.data != null) {
const rawStaffList = staffResponse.data as Array<any>
if (rawStaffList.length > 0) {
parsed.staffName = readString(rawStaffList[0], 'nickname')
parsed.staffPhone = readString(rawStaffList[0], 'phone')
}
}
}
return parsed
}
async function tryCreateCareTask(params: CreateServiceOrderParams): Promise<ServiceOrderType | null> {
const userId = getCurrentUserId()
if (userId == '') {
return null
}
const orderId = buildId('so')
const orderNo = buildOrderNo()
const now = new Date().toISOString()
const requestId = buildId('sr')
const taskId = buildId('ct')
const taskNo = buildOrderNo()
const createdAt = nowIso()
const appointmentTime = normalizeAppointmentTime(params.appointmentTime)
const response = await supa.from('hss_service_orders').insert({
id: orderId,
order_no: orderNo,
const requestResponse = await supa.from('ec_service_requests').insert({
id: requestId,
user_id: userId,
service_id: params.service.id,
service_catalog_id: params.service.id,
service_name: params.service.name,
service_snapshot_json: params.service as any,
service_address_id: normalizeUuidOrNull(params.address.addressId),
address_snapshot_json: params.address as any,
recipient_name: params.recipientName,
recipient_phone: params.recipientPhone,
service_category: params.service.category,
elder_name: params.recipientName,
elder_phone: params.recipientPhone,
contact_name: params.contactName,
contact_phone: params.contactPhone,
appointment_time: appointmentTime,
address_snapshot_json: params.address as any,
scheduled_at: appointmentTime,
remark: params.remark,
status: 'created',
created_at: now,
updated_at: now
status: 'ORDER_CREATED',
created_at: createdAt,
updated_at: createdAt
}).execute()
if (response.error != null) {
console.error('createServiceOrder failed', response.error)
if (requestResponse.error != null) {
return null
}
await insertStatusLog(orderId, '', 'created', userId, 'consumer', '创建服务订单')
const taskResponse = await supa.from('ec_care_tasks').insert({
id: taskId,
task_no: taskNo,
request_id: requestId,
user_id: userId,
service_catalog_id: params.service.id,
service_name: params.service.name,
service_category: params.service.category,
service_snapshot_json: params.service as any,
address_snapshot_json: params.address as any,
elder_name: params.recipientName,
elder_phone: params.recipientPhone,
contact_name: params.contactName,
contact_phone: params.contactPhone,
scheduled_at: appointmentTime,
remark: params.remark,
status: 'ORDER_CREATED',
created_at: createdAt,
updated_at: createdAt
}).execute()
if (taskResponse.error != null) {
return null
}
await insertWorkOrderEvent(taskId, '', 'ORDER_CREATED', userId, 'consumer', 'create_task', '创建服务申请')
const staffResponse = await supa
.from('ml_delivery_staff')
.select('id, station_id, nickname, phone, status, deleted_at')
.select('id, uid, station_id, nickname, phone, status, deleted_at')
.eq('status', 1)
.order('created_at', { ascending: true })
.execute()
if (staffResponse.data != null) {
const rawStaffList = staffResponse.data as any[]
const rawStaffList = staffResponse.data as Array<any>
if (rawStaffList.length > 0) {
const staffObj = plainObject(rawStaffList[0])
const assignmentId = buildId('sa')
await supa.from('hss_service_assignments').insert({
id: assignmentId,
order_id: orderId,
staff_id: readString(staffObj, 'id'),
station_id: readString(staffObj, 'station_id') == '' ? null : readString(staffObj, 'station_id'),
status: 'assigned',
assigned_at: now,
created_at: now,
updated_at: now
}).execute()
await supa.from('hss_service_orders').update({
status: 'assigned',
current_assignment_id: assignmentId,
current_staff_id: readString(staffObj, 'id'),
updated_at: now
}).eq('id', orderId).execute()
await insertStatusLog(orderId, 'created', 'assigned', userId, 'system', '系统已自动派单')
const staffObj = rawStaffList[0]
const assignedUserId = readFirstString(staffObj, ['uid', 'id'])
if (assignedUserId != '') {
await supa.from('ec_care_tasks').update({
status: 'ORDER_ASSIGNED',
assigned_to: assignedUserId,
updated_at: createdAt
}).eq('id', taskId).execute()
await insertWorkOrderEvent(taskId, 'ORDER_CREATED', 'ORDER_ASSIGNED', userId, 'system', 'assign_task', '系统已自动派单')
}
}
}
return await getServiceOrderDetail(orderId)
return await getCareTaskDetail(taskId)
}
export async function listConsumerServiceOrders(): Promise<Array<ServiceOrderType>> {
const userId = getCurrentUserId()
if (userId == '') {
return [] as Array<ServiceOrderType>
}
const response = await supa.from('hss_service_orders').select('*').eq('user_id', userId).order('created_at', { ascending: false }).execute()
if (response.error != null || response.data == null) {
return [] as Array<ServiceOrderType>
}
const list = response.data as any[]
const result = [] as Array<ServiceOrderType>
for (let i = 0; i < list.length; i++) {
const parsed = await getServiceOrderDetail(JSON.parse(JSON.stringify(list[i]))['id'] as string)
if (parsed != null) {
result.push(parsed)
}
}
return result
}
export async function getServiceOrderDetail(orderId: string): Promise<ServiceOrderType | null> {
async function getLegacyServiceOrderDetail(orderId: string): Promise<ServiceOrderType | null> {
const orderResponse = await supa.from('hss_service_orders').select('*').eq('id', orderId).limit(1).execute()
if (orderResponse.error != null || orderResponse.data == null) {
return null
@@ -454,19 +666,173 @@ export async function getServiceOrderDetail(orderId: string): Promise<ServiceOrd
const rawStaffList = staffResponse.data as any[]
if (rawStaffList.length > 0) {
const staffObj = plainObject(rawStaffList[0])
parsed.staffName = readString(staffObj, 'nickname')
parsed.staffPhone = readString(staffObj, 'phone')
parsed.staffName = readString(staffObj, 'nickname')
parsed.staffPhone = readString(staffObj, 'phone')
}
}
}
return parsed
}
export function buildAddressSnapshot(address: UserAddress, latitude: number, longitude: number): ServiceOrderAddressSnapshotType {
return {
addressId: address.id,
contactName: address.recipient_name,
contactPhone: address.phone,
province: address.province,
city: address.city,
district: address.district,
detailAddress: address.detail_address,
fullAddress: address.province + address.city + address.district + ' ' + address.detail_address,
latitude,
longitude,
coordinateType: 'gcj02',
remark: address.label ?? ''
}
}
export async function createServiceOrder(params: CreateServiceOrderParams): Promise<ServiceOrderType | null> {
const newTask = await tryCreateCareTask(params)
if (newTask != null) {
return newTask
}
const userId = getCurrentUserId()
if (userId == '') {
return null
}
const orderId = buildId('so')
const orderNo = buildOrderNo()
const now = new Date().toISOString()
const appointmentTime = normalizeAppointmentTime(params.appointmentTime)
const response = await supa.from('hss_service_orders').insert({
id: orderId,
order_no: orderNo,
user_id: userId,
service_id: params.service.id,
service_name: params.service.name,
service_snapshot_json: params.service as any,
service_address_id: normalizeUuidOrNull(params.address.addressId),
address_snapshot_json: params.address as any,
recipient_name: params.recipientName,
recipient_phone: params.recipientPhone,
contact_name: params.contactName,
contact_phone: params.contactPhone,
appointment_time: appointmentTime,
remark: params.remark,
status: 'created',
created_at: now,
updated_at: now
}).execute()
if (response.error != null) {
console.error('createServiceOrder failed', response.error)
return null
}
await insertLegacyStatusLog(orderId, '', 'created', userId, 'consumer', '创建服务订单')
const staffResponse = await supa
.from('ml_delivery_staff')
.select('id, station_id, nickname, phone, status, deleted_at')
.eq('status', 1)
.order('created_at', { ascending: true })
.execute()
if (staffResponse.data != null) {
const rawStaffList = staffResponse.data as any[]
if (rawStaffList.length > 0) {
const staffObj = plainObject(rawStaffList[0])
const assignmentId = buildId('sa')
await supa.from('hss_service_assignments').insert({
id: assignmentId,
order_id: orderId,
staff_id: readString(staffObj, 'id'),
station_id: readString(staffObj, 'station_id') == '' ? null : readString(staffObj, 'station_id'),
status: 'assigned',
assigned_at: now,
created_at: now,
updated_at: now
}).execute()
await supa.from('hss_service_orders').update({
status: 'assigned',
current_assignment_id: assignmentId,
current_staff_id: readString(staffObj, 'id'),
updated_at: now
}).eq('id', orderId).execute()
await insertLegacyStatusLog(orderId, 'created', 'assigned', userId, 'system', '系统已自动派单')
}
}
return await getLegacyServiceOrderDetail(orderId)
}
export async function listConsumerServiceOrders(): Promise<Array<ServiceOrderType>> {
const userId = getCurrentUserId()
if (userId == '') {
return [] as Array<ServiceOrderType>
}
const careTaskResponse = await supa.from('ec_care_tasks').select('*').eq('user_id', userId).order('created_at', { ascending: false }).execute()
if (careTaskResponse.error == null && careTaskResponse.data != null) {
const rawTasks = careTaskResponse.data as Array<any>
const taskResult = [] as Array<ServiceOrderType>
for (let i = 0; i < rawTasks.length; i++) {
const parsed = await getCareTaskDetail(readString(rawTasks[i], 'id'))
if (parsed != null) {
taskResult.push(parsed)
}
}
return taskResult
}
const response = await supa.from('hss_service_orders').select('*').eq('user_id', userId).order('created_at', { ascending: false }).execute()
if (response.error != null || response.data == null) {
return [] as Array<ServiceOrderType>
}
const list = response.data as any[]
const result = [] as Array<ServiceOrderType>
for (let i = 0; i < list.length; i++) {
const parsed = await getLegacyServiceOrderDetail(JSON.parse(JSON.stringify(list[i]))['id'] as string)
if (parsed != null) {
result.push(parsed)
}
}
return result
}
export async function getServiceOrderDetail(orderId: string): Promise<ServiceOrderType | null> {
const careTask = await getCareTaskDetail(orderId)
if (careTask != null) {
return careTask
}
return await getLegacyServiceOrderDetail(orderId)
}
export async function confirmServiceOrder(orderId: string, rating: number, content: string, tags: Array<string>): Promise<ServiceOrderType | null> {
const userId = getCurrentUserId()
if (userId == '') {
return null
}
const careTask = await getCareTaskDetail(orderId)
if (careTask != null) {
const acceptedAt = nowIso()
const updateResponse = await supa.from('ec_care_tasks').update({
status: 'ACCEPTED',
accepted_by_family_at: acceptedAt,
updated_at: acceptedAt
}).eq('id', orderId).execute()
if (updateResponse.error == null) {
await insertWorkOrderEvent(orderId, 'ACCEPTANCE_PENDING', 'ACCEPTED', userId, 'consumer', 'accept_task', '用户确认验收')
if (rating > 0 || content != '' || tags.length > 0) {
await supa.from('ec_care_records').insert({
id: buildId('care-review'),
task_id: orderId,
record_type: 'review',
created_by: userId,
rating,
tags_json: tags as any,
content,
created_at: acceptedAt,
updated_at: acceptedAt
}).execute()
await insertWorkOrderEvent(orderId, 'ACCEPTED', 'ACCEPTED', userId, 'consumer', 'submit_review', '用户提交评价')
}
return await getCareTaskDetail(orderId)
}
}
const current = await getServiceOrderDetail(orderId)
if (current == null) {
return null
@@ -480,7 +846,7 @@ export async function confirmServiceOrder(orderId: string, rating: number, conte
if (updateResponse.error != null) {
return null
}
await insertStatusLog(orderId, current.status, 'accepted_by_user', userId, 'consumer', '用户确认验收')
await insertLegacyStatusLog(orderId, current.status, 'accepted_by_user', userId, 'consumer', '用户确认验收')
await supa.from('hss_service_reviews').insert({
id: buildId('srv'),
order_id: orderId,
@@ -495,8 +861,8 @@ export async function confirmServiceOrder(orderId: string, rating: number, conte
reviewed_at: acceptedAt,
updated_at: acceptedAt
}).eq('id', orderId).execute()
await insertStatusLog(orderId, 'accepted_by_user', 'reviewed', userId, 'consumer', '用户提交评价')
return await getServiceOrderDetail(orderId)
await insertLegacyStatusLog(orderId, 'accepted_by_user', 'reviewed', userId, 'consumer', '用户提交评价')
return await getLegacyServiceOrderDetail(orderId)
}
export async function rejectServiceOrderAcceptance(orderId: string, content: string): Promise<ServiceOrderType | null> {
@@ -504,6 +870,33 @@ export async function rejectServiceOrderAcceptance(orderId: string, content: str
if (userId == '') {
return null
}
const careTask = await getCareTaskDetail(orderId)
if (careTask != null) {
const rejectedAt = nowIso()
const updateResponse = await supa.from('ec_care_tasks').update({
status: 'ACCEPTANCE_REJECTED',
updated_at: rejectedAt
}).eq('id', orderId).execute()
if (updateResponse.error == null) {
await supa.from('hc_work_order_exceptions').insert({
id: buildId('hc-ex'),
task_id: orderId,
exception_type: 'acceptance_rejected',
description: content == '' ? '用户退回整改' : content,
occurred_at: rejectedAt,
location_text: '',
images_json: [] as Array<string>,
need_platform_intervention: false,
request_cancel_order: false,
request_reschedule: false,
created_by: userId,
created_at: rejectedAt,
updated_at: rejectedAt
}).execute()
await insertWorkOrderEvent(orderId, 'ACCEPTANCE_PENDING', 'ACCEPTANCE_REJECTED', userId, 'consumer', 'reject_acceptance', content == '' ? '用户退回整改' : content)
return await getCareTaskDetail(orderId)
}
}
const current = await getServiceOrderDetail(orderId)
if (current == null) {
return null
@@ -515,10 +908,81 @@ export async function rejectServiceOrderAcceptance(orderId: string, content: str
if (updateResponse.error != null) {
return null
}
await insertStatusLog(orderId, current.status, 'exception', userId, 'consumer', content == '' ? '用户退回整改' : content)
return await getServiceOrderDetail(orderId)
await insertLegacyStatusLog(orderId, current.status, 'exception', userId, 'consumer', content == '' ? '用户退回整改' : content)
return await getLegacyServiceOrderDetail(orderId)
}
export async function getCurrentConsumerUser() {
return await getCurrentUser()
}
export async function getOrdersByTab(tab: string): Promise<Array<ServiceOrderType>> {
const orders = await listConsumerServiceOrders()
if (tab == 'pending') {
return orders.filter((order) => {
return order.status != 'ACCEPTED' && order.status != 'COMPLETED' && order.status != 'CANCELLED'
})
}
if (tab == 'history') {
return orders.filter((order) => {
return order.status == 'ACCEPTED' || order.status == 'COMPLETED' || order.status == 'CANCELLED'
})
}
return orders.filter((order) => {
return order.status != 'ACCEPTED' && order.status != 'COMPLETED' && order.status != 'CANCELLED'
})
}
export async function getOrderDetail(orderId: string): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function getDashboard(): Promise<UTSJSONObject> {
const orders = await listConsumerServiceOrders()
let pendingCount = 0
let todayCount = 0
let completedCount = 0
for (let i = 0; i < orders.length; i++) {
const order = orders[i]
if (order.status == 'ACCEPTED' || order.status == 'COMPLETED' || order.status == 'CANCELLED') {
completedCount += 1
} else {
pendingCount += 1
todayCount += 1
}
}
return {
pendingCount,
todayCount,
completedCount,
totalCount: orders.length
} as UTSJSONObject
}
export async function acceptOrder(orderId: string): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function departOrder(orderId: string, _location: any): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function arriveOrder(orderId: string, _location: any): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function checkinOrder(orderId: string, _payload: any): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function startService(orderId: string): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function finishOrder(orderId: string): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}
export async function saveServiceRecord(orderId: string, _payload: any): Promise<ServiceOrderType | null> {
return await getServiceOrderDetail(orderId)
}

View File

@@ -385,6 +385,11 @@ export type UserProfile = {
bio?: string;
avatar_url?: string;
preferred_language?: string;
health_goal?: string;
service_address?: string;
emergency_contact?: string;
chronic_notes?: string;
care_preference?: string;
role?: string;
school_id?: string;
grade_id?: string;

View File

@@ -168,6 +168,17 @@ export function getServiceOrderStatusText(status: ServiceOrderStatus): string {
}
export function normalizeServiceOrderStatus(status: string): ServiceOrderStatus {
if (status == 'ORDER_CREATED') return 'created'
if (status == 'ORDER_ASSIGNED') return 'assigned'
if (status == 'ORDER_ACCEPTED') return 'accepted'
if (status == 'ORDER_REJECTED') return 'rejected'
if (status == 'ORDER_CHECKED_IN') return 'arrived'
if (status == 'ORDER_IN_SERVICE') return 'in_service'
if (status == 'ORDER_COMPLETED' || status == 'ACCEPTANCE_PENDING') return 'pending_acceptance'
if (status == 'ACCEPTED') return 'accepted_by_user'
if (status == 'SETTLEMENT_READY' || status == 'ARCHIVED') return 'settled'
if (status == 'ORDER_CANCELLED') return 'cancelled'
if (status == 'ORDER_EXCEPTION' || status == 'ACCEPTANCE_REJECTED') return 'exception'
if (status == 'created' || status == 'submitted') return 'created'
if (status == 'paid') return 'paid'
if (status == 'assigned' || status == 'pending_dispatch' || status == 'pending_assignment') return 'assigned'

View File

@@ -290,6 +290,22 @@ export class AkReq {
data ?? {},
res.header as UTSJSONObject
);
if (res.statusCode >= 400) {
let bodyPreview = ''
try {
if (typeof res.data == 'string') {
bodyPreview = (res.data as string).substring(0, 500)
} else {
bodyPreview = JSON.stringify(res.data).substring(0, 500)
}
} catch (e) {
bodyPreview = '[unserializable response body]'
}
console.error('[ak-req] HTTP error response')
console.error('[ak-req] status:', res.statusCode)
console.error('[ak-req] url:', options.url)
console.error('[ak-req] body:', bodyPreview)
}
resolve(result);
},
fail: (err) => {

View File

@@ -1 +1 @@
export const CURRENT_PAGES_MODE = 'delivery'
export const CURRENT_PAGES_MODE = 'consumer'

606
utils/profileRegionData.uts Normal file
View File

@@ -0,0 +1,606 @@
export type RegionCity = {
name: string
districts: Array<string>
}
export type RegionProvince = {
name: string
cities: Array<RegionCity>
}
export const PROFILE_REGION_OPTIONS: Array<RegionProvince> = [
{
name: '北京市',
cities: [
{ name: '北京市', districts: [] }
]
},
{
name: '天津市',
cities: [
{ name: '天津市', districts: [] }
]
},
{
name: '河北省',
cities: [
{ name: '石家庄市', districts: [] },
{ name: '唐山市', districts: [] },
{ name: '秦皇岛市', districts: [] },
{ name: '邯郸市', districts: [] },
{ name: '邢台市', districts: [] },
{ name: '保定市', districts: [] },
{ name: '张家口市', districts: [] },
{ name: '承德市', districts: [] },
{ name: '沧州市', districts: [] },
{ name: '廊坊市', districts: [] },
{ name: '衡水市', districts: [] }
]
},
{
name: '山西省',
cities: [
{ name: '太原市', districts: [] },
{ name: '大同市', districts: [] },
{ name: '阳泉市', districts: [] },
{ name: '长治市', districts: [] },
{ name: '晋城市', districts: [] },
{ name: '朔州市', districts: [] },
{ name: '晋中市', districts: [] },
{ name: '运城市', districts: [] },
{ name: '忻州市', districts: [] },
{ name: '临汾市', districts: [] },
{ name: '吕梁市', districts: [] }
]
},
{
name: '内蒙古自治区',
cities: [
{ name: '呼和浩特市', districts: [] },
{ name: '包头市', districts: [] },
{ name: '乌海市', districts: [] },
{ name: '赤峰市', districts: [] },
{ name: '通辽市', districts: [] },
{ name: '鄂尔多斯市', districts: [] },
{ name: '呼伦贝尔市', districts: [] },
{ name: '巴彦淖尔市', districts: [] },
{ name: '乌兰察布市', districts: [] },
{ name: '兴安盟', districts: [] },
{ name: '锡林郭勒盟', districts: [] },
{ name: '阿拉善盟', districts: [] }
]
},
{
name: '辽宁省',
cities: [
{ name: '沈阳市', districts: [] },
{ name: '大连市', districts: [] },
{ name: '鞍山市', districts: [] },
{ name: '抚顺市', districts: [] },
{ name: '本溪市', districts: [] },
{ name: '丹东市', districts: [] },
{ name: '锦州市', districts: [] },
{ name: '营口市', districts: [] },
{ name: '阜新市', districts: [] },
{ name: '辽阳市', districts: [] },
{ name: '盘锦市', districts: [] },
{ name: '铁岭市', districts: [] },
{ name: '朝阳市', districts: [] },
{ name: '葫芦岛市', districts: [] }
]
},
{
name: '吉林省',
cities: [
{ name: '长春市', districts: [] },
{ name: '吉林市', districts: [] },
{ name: '四平市', districts: [] },
{ name: '辽源市', districts: [] },
{ name: '通化市', districts: [] },
{ name: '白山市', districts: [] },
{ name: '松原市', districts: [] },
{ name: '白城市', districts: [] },
{ name: '延边朝鲜族自治州', districts: [] }
]
},
{
name: '黑龙江省',
cities: [
{ name: '哈尔滨市', districts: [] },
{ name: '齐齐哈尔市', districts: [] },
{ name: '鸡西市', districts: [] },
{ name: '鹤岗市', districts: [] },
{ name: '双鸭山市', districts: [] },
{ name: '大庆市', districts: [] },
{ name: '伊春市', districts: [] },
{ name: '佳木斯市', districts: [] },
{ name: '七台河市', districts: [] },
{ name: '牡丹江市', districts: [] },
{ name: '黑河市', districts: [] },
{ name: '绥化市', districts: [] },
{ name: '大兴安岭地区', districts: [] }
]
},
{
name: '上海市',
cities: [
{ name: '上海市', districts: [] }
]
},
{
name: '江苏省',
cities: [
{ name: '南京市', districts: [] },
{ name: '无锡市', districts: [] },
{ name: '徐州市', districts: [] },
{ name: '常州市', districts: [] },
{ name: '苏州市', districts: [] },
{ name: '南通市', districts: [] },
{ name: '连云港市', districts: [] },
{ name: '淮安市', districts: [] },
{ name: '盐城市', districts: [] },
{ name: '扬州市', districts: [] },
{ name: '镇江市', districts: [] },
{ name: '泰州市', districts: [] },
{ name: '宿迁市', districts: [] }
]
},
{
name: '浙江省',
cities: [
{ name: '杭州市', districts: [] },
{ name: '宁波市', districts: [] },
{ name: '温州市', districts: [] },
{ name: '嘉兴市', districts: [] },
{ name: '湖州市', districts: [] },
{ name: '绍兴市', districts: [] },
{ name: '金华市', districts: [] },
{ name: '衢州市', districts: [] },
{ name: '舟山市', districts: [] },
{ name: '台州市', districts: [] },
{ name: '丽水市', districts: [] }
]
},
{
name: '安徽省',
cities: [
{ name: '合肥市', districts: [] },
{ name: '芜湖市', districts: [] },
{ name: '蚌埠市', districts: [] },
{ name: '淮南市', districts: [] },
{ name: '马鞍山市', districts: [] },
{ name: '淮北市', districts: [] },
{ name: '铜陵市', districts: [] },
{ name: '安庆市', districts: [] },
{ name: '黄山市', districts: [] },
{ name: '滁州市', districts: [] },
{ name: '阜阳市', districts: [] },
{ name: '宿州市', districts: [] },
{ name: '六安市', districts: [] },
{ name: '亳州市', districts: [] },
{ name: '池州市', districts: [] },
{ name: '宣城市', districts: [] }
]
},
{
name: '福建省',
cities: [
{ name: '福州市', districts: [] },
{ name: '厦门市', districts: [] },
{ name: '莆田市', districts: [] },
{ name: '三明市', districts: [] },
{ name: '泉州市', districts: [] },
{ name: '漳州市', districts: [] },
{ name: '南平市', districts: [] },
{ name: '龙岩市', districts: [] },
{ name: '宁德市', districts: [] }
]
},
{
name: '江西省',
cities: [
{ name: '南昌市', districts: [] },
{ name: '景德镇市', districts: [] },
{ name: '萍乡市', districts: [] },
{ name: '九江市', districts: [] },
{ name: '新余市', districts: [] },
{ name: '鹰潭市', districts: [] },
{ name: '赣州市', districts: [] },
{ name: '吉安市', districts: [] },
{ name: '宜春市', districts: [] },
{ name: '抚州市', districts: [] },
{ name: '上饶市', districts: [] }
]
},
{
name: '山东省',
cities: [
{ name: '济南市', districts: [] },
{ name: '青岛市', districts: [] },
{ name: '淄博市', districts: [] },
{ name: '枣庄市', districts: [] },
{ name: '东营市', districts: [] },
{ name: '烟台市', districts: [] },
{ name: '潍坊市', districts: [] },
{ name: '济宁市', districts: [] },
{ name: '泰安市', districts: [] },
{ name: '威海市', districts: [] },
{ name: '日照市', districts: [] },
{ name: '临沂市', districts: [] },
{ name: '德州市', districts: [] },
{ name: '聊城市', districts: [] },
{ name: '滨州市', districts: [] },
{ name: '菏泽市', districts: [] }
]
},
{
name: '河南省',
cities: [
{ name: '郑州市', districts: [] },
{ name: '开封市', districts: [] },
{ name: '洛阳市', districts: [] },
{ name: '平顶山市', districts: [] },
{ name: '安阳市', districts: [] },
{ name: '鹤壁市', districts: [] },
{ name: '新乡市', districts: [] },
{ name: '焦作市', districts: [] },
{ name: '濮阳市', districts: [] },
{ name: '许昌市', districts: [] },
{ name: '漯河市', districts: [] },
{ name: '三门峡市', districts: [] },
{ name: '南阳市', districts: [] },
{ name: '商丘市', districts: [] },
{ name: '信阳市', districts: [] },
{ name: '周口市', districts: [] },
{ name: '驻马店市', districts: [] },
{ name: '济源市', districts: [] }
]
},
{
name: '湖北省',
cities: [
{ name: '武汉市', districts: [] },
{ name: '黄石市', districts: [] },
{ name: '十堰市', districts: [] },
{ name: '宜昌市', districts: [] },
{ name: '襄阳市', districts: [] },
{ name: '鄂州市', districts: [] },
{ name: '荆门市', districts: [] },
{ name: '孝感市', districts: [] },
{ name: '荆州市', districts: [] },
{ name: '黄冈市', districts: [] },
{ name: '咸宁市', districts: [] },
{ name: '随州市', districts: [] },
{ name: '恩施土家族苗族自治州', districts: [] },
{ name: '仙桃市', districts: [] },
{ name: '潜江市', districts: [] },
{ name: '天门市', districts: [] },
{ name: '神农架林区', districts: [] }
]
},
{
name: '湖南省',
cities: [
{ name: '长沙市', districts: [] },
{ name: '株洲市', districts: [] },
{ name: '湘潭市', districts: [] },
{ name: '衡阳市', districts: [] },
{ name: '邵阳市', districts: [] },
{ name: '岳阳市', districts: [] },
{ name: '常德市', districts: [] },
{ name: '张家界市', districts: [] },
{ name: '益阳市', districts: [] },
{ name: '郴州市', districts: [] },
{ name: '永州市', districts: [] },
{ name: '怀化市', districts: [] },
{ name: '娄底市', districts: [] },
{ name: '湘西土家族苗族自治州', districts: [] }
]
},
{
name: '广东省',
cities: [
{ name: '广州市', districts: [] },
{ name: '韶关市', districts: [] },
{ name: '深圳市', districts: [] },
{ name: '珠海市', districts: [] },
{ name: '汕头市', districts: [] },
{ name: '佛山市', districts: [] },
{ name: '江门市', districts: [] },
{ name: '湛江市', districts: [] },
{ name: '茂名市', districts: [] },
{ name: '肇庆市', districts: [] },
{ name: '惠州市', districts: [] },
{ name: '梅州市', districts: [] },
{ name: '汕尾市', districts: [] },
{ name: '河源市', districts: [] },
{ name: '阳江市', districts: [] },
{ name: '清远市', districts: [] },
{ name: '东莞市', districts: [] },
{ name: '中山市', districts: [] },
{ name: '潮州市', districts: [] },
{ name: '揭阳市', districts: [] },
{ name: '云浮市', districts: [] }
]
},
{
name: '广西壮族自治区',
cities: [
{ name: '南宁市', districts: [] },
{ name: '柳州市', districts: [] },
{ name: '桂林市', districts: [] },
{ name: '梧州市', districts: [] },
{ name: '北海市', districts: [] },
{ name: '防城港市', districts: [] },
{ name: '钦州市', districts: [] },
{ name: '贵港市', districts: [] },
{ name: '玉林市', districts: [] },
{ name: '百色市', districts: [] },
{ name: '贺州市', districts: [] },
{ name: '河池市', districts: [] },
{ name: '来宾市', districts: [] },
{ name: '崇左市', districts: [] }
]
},
{
name: '海南省',
cities: [
{ name: '海口市', districts: [] },
{ name: '三亚市', districts: [] },
{ name: '三沙市', districts: [] },
{ name: '儋州市', districts: [] },
{ name: '五指山市', districts: [] },
{ name: '琼海市', districts: [] },
{ name: '文昌市', districts: [] },
{ name: '万宁市', districts: [] },
{ name: '东方市', districts: [] },
{ name: '定安县', districts: [] },
{ name: '屯昌县', districts: [] },
{ name: '澄迈县', districts: [] },
{ name: '临高县', districts: [] },
{ name: '白沙黎族自治县', districts: [] },
{ name: '昌江黎族自治县', districts: [] },
{ name: '乐东黎族自治县', districts: [] },
{ name: '陵水黎族自治县', districts: [] },
{ name: '保亭黎族苗族自治县', districts: [] },
{ name: '琼中黎族苗族自治县', districts: [] }
]
},
{
name: '重庆市',
cities: [
{ name: '重庆市', districts: [] }
]
},
{
name: '四川省',
cities: [
{ name: '成都市', districts: [] },
{ name: '自贡市', districts: [] },
{ name: '攀枝花市', districts: [] },
{ name: '泸州市', districts: [] },
{ name: '德阳市', districts: [] },
{ name: '绵阳市', districts: [] },
{ name: '广元市', districts: [] },
{ name: '遂宁市', districts: [] },
{ name: '内江市', districts: [] },
{ name: '乐山市', districts: [] },
{ name: '南充市', districts: [] },
{ name: '眉山市', districts: [] },
{ name: '宜宾市', districts: [] },
{ name: '广安市', districts: [] },
{ name: '达州市', districts: [] },
{ name: '雅安市', districts: [] },
{ name: '巴中市', districts: [] },
{ name: '资阳市', districts: [] },
{ name: '阿坝藏族羌族自治州', districts: [] },
{ name: '甘孜藏族自治州', districts: [] },
{ name: '凉山彝族自治州', districts: [] }
]
},
{
name: '贵州省',
cities: [
{ name: '贵阳市', districts: [] },
{ name: '六盘水市', districts: [] },
{ name: '遵义市', districts: [] },
{ name: '安顺市', districts: [] },
{ name: '毕节市', districts: [] },
{ name: '铜仁市', districts: [] },
{ name: '黔西南布依族苗族自治州', districts: [] },
{ name: '黔东南苗族侗族自治州', districts: [] },
{ name: '黔南布依族苗族自治州', districts: [] }
]
},
{
name: '云南省',
cities: [
{ name: '昆明市', districts: [] },
{ name: '曲靖市', districts: [] },
{ name: '玉溪市', districts: [] },
{ name: '保山市', districts: [] },
{ name: '昭通市', districts: [] },
{ name: '丽江市', districts: [] },
{ name: '普洱市', districts: [] },
{ name: '临沧市', districts: [] },
{ name: '楚雄彝族自治州', districts: [] },
{ name: '红河哈尼族彝族自治州', districts: [] },
{ name: '文山壮族苗族自治州', districts: [] },
{ name: '西双版纳傣族自治州', districts: [] },
{ name: '大理白族自治州', districts: [] },
{ name: '德宏傣族景颇族自治州', districts: [] },
{ name: '怒江傈僳族自治州', districts: [] },
{ name: '迪庆藏族自治州', districts: [] }
]
},
{
name: '西藏自治区',
cities: [
{ name: '拉萨市', districts: [] },
{ name: '日喀则市', districts: [] },
{ name: '昌都市', districts: [] },
{ name: '林芝市', districts: [] },
{ name: '山南市', districts: [] },
{ name: '那曲市', districts: [] },
{ name: '阿里地区', districts: [] }
]
},
{
name: '陕西省',
cities: [
{ name: '西安市', districts: [] },
{ name: '铜川市', districts: [] },
{ name: '宝鸡市', districts: [] },
{ name: '咸阳市', districts: [] },
{ name: '渭南市', districts: [] },
{ name: '延安市', districts: [] },
{ name: '汉中市', districts: [] },
{ name: '榆林市', districts: [] },
{ name: '安康市', districts: [] },
{ name: '商洛市', districts: [] }
]
},
{
name: '甘肃省',
cities: [
{ name: '兰州市', districts: [] },
{ name: '嘉峪关市', districts: [] },
{ name: '金昌市', districts: [] },
{ name: '白银市', districts: [] },
{ name: '天水市', districts: [] },
{ name: '武威市', districts: [] },
{ name: '张掖市', districts: [] },
{ name: '平凉市', districts: [] },
{ name: '酒泉市', districts: [] },
{ name: '庆阳市', districts: [] },
{ name: '定西市', districts: [] },
{ name: '陇南市', districts: [] },
{ name: '临夏回族自治州', districts: [] },
{ name: '甘南藏族自治州', districts: [] }
]
},
{
name: '青海省',
cities: [
{ name: '西宁市', districts: [] },
{ name: '海东市', districts: [] },
{ name: '海北藏族自治州', districts: [] },
{ name: '黄南藏族自治州', districts: [] },
{ name: '海南藏族自治州', districts: [] },
{ name: '果洛藏族自治州', districts: [] },
{ name: '玉树藏族自治州', districts: [] },
{ name: '海西蒙古族藏族自治州', districts: [] }
]
},
{
name: '宁夏回族自治区',
cities: [
{ name: '银川市', districts: [] },
{ name: '石嘴山市', districts: [] },
{ name: '吴忠市', districts: [] },
{ name: '固原市', districts: [] },
{ name: '中卫市', districts: [] }
]
},
{
name: '新疆维吾尔自治区',
cities: [
{ name: '乌鲁木齐市', districts: [] },
{ name: '克拉玛依市', districts: [] },
{ name: '吐鲁番市', districts: [] },
{ name: '哈密市', districts: [] },
{ name: '昌吉回族自治州', districts: [] },
{ name: '博尔塔拉蒙古自治州', districts: [] },
{ name: '巴音郭楞蒙古自治州', districts: [] },
{ name: '阿克苏地区', districts: [] },
{ name: '克孜勒苏柯尔克孜自治州', districts: [] },
{ name: '喀什地区', districts: [] },
{ name: '和田地区', districts: [] },
{ name: '伊犁哈萨克自治州', districts: [] },
{ name: '塔城地区', districts: [] },
{ name: '阿勒泰地区', districts: [] },
{ name: '石河子市', districts: [] },
{ name: '阿拉尔市', districts: [] },
{ name: '图木舒克市', districts: [] },
{ name: '五家渠市', districts: [] },
{ name: '北屯市', districts: [] },
{ name: '铁门关市', districts: [] },
{ name: '双河市', districts: [] },
{ name: '可克达拉市', districts: [] },
{ name: '昆玉市', districts: [] },
{ name: '胡杨河市', districts: [] },
{ name: '新星市', districts: [] }
]
},
{
name: '台湾省',
cities: [
{ name: '台北市', districts: [] },
{ name: '高雄市', districts: [] },
{ name: '新北市', districts: [] },
{ name: '台中市', districts: [] },
{ name: '台南市', districts: [] },
{ name: '桃园市', districts: [] },
{ name: '基隆市', districts: [] },
{ name: '新竹市', districts: [] },
{ name: '嘉义市', districts: [] },
{ name: '新竹县', districts: [] },
{ name: '苗栗县', districts: [] },
{ name: '彰化县', districts: [] },
{ name: '南投县', districts: [] },
{ name: '云林县', districts: [] },
{ name: '嘉义县', districts: [] },
{ name: '屏东县', districts: [] },
{ name: '宜兰县', districts: [] },
{ name: '花莲县', districts: [] },
{ name: '台东县', districts: [] },
{ name: '澎湖县', districts: [] },
{ name: '金门县', districts: [] },
{ name: '连江县', districts: [] }
]
},
{
name: '香港特别行政区',
cities: [
{ name: '中西区', districts: [] },
{ name: '湾仔区', districts: [] },
{ name: '东区', districts: [] },
{ name: '南区', districts: [] },
{ name: '油尖旺区', districts: [] },
{ name: '深水埗区', districts: [] },
{ name: '九龙城区', districts: [] },
{ name: '黄大仙区', districts: [] },
{ name: '观塘区', districts: [] },
{ name: '荃湾区', districts: [] },
{ name: '屯门区', districts: [] },
{ name: '元朗区', districts: [] },
{ name: '北区', districts: [] },
{ name: '大埔区', districts: [] },
{ name: '西贡区', districts: [] },
{ name: '沙田区', districts: [] },
{ name: '葵青区', districts: [] },
{ name: '离岛区', districts: [] }
]
},
{
name: '澳门特别行政区',
cities: [
{ name: '花地玛堂区', districts: [] },
{ name: '圣安多尼堂区', districts: [] },
{ name: '大堂区', districts: [] },
{ name: '望德堂区', districts: [] },
{ name: '风顺堂区', districts: [] },
{ name: '嘉模堂区', districts: [] },
{ name: '圣方济各堂区', districts: [] },
{ name: '路氹填海区', districts: [] }
]
}
]
export const PROFILE_COMMON_ADDRESS_SUGGESTIONS: Array<string> = [
'广东省梅州市 学海路康养公寓 A 座 907 室',
'广东省广州市 天河路康复护理中心 3 层',
'北京市 望京康养服务站 2 号楼 301 室',
'上海市 花木社区照护点 6 号',
'浙江省杭州市 文二路护理服务中心 3 层'
]

View File

@@ -4656,6 +4656,17 @@ class SupabaseService {
}
private normalizeServiceStatus(status: string): string {
if (status == 'ORDER_CREATED') return 'created'
if (status == 'ORDER_ASSIGNED') return 'assigned'
if (status == 'ORDER_ACCEPTED') return 'accepted'
if (status == 'ORDER_REJECTED') return 'rejected'
if (status == 'ORDER_CHECKED_IN') return 'arrived'
if (status == 'ORDER_IN_SERVICE') return 'in_service'
if (status == 'ORDER_COMPLETED' || status == 'ACCEPTANCE_PENDING') return 'pending_acceptance'
if (status == 'ACCEPTED') return 'accepted_by_user'
if (status == 'SETTLEMENT_READY' || status == 'ARCHIVED') return 'settled'
if (status == 'ORDER_CANCELLED') return 'cancelled'
if (status == 'ORDER_EXCEPTION' || status == 'ACCEPTANCE_REJECTED') return 'exception'
if (status == 'created' || status == 'submitted') return 'created'
if (status == 'paid') return 'paid'
if (status == 'assigned' || status == 'pending_dispatch' || status == 'pending_assignment') return 'assigned'

View File

@@ -149,28 +149,15 @@ export function responsiveState() {
}
}
export function goToLogin(redirectUrl?: string | null) {
try {
const target = redirectUrl != null && redirectUrl.length > 0 ? redirectUrl : ''
uni.showModal({
title: '提示',
content: '当前操作需要登录,是否前往登录页继续?',
confirmText: '去登录',
cancelText: '先逛逛',
success: (res) => {
if (res.confirm) {
if (target.length > 0) {
const redirect = encodeURIComponent(target)
uni.navigateTo({ url: `/pages/user/login?redirect=${redirect}` })
} else {
uni.navigateTo({ url: '/pages/user/login' })
}
}
}
})
} catch (e) {
uni.navigateTo({ url: '/pages/user/login' })
export function goToLogin(redirectUrl: string = ''): void {
let url = '/pages/user/login'
if (redirectUrl != null && redirectUrl !== '') {
url = url + '?redirect=' + encodeURIComponent(redirectUrl)
}
uni.navigateTo({
url
})
}
/**

View File

@@ -1,11 +1,14 @@
<<<<<<< HEAD
uni.api.esm.js:1042 POST http://192.168.1.62:18000/auth/v1/token?grant_type=password 401 (Unauthorized)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
mp.esm.js:529 saveProfile context: {"profileRowId":"b653fded-7d5e-4950-aa0d-725595543e3c","profileId":"b653fded-7d5e-4950-aa0d-725595543e3c","birthday":null,"hasHealthGoal":false,"hasServiceAddress":true}
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ak_users filter: id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] PATCH http://119.146.131.237:9126/rest/v1/ak_users?id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...Tozk | auth-mode: pre-set | prefer: return=representation
uni.api.esm.js:1042 PATCH http://119.146.131.237:9126/rest/v1/ak_users?id=eq.b653fded-7d5e-4950-aa0d-725595543e3c 400 (Bad Request)(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ uni.api.esm.js:1042
invokeApi @ uni.api.esm.js:330
promiseApi @ uni.api.esm.js:889
(anonymous) @ ak-req.uts:214
doOnce @ ak-req.uts:213
_loop$ @ ak-req.uts:312
_loop$ @ ak-req.uts:328
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
@@ -13,831 +16,144 @@ s @ regeneratorRuntime.js?forceSync=true:1
_ @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
=======
mp.esm.js:529 [getOrderDetail] 开始获取订单详情orderId: so-1779679148063-14086
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*%2C%20ml_order_items(*)&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrderDetail] response.error: null
mp.esm.js:529 [getOrderDetail] response.data: []
mp.esm.js:529 [getOrderDetail] 未找到订单
mp.esm.js:529 [confirmPayment] 开始支付, orderId: so-1779679148063-14086 method: wechat
mp.esm.js:529 [getOrderDetail] 开始获取订单详情orderId: so-1779679148063-14086
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*%2C%20ml_order_items(*)&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrderDetail] response.error: null
mp.esm.js:529 [getOrderDetail] response.data: []
mp.esm.js:529 [getOrderDetail] 未找到订单
mp.esm.js:529 [payOrder] 订单不存在,无法支付(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee73$ @ supabaseService.uts:5491
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
_callee19$ @ aksupa.uts:1290
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
requestWithAutoRefresh @ aksupa.uts:1289
_callee14$ @ aksupa.uts:1143
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
update @ aksupa.uts:1119
_callee$ @ aksupa.uts:477
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
execute @ aksupa.uts:369
_callee2$ @ profile.uvue:1057
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
handleLogin @ login.uvue:477
=======
payOrder @ supabaseService.uts:5481
_callee6$ @ payment.uvue:1291
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
confirmPayment @ payment.uvue:1232
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
saveProfile @ profile.uvue:1015
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
<<<<<<< HEAD
Show 19 more frames
mp.esm.js:529 [ak-req] ★ 401 Unauthorized(env: Windows,mp,1.06.2504030; lib: 3.15.2)
mp.esm.js:529 [ak-req] HTTP error response(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:336
=======
mp.esm.js:529 [confirmPayment] 支付结果: false
mp.esm.js:529 [confirmPayment] payOrder 返回 false(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee6$ @ payment.uvue:1295
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
<<<<<<< HEAD
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
handleLogin @ login.uvue:477
=======
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
confirmPayment @ payment.uvue:1232
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
<<<<<<< HEAD
Show 14 more frames
mp.esm.js:529 [ak-req] url: http://192.168.1.62:18000/auth/v1/token?grant_type=password(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:337
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
=======
mp.esm.js:529 [getOrderDetail] 开始获取订单详情orderId: so-1779679148063-14086
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*%2C%20ml_order_items(*)&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrderDetail] response.error: null
mp.esm.js:529 [getOrderDetail] response.data: []
mp.esm.js:529 [getOrderDetail] 未找到订单
mp.esm.js:529 [getOrderDetail] 开始获取订单详情orderId: so-1779679148063-14086
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*%2C%20ml_order_items(*)&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrderDetail] response.error: null
mp.esm.js:529 [getOrderDetail] response.data: []
mp.esm.js:529 [getOrderDetail] 未找到订单
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] PATCH http://119.146.131.237:9126/rest/v1/ml_orders?id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: return=representation
uni.api.esm.js:1042 PATCH http://119.146.131.237:9126/rest/v1/ml_orders?id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c 400 (Bad Request)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ uni.api.esm.js:1042
invokeApi @ uni.api.esm.js:330
promiseApi @ uni.api.esm.js:889
(anonymous) @ ak-req.uts:214
doOnce @ ak-req.uts:213
_loop$ @ ak-req.uts:312
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
s @ regeneratorRuntime.js?forceSync=true:1
_ @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
<<<<<<< HEAD
_callee9$ @ aksupa.uts:887
=======
_callee19$ @ aksupa.uts:1288
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
=======
requestWithAutoRefresh @ aksupa.uts:1287
_callee14$ @ aksupa.uts:1141
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
=======
update @ aksupa.uts:1117
_callee$ @ aksupa.uts:477
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
=======
execute @ aksupa.uts:369
_callee61$ @ supabaseService.uts:4508
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
handleLogin @ login.uvue:477
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 14 more frames
mp.esm.js:529 [ak-req] auth-mode: apikey-only(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:338
=======
markOrderPaymentCancelled @ supabaseService.uts:4491
_callee6$ @ payment.uvue:1271
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
=======
confirmPayment @ payment.uvue:1232
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 21 more frames
mp.esm.js:529 [markOrderPaymentCancelled] 保留待付款订单失败: UniError: 请求失败: 400
at _construct (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/construct.js?forceSync=true:1:1227)
at new r (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/wrapNativeSuper.js?forceSync=true:1:1357)
at UniError2.<anonymous> (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/createSuper.js?forceSync=true:1:1176)
at new UniError2 (weapp:///http://127.0.0.1:60394/appservice/common/vendor.js?t=wechat&s=1779670571338&v=2c3f4623fbd33b44aa0c0065a9eb296b:890:22)
at Object.toUniError (weapp:///http://127.0.0.1:60394/appservice/utils/utils.js?t=wechat&s=1779670571338&v=44243ae0f2468b2c481e39a715a29204:77:18)
at AkSupa._callee19$ (weapp:///http://127.0.0.1:60394/appservice/components/supadb/aksupa.js?t=wechat&s=1779670571338&v=f87225c7384edc68270412f64fbd4e8a:1959:41)
at s (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1588)
at Generator.<anonymous> (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:2925)
at Generator.next (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1951)
at fulfilled (weapp:///http://127.0.0.1:60394/appservice/common/vendor.js?t=wechat&s=1779670571338&v=2c3f4623fbd33b44aa0c0065a9eb296b:10009:24)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee61$ @ supabaseService.uts:4511
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
markOrderPaymentCancelled @ supabaseService.uts:4491
_callee6$ @ payment.uvue:1271
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
confirmPayment @ payment.uvue:1232
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
mp.esm.js:529 收到订单更新事件: UTSJSONObject {orderId: "so-1779679148063-14086", status: 1, paymentStatus: 1, cancelReason: "", payExpireAt: "", …}
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_user_profiles filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_user_coupons filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&status=eq.1&expire_at=gt.2026-05-25T03%3A20%3A04.256Z
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_user_profiles?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*%2C%20ml_order_items(*)%2C%20ml_shops(shop_name)&order=created_at.desc&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: (none)
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_user_coupons?select=id&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&status=eq.1&expire_at=gt.2026-05-25T03%3A20%3A04.256Z
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_user_balance filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_user_balance?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.1
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.1
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_user_points filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_user_points?select=points&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact,return=representation,single-object
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.2
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.2
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.3
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.3
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.4
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.4
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=in.(6,7)
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=in.(6,7)
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrders] response.error: null
mp.esm.js:529 [getOrders] 订单数量: 104
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.5
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_status=eq.5
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: hss_service_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/hss_service_orders?select=status&limit=500&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrderDetail] 开始获取订单详情orderId: so-1779679148063-14086
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] GET http://119.146.131.237:9126/rest/v1/ml_orders?select=*%2C%20ml_order_items(*)&limit=1&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&consumer_deleted_at=is.null&order_no=eq.so-1779679148063-14086
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: count=exact
mp.esm.js:529 [getOrderDetail] response.error: null
mp.esm.js:529 [getOrderDetail] response.data: []
mp.esm.js:529 [getOrderDetail] 未找到订单
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] PATCH http://119.146.131.237:9126/rest/v1/ml_orders?id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: return=representation
uni.api.esm.js:1042 PATCH http://119.146.131.237:9126/rest/v1/ml_orders?id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c 400 (Bad Request)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ uni.api.esm.js:1042
invokeApi @ uni.api.esm.js:330
promiseApi @ uni.api.esm.js:889
(anonymous) @ ak-req.uts:214
doOnce @ ak-req.uts:213
_loop$ @ ak-req.uts:312
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
s @ regeneratorRuntime.js?forceSync=true:1
_ @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee19$ @ aksupa.uts:1288
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
=======
requestWithAutoRefresh @ aksupa.uts:1287
_callee14$ @ aksupa.uts:1141
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
=======
update @ aksupa.uts:1117
_callee$ @ aksupa.uts:477
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
=======
execute @ aksupa.uts:369
_callee52$ @ supabaseService.uts:4038
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
handleLogin @ login.uvue:477
=======
cancelOrder @ supabaseService.uts:4018
_callee5$ @ payment.uvue:1153
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
confirmCancelOrder @ payment.uvue:1141
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
<<<<<<< HEAD
Show 14 more frames
mp.esm.js:529 [ak-req] 发送 apikey: eyJhbG...7890(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:339
=======
Show 26 more frames
mp.esm.js:529 取消订单失败: UniError: 请求失败: 400
at _construct (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/construct.js?forceSync=true:1:1227)
at new r (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/wrapNativeSuper.js?forceSync=true:1:1357)
at UniError2.<anonymous> (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/createSuper.js?forceSync=true:1:1176)
at new UniError2 (weapp:///http://127.0.0.1:60394/appservice/common/vendor.js?t=wechat&s=1779670571338&v=2c3f4623fbd33b44aa0c0065a9eb296b:890:22)
at Object.toUniError (weapp:///http://127.0.0.1:60394/appservice/utils/utils.js?t=wechat&s=1779670571338&v=44243ae0f2468b2c481e39a715a29204:77:18)
at AkSupa._callee19$ (weapp:///http://127.0.0.1:60394/appservice/components/supadb/aksupa.js?t=wechat&s=1779670571338&v=f87225c7384edc68270412f64fbd4e8a:1959:41)
at s (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1588)
at Generator.<anonymous> (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:2925)
at Generator.next (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1951)
at fulfilled (weapp:///http://127.0.0.1:60394/appservice/common/vendor.js?t=wechat&s=1779670571338&v=2c3f4623fbd33b44aa0c0065a9eb296b:10009:24)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee52$ @ supabaseService.uts:4041
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
<<<<<<< HEAD
=======
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
cancelOrder @ supabaseService.uts:4018
_callee5$ @ payment.uvue:1153
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
confirmCancelOrder @ payment.uvue:1141
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
[自动热重载] 已开启代码文件保存后自动热重载
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ml_orders filter: id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] PATCH http://119.146.131.237:9126/rest/v1/ml_orders?id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...YFxs | auth-mode: pre-set | prefer: return=representation
uni.api.esm.js:1042 PATCH http://119.146.131.237:9126/rest/v1/ml_orders?id=eq.so-1779679148063-14086&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c 400 (Bad Request)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ uni.api.esm.js:1042
invokeApi @ uni.api.esm.js:330
promiseApi @ uni.api.esm.js:889
(anonymous) @ ak-req.uts:214
doOnce @ ak-req.uts:213
_loop$ @ ak-req.uts:312
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
s @ regeneratorRuntime.js?forceSync=true:1
_ @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
<<<<<<< HEAD
_callee9$ @ aksupa.uts:887
=======
_callee19$ @ aksupa.uts:1288
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
=======
requestWithAutoRefresh @ aksupa.uts:1287
_callee14$ @ aksupa.uts:1141
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
=======
update @ aksupa.uts:1117
_callee$ @ aksupa.uts:477
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
=======
execute @ aksupa.uts:369
_callee52$ @ supabaseService.uts:4038
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
handleLogin @ login.uvue:477
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 14 more frames
mp.esm.js:529 [ak-req] 发送 Authorization: (MISSING!)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:340
=======
cancelOrder @ supabaseService.uts:4018
_callee7$ @ orders.uvue:1422
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
doCancelOrder @ orders.uvue:1417
success @ orders.uvue:1443
success @ ak-req.uts:304
(anonymous) @ uni.api.esm.js:946
Show 25 more frames
mp.esm.js:529 取消订单失败: UniError: 请求失败: 400
at _construct (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/construct.js?forceSync=true:1:1227)
at new r (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/wrapNativeSuper.js?forceSync=true:1:1357)
at UniError2.<anonymous> (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/createSuper.js?forceSync=true:1:1176)
at new UniError2 (weapp:///http://127.0.0.1:60394/appservice/common/vendor.js?t=wechat&s=1779670571338&v=2c3f4623fbd33b44aa0c0065a9eb296b:890:22)
at Object.toUniError (weapp:///http://127.0.0.1:60394/appservice/utils/utils.js?t=wechat&s=1779670571338&v=44243ae0f2468b2c481e39a715a29204:77:18)
at AkSupa._callee19$ (weapp:///http://127.0.0.1:60394/appservice/components/supadb/aksupa.js?t=wechat&s=1779670571338&v=f87225c7384edc68270412f64fbd4e8a:1959:41)
at s (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1588)
at Generator.<anonymous> (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:2925)
at Generator.next (weapp:///http://127.0.0.1:60394/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1951)
at fulfilled (weapp:///http://127.0.0.1:60394/appservice/common/vendor.js?t=wechat&s=1779670571338&v=2c3f4623fbd33b44aa0c0065a9eb296b:10009:24)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
mp.esm.js:529 [ak-req] status: 400(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee52$ @ supabaseService.uts:4041
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
<<<<<<< HEAD
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
=======
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
cancelOrder @ supabaseService.uts:4018
_callee7$ @ orders.uvue:1422
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
<<<<<<< HEAD
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
handleLogin @ login.uvue:477
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 14 more frames
mp.esm.js:529 [ak-req] response body: {"message":"Invalid authentication credentials"}(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:341
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
handleLogin @ login.uvue:477
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 14 more frames
mp.esm.js:529 [ak-req] 当前请求按 apikey-only 模式发送,这是匿名登录/匿名接口的预期行为(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:346
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
handleLogin @ login.uvue:477
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 14 more frames
mp.esm.js:529 [ak-req] ✗ 401 更可能来自服务端网关认证:请检查 SUPA_URL 对应实例与 SUPA_KEY/ANON_KEY 是否匹配(env: Windows,mp,1.06.2504030; lib: 3.15.2)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
_callee2$ @ ak-req.uts:347
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee9$ @ aksupa.uts:887
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
signIn @ aksupa.uts:876
_callee3$ @ delivery.uts:1506
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ delivery.uts:1500
_callee$ @ deliveryService.uts:42
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
loginDelivery @ deliveryService.uts:41
_callee5$ @ login.uvue:495
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
handleLogin @ login.uvue:477
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
Show 14 more frames
Error: timeout
at Function.<anonymous> (WAServiceMainContext.js?t=wechat&v=3.15.2:1)
at p (WAServiceMainContext.js?t=wechat&v=3.15.2:1)
at WAServiceMainContext.js?t=wechat&v=3.15.2:1
at WAServiceMainContext.js?t=wechat&v=3.15.2:1(env: Windows,mp,1.06.2504030; lib: 3.15.2)
15:42:21.953 [plugin:uts] Invalid end tag.
15:42:22.203 at pages/mall/delivery/home/index.uvue:454:1
=======
doCancelOrder @ orders.uvue:1417
success @ orders.uvue:1443
success @ ak-req.uts:305
(anonymous) @ uni.api.esm.js:946
>>>>>>> d9103c9bf (完善下单逻辑及其ui展示修复支付倒计时显示错误bug)
mp.esm.js:529 [ak-req] url: http://119.146.131.237:9126/rest/v1/ak_users?id=eq.b653fded-7d5e-4950-aa0d-725595543e3c(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
success @ ak-req.uts:306
(anonymous) @ uni.api.esm.js:946
mp.esm.js:529 [ak-req] body: {"code":"22P02","details":null,"hint":null,"message":"invalid input syntax for type uuid: \"zh-CN\""}(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
success @ ak-req.uts:307
(anonymous) @ uni.api.esm.js:946
mp.esm.js:529 saveProfile update ak_users error: {"errSubject":"AppError","errCode":-1,"errMsg":"请求失败: 400"}
mp.esm.js:529 [AkSupaQueryBuilder] execute - 表: ak_users filter: id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] PATCH http://119.146.131.237:9126/rest/v1/ak_users?id=eq.b653fded-7d5e-4950-aa0d-725595543e3c
mp.esm.js:529 [ak-req] apikey: eyJhbG...7890 | Authorization: Bearer eyJhbG...Tozk | auth-mode: pre-set | prefer: return=representation
uni.api.esm.js:1042 PATCH http://119.146.131.237:9126/rest/v1/ak_users?id=eq.b653fded-7d5e-4950-aa0d-725595543e3c 400 (Bad Request)(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ uni.api.esm.js:1042
invokeApi @ uni.api.esm.js:330
promiseApi @ uni.api.esm.js:889
(anonymous) @ ak-req.uts:214
doOnce @ ak-req.uts:213
_loop$ @ ak-req.uts:328
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
s @ regeneratorRuntime.js?forceSync=true:1
_ @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
request @ ak-req.uts:148
_callee19$ @ aksupa.uts:1290
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
requestWithAutoRefresh @ aksupa.uts:1289
_callee14$ @ aksupa.uts:1143
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
update @ aksupa.uts:1119
_callee$ @ aksupa.uts:477
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
execute @ aksupa.uts:369
_callee2$ @ profile.uvue:1071
s @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
(anonymous) @ regeneratorRuntime.js?forceSync=true:1
fulfilled @ uni.mp.esm.js:1134
Promise.then (async)
step @ uni.mp.esm.js:1134
(anonymous) @ uni.mp.esm.js:1134
__awaiter @ uni.mp.esm.js:1134
saveProfile @ profile.uvue:1015
callWithErrorHandling @ vue.runtime.esm.js:1356
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
invoke @ vue.runtime.esm.js:6223
setTimeout (async)
invoker @ vue.runtime.esm.js:6232
mp.esm.js:529 [ak-req] HTTP error response(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
success @ ak-req.uts:304
(anonymous) @ uni.api.esm.js:946
mp.esm.js:529 [ak-req] status: 400(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
success @ ak-req.uts:305
(anonymous) @ uni.api.esm.js:946
mp.esm.js:529 [ak-req] url: http://119.146.131.237:9126/rest/v1/ak_users?id=eq.b653fded-7d5e-4950-aa0d-725595543e3c(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
success @ ak-req.uts:306
(anonymous) @ uni.api.esm.js:946
mp.esm.js:529 [ak-req] body: {"code":"22P02","details":null,"hint":null,"message":"invalid input syntax for type uuid: \"zh-CN\""}(env: Windows,mp,1.06.2504030; lib: 3.16.0)
(anonymous) @ mp.esm.js:529
__f__ @ uni.api.esm.js:590
success @ ak-req.uts:307
(anonymous) @ uni.api.esm.js:946
mp.esm.js:529 saveProfile fallback update ak_users error: {"errSubject":"AppError","errCode":-1,"errMsg":"请求失败: 400"}