修复订单显示bug

This commit is contained in:
2026-06-10 20:20:47 +08:00
parent de62513987
commit 9fbc6f8cd1
45 changed files with 7514 additions and 2025 deletions

View File

@@ -0,0 +1,143 @@
-- ===================================================================
-- 用途:为已存在的 auth 用户创建 ak_users + ml_delivery_staff 档案
-- 特点:自动探测 ak_users 表结构(有 auth_id 则插 auth_id无则插 id
-- ===================================================================
DO $$
DECLARE
v_auth_id UUID;
v_ak_user_id UUID;
v_has_auth_id BOOLEAN := FALSE;
v_has_phone BOOLEAN := FALSE;
v_has_avatar_url BOOLEAN := FALSE;
v_has_status BOOLEAN := FALSE;
v_has_registration_source BOOLEAN := FALSE;
v_has_v2 BOOLEAN := FALSE;
v_email TEXT := 'homecare_worker@test.com';
v_nickname TEXT := '居家服务员';
v_phone TEXT := '13800138000';
BEGIN
-- 1. 获取 auth.users.id
SELECT id INTO v_auth_id FROM auth.users WHERE email = v_email LIMIT 1;
IF v_auth_id IS NULL THEN
RAISE EXCEPTION 'auth.users 中不存在 %', v_email;
END IF;
-- 2. 探测 ak_users 表结构
SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'auth_id')
INTO v_has_auth_id;
SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'phone')
INTO v_has_phone;
SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'avatar_url')
INTO v_has_avatar_url;
SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'status')
INTO v_has_status;
SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'registration_source')
INTO v_has_registration_source;
RAISE NOTICE 'ak_users 结构探测: auth_id=%, phone=%, avatar_url=%, status=%, registration_source=%',
v_has_auth_id, v_has_phone, v_has_avatar_url, v_has_status, v_has_registration_source;
-- 3. 插入 ak_users动态字段
IF v_has_auth_id THEN
-- 有 auth_id 字段id 用 gen_random_uuidauth_id 关联 auth.users.id
INSERT INTO public.ak_users (
id, auth_id, username, email, role,
phone, avatar_url, status, registration_source,
created_at, updated_at
) VALUES (
gen_random_uuid(), v_auth_id, v_nickname, v_email, 'delivery',
v_phone, 'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare', 'active', 'web',
NOW(), NOW()
)
ON CONFLICT (auth_id) DO UPDATE SET
username = EXCLUDED.username,
email = EXCLUDED.email,
role = EXCLUDED.role,
phone = EXCLUDED.phone,
avatar_url = EXCLUDED.avatar_url,
status = EXCLUDED.status,
updated_at = NOW()
RETURNING id INTO v_ak_user_id;
RAISE NOTICE '✓ ak_users 已插入(含 auth_id业务主键 id: %', v_ak_user_id;
ELSE
-- 无 auth_id 字段id 直接等于 auth.users.id
INSERT INTO public.ak_users (
id, username, email, role,
created_at, updated_at
) VALUES (
v_auth_id, v_nickname, v_email, 'delivery',
NOW(), NOW()
)
ON CONFLICT (id) DO UPDATE SET
username = EXCLUDED.username,
email = EXCLUDED.email,
role = EXCLUDED.role,
updated_at = NOW()
RETURNING id INTO v_ak_user_id;
RAISE NOTICE '✓ ak_users 已插入id = auth_idid: %', v_ak_user_id;
END IF;
-- 4. 探测 ml_delivery_staff v2 字段
SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ml_delivery_staff' AND column_name = 'online_status')
INTO v_has_v2;
-- 5. 插入 ml_delivery_staffuid 必须等于 ak_users.id / ak_users 业务主键)
IF v_has_v2 THEN
INSERT INTO public.ml_delivery_staff (
id, uid, nickname, avatar, phone,
status, is_active,
staff_no, online_status, certificate_status,
certificate_expire_at, service_area, skills,
created_at, updated_at
) VALUES (
gen_random_uuid(),
v_ak_user_id, -- 关键:必须是 ak_users 的业务主键 id
v_nickname,
'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare',
v_phone,
1, TRUE,
'HC' || EXTRACT(YEAR FROM NOW()) || LPAD(FLOOR(RANDOM() * 10000)::TEXT, 4, '0'),
'resting', 'valid',
(NOW() + INTERVAL '1 year')::DATE,
'北京市朝阳区',
'["基础护理", "康复训练", "上门照护"]'::jsonb,
NOW(), NOW()
)
ON CONFLICT (uid) WHERE deleted_at IS NULL DO UPDATE SET
nickname = EXCLUDED.nickname,
status = EXCLUDED.status,
is_active = EXCLUDED.is_active,
updated_at = NOW();
RAISE NOTICE '✓ ml_delivery_staff (v2) 已插入/更新';
ELSE
INSERT INTO public.ml_delivery_staff (
id, uid, nickname, avatar, phone,
status, is_active, created_at, updated_at
) VALUES (
gen_random_uuid(),
v_ak_user_id, -- 关键:必须是 ak_users 的业务主键 id
v_nickname,
'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare',
v_phone,
1, TRUE,
NOW(), NOW()
)
ON CONFLICT (uid) DO UPDATE SET
nickname = EXCLUDED.nickname,
status = EXCLUDED.status,
is_active = EXCLUDED.is_active,
updated_at = NOW();
RAISE NOTICE '✓ ml_delivery_staff (v1) 已插入/更新';
END IF;
RAISE NOTICE '============================================';
RAISE NOTICE '建档完成!';
RAISE NOTICE 'auth.users.id: %', v_auth_id;
RAISE NOTICE 'ak_users.id: %', v_ak_user_id;
RAISE NOTICE 'ml_delivery_staff.uid: %', v_ak_user_id;
RAISE NOTICE '============================================';
END $$;

