补充profile页面功能区功能
This commit is contained in:
470
.pages-backup/pages.consumer.2026-06-08T00-49-54-379Z.json
Normal file
470
.pages-backup/pages.consumer.2026-06-08T00-49-54-379Z.json
Normal file
@@ -0,0 +1,470 @@
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/main/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页",
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/boot",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户登录",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/register",
|
||||
"style": {
|
||||
"navigationBarTitleText": "注册"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/forgot-password",
|
||||
"style": {
|
||||
"navigationBarTitleText": "忘记密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/terms",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户协议与隐私政策"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/center",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户中心"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/profile",
|
||||
"style": {
|
||||
"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/main/profile",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/main/category",
|
||||
"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": "message-batch-delete",
|
||||
"style": {
|
||||
"navigationBarTitleText": "批量删除"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "member/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "会员中心"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "product-reviews",
|
||||
"style": {
|
||||
"navigationBarTitleText": "商品评价"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
"color": "#999999",
|
||||
"selectedColor": "#ff5000",
|
||||
"backgroundColor": "#ffffff",
|
||||
"borderStyle": "black",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/main/index",
|
||||
"text": "首页",
|
||||
"iconPath": "static/tabbar/home.png",
|
||||
"selectedIconPath": "static/tabbar/home-active.png"
|
||||
},
|
||||
{
|
||||
"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/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": "consumer端",
|
||||
"path": "pages/main/index",
|
||||
"query": "role=consumer"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
607
mall_sql/migrations/20260603_homecare_checkin_rpc_fixed.sql
Normal file
607
mall_sql/migrations/20260603_homecare_checkin_rpc_fixed.sql
Normal file
@@ -0,0 +1,607 @@
|
||||
-- Homecare location-distance RPCs (precheck + submit) — Fixed for uuid types
|
||||
-- Date: 2026-06-03 (original), 2026-06-08 (fixed for uuid alignment)
|
||||
-- Purpose: move checkin distance flow to RPC-only for phase1 tables
|
||||
-- Fixed: p_org_id, p_team_id, p_operator_id changed from text to uuid
|
||||
-- to match hc_dispatch_assignments table schema
|
||||
|
||||
create or replace function public.rpc_homecare_dispatch_assignment_upsert(
|
||||
p_work_order_id uuid,
|
||||
p_org_id uuid, -- ✅ fixed: was text, now uuid
|
||||
p_team_id uuid, -- ✅ fixed: was text, now uuid
|
||||
p_worker_id uuid,
|
||||
p_service_latitude numeric,
|
||||
p_service_longitude numeric,
|
||||
p_service_coordinate_type text default 'gcj02',
|
||||
p_operator_id uuid default null, -- ✅ fixed: was text, now uuid
|
||||
p_dispatch_reason text default null
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public, app
|
||||
as $$
|
||||
declare
|
||||
v_prev_version integer := 0;
|
||||
v_prev_id text;
|
||||
begin
|
||||
if p_work_order_id is null then
|
||||
raise exception 'p_work_order_id is required';
|
||||
end if;
|
||||
|
||||
if p_org_id is null then
|
||||
raise exception 'p_org_id is required';
|
||||
end if;
|
||||
|
||||
if p_service_latitude is null or p_service_longitude is null then
|
||||
raise exception 'service coordinates are required';
|
||||
end if;
|
||||
|
||||
if to_regclass('public.hc_dispatch_assignments') is null then
|
||||
raise exception 'hc_dispatch_assignments table is required';
|
||||
end if;
|
||||
|
||||
select id, assign_version
|
||||
into v_prev_id, v_prev_version
|
||||
from public.hc_dispatch_assignments
|
||||
where work_order_id = p_work_order_id
|
||||
and is_current = true
|
||||
order by created_at desc
|
||||
limit 1;
|
||||
|
||||
if found then
|
||||
update public.hc_dispatch_assignments
|
||||
set is_current = false,
|
||||
updated_at = now(),
|
||||
updated_by = coalesce(p_operator_id, updated_by)
|
||||
where id = v_prev_id;
|
||||
end if;
|
||||
|
||||
insert into public.hc_dispatch_assignments(
|
||||
id,
|
||||
work_order_id,
|
||||
org_id,
|
||||
team_id,
|
||||
assign_version,
|
||||
worker_id,
|
||||
service_latitude,
|
||||
service_longitude,
|
||||
service_coordinate_type,
|
||||
dispatch_status,
|
||||
dispatch_reason,
|
||||
is_current,
|
||||
dispatched_at,
|
||||
created_by,
|
||||
updated_by,
|
||||
created_at,
|
||||
updated_at
|
||||
) values (
|
||||
'dsp_' || gen_random_uuid()::text,
|
||||
p_work_order_id,
|
||||
p_org_id,
|
||||
p_team_id,
|
||||
v_prev_version + 1,
|
||||
p_worker_id,
|
||||
p_service_latitude,
|
||||
p_service_longitude,
|
||||
lower(coalesce(p_service_coordinate_type, 'gcj02')),
|
||||
'PENDING',
|
||||
p_dispatch_reason,
|
||||
true,
|
||||
now(),
|
||||
p_operator_id,
|
||||
p_operator_id,
|
||||
now(),
|
||||
now()
|
||||
);
|
||||
|
||||
return jsonb_build_object('ok', true, 'assignVersion', v_prev_version + 1);
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace function public.rpc_homecare_checkin_precheck(
|
||||
p_work_order_id uuid,
|
||||
p_worker_id uuid,
|
||||
p_latitude numeric,
|
||||
p_longitude numeric,
|
||||
p_coordinate_type text default 'gcj02',
|
||||
p_accuracy numeric default null,
|
||||
p_reported_at timestamptz default null,
|
||||
p_location_scene text default 'CHECKIN_PRECHECK'
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public, app
|
||||
as $$
|
||||
declare
|
||||
v_assignment public.hc_dispatch_assignments%rowtype;
|
||||
v_radius_meters numeric := 200;
|
||||
v_distance_meters numeric;
|
||||
v_can_checkin boolean := false;
|
||||
v_reason_code text := 'WORK_ORDER_NOT_ASSIGNABLE';
|
||||
v_scene text := upper(coalesce(p_location_scene, 'CHECKIN_PRECHECK'));
|
||||
v_reported_at timestamptz := coalesce(p_reported_at, now());
|
||||
v_worker_location_accepted boolean := false;
|
||||
v_service_location_ready boolean := false;
|
||||
v_insert_location boolean := false;
|
||||
v_lat1 double precision;
|
||||
v_lng1 double precision;
|
||||
v_lat2 double precision;
|
||||
v_lng2 double precision;
|
||||
v_a double precision;
|
||||
v_c double precision;
|
||||
begin
|
||||
if p_work_order_id is null then
|
||||
raise exception 'p_work_order_id is required';
|
||||
end if;
|
||||
|
||||
if p_worker_id is null then
|
||||
raise exception 'p_worker_id is required';
|
||||
end if;
|
||||
|
||||
if p_latitude is null or p_longitude is null then
|
||||
raise exception 'p_latitude and p_longitude are required';
|
||||
end if;
|
||||
|
||||
if v_scene not in ('CHECKIN_PRECHECK', 'CHECKIN') then
|
||||
raise exception 'invalid p_location_scene: %', v_scene;
|
||||
end if;
|
||||
|
||||
if to_regclass('public.hc_dispatch_assignments') is null then
|
||||
raise exception 'hc_dispatch_assignments table is required';
|
||||
end if;
|
||||
|
||||
if to_regclass('public.hc_worker_locations') is null then
|
||||
raise exception 'hc_worker_locations table is required';
|
||||
end if;
|
||||
|
||||
if to_regclass('public.sys_sla_config') is null then
|
||||
raise exception 'sys_sla_config table is required';
|
||||
end if;
|
||||
|
||||
select *
|
||||
into v_assignment
|
||||
from public.hc_dispatch_assignments
|
||||
where work_order_id = p_work_order_id
|
||||
and is_current = true
|
||||
order by created_at desc
|
||||
limit 1;
|
||||
|
||||
if not found then
|
||||
v_reason_code := 'SERVICE_LOCATION_MISSING';
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', v_reason_code,
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
if coalesce(v_assignment.dispatch_status, '') not in ('PENDING', 'ACCEPTED') then
|
||||
v_reason_code := 'WORK_ORDER_NOT_ASSIGNABLE';
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', v_reason_code,
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
if v_assignment.worker_id is not null and v_assignment.worker_id <> p_worker_id then
|
||||
v_reason_code := 'WORKER_NOT_MATCHED';
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', v_reason_code,
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', true
|
||||
);
|
||||
end if;
|
||||
|
||||
if v_assignment.service_latitude is null or v_assignment.service_longitude is null then
|
||||
v_reason_code := 'SERVICE_LOCATION_MISSING';
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', v_reason_code,
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
v_service_location_ready := true;
|
||||
|
||||
-- SLA lookup priority: WORK_ORDER > ORG > TEAM > GLOBAL
|
||||
select config_value::numeric
|
||||
into v_radius_meters
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_RADIUS_METERS'
|
||||
and scope_type = 'WORK_ORDER'
|
||||
and scope_id = p_work_order_id::text
|
||||
and is_active = true
|
||||
limit 1;
|
||||
|
||||
if v_radius_meters is null and v_assignment.org_id is not null then
|
||||
select config_value::numeric
|
||||
into v_radius_meters
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_RADIUS_METERS'
|
||||
and scope_type = 'ORG'
|
||||
and scope_id = v_assignment.org_id::text
|
||||
and is_active = true
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
if v_radius_meters is null and v_assignment.team_id is not null then
|
||||
select config_value::numeric
|
||||
into v_radius_meters
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_RADIUS_METERS'
|
||||
and scope_type = 'TEAM'
|
||||
and scope_id = v_assignment.team_id::text
|
||||
and is_active = true
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
if v_radius_meters is null then
|
||||
select config_value::numeric
|
||||
into v_radius_meters
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_RADIUS_METERS'
|
||||
and scope_type = 'GLOBAL'
|
||||
and scope_id is null
|
||||
and is_active = true
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
v_radius_meters := coalesce(v_radius_meters, 200);
|
||||
|
||||
-- Haversine distance
|
||||
v_lat1 := radians(p_latitude::double precision);
|
||||
v_lng1 := radians(p_longitude::double precision);
|
||||
v_lat2 := radians(v_assignment.service_latitude::double precision);
|
||||
v_lng2 := radians(v_assignment.service_longitude::double precision);
|
||||
|
||||
v_a := power(sin((v_lat2 - v_lat1) / 2), 2)
|
||||
+ cos(v_lat1) * cos(v_lat2) * power(sin((v_lng2 - v_lng1) / 2), 2);
|
||||
v_c := 2 * atan2(sqrt(v_a), sqrt(1 - v_a));
|
||||
v_distance_meters := round((6371000 * v_c)::numeric, 2);
|
||||
|
||||
v_can_checkin := (v_distance_meters <= v_radius_meters);
|
||||
v_reason_code := case when v_can_checkin then 'OK' else 'OUT_OF_RADIUS' end;
|
||||
v_insert_location := (v_scene = 'CHECKIN_PRECHECK') or (v_scene = 'CHECKIN');
|
||||
|
||||
if v_insert_location then
|
||||
insert into public.hc_worker_locations(
|
||||
id,
|
||||
work_order_id,
|
||||
worker_id,
|
||||
latitude,
|
||||
longitude,
|
||||
coordinate_type,
|
||||
accuracy,
|
||||
location_scene,
|
||||
reported_at,
|
||||
distance_meters,
|
||||
created_at
|
||||
) values (
|
||||
'loc_' || gen_random_uuid()::text,
|
||||
p_work_order_id,
|
||||
p_worker_id,
|
||||
p_latitude,
|
||||
p_longitude,
|
||||
lower(coalesce(p_coordinate_type, 'gcj02')),
|
||||
p_accuracy,
|
||||
v_scene,
|
||||
v_reported_at,
|
||||
v_distance_meters,
|
||||
now()
|
||||
);
|
||||
|
||||
v_worker_location_accepted := true;
|
||||
end if;
|
||||
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', v_distance_meters,
|
||||
'allowedRadiusMeters', v_radius_meters,
|
||||
'canCheckin', v_can_checkin,
|
||||
'reasonCode', v_reason_code,
|
||||
'workerLocationAccepted', v_worker_location_accepted,
|
||||
'serviceLocationReady', v_service_location_ready
|
||||
);
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace function public.rpc_homecare_checkin_submit(
|
||||
p_work_order_id uuid,
|
||||
p_worker_id uuid,
|
||||
p_latitude numeric,
|
||||
p_longitude numeric,
|
||||
p_coordinate_type text default 'gcj02',
|
||||
p_accuracy numeric default null,
|
||||
p_reported_at timestamptz default null,
|
||||
p_evidence_file_ids jsonb default '[]'::jsonb,
|
||||
p_signature_payload text default null,
|
||||
p_reason text default null
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public, app
|
||||
as $$
|
||||
declare
|
||||
v_precheck jsonb;
|
||||
v_can_checkin boolean := false;
|
||||
v_assignment public.hc_dispatch_assignments%rowtype;
|
||||
v_assignment_found boolean := false;
|
||||
v_max_photo_count numeric := 3;
|
||||
v_requested_count integer := 0;
|
||||
v_existing_count integer := 0;
|
||||
v_mismatch_count integer := 0;
|
||||
v_not_owned_count integer := 0;
|
||||
v_not_ready_count integer := 0;
|
||||
begin
|
||||
if to_regclass('public.hc_work_order_confirmations') is null then
|
||||
raise exception 'hc_work_order_confirmations table is required';
|
||||
end if;
|
||||
|
||||
if p_signature_payload is null or length(trim(p_signature_payload)) = 0 then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'SIGNATURE_REQUIRED',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
if length(trim(p_signature_payload)) < 8 then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'SIGNATURE_INVALID',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
if p_evidence_file_ids is null or jsonb_typeof(p_evidence_file_ids) <> 'array' then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'EVIDENCE_FILE_NOT_EXIST',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
v_requested_count := jsonb_array_length(p_evidence_file_ids);
|
||||
if v_requested_count < 1 then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'EVIDENCE_FILE_NOT_EXIST',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
select *
|
||||
into v_assignment
|
||||
from public.hc_dispatch_assignments
|
||||
where work_order_id = p_work_order_id
|
||||
and is_current = true
|
||||
order by created_at desc
|
||||
limit 1;
|
||||
|
||||
v_assignment_found := found;
|
||||
|
||||
select config_value::numeric
|
||||
into v_max_photo_count
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_MAX_PHOTO_COUNT'
|
||||
and scope_type = 'WORK_ORDER'
|
||||
and scope_id = p_work_order_id::text
|
||||
and is_active = true
|
||||
limit 1;
|
||||
|
||||
if v_max_photo_count is null and v_assignment_found and v_assignment.org_id is not null then
|
||||
select config_value::numeric
|
||||
into v_max_photo_count
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_MAX_PHOTO_COUNT'
|
||||
and scope_type = 'ORG'
|
||||
and scope_id = v_assignment.org_id::text
|
||||
and is_active = true
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
if v_max_photo_count is null and v_assignment_found and v_assignment.team_id is not null then
|
||||
select config_value::numeric
|
||||
into v_max_photo_count
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_MAX_PHOTO_COUNT'
|
||||
and scope_type = 'TEAM'
|
||||
and scope_id = v_assignment.team_id::text
|
||||
and is_active = true
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
if v_max_photo_count is null then
|
||||
select config_value::numeric
|
||||
into v_max_photo_count
|
||||
from public.sys_sla_config
|
||||
where config_key = 'HOMECARE_CHECKIN_MAX_PHOTO_COUNT'
|
||||
and scope_type = 'GLOBAL'
|
||||
and scope_id is null
|
||||
and is_active = true
|
||||
limit 1;
|
||||
end if;
|
||||
|
||||
v_max_photo_count := coalesce(v_max_photo_count, 3);
|
||||
if v_requested_count > v_max_photo_count then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'PHOTO_COUNT_EXCEED_LIMIT',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
select count(*)
|
||||
into v_existing_count
|
||||
from public.hc_evidence_files e
|
||||
where e.id in (select jsonb_array_elements_text(p_evidence_file_ids));
|
||||
|
||||
if v_existing_count <> v_requested_count then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'EVIDENCE_FILE_NOT_EXIST',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
select count(*)
|
||||
into v_mismatch_count
|
||||
from public.hc_evidence_files e
|
||||
where e.id in (select jsonb_array_elements_text(p_evidence_file_ids))
|
||||
and e.work_order_id <> p_work_order_id;
|
||||
|
||||
if v_mismatch_count > 0 then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'EVIDENCE_FILE_WORK_ORDER_MISMATCH',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
select count(*)
|
||||
into v_not_owned_count
|
||||
from public.hc_evidence_files e
|
||||
where e.id in (select jsonb_array_elements_text(p_evidence_file_ids))
|
||||
and e.work_order_id = p_work_order_id
|
||||
and coalesce(e.uploader_id, '') <> p_worker_id::text;
|
||||
|
||||
if v_not_owned_count > 0 then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'EVIDENCE_FILE_NOT_OWNED',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
select count(*)
|
||||
into v_not_ready_count
|
||||
from public.hc_evidence_files e
|
||||
where e.id in (select jsonb_array_elements_text(p_evidence_file_ids))
|
||||
and e.work_order_id = p_work_order_id
|
||||
and (e.file_url is null or length(trim(e.file_url)) = 0);
|
||||
|
||||
if v_not_ready_count > 0 then
|
||||
return jsonb_build_object(
|
||||
'distanceMeters', null,
|
||||
'allowedRadiusMeters', 0,
|
||||
'canCheckin', false,
|
||||
'reasonCode', 'EVIDENCE_FILE_NOT_READY',
|
||||
'workerLocationAccepted', false,
|
||||
'serviceLocationReady', false
|
||||
);
|
||||
end if;
|
||||
|
||||
v_precheck := public.rpc_homecare_checkin_precheck(
|
||||
p_work_order_id,
|
||||
p_worker_id,
|
||||
p_latitude,
|
||||
p_longitude,
|
||||
p_coordinate_type,
|
||||
p_accuracy,
|
||||
p_reported_at,
|
||||
'CHECKIN'
|
||||
);
|
||||
|
||||
v_can_checkin := coalesce((v_precheck ->> 'canCheckin')::boolean, false);
|
||||
if not v_can_checkin then
|
||||
return v_precheck;
|
||||
end if;
|
||||
|
||||
insert into public.hc_work_order_confirmations(
|
||||
id,
|
||||
work_order_id,
|
||||
confirmation_type,
|
||||
status,
|
||||
confirmed_by,
|
||||
confirmed_at,
|
||||
reason,
|
||||
payload,
|
||||
created_at,
|
||||
updated_at
|
||||
) values (
|
||||
'woc_' || gen_random_uuid()::text,
|
||||
p_work_order_id,
|
||||
'ARRIVAL',
|
||||
'PENDING',
|
||||
p_worker_id,
|
||||
null,
|
||||
coalesce(p_reason, 'worker_checkin_submitted'),
|
||||
jsonb_build_object(
|
||||
'distanceMeters', (v_precheck ->> 'distanceMeters')::numeric,
|
||||
'allowedRadiusMeters', (v_precheck ->> 'allowedRadiusMeters')::numeric,
|
||||
'coordinateType', coalesce(lower(p_coordinate_type), 'gcj02'),
|
||||
'reportedAt', coalesce(p_reported_at, now()),
|
||||
'signatureProvided', (p_signature_payload is not null and length(trim(p_signature_payload)) > 0),
|
||||
'evidenceFileIds', coalesce(p_evidence_file_ids, '[]'::jsonb)
|
||||
),
|
||||
now(),
|
||||
now()
|
||||
);
|
||||
|
||||
return v_precheck || jsonb_build_object('confirmationInserted', true);
|
||||
end;
|
||||
$$;
|
||||
|
||||
-- ============================================================
|
||||
-- Grants (updated for uuid types)
|
||||
-- ============================================================
|
||||
|
||||
revoke all on function public.rpc_homecare_checkin_precheck(uuid, uuid, numeric, numeric, text, numeric, timestamptz, text) from public;
|
||||
grant execute on function public.rpc_homecare_checkin_precheck(uuid, uuid, numeric, numeric, text, numeric, timestamptz, text) to service_role;
|
||||
|
||||
revoke all on function public.rpc_homecare_dispatch_assignment_upsert(uuid, uuid, uuid, uuid, numeric, numeric, text, uuid, text) from public;
|
||||
grant execute on function public.rpc_homecare_dispatch_assignment_upsert(uuid, uuid, uuid, uuid, numeric, numeric, text, uuid, text) to service_role;
|
||||
|
||||
revoke all on function public.rpc_homecare_checkin_submit(uuid, uuid, numeric, numeric, text, numeric, timestamptz, jsonb, text, text) from public;
|
||||
grant execute on function public.rpc_homecare_checkin_submit(uuid, uuid, numeric, numeric, text, numeric, timestamptz, jsonb, text, text) to service_role;
|
||||
|
||||
-- ============================================================
|
||||
-- Comments
|
||||
-- ============================================================
|
||||
|
||||
comment on function public.rpc_homecare_checkin_precheck(uuid, uuid, numeric, numeric, text, numeric, timestamptz, text)
|
||||
is 'Homecare checkin distance precheck RPC with SLA lookup and optional location snapshot insert';
|
||||
|
||||
comment on function public.rpc_homecare_dispatch_assignment_upsert(uuid, uuid, uuid, uuid, numeric, numeric, text, uuid, text)
|
||||
is 'Homecare dispatch assignment upsert RPC; rotates current assignment and snapshots service location for distance checkin (uuid types)';
|
||||
|
||||
comment on function public.rpc_homecare_checkin_submit(uuid, uuid, numeric, numeric, text, numeric, timestamptz, jsonb, text, text)
|
||||
is 'Homecare checkin submit RPC; re-runs distance precheck and writes confirmation snapshot when checkin is allowed';
|
||||
916
mall_sql/migrations/20260605_homecare_migration_fixed.sql
Normal file
916
mall_sql/migrations/20260605_homecare_migration_fixed.sql
Normal file
@@ -0,0 +1,916 @@
|
||||
-- ============================================================
|
||||
-- Homecare Migration SQL - Phase 1 (Location & Checkin)
|
||||
-- Date: 2026-06-05
|
||||
-- Purpose: Formal migration for homecare location distance phase 1
|
||||
-- Scope: Create/alter tables, indexes, foreign keys, seed data
|
||||
-- ID Type: All user/org/team/elder IDs unified to uuid
|
||||
-- Checkin Radius: 50 meters (phase 1)
|
||||
-- ============================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Needed for gen_random_uuid() defaults used by UUID primary keys.
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
-- ============================================================
|
||||
-- Part 1: Create/Alter Foundation Tables
|
||||
-- ============================================================
|
||||
|
||||
-- Table: public.hc_work_order_events
|
||||
-- Source: 20260518_homecare_foundation.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_work_order_events (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
worker_id uuid,
|
||||
action text not null,
|
||||
from_status text not null,
|
||||
to_status text not null,
|
||||
operator_id uuid not null,
|
||||
reason text,
|
||||
payload jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_work_order_exceptions
|
||||
-- Source: 20260518_homecare_foundation.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_work_order_exceptions (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
worker_id uuid,
|
||||
exception_type text not null,
|
||||
description text not null,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'HANDLED')),
|
||||
decision text,
|
||||
reason text,
|
||||
created_by uuid not null,
|
||||
handled_by uuid,
|
||||
evidence_urls jsonb not null default '[]'::jsonb,
|
||||
created_at timestamptz not null default now(),
|
||||
handled_at timestamptz
|
||||
);
|
||||
|
||||
-- Table: public.hc_evidence_files
|
||||
-- Source: 20260518_homecare_foundation.sql
|
||||
-- Phase 1 Update: Add fields for checkin evidence support
|
||||
CREATE TABLE IF NOT EXISTS public.hc_evidence_files (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
owner_id uuid,
|
||||
uploader_id uuid not null,
|
||||
file_url text not null,
|
||||
mime_type text,
|
||||
evidence_type text,
|
||||
-- Phase 1新增字段
|
||||
file_size_bytes bigint not null default 0,
|
||||
upload_status text not null default 'TEMP' check (upload_status in ('TEMP', 'READY', 'BOUND', 'LOCKED', 'DELETED')),
|
||||
storage_bucket text,
|
||||
storage_path text,
|
||||
file_hash text,
|
||||
bound_action text check (bound_action in ('CHECKIN', 'CHECKOUT', 'EXCEPTION')),
|
||||
bound_record_id text,
|
||||
is_locked boolean not null default false,
|
||||
locked_at timestamptz,
|
||||
expires_at timestamptz,
|
||||
updated_at timestamptz not null default now(),
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_worker_qualifications
|
||||
-- Source: 20260518_homecare_foundation.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_worker_qualifications (
|
||||
id text primary key,
|
||||
org_id uuid not null,
|
||||
worker_id uuid not null,
|
||||
qualification_type text not null,
|
||||
qualification_no text,
|
||||
issue_org text,
|
||||
valid_from date,
|
||||
valid_to date,
|
||||
review_status text not null default 'PENDING' check (review_status in ('PENDING', 'APPROVED', 'REJECTED', 'EXPIRED')),
|
||||
reviewed_by uuid,
|
||||
reviewed_at timestamptz,
|
||||
file_urls jsonb not null default '[]'::jsonb,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_settlements
|
||||
-- Source: 20260518_homecare_foundation.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_settlements (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
work_order_id uuid not null unique,
|
||||
org_id uuid not null,
|
||||
finance_owner_id uuid,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'READY', 'CONFIRMED')),
|
||||
amount numeric(12, 2) not null default 0,
|
||||
currency text not null default 'CNY',
|
||||
settled_at timestamptz,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Part 2: Business Closure Extension Tables
|
||||
-- ============================================================
|
||||
|
||||
-- Table: public.hc_acceptances
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_acceptances (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
worker_id uuid,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'ACCEPTED', 'REJECTED', 'CLOSED')),
|
||||
result text check (result in ('PASS', 'REJECT')),
|
||||
rating smallint check (rating between 1 and 5),
|
||||
tags jsonb not null default '[]'::jsonb,
|
||||
comment text,
|
||||
rejected_reason text,
|
||||
accepted_by uuid,
|
||||
accepted_at timestamptz,
|
||||
created_by uuid,
|
||||
updated_by uuid,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_acceptance_issues
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_acceptance_issues (
|
||||
id text primary key,
|
||||
acceptance_id text not null,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
worker_id uuid,
|
||||
issue_type text not null,
|
||||
priority text,
|
||||
description text not null,
|
||||
evidence_urls jsonb not null default '[]'::jsonb,
|
||||
status text not null default 'OPEN' check (status in ('OPEN', 'PROCESSING', 'RESOLVED', 'CLOSED')),
|
||||
reporter_id uuid not null,
|
||||
handler_id uuid,
|
||||
resolution text,
|
||||
resolved_at timestamptz,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_complaints
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_complaints (
|
||||
id text primary key,
|
||||
work_order_id uuid,
|
||||
acceptance_issue_id text,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
worker_id uuid,
|
||||
complainant_id uuid not null,
|
||||
complaint_type text not null,
|
||||
description text not null,
|
||||
evidence_urls jsonb not null default '[]'::jsonb,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'PROCESSING', 'RESOLVED', 'CLOSED')),
|
||||
handler_id uuid,
|
||||
resolution text,
|
||||
resolved_at timestamptz,
|
||||
created_by uuid,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_exception_actions
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_exception_actions (
|
||||
id text primary key,
|
||||
exception_id text not null,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
worker_id uuid,
|
||||
action_type text not null,
|
||||
description text,
|
||||
payload jsonb not null default '{}'::jsonb,
|
||||
operator_id uuid not null,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_settlement_items
|
||||
CREATE TABLE IF NOT EXISTS public.hc_settlement_items (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
settlement_id uuid not null,
|
||||
work_order_id uuid not null,
|
||||
execution_record_id uuid,
|
||||
item_name text not null,
|
||||
unit_price numeric(12, 2) not null default 0,
|
||||
quantity numeric(10, 2) not null default 1,
|
||||
actual_amount numeric(12, 2) not null default 0,
|
||||
deduction_amount numeric(12, 2) not null default 0,
|
||||
self_pay_amount numeric(12, 2) not null default 0,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'APPROVED', 'REJECTED', 'WAIVED')),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_payments
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_payments (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
settlement_id uuid not null,
|
||||
org_id uuid not null,
|
||||
payer_id uuid,
|
||||
payment_channel text not null,
|
||||
transaction_id text,
|
||||
amount numeric(12, 2) not null,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'PAID', 'FAILED', 'CANCELLED', 'REFUNDING', 'REFUNDED')),
|
||||
callback_payload jsonb not null default '{}'::jsonb,
|
||||
paid_at timestamptz,
|
||||
failed_at timestamptz,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_refunds
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_refunds (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
payment_id uuid not null,
|
||||
settlement_id uuid not null,
|
||||
org_id uuid not null,
|
||||
amount numeric(12, 2) not null,
|
||||
reason text not null,
|
||||
status text not null default 'PENDING' check (status in ('PENDING', 'PROCESSING', 'REFUNDED', 'FAILED', 'CLOSED')),
|
||||
refund_transaction_id text,
|
||||
created_by uuid,
|
||||
refunded_at timestamptz,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_ledgers
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_ledgers (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
settlement_id uuid not null,
|
||||
org_id uuid not null,
|
||||
archive_period text not null,
|
||||
ledger_type text not null default 'SETTLEMENT',
|
||||
content jsonb not null default '{}'::jsonb,
|
||||
archived_at timestamptz,
|
||||
created_by uuid,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_archive_files
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_archive_files (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
ledger_id uuid not null,
|
||||
org_id uuid not null,
|
||||
file_url text not null,
|
||||
file_name text,
|
||||
file_size bigint,
|
||||
mime_type text,
|
||||
created_by uuid,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_consent_records
|
||||
-- Source: 20260527_homecare_business_closure_extensions.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_consent_records (
|
||||
id text primary key,
|
||||
org_id uuid not null,
|
||||
elder_id uuid not null,
|
||||
consent_type text not null,
|
||||
consent_status text not null default 'GRANTED' check (consent_status in ('GRANTED', 'REVOKED', 'EXPIRED')),
|
||||
consent_version text,
|
||||
granted_by uuid,
|
||||
granted_at timestamptz,
|
||||
revoked_at timestamptz,
|
||||
expires_at timestamptz,
|
||||
evidence_urls jsonb not null default '[]'::jsonb,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Part 3: Location Distance Phase 1 Tables
|
||||
-- ============================================================
|
||||
|
||||
-- Table: public.hc_dispatch_assignments
|
||||
-- Source: 20260602_homecare_location_distance_phase1_tables.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_dispatch_assignments (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
org_id uuid not null,
|
||||
team_id uuid,
|
||||
assign_version integer not null default 1 check (assign_version > 0),
|
||||
worker_id uuid,
|
||||
service_latitude numeric(10,7) not null,
|
||||
service_longitude numeric(10,7) not null,
|
||||
service_coordinate_type text not null default 'gcj02',
|
||||
dispatch_status text not null default 'PENDING'
|
||||
check (dispatch_status in ('PENDING', 'ACCEPTED', 'REJECTED', 'TIMEOUT', 'REASSIGNED', 'CANCELLED')),
|
||||
dispatch_reason text,
|
||||
is_current boolean not null default true,
|
||||
dispatched_at timestamptz not null default now(),
|
||||
accepted_at timestamptz,
|
||||
rejected_at timestamptz,
|
||||
timeout_at timestamptz,
|
||||
reassigned_at timestamptz,
|
||||
cancelled_at timestamptz,
|
||||
created_by uuid,
|
||||
updated_by uuid,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
constraint chk_hc_dispatch_assignments_lat_range check (service_latitude between -90 and 90),
|
||||
constraint chk_hc_dispatch_assignments_lng_range check (service_longitude between -180 and 180),
|
||||
constraint uq_hc_dispatch_assignments_version unique (work_order_id, assign_version)
|
||||
);
|
||||
|
||||
-- Table: public.hc_worker_locations
|
||||
-- Source: 20260602_homecare_location_distance_phase1_tables.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_worker_locations (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
worker_id uuid not null,
|
||||
latitude numeric(10,7) not null,
|
||||
longitude numeric(10,7) not null,
|
||||
coordinate_type text not null default 'gcj02',
|
||||
accuracy numeric(10,2),
|
||||
location_scene text not null
|
||||
check (location_scene in ('ON_THE_WAY', 'CHECKIN_PRECHECK', 'CHECKIN', 'CHECKOUT')),
|
||||
reported_at timestamptz not null,
|
||||
distance_meters numeric(10,2),
|
||||
formatted_address text,
|
||||
province text,
|
||||
city text,
|
||||
district text,
|
||||
street text,
|
||||
poi_title text,
|
||||
geocode_provider text,
|
||||
geocode_status text,
|
||||
address_updated_at timestamptz,
|
||||
created_at timestamptz not null default now(),
|
||||
constraint chk_hc_worker_locations_lat_range check (latitude between -90 and 90),
|
||||
constraint chk_hc_worker_locations_lng_range check (longitude between -180 and 180)
|
||||
);
|
||||
|
||||
-- Table: public.hc_work_order_confirmations
|
||||
-- Source: 20260602_homecare_location_distance_phase1_tables.sql
|
||||
CREATE TABLE IF NOT EXISTS public.hc_work_order_confirmations (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
confirmation_type text not null default 'ARRIVAL',
|
||||
status text not null default 'PENDING'
|
||||
check (status in ('PENDING', 'CONFIRMED', 'REJECTED')),
|
||||
confirmed_by uuid,
|
||||
confirmed_at timestamptz,
|
||||
reason text,
|
||||
payload jsonb not null default '{}'::jsonb,
|
||||
-- Phase 1预留:二期电子签名扩展字段
|
||||
signature_url text,
|
||||
signature_hash text,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.sys_sla_config
|
||||
-- Source: 20260602_homecare_location_distance_phase1_tables.sql
|
||||
CREATE TABLE IF NOT EXISTS public.sys_sla_config (
|
||||
id text primary key,
|
||||
config_key text not null,
|
||||
config_value text not null,
|
||||
value_type text not null default 'string',
|
||||
scope_type text not null default 'GLOBAL'
|
||||
check (scope_type in ('WORK_ORDER', 'ORG', 'TEAM', 'GLOBAL')),
|
||||
scope_id text,
|
||||
is_active boolean not null default true,
|
||||
description text,
|
||||
updated_by uuid,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
constraint chk_sys_sla_config_scope check (
|
||||
(scope_type = 'GLOBAL' and scope_id is null)
|
||||
or (scope_type <> 'GLOBAL')
|
||||
)
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Part 4: Audit Extension Tables (if not exist)
|
||||
-- ============================================================
|
||||
|
||||
-- Table: public.hc_state_transitions
|
||||
CREATE TABLE IF NOT EXISTS public.hc_state_transitions (
|
||||
id text primary key,
|
||||
work_order_id uuid not null,
|
||||
from_status text not null,
|
||||
to_status text not null,
|
||||
triggered_by uuid not null,
|
||||
reason text,
|
||||
payload jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_audit_logs
|
||||
CREATE TABLE IF NOT EXISTS public.hc_audit_logs (
|
||||
id text primary key,
|
||||
work_order_id uuid,
|
||||
org_id uuid,
|
||||
actor_id uuid not null,
|
||||
actor_role text not null,
|
||||
action text not null,
|
||||
resource_type text not null,
|
||||
resource_id text not null,
|
||||
details jsonb,
|
||||
ip_address inet,
|
||||
user_agent text,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
-- Table: public.hc_sensitive_access_logs
|
||||
CREATE TABLE IF NOT EXISTS public.hc_sensitive_access_logs (
|
||||
id text primary key,
|
||||
accessor_id uuid not null,
|
||||
accessed_resource_type text not null,
|
||||
accessed_resource_id text not null,
|
||||
access_purpose text not null,
|
||||
approved_by uuid,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
|
||||
-- ============================================================
|
||||
-- Part 4.5: Legacy Compatibility Fixes
|
||||
-- ============================================================
|
||||
-- These fixes make reruns safe when older hc_* tables already exist.
|
||||
-- CREATE TABLE IF NOT EXISTS does not upgrade existing table definitions,
|
||||
-- so referenced columns and FK columns are normalized before indexes/FKs.
|
||||
|
||||
-- Existing settlements table may already have id uuid in current database.
|
||||
-- If settlement-related child tables already exist with text FK columns,
|
||||
-- convert them to uuid before FK creation. This succeeds only when existing
|
||||
-- values are empty or valid UUID strings.
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('public.hc_settlement_items') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name='hc_settlement_items'
|
||||
AND column_name='settlement_id'
|
||||
AND udt_name <> 'uuid'
|
||||
)
|
||||
THEN
|
||||
ALTER TABLE public.hc_settlement_items
|
||||
ALTER COLUMN settlement_id TYPE uuid USING NULLIF(settlement_id, '')::uuid;
|
||||
END IF;
|
||||
|
||||
IF to_regclass('public.hc_payments') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name='hc_payments'
|
||||
AND column_name='settlement_id'
|
||||
AND udt_name <> 'uuid'
|
||||
)
|
||||
THEN
|
||||
ALTER TABLE public.hc_payments
|
||||
ALTER COLUMN settlement_id TYPE uuid USING NULLIF(settlement_id, '')::uuid;
|
||||
END IF;
|
||||
|
||||
IF to_regclass('public.hc_refunds') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name='hc_refunds'
|
||||
AND column_name='settlement_id'
|
||||
AND udt_name <> 'uuid'
|
||||
)
|
||||
THEN
|
||||
ALTER TABLE public.hc_refunds
|
||||
ALTER COLUMN settlement_id TYPE uuid USING NULLIF(settlement_id, '')::uuid;
|
||||
END IF;
|
||||
|
||||
IF to_regclass('public.hc_refunds') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name='hc_refunds'
|
||||
AND column_name='payment_id'
|
||||
AND udt_name <> 'uuid'
|
||||
)
|
||||
THEN
|
||||
ALTER TABLE public.hc_refunds
|
||||
ALTER COLUMN payment_id TYPE uuid USING NULLIF(payment_id, '')::uuid;
|
||||
END IF;
|
||||
|
||||
IF to_regclass('public.hc_ledgers') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name='hc_ledgers'
|
||||
AND column_name='settlement_id'
|
||||
AND udt_name <> 'uuid'
|
||||
)
|
||||
THEN
|
||||
ALTER TABLE public.hc_ledgers
|
||||
ALTER COLUMN settlement_id TYPE uuid USING NULLIF(settlement_id, '')::uuid;
|
||||
END IF;
|
||||
|
||||
IF to_regclass('public.hc_archive_files') IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name='hc_archive_files'
|
||||
AND column_name='ledger_id'
|
||||
AND udt_name <> 'uuid'
|
||||
)
|
||||
THEN
|
||||
ALTER TABLE public.hc_archive_files
|
||||
ALTER COLUMN ledger_id TYPE uuid USING NULLIF(ledger_id, '')::uuid;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ============================================================
|
||||
-- Part 5: Indexes
|
||||
-- ============================================================
|
||||
|
||||
-- hc_dispatch_assignments indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_dispatch_assignments_wo_created
|
||||
ON public.hc_dispatch_assignments (work_order_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_dispatch_assignments_current
|
||||
ON public.hc_dispatch_assignments (work_order_id) WHERE is_current = true;
|
||||
|
||||
-- Ensure each work order has at most one current assignment for distance/checkin RPC lookup.
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_hc_dispatch_assignments_one_current
|
||||
ON public.hc_dispatch_assignments (work_order_id) WHERE is_current = true;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_dispatch_assignments_worker_status
|
||||
ON public.hc_dispatch_assignments (worker_id, dispatch_status, created_at DESC);
|
||||
|
||||
-- hc_worker_locations indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_worker_locations_wo_reported
|
||||
ON public.hc_worker_locations (work_order_id, reported_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_worker_locations_worker_reported
|
||||
ON public.hc_worker_locations (worker_id, reported_at DESC);
|
||||
|
||||
-- hc_work_order_confirmations indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_work_order_confirmations_wo_created
|
||||
ON public.hc_work_order_confirmations (work_order_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_work_order_confirmations_status
|
||||
ON public.hc_work_order_confirmations (status, updated_at DESC);
|
||||
|
||||
-- hc_evidence_files indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_evidence_files_wo_created
|
||||
ON public.hc_evidence_files (work_order_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_evidence_files_upload_status
|
||||
ON public.hc_evidence_files (upload_status) WHERE upload_status != 'DELETED';
|
||||
|
||||
-- sys_sla_config indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_sys_sla_config_key_scope
|
||||
ON public.sys_sla_config (config_key, scope_type, scope_id, is_active) WHERE is_active = true;
|
||||
|
||||
-- hc_work_order_exceptions indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_work_order_exceptions_wo_created
|
||||
ON public.hc_work_order_exceptions (work_order_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_work_order_exceptions_status
|
||||
ON public.hc_work_order_exceptions (status, created_at DESC);
|
||||
|
||||
-- hc_work_order_events indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_work_order_events_wo_created
|
||||
ON public.hc_work_order_events (work_order_id, created_at DESC);
|
||||
|
||||
-- hc_settlements indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_hc_settlements_wo
|
||||
ON public.hc_settlements (work_order_id);
|
||||
|
||||
-- ============================================================
|
||||
-- Part 6: Foreign Keys
|
||||
-- ============================================================
|
||||
|
||||
-- Make foreign key creation idempotent for reruns
|
||||
ALTER TABLE public.hc_work_order_events
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_events_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_events_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_events_operator;
|
||||
|
||||
ALTER TABLE public.hc_work_order_exceptions
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_exceptions_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_exceptions_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_exceptions_created_by,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_exceptions_handled_by;
|
||||
|
||||
ALTER TABLE public.hc_evidence_files
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_evidence_files_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_evidence_files_uploader;
|
||||
|
||||
ALTER TABLE public.hc_worker_qualifications
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_worker_qualifications_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_worker_qualifications_reviewed_by;
|
||||
|
||||
ALTER TABLE public.hc_settlements
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_settlements_work_order;
|
||||
|
||||
ALTER TABLE public.hc_acceptances
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptances_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptances_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptances_accepted_by;
|
||||
|
||||
ALTER TABLE public.hc_acceptance_issues
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptance_issues_acceptance,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptance_issues_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptance_issues_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptance_issues_reporter,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_acceptance_issues_handler;
|
||||
|
||||
ALTER TABLE public.hc_complaints
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_complaints_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_complaints_acceptance_issue,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_complaints_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_complaints_complainant,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_complaints_handler;
|
||||
|
||||
ALTER TABLE public.hc_exception_actions
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_exception_actions_exception,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_exception_actions_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_exception_actions_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_exception_actions_operator;
|
||||
|
||||
ALTER TABLE public.hc_settlement_items
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_settlement_items_settlement,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_settlement_items_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_settlement_items_execution_record;
|
||||
|
||||
ALTER TABLE public.hc_payments
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_payments_settlement,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_payments_payer;
|
||||
|
||||
ALTER TABLE public.hc_refunds
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_refunds_payment,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_refunds_settlement,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_refunds_created_by;
|
||||
|
||||
ALTER TABLE public.hc_ledgers
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_ledgers_settlement,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_ledgers_created_by;
|
||||
|
||||
ALTER TABLE public.hc_archive_files
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_archive_files_ledger,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_archive_files_created_by;
|
||||
|
||||
ALTER TABLE public.hc_consent_records
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_consent_records_elder,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_consent_records_granted_by;
|
||||
|
||||
ALTER TABLE public.hc_dispatch_assignments
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_dispatch_assignments_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_dispatch_assignments_worker,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_dispatch_assignments_created_by,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_dispatch_assignments_updated_by;
|
||||
|
||||
ALTER TABLE public.hc_worker_locations
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_worker_locations_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_worker_locations_worker;
|
||||
|
||||
ALTER TABLE public.hc_work_order_confirmations
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_confirmations_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_work_order_confirmations_confirmed_by;
|
||||
|
||||
ALTER TABLE public.hc_state_transitions
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_state_transitions_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_state_transitions_triggered_by;
|
||||
|
||||
ALTER TABLE public.hc_audit_logs
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_audit_logs_work_order,
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_audit_logs_actor;
|
||||
|
||||
ALTER TABLE public.hc_sensitive_access_logs
|
||||
DROP CONSTRAINT IF EXISTS fk_hc_sensitive_access_logs_accessor;
|
||||
|
||||
-- hc_work_order_events foreign keys
|
||||
ALTER TABLE public.hc_work_order_events
|
||||
ADD CONSTRAINT fk_hc_work_order_events_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_work_order_events_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_work_order_events_operator
|
||||
FOREIGN KEY (operator_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
-- hc_work_order_exceptions foreign keys
|
||||
ALTER TABLE public.hc_work_order_exceptions
|
||||
ADD CONSTRAINT fk_hc_work_order_exceptions_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_work_order_exceptions_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_work_order_exceptions_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES public.ak_users(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_work_order_exceptions_handled_by
|
||||
FOREIGN KEY (handled_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_evidence_files foreign keys
|
||||
ALTER TABLE public.hc_evidence_files
|
||||
ADD CONSTRAINT fk_hc_evidence_files_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_evidence_files_uploader
|
||||
FOREIGN KEY (uploader_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
-- hc_worker_qualifications foreign keys
|
||||
ALTER TABLE public.hc_worker_qualifications
|
||||
ADD CONSTRAINT fk_hc_worker_qualifications_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_worker_qualifications_reviewed_by
|
||||
FOREIGN KEY (reviewed_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_settlements foreign keys
|
||||
ALTER TABLE public.hc_settlements
|
||||
ADD CONSTRAINT fk_hc_settlements_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT;
|
||||
|
||||
-- hc_acceptances foreign keys
|
||||
ALTER TABLE public.hc_acceptances
|
||||
ADD CONSTRAINT fk_hc_acceptances_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_acceptances_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_acceptances_accepted_by
|
||||
FOREIGN KEY (accepted_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_acceptance_issues foreign keys
|
||||
ALTER TABLE public.hc_acceptance_issues
|
||||
ADD CONSTRAINT fk_hc_acceptance_issues_acceptance
|
||||
FOREIGN KEY (acceptance_id) REFERENCES public.hc_acceptances(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_acceptance_issues_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_acceptance_issues_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_acceptance_issues_reporter
|
||||
FOREIGN KEY (reporter_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_acceptance_issues_handler
|
||||
FOREIGN KEY (handler_id) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_complaints foreign keys
|
||||
ALTER TABLE public.hc_complaints
|
||||
ADD CONSTRAINT fk_hc_complaints_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_complaints_acceptance_issue
|
||||
FOREIGN KEY (acceptance_issue_id) REFERENCES public.hc_acceptance_issues(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_complaints_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_complaints_complainant
|
||||
FOREIGN KEY (complainant_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_complaints_handler
|
||||
FOREIGN KEY (handler_id) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_exception_actions foreign keys
|
||||
ALTER TABLE public.hc_exception_actions
|
||||
ADD CONSTRAINT fk_hc_exception_actions_exception
|
||||
FOREIGN KEY (exception_id) REFERENCES public.hc_work_order_exceptions(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_exception_actions_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_exception_actions_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_exception_actions_operator
|
||||
FOREIGN KEY (operator_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
-- hc_settlement_items foreign keys
|
||||
ALTER TABLE public.hc_settlement_items
|
||||
ADD CONSTRAINT fk_hc_settlement_items_settlement
|
||||
FOREIGN KEY (settlement_id) REFERENCES public.hc_settlements(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_settlement_items_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_settlement_items_execution_record
|
||||
FOREIGN KEY (execution_record_id) REFERENCES public.ec_care_records(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_payments foreign keys
|
||||
ALTER TABLE public.hc_payments
|
||||
ADD CONSTRAINT fk_hc_payments_settlement
|
||||
FOREIGN KEY (settlement_id) REFERENCES public.hc_settlements(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_payments_payer
|
||||
FOREIGN KEY (payer_id) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_refunds foreign keys
|
||||
ALTER TABLE public.hc_refunds
|
||||
ADD CONSTRAINT fk_hc_refunds_payment
|
||||
FOREIGN KEY (payment_id) REFERENCES public.hc_payments(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_refunds_settlement
|
||||
FOREIGN KEY (settlement_id) REFERENCES public.hc_settlements(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_refunds_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_ledgers foreign keys
|
||||
ALTER TABLE public.hc_ledgers
|
||||
ADD CONSTRAINT fk_hc_ledgers_settlement
|
||||
FOREIGN KEY (settlement_id) REFERENCES public.hc_settlements(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_ledgers_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_archive_files foreign keys
|
||||
ALTER TABLE public.hc_archive_files
|
||||
ADD CONSTRAINT fk_hc_archive_files_ledger
|
||||
FOREIGN KEY (ledger_id) REFERENCES public.hc_ledgers(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_archive_files_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- hc_consent_records foreign keys
|
||||
ALTER TABLE public.hc_consent_records
|
||||
ADD CONSTRAINT fk_hc_consent_records_elder
|
||||
FOREIGN KEY (elder_id) REFERENCES public.ec_elders(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_consent_records_granted_by
|
||||
FOREIGN KEY (granted_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- Location distance phase 1 foreign keys
|
||||
ALTER TABLE public.hc_dispatch_assignments
|
||||
ADD CONSTRAINT fk_hc_dispatch_assignments_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_dispatch_assignments_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_dispatch_assignments_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES public.ak_users(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_dispatch_assignments_updated_by
|
||||
FOREIGN KEY (updated_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE public.hc_worker_locations
|
||||
ADD CONSTRAINT fk_hc_worker_locations_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_worker_locations_worker
|
||||
FOREIGN KEY (worker_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
ALTER TABLE public.hc_work_order_confirmations
|
||||
ADD CONSTRAINT fk_hc_work_order_confirmations_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_work_order_confirmations_confirmed_by
|
||||
FOREIGN KEY (confirmed_by) REFERENCES public.ak_users(id) ON DELETE SET NULL;
|
||||
|
||||
-- Audit extension tables foreign keys
|
||||
ALTER TABLE public.hc_state_transitions
|
||||
ADD CONSTRAINT fk_hc_state_transitions_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE RESTRICT,
|
||||
ADD CONSTRAINT fk_hc_state_transitions_triggered_by
|
||||
FOREIGN KEY (triggered_by) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
ALTER TABLE public.hc_audit_logs
|
||||
ADD CONSTRAINT fk_hc_audit_logs_work_order
|
||||
FOREIGN KEY (work_order_id) REFERENCES public.ec_care_tasks(id) ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_hc_audit_logs_actor
|
||||
FOREIGN KEY (actor_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
ALTER TABLE public.hc_sensitive_access_logs
|
||||
ADD CONSTRAINT fk_hc_sensitive_access_logs_accessor
|
||||
FOREIGN KEY (accessor_id) REFERENCES public.ak_users(id) ON DELETE RESTRICT;
|
||||
|
||||
-- ============================================================
|
||||
-- Part 7: Seed Data - SLA Config
|
||||
-- ============================================================
|
||||
|
||||
-- Phase 1 SLA configuration
|
||||
-- Checkin radius: 50 meters (phase 1 final)
|
||||
INSERT INTO public.sys_sla_config (id, config_key, config_value, value_type, scope_type, description)
|
||||
VALUES
|
||||
('sla_001', 'HOMECARE_CHECKIN_RADIUS_METERS', '50', 'integer', 'GLOBAL', '签到半径(一期50米)'),
|
||||
('sla_002', 'HOMECARE_LOCATION_REFRESH_SECONDS', '30', 'integer', 'GLOBAL', '定位刷新间隔(秒)'),
|
||||
('sla_003', 'HOMECARE_CHECKIN_MAX_PHOTO_COUNT', '3', 'integer', 'GLOBAL', '签到最大照片数'),
|
||||
('sla_004', 'HOMECARE_CHECKIN_MAX_PHOTO_SIZE_MB', '5', 'integer', 'GLOBAL', '单张最大照片大小(MB)')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================
|
||||
-- Part 8: Comments
|
||||
-- ============================================================
|
||||
|
||||
COMMENT ON TABLE public.hc_work_order_events IS '居家服务工单事件表 - 业务时间线展示';
|
||||
COMMENT ON TABLE public.hc_work_order_exceptions IS '居家服务工单异常表';
|
||||
COMMENT ON TABLE public.hc_evidence_files IS '居家服务证据文件表 - 签到照片、异常图片等';
|
||||
COMMENT ON TABLE public.hc_worker_qualifications IS '居家服务人员资质表';
|
||||
COMMENT ON TABLE public.hc_settlements IS '居家服务结算表';
|
||||
COMMENT ON TABLE public.hc_acceptances IS '居家服务确认表';
|
||||
COMMENT ON TABLE public.hc_acceptance_issues IS '居家服务确认问题表';
|
||||
COMMENT ON TABLE public.hc_complaints IS '居家服务投诉表';
|
||||
COMMENT ON TABLE public.hc_exception_actions IS '居家服务异常操作表';
|
||||
COMMENT ON TABLE public.hc_settlement_items IS '居家服务结算明细表';
|
||||
COMMENT ON TABLE public.hc_payments IS '居家服务支付表';
|
||||
COMMENT ON TABLE public.hc_refunds IS '居家服务退款表';
|
||||
COMMENT ON TABLE public.hc_ledgers IS '居家服务账簿表';
|
||||
COMMENT ON TABLE public.hc_archive_files IS '居家服务归档文件表';
|
||||
COMMENT ON TABLE public.hc_consent_records IS '居家服务同意记录表';
|
||||
COMMENT ON TABLE public.hc_dispatch_assignments IS '居家服务派单记录表 - 定位距离一期';
|
||||
COMMENT ON TABLE public.hc_worker_locations IS '居家服务人员定位表 - 定位距离一期';
|
||||
COMMENT ON TABLE public.hc_work_order_confirmations IS '居家服务工单确认表 - 定位距离一期';
|
||||
COMMENT ON TABLE public.sys_sla_config IS '居家服务SLA配置表';
|
||||
COMMENT ON TABLE public.hc_state_transitions IS '居家服务状态变迁表 - 审计';
|
||||
COMMENT ON TABLE public.hc_audit_logs IS '居家服务操作审计表';
|
||||
COMMENT ON TABLE public.hc_sensitive_access_logs IS '居家服务敏感访问日志表';
|
||||
|
||||
COMMENT ON COLUMN public.hc_evidence_files.upload_status IS '上传状态: TEMP/READY/BOUND/LOCKED/DELETED';
|
||||
COMMENT ON COLUMN public.hc_evidence_files.bound_action IS '绑定动作: CHECKIN/CHECKOUT/EXCEPTION';
|
||||
COMMENT ON COLUMN public.hc_worker_locations.location_scene IS '定位场景: ON_THE_WAY/CHECKIN_PRECHECK/CHECKIN/CHECKOUT';
|
||||
COMMENT ON COLUMN public.hc_work_order_confirmations.confirmation_type IS '确认类型: ARRIVAL(二期扩展CHECKOUT)';
|
||||
COMMENT ON COLUMN public.hc_work_order_confirmations.signature_url IS '二期电子签名图片URL(预留)';
|
||||
COMMENT ON COLUMN public.hc_work_order_confirmations.signature_hash IS '二期电子签名哈希(预留)';
|
||||
|
||||
COMMIT;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,7 +137,29 @@
|
||||
</view>
|
||||
|
||||
<view class="my-services service-card">
|
||||
<scroll-view class="service-scroll" direction="horizontal" scroll-x="true" :scroll-y="false" :show-scrollbar="false" scroll-with-animation>
|
||||
<view class="service-scroll-wrap">
|
||||
<!-- #ifdef APP -->
|
||||
<scroll-view
|
||||
class="service-scroll"
|
||||
direction="horizontal"
|
||||
scroll-x="true"
|
||||
:scroll-y="false"
|
||||
:show-scrollbar="false"
|
||||
scroll-with-animation
|
||||
@scroll="onServiceScroll"
|
||||
>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 || MP -->
|
||||
<scroll-view
|
||||
class="service-scroll"
|
||||
direction="horizontal"
|
||||
scroll-x="true"
|
||||
:scroll-y="false"
|
||||
:show-scrollbar="false"
|
||||
scroll-with-animation
|
||||
@scroll="onServiceScroll"
|
||||
>
|
||||
<!-- #endif -->
|
||||
<view class="service-row">
|
||||
<view class="service-item" @click="goToMessages">
|
||||
<view class="service-icon-wrap">
|
||||
@@ -153,11 +175,12 @@
|
||||
</view>
|
||||
<text class="service-name">优惠券</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToAddress">
|
||||
<view class="service-item" @click="goToFollowedShops">
|
||||
<view class="service-icon-wrap">
|
||||
<text class="service-text-icon">址</text>
|
||||
<image class="service-icon-img" src="/static/consumer/store.png" mode="aspectFit" @error="shopIconError = true" v-if="!shopIconError" />
|
||||
<text v-if="shopIconError" class="service-text-icon">店</text>
|
||||
</view>
|
||||
<text class="service-name">收货地址</text>
|
||||
<text class="service-name">店铺关注</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToFavorites">
|
||||
<view class="service-icon-wrap">
|
||||
@@ -184,15 +207,28 @@
|
||||
</view>
|
||||
<text class="service-name">我的评价</text>
|
||||
</view>
|
||||
<view class="service-item" @click="goToFollowedShops">
|
||||
<view class="service-item" @click="goToAddress">
|
||||
<view class="service-icon-wrap">
|
||||
<image class="service-icon-img" src="/static/consumer/store.png" mode="aspectFit" />
|
||||
<text class="service-text-icon">址</text>
|
||||
</view>
|
||||
<text class="service-name">关注店铺</text>
|
||||
<text class="service-name">收货地址</text>
|
||||
</view>
|
||||
<view class="service-row-end-spacer"></view>
|
||||
</view>
|
||||
<!-- #ifdef APP -->
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 || MP -->
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
<view class="service-right-fade"></view>
|
||||
</view>
|
||||
|
||||
<view class="service-scroll-indicator">
|
||||
<view class="service-scroll-track">
|
||||
<view class="service-scroll-thumb" :style="getServiceThumbStyle()"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<GuessYouLike
|
||||
@@ -342,6 +378,9 @@ export default {
|
||||
pageWindowHeight: 0,
|
||||
isLoggedIn: false,
|
||||
guessLoadMoreKey: 0,
|
||||
serviceScrollLeft: 0,
|
||||
serviceScrollMax: 160,
|
||||
shopIconError: false,
|
||||
statusBarHeight: 0,
|
||||
isAndroidApp: false,
|
||||
capsuleTop: 0,
|
||||
@@ -582,6 +621,28 @@ export default {
|
||||
return
|
||||
},
|
||||
|
||||
onServiceScroll(event: any) {
|
||||
const detailObj = this.toRecommendScrollJson(event.detail)
|
||||
if (detailObj == null) {
|
||||
return
|
||||
}
|
||||
const scrollLeft = this.readRecommendScrollMetric(detailObj, 'scrollLeft')
|
||||
this.serviceScrollLeft = scrollLeft
|
||||
},
|
||||
|
||||
getServiceThumbStyle(): string {
|
||||
const ratio = this.serviceScrollLeft / this.serviceScrollMax
|
||||
const maxTranslate = 20
|
||||
let translateX = ratio * maxTranslate
|
||||
if (translateX < 0) {
|
||||
translateX = 0
|
||||
}
|
||||
if (translateX > maxTranslate) {
|
||||
translateX = maxTranslate
|
||||
}
|
||||
return 'transform: translateX(' + translateX + 'px);'
|
||||
},
|
||||
|
||||
handleGuessProductClick(productId: string) {
|
||||
if (productId == null || productId === '') {
|
||||
return
|
||||
@@ -2316,13 +2377,63 @@ export default {
|
||||
|
||||
.service-card {
|
||||
margin: 12px 14px 0 14px;
|
||||
padding: 14px 0 14px;
|
||||
padding: 14px 0 10px;
|
||||
border-radius: 18px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.service-scroll-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.service-scroll {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.service-right-fade {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 24px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
background-image: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
|
||||
}
|
||||
|
||||
.service-scroll-indicator {
|
||||
height: 10px;
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.service-scroll-track {
|
||||
width: 38px;
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: #e5e5e5;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.service-scroll-thumb {
|
||||
width: 18px;
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: #e4393c;
|
||||
transition-property: transform;
|
||||
transition-duration: 120ms;
|
||||
}
|
||||
|
||||
.service-header {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
@@ -2339,12 +2450,6 @@ export default {
|
||||
color: #222222;
|
||||
}
|
||||
|
||||
.service-scroll {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.service-row {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
@@ -2352,6 +2457,7 @@ export default {
|
||||
align-items: flex-start;
|
||||
padding-left: 12px;
|
||||
padding-right: 18px;
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
|
||||
@@ -2,14 +2,7 @@
|
||||
<template>
|
||||
<view class="favorites-page">
|
||||
<view class="favorites-nav">
|
||||
<view class="nav-left" @click="handleBack">
|
||||
<text class="back-icon">‹</text>
|
||||
</view>
|
||||
|
||||
<view v-if="!isSearchMode" class="nav-center">
|
||||
<text class="nav-title">我的收藏</text>
|
||||
</view>
|
||||
<view v-else class="nav-search-panel">
|
||||
<view class="nav-search-panel">
|
||||
<view class="search-input-wrap">
|
||||
<view class="search-icon">
|
||||
<view class="search-icon-circle"></view>
|
||||
|
||||
@@ -3281,6 +3281,89 @@ class SupabaseService {
|
||||
}
|
||||
}
|
||||
|
||||
// 标记单条通知为已读 (ml_notifications)
|
||||
async markUserNotificationRead(notificationId: string): Promise<boolean> {
|
||||
try {
|
||||
const res = await supa
|
||||
.from('ml_notifications')
|
||||
.update({ is_read: true })
|
||||
.eq('id', notificationId)
|
||||
.execute()
|
||||
return res.error == null
|
||||
} catch (e) {
|
||||
console.error('[markUserNotificationRead] 标记通知已读失败:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 标记聊天会话为已读
|
||||
async markChatRoomRead(merchantId: string): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (userId == null) return false
|
||||
const res = await supa
|
||||
.from('ml_chat_rooms')
|
||||
.update({ unread_count: 0 })
|
||||
.eq('user_id', userId)
|
||||
.eq('merchant_id', merchantId)
|
||||
.execute()
|
||||
return res.error == null
|
||||
} catch (e) {
|
||||
console.error('[markChatRoomRead] 标记会话已读失败:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 一键已读:所有通知 + 所有会话
|
||||
async markAllMessagesRead(): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (userId == null) return false
|
||||
|
||||
const noteRes = await supa
|
||||
.from('ml_notifications')
|
||||
.update({ is_read: true })
|
||||
.eq('user_id', userId)
|
||||
.eq('is_read', false)
|
||||
.execute()
|
||||
if (noteRes.error != null) {
|
||||
console.error('[markAllMessagesRead] 通知已读失败:', noteRes.error)
|
||||
}
|
||||
|
||||
const roomRes = await supa
|
||||
.from('ml_chat_rooms')
|
||||
.update({ unread_count: 0 })
|
||||
.eq('user_id', userId)
|
||||
.gt('unread_count', 0)
|
||||
.execute()
|
||||
if (roomRes.error != null) {
|
||||
console.error('[markAllMessagesRead] 会话已读失败:', roomRes.error)
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('[markAllMessagesRead] 一键已读失败:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 软删除消息(前端兜底:后端表缺少软删除字段时仅 console.warn)
|
||||
async softDeleteMessages(messageIds: Array<string>): Promise<boolean> {
|
||||
try {
|
||||
const userId = this.getCurrentUserId()
|
||||
if (userId == null) return false
|
||||
if (messageIds.length === 0) return true
|
||||
|
||||
// TODO: 后端 ml_notifications / ml_chat_rooms 表当前缺少 consumer_deleted_at / deleted_at / user_deleted_at 字段
|
||||
// 现阶段不执行数据库删除/更新,仅打印警告。如需持久化软删除,请先在相关表增加对应字段并补充 API。
|
||||
console.warn('[softDeleteMessages] 后端缺少软删除字段/API,本次跳过数据库操作。messageIds:', messageIds)
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('[softDeleteMessages] 软删除失败:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户通知 (系统、活动、订单)
|
||||
async getUserNotifications(type: string | null = null): Promise<Notification[]> {
|
||||
try {
|
||||
|
||||
727
报错信息.txt
727
报错信息.txt
@@ -1,119 +1,640 @@
|
||||
[自动热重载] 已开启代码文件保存后自动热重载
|
||||
mp.esm.js:529 [getUserNotifications] 开始获取通知
|
||||
mp.esm.js:529 [ak-req] request GET auth-mode: pre-set prefer: (none)
|
||||
uni.api.esm.js:1042 GET http://119.146.131.237:9126/rest/v1/ml_user_coupons?select=*%2C%20template%3Aml_coupon_templates(name%2C%20amount%2C%20min_spend)&order=expire_at.asc&user_id=eq.b653fded-7d5e-4950-aa0d-725595543e3c&status=eq.1 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:207
|
||||
doOnce @ ak-req.uts:206
|
||||
_loop$ @ ak-req.uts:320
|
||||
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
|
||||
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:1287
|
||||
_callee11$ @ aksupa.uts:1069
|
||||
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
|
||||
select @ aksupa.uts:984
|
||||
_callee$ @ aksupa.uts:388
|
||||
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:368
|
||||
_callee109$ @ supabaseService.uts:7726
|
||||
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
|
||||
getUserCoupons @ supabaseService.uts:7709
|
||||
_callee$ @ coupons.uvue:41
|
||||
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
|
||||
loadCoupons @ coupons.uvue:38
|
||||
(anonymous) @ coupons.uvue:67
|
||||
(anonymous) @ vue.runtime.esm.js:2483
|
||||
mp.esm.js:529 [getUserNotifications] 获取到通知数量: 3
|
||||
mp.esm.js:529 [getChatRooms] 开始获取聊天会话
|
||||
mp.esm.js:529 [ak-req] request GET auth-mode: pre-set prefer: (none)
|
||||
mp.esm.js:529 [getChatRooms] 获取到会话数量: 2
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
ready @ uni.mp.esm.js:1039
|
||||
Show 31 more frames
|
||||
mp.esm.js:529 [ak-req] HTTP error response(env: Windows,mp,1.06.2504030; lib: 3.15.2)
|
||||
(anonymous) @ mp.esm.js:529
|
||||
__f__ @ uni.api.esm.js:590
|
||||
success @ ak-req.uts:297
|
||||
(anonymous) @ uni.api.esm.js:946
|
||||
mp.esm.js:529 [ak-req] status: 400(env: Windows,mp,1.06.2504030; lib: 3.15.2)
|
||||
(anonymous) @ mp.esm.js:529
|
||||
__f__ @ uni.api.esm.js:590
|
||||
success @ ak-req.uts:298
|
||||
(anonymous) @ uni.api.esm.js:946
|
||||
mp.esm.js:529 [ak-req] body: {"code":"42703","details":null,"hint":null,"message":"column ml_coupon_templates_1.amount does not exist"}(env: Windows,mp,1.06.2504030; lib: 3.15.2)
|
||||
(anonymous) @ mp.esm.js:529
|
||||
__f__ @ uni.api.esm.js:590
|
||||
success @ ak-req.uts:299
|
||||
(anonymous) @ uni.api.esm.js:946
|
||||
mp.esm.js:529 获取优惠券失败: UniError: 请求失败: 400
|
||||
at _construct (weapp:///http://127.0.0.1:54597/appservice/@babel/runtime/helpers/construct.js?forceSync=true:1:1227)
|
||||
at new r (weapp:///http://127.0.0.1:54597/appservice/@babel/runtime/helpers/wrapNativeSuper.js?forceSync=true:1:1357)
|
||||
at UniError2.<anonymous> (weapp:///http://127.0.0.1:54597/appservice/@babel/runtime/helpers/createSuper.js?forceSync=true:1:1176)
|
||||
at new UniError2 (weapp:///http://127.0.0.1:54597/appservice/common/vendor.js?t=wechat&s=1780447358541&v=9f592ae44ab8ade1f25e60a1b13f3b53:890:22)
|
||||
at Object.toUniError (weapp:///http://127.0.0.1:54597/appservice/utils/utils.js?t=wechat&s=1780447358541&v=3d196abbae2c5ba600f3f4f5ac011322:77:18)
|
||||
at AkSupa._callee19$ (weapp:///http://127.0.0.1:54597/appservice/components/supadb/aksupa.js?t=wechat&s=1780447358541&v=115b88a2780d4bcec72cc60e543be136:1959:41)
|
||||
at s (weapp:///http://127.0.0.1:54597/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1588)
|
||||
at Generator.<anonymous> (weapp:///http://127.0.0.1:54597/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:2925)
|
||||
at Generator.next (weapp:///http://127.0.0.1:54597/appservice/@babel/runtime/helpers/regeneratorRuntime.js?forceSync=true:1:1951)
|
||||
at fulfilled (weapp:///http://127.0.0.1:54597/appservice/common/vendor.js?t=wechat&s=1780447358541&v=9f592ae44ab8ade1f25e60a1b13f3b53:10009:24)(env: Windows,mp,1.06.2504030; lib: 3.15.2)
|
||||
(anonymous) @ mp.esm.js:529
|
||||
__f__ @ uni.api.esm.js:590
|
||||
_callee109$ @ supabaseService.uts:7729
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
getUserCoupons @ supabaseService.uts:7709
|
||||
_callee$ @ coupons.uvue:41
|
||||
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
|
||||
loadCoupons @ coupons.uvue:38
|
||||
(anonymous) @ coupons.uvue:67
|
||||
(anonymous) @ vue.runtime.esm.js:2483
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
ready @ uni.mp.esm.js:1039
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
triggerEffects @ vue.runtime.esm.js:307
|
||||
triggerRefValue @ vue.runtime.esm.js:1067
|
||||
set @ vue.runtime.esm.js:1112
|
||||
_callee$ @ messages.uvue:639
|
||||
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
|
||||
loadMessages @ messages.uvue:416
|
||||
(anonymous) @ messages.uvue:759
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
hook.__weh.hook.__weh @ vue.runtime.esm.js:2461
|
||||
invokeArrayFns @ uni-shared.es.js:1344
|
||||
callHook @ uni.mp.esm.js:241
|
||||
mpOptions.<computed> @ uni.mp.esm.js:281
|
||||
[渲染层网络层错误] Failed to load local image resource /static/icons/system-notice.png
|
||||
the server responded with a status of 500 (HTTP/1.1 500 Internal Server Error)
|
||||
(env: Windows,mp,1.06.2504030; lib: 3.15.2)
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
mp.esm.js:529 [Vue warn]: Property "manageMode" was accessed during render but is not defined on instance.
|
||||
at <Messages >
|
||||
(anonymous) @ mp.esm.js:529
|
||||
warn$1 @ vue.runtime.esm.js:1251
|
||||
get @ vue.runtime.esm.js:2629
|
||||
(anonymous) @ messages.uvue:760
|
||||
vFor @ vue.runtime.esm.js:6364
|
||||
f @ vue.runtime.esm.js:6718
|
||||
(anonymous) @ messages.uvue:760
|
||||
renderComponentRoot @ vue.runtime.esm.js:5065
|
||||
componentUpdateFn @ vue.runtime.esm.js:5192
|
||||
run @ vue.runtime.esm.js:180
|
||||
instance.update @ vue.runtime.esm.js:5216
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
flushJobs @ vue.runtime.esm.js:1563
|
||||
Promise.then (async)
|
||||
queueFlush @ vue.runtime.esm.js:1472
|
||||
queueJob @ vue.runtime.esm.js:1466
|
||||
(anonymous) @ vue.runtime.esm.js:5210
|
||||
resetScheduling @ vue.runtime.esm.js:263
|
||||
trigger @ vue.runtime.esm.js:403
|
||||
set @ vue.runtime.esm.js:524
|
||||
(anonymous) @ messages.uvue:760
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1356
|
||||
callWithAsyncErrorHandling @ vue.runtime.esm.js:1363
|
||||
invoke @ vue.runtime.esm.js:6223
|
||||
invoker @ vue.runtime.esm.js:6235
|
||||
Reference in New Issue
Block a user