View File

@@ -0,0 +1,90 @@
-- ===================================================================
-- 用途:为已存在的 auth 用户创建 ml_delivery_staff 服务人员档案(兼容 v1/v2
-- 前提auth.users 中已有 homecare_worker@test.com
-- ===================================================================
DO $$
DECLARE
v_uid UUID;
v_has_v2 BOOLEAN := FALSE;
BEGIN
-- 1. 通过邮箱找到用户 ID
SELECT id INTO v_uid FROM auth.users WHERE email = 'homecare_worker@test.com' LIMIT 1;
IF v_uid IS NULL THEN
RAISE EXCEPTION 'auth.users 中不存在 homecare_worker@test.com请先创建该用户';
END IF;
-- 2. 确保 ak_users 中有对应记录role 必须是 delivery
INSERT INTO public.ak_users (id, username, email, role, created_at, updated_at)
VALUES (v_uid, '居家服务员', 'homecare_worker@test.com', 'delivery', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET
username = EXCLUDED.username,
role = EXCLUDED.role,
updated_at = NOW();
RAISE NOTICE '✓ ak_users 已就绪uid: %', v_uid;
-- 3. 探测 ml_delivery_staff 是否为 v2 结构(是否有 online_status 字段)
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'ml_delivery_staff'
AND column_name = 'online_status'
) INTO v_has_v2;
-- 4. 根据表结构版本执行对应插入
IF v_has_v2 THEN
-- v2 结构(含 online_status, certificate_status, staff_no 等)
INSERT INTO public.ml_delivery_staff (
id, uid, nickname, avatar, phone,
status, is_active,
staff_no, online_status, certificate_status,
certificate_expire_at, service_area, skills,
created_at, updated_at
) VALUES (
gen_random_uuid(), v_uid, '居家服务员',
'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare',
'13800138000',
1, TRUE,
'HC' || EXTRACT(YEAR FROM NOW()) || LPAD(FLOOR(RANDOM() * 10000)::TEXT, 4, '0'),
'resting', 'valid',
(NOW() + INTERVAL '1 year')::DATE,
'北京市朝阳区',
'["基础护理", "康复训练", "上门照护"]'::jsonb,
NOW(), NOW()
)
ON CONFLICT (uid) WHERE deleted_at IS NULL DO UPDATE SET
nickname = EXCLUDED.nickname,
status = EXCLUDED.status,
is_active = EXCLUDED.is_active,
updated_at = NOW();
RAISE NOTICE '✓ ml_delivery_staff (v2) 档案已创建/更新';
ELSE
-- v1 结构(仅基础字段)
INSERT INTO public.ml_delivery_staff (
id, uid, nickname, avatar, phone,
status, is_active,
created_at, updated_at
) VALUES (
gen_random_uuid(), v_uid, '居家服务员',
'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare',
'13800138000',
1, TRUE,
NOW(), NOW()
)
ON CONFLICT (uid) DO UPDATE SET
nickname = EXCLUDED.nickname,
status = EXCLUDED.status,
is_active = EXCLUDED.is_active,
updated_at = NOW();
RAISE NOTICE '✓ ml_delivery_staff (v1) 档案已创建/更新';
END IF;
RAISE NOTICE '============================================';
RAISE NOTICE '建档完成!请重新编译小程序后登录测试。';
RAISE NOTICE '============================================';
END $$;

View File

@@ -0,0 +1,94 @@
#!/usr/bin/env node
/**
* 创建居家服务员 auth 用户Supabase Admin API
* 用法:
* 1. cd mall_sql/scripts
* 2. 设置环境变量 SUPABASE_URL 和 SUPABASE_SERVICE_ROLE_KEY
* 3. node create_homecare_auth_user.js
*
* 如果未安装 @supabase/supabase-js先执行
* npm install @supabase/supabase-js
*/
const { createClient } = require('@supabase/supabase-js');
const SUPABASE_URL = process.env.SUPABASE_URL || 'http://119.146.131.237:9126';
const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || '';
if (!SUPABASE_SERVICE_ROLE_KEY) {
console.error('❌ 请设置环境变量 SUPABASE_SERVICE_ROLE_KEY');
console.error(' 该 key 可在 Supabase Dashboard -> Project Settings -> API -> service_role key 获取');
process.exit(1);
}
const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, {
auth: { autoRefreshToken: false, persistSession: false }
});
async function main() {
const email = 'homecare_worker@test.com';
const password = 'Homecare123!';
console.log(`📝 正在创建/更新 auth 用户: ${email}`);
// 先尝试查找现有用户
const { data: existingUsers, error: listError } = await supabase.auth.admin.listUsers({
page: 1,
perPage: 1000
});
if (listError) {
console.error('❌ 查询用户列表失败:', listError.message);
process.exit(1);
}
const existingUser = existingUsers.users.find(u => u.email === email);
if (existingUser) {
console.log(`⚠️ 用户已存在 (ID: ${existingUser.id}),更新密码...`);
const { data: updateData, error: updateError } = await supabase.auth.admin.updateUserById(
existingUser.id,
{ password, email_confirm: true }
);
if (updateError) {
console.error('❌ 更新用户失败:', updateError.message);
process.exit(1);
}
console.log('✅ 密码已更新');
console.log(` 用户ID: ${updateData.user.id}`);
console.log(` 邮箱: ${updateData.user.email}`);
} else {
console.log('🔨 创建新用户...');
const { data: createData, error: createError } = await supabase.auth.admin.createUser({
email,
password,
email_confirm: true,
user_metadata: {
name: '居家服务员',
role: 'delivery',
nickname: '居家服务员'
}
});
if (createError) {
console.error('❌ 创建用户失败:', createError.message);
process.exit(1);
}
console.log('✅ 用户创建成功');
console.log(` 用户ID: ${createData.user.id}`);
console.log(` 邮箱: ${createData.user.email}`);
}
console.log('\n📋 下一步:');
console.log(' 在 Supabase SQL Editor 中执行 seed_homecare_worker.sql');
console.log(' 以创建 ak_users 和 ml_delivery_staff 记录。');
}
main().catch(err => {
console.error('❌ 未捕获错误:', err);
process.exit(1);
});

View File

@@ -0,0 +1,269 @@
-- =====================================================================================
-- 脚本:创建居家服务员测试账号及完整档案(一站式 SQL
-- 用途:为 delivery 端登录提供真实的服务人员档案
-- 执行环境Supabase SQL Editor需 postgres/superuser 权限)
-- 对应前端配置:医疗-delivery/ak/config.uts
-- - SUPA_URL: http://119.146.131.237:9126
-- - 测试账号: homecare_worker@test.com / Homecare123!
-- =====================================================================================
-- 0. 确保 pgcrypto 扩展可用(用于 bcrypt 密码哈希)
CREATE EXTENSION IF NOT EXISTS pgcrypto;
DO $$
DECLARE
v_auth_id UUID;
v_instance_id UUID;
v_email TEXT := 'homecare_worker@test.com';
v_password TEXT := 'Homecare123!';
v_nickname TEXT := '居家服务员';
v_phone TEXT := '13800138000';
BEGIN
-- -------------------------------------------------------------------------
-- 步骤 1获取 instance_id自托管 Supabase 通常只有一个 instance
-- -------------------------------------------------------------------------
SELECT id INTO v_instance_id FROM auth.instances LIMIT 1;
IF v_instance_id IS NULL THEN
v_instance_id := '00000000-0000-0000-0000-000000000000'::UUID;
END IF;
-- -------------------------------------------------------------------------
-- 步骤 2创建/更新 auth.usersSupabase Auth 核心用户表)
-- 使用 crypt(..., gen_salt('bf')) 生成 bcrypt 哈希,与 gotrue 兼容
-- -------------------------------------------------------------------------
INSERT INTO auth.users (
instance_id,
id,
aud,
role,
email,
encrypted_password,
email_confirmed_at,
confirmation_sent_at,
recovery_sent_at,
email_change_sent_at,
new_email,
invited_at,
confirmation_token,
recovery_token,
email_change_token_new,
email_change_token_current,
email_change,
email_change_confirm_status,
banned_until,
reauthentication_token,
reauthentication_sent_at,
is_super_admin,
created_at,
updated_at,
phone,
phone_confirmed_at,
phone_change,
phone_change_token,
phone_change_sent_at,
confirmed_at,
raw_app_meta_data,
raw_user_meta_data,
is_sso_user,
deleted_at,
is_anonymous
) VALUES (
v_instance_id,
gen_random_uuid(),
'authenticated',
'authenticated',
v_email,
crypt(v_password, gen_salt('bf')),
NOW(),
NULL,
NULL,
NULL,
NULL,
NULL,
'',
'',
'',
'',
'',
0,
NULL,
'',
NULL,
FALSE,
NOW(),
NOW(),
NULL,
NULL,
NULL,
'',
NULL,
NOW(),
'{"provider":"email","providers":["email"]}'::jsonb,
'{"name":"居家服务员","role":"delivery","nickname":"居家服务员"}'::jsonb,
FALSE,
NULL,
FALSE
)
ON CONFLICT (email) DO UPDATE SET
encrypted_password = crypt(v_password, gen_salt('bf')),
email_confirmed_at = COALESCE(auth.users.email_confirmed_at, NOW()),
confirmed_at = COALESCE(auth.users.confirmed_at, NOW()),
updated_at = NOW(),
raw_user_meta_data = '{"name":"居家服务员","role":"delivery","nickname":"居家服务员"}'::jsonb,
deleted_at = NULL,
is_anonymous = FALSE;
-- 获取刚创建/更新的用户 ID
SELECT id INTO v_auth_id FROM auth.users WHERE email = v_email LIMIT 1;
IF v_auth_id IS NULL THEN
RAISE EXCEPTION 'auth.users 插入失败,请检查权限或表结构';
END IF;
RAISE NOTICE '✓ auth.users 已创建/更新: % (ID: %)', v_email, v_auth_id;
-- -------------------------------------------------------------------------
-- 步骤 3创建 auth.identitiesSupabase Auth 身份表,某些版本必需)
-- -------------------------------------------------------------------------
INSERT INTO auth.identities (
id,
user_id,
identity_data,
provider,
created_at,
updated_at
) VALUES (
v_auth_id::TEXT,
v_auth_id,
jsonb_build_object('sub', v_auth_id::TEXT, 'email', v_email),
'email',
NOW(),
NOW()
)
ON CONFLICT (id) DO UPDATE SET
identity_data = jsonb_build_object('sub', v_auth_id::TEXT, 'email', v_email),
updated_at = NOW();
RAISE NOTICE '✓ auth.identities 已创建/更新';
-- -------------------------------------------------------------------------
-- 步骤 4创建 public.ak_users业务用户资料表
-- -------------------------------------------------------------------------
INSERT INTO public.ak_users (
id,
username,
email,
gender,
birthday,
height_cm,
weight_kg,
bio,
avatar_url,
preferred_language,
health_goal,
service_address,
emergency_contact,
chronic_notes,
care_preference,
role,
school_id,
grade_id,
class_id,
created_at,
updated_at
) VALUES (
v_auth_id,
v_nickname,
v_email,
'unknown',
NULL,
0,
0,
'居家养老护理员,具备基础护理和康复训练资质',
'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare',
'zh-CN',
'',
'',
'',
'',
'',
'delivery',
'',
'',
'',
NOW(),
NOW()
)
ON CONFLICT (id) DO UPDATE SET
username = EXCLUDED.username,
email = EXCLUDED.email,
role = EXCLUDED.role,
bio = EXCLUDED.bio,
avatar_url = EXCLUDED.avatar_url,
updated_at = NOW();
RAISE NOTICE '✓ public.ak_users 已插入/更新';
-- -------------------------------------------------------------------------
-- 步骤 5创建 public.ml_delivery_staff服务人员档案表
-- -------------------------------------------------------------------------
INSERT INTO public.ml_delivery_staff (
id,
uid,
nickname,
avatar,
phone,
status,
is_active,
station_id,
staff_no,
online_status,
certificate_status,
certificate_expire_at,
service_area,
skills,
created_at,
updated_at
) VALUES (
gen_random_uuid(),
v_auth_id,
v_nickname,
'https://api.dicebear.com/7.x/avataaars/svg?seed=homecare',
v_phone,
1, -- 状态: 1-启用
TRUE, -- 是否激活
NULL, -- 所属站点(可选)
'HC' || EXTRACT(YEAR FROM NOW()) || LPAD(FLOOR(RANDOM() * 10000)::TEXT, 4, '0'), -- 工号
'resting', -- 在线状态
'valid', -- 资质状态
(NOW() + INTERVAL '1 year')::DATE, -- 资质到期日
'北京市朝阳区',
'["基础护理", "康复训练", "上门照护", "健康监测"]'::jsonb,
NOW(),
NOW()
)
ON CONFLICT (uid) WHERE deleted_at IS NULL DO UPDATE SET
nickname = EXCLUDED.nickname,
phone = EXCLUDED.phone,
status = EXCLUDED.status,
is_active = EXCLUDED.is_active,
online_status = EXCLUDED.online_status,
certificate_status = EXCLUDED.certificate_status,
service_area = EXCLUDED.service_area,
skills = EXCLUDED.skills,
updated_at = NOW();
RAISE NOTICE '✓ public.ml_delivery_staff 已插入/更新';
-- -------------------------------------------------------------------------
-- 完成
-- -------------------------------------------------------------------------
RAISE NOTICE '============================================';
RAISE NOTICE '居家服务员账号初始化完成!';
RAISE NOTICE '邮箱: %', v_email;
RAISE NOTICE '密码: %', v_password;
RAISE NOTICE '用户ID: %', v_auth_id;
RAISE NOTICE 'SUPA_URL: http://119.146.131.237:9126';
RAISE NOTICE '============================================';
END $$;