From 1c1e44ade7521ba607683ef05ba39d1f406c0c84 Mon Sep 17 00:00:00 2001 From: li Date: Sat, 14 Mar 2026 21:07:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20H5=E9=A6=96=E9=A1=B5=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E5=8E=9F=E5=9E=8B(=E6=9A=97=E8=89=B2=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E5=8D=A1/=E5=9C=86=E5=BD=A2=E5=9B=BE=E6=A0=87/=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E6=8E=92=E6=9C=9F)=20+=20demo=E6=BC=94=E7=A4=BA?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/database/seeders/DemoClientSeeder.php | 254 +++++++++++++++ client/src/views/home/index.vue | 291 ++++++++++-------- 2 files changed, 416 insertions(+), 129 deletions(-) create mode 100644 backend/database/seeders/DemoClientSeeder.php diff --git a/backend/database/seeders/DemoClientSeeder.php b/backend/database/seeders/DemoClientSeeder.php new file mode 100644 index 0000000..4768f86 --- /dev/null +++ b/backend/database/seeders/DemoClientSeeder.php @@ -0,0 +1,254 @@ +first(); + if (!$store) { + $this->command->warn('No store found. Run InitSeeder first.'); + return; + } + $storeId = $store->id; + + // ── 1. Demo 客户 ────────────────────────────────────────────────────── + $customerId = DB::table('customers')->insertGetId([ + 'store_id' => $storeId, + 'name' => '李婉婷', + 'phone' => '13800138001', + 'password' => Hash::make('123456'), + 'wechat' => 'liwanting88', + 'expected_date' => now()->subDays(14)->toDateString(), + 'actual_date' => now()->subDays(14)->toDateString(), + 'baby_count' => 1, + 'status' => 3, // 在住 + 'remark' => '顺产,宝宝健康,无过敏史', + 'created_at' => now(), + 'updated_at' => now(), + ]); + + // ── 2. 护理档案 ─────────────────────────────────────────────────────── + $profileId = DB::table('care_profiles')->insertGetId([ + 'customer_id' => $customerId, + 'type' => 1, + 'birth_method' => 1, // 顺产 + 'risk_level' => 0, + 'created_at' => now(), + 'updated_at' => now(), + ]); + + // ── 3. 护理记录(近7天)───────────────────────────────────────────── + $careTypes = [ + [1, '产后按摩,疏通经络,妈妈表示很舒适'], + [1, '乳腺疏通护理,双侧通畅'], + [2, '宝宝抚触操,脐带护理正常'], + [1, '产后盆底肌恢复训练,第3次'], + [2, '宝宝沐浴、脐带护理、黄疸监测'], + [1, '子宫复旧按摩,复旧良好'], + [2, '宝宝生长评估,体重增长正常'], + ]; + foreach ($careTypes as $i => [$type, $remark]) { + DB::table('care_records')->insert([ + 'care_profile_id' => $profileId, + 'type' => $type, + 'remark' => $remark, + 'nurse_id' => 1, + 'recorded_at' => now()->subDays($i)->setHour(10)->setMinute(0), + 'created_at' => now()->subDays($i), + 'updated_at' => now()->subDays($i), + ]); + } + + // ── 4. 健康指标(近10条)────────────────────────────────────────────── + $metricData = [ + [1, 36.5, '℃'], + [2, 58.2, 'kg'], + [1, 36.7, '℃'], + [4, 8.2, 'mg/dL'], + [5, 3.65, 'kg'], + [6, 36.8, '℃'], + [1, 36.4, '℃'], + [2, 57.9, 'kg'], + [3, '110/70', 'mmHg'], + [5, 3.72, 'kg'], + ]; + foreach ($metricData as $i => [$type, $value, $unit]) { + DB::table('health_metrics')->insert([ + 'care_profile_id' => $profileId, + 'metric_type' => $type, + 'value' => $value, + 'unit' => $unit, + 'measured_at' => now()->subDays((int)($i / 2))->setHour(8 + $i % 3), + 'created_at' => now()->subDays((int)($i / 2)), + ]); + } + + // ── 5. 今日 & 近7天膳食计划 ─────────────────────────────────────────── + $mealsByDay = [ + // 今天 + [0, 1, [['name'=>'小米红枣粥'],['name'=>'鸡蛋羹'],['name'=>'红糖姜水']]], + [0, 2, [['name'=>'清蒸鲈鱼'],['name'=>'猪肝菠菜汤'],['name'=>'米饭']]], + [0, 3, [['name'=>'枸杞红枣炖乌鸡'],['name'=>'核桃露']]], + [0, 4, [['name'=>'番茄蛋花汤'],['name'=>'清炒时蔬'],['name'=>'糙米饭']]], + // 昨天 + [1, 1, [['name'=>'燕麦南瓜粥'],['name'=>'水煮蛋']]], + [1, 2, [['name'=>'鲫鱼豆腐汤'],['name'=>'香菇蒸鸡'],['name'=>'米饭']]], + [1, 4, [['name'=>'花生猪脚汤'],['name'=>'蒜蓉青菜']]], + [1, 5, [['name'=>'红豆薏米水']]], + // 前天 + [2, 1, [['name'=>'黑米红豆粥'],['name'=>'荷包蛋']]], + [2, 2, [['name'=>'冬瓜排骨汤'],['name'=>'清炒豆芽'],['name'=>'米饭']]], + [2, 4, [['name'=>'参鸡汤'],['name'=>'蒸南瓜']]], + // 3天前 + [3, 1, [['name'=>'紫米粥'],['name'=>'银耳莲子羹']]], + [3, 2, [['name'=>'红枣枸杞炖排骨'],['name'=>'米饭']]], + [3, 3, [['name'=>'核桃芝麻糊']]], + [3, 4, [['name'=>'番茄豆腐汤'],['name'=>'清蒸时蔬']]], + ]; + foreach ($mealsByDay as [$daysAgo, $mealType, $dishes]) { + DB::table('daily_meal_plans')->insert([ + 'store_id' => $storeId, + 'customer_id' => $customerId, + 'plan_date' => now()->subDays($daysAgo)->toDateString(), + 'meal_type' => $mealType, + 'dishes' => json_encode($dishes), + 'status' => $daysAgo > 0 ? 2 : 1, // 历史=已送达, 今天=已备餐 + 'created_at' => now()->subDays($daysAgo), + 'updated_at' => now()->subDays($daysAgo), + ]); + } + + // 给昨天2条膳食添加评价 + $planIds = DB::table('daily_meal_plans') + ->where('customer_id', $customerId) + ->where('plan_date', now()->subDay()->toDateString()) + ->pluck('id'); + foreach ($planIds->take(2) as $planId) { + DB::table('meal_reviews')->insert([ + 'daily_meal_plan_id' => $planId, + 'customer_id' => $customerId, + 'score' => rand(4, 5), + 'content' => '味道很好,营养均衡,非常感谢厨师团队!', + 'created_at' => now()->subDay(), + ]); + } + + // ── 6. 月嫂 + 派单 ──────────────────────────────────────────────────── + $nannyId = DB::table('nannies')->insertGetId([ + 'store_id' => $storeId, + 'name' => '王秀珍', + 'phone' => '13900139001', + 'level' => 3, // 高级 + 'experience_years' => 8, + 'skills' => json_encode(['产后护理', '宝宝沐浴', '乳腺疏通', '产后恢复']), + 'introduction' => '从业8年,持高级育婴师证书,服务过200余位妈妈,口碑优秀', + 'status' => 2, // 服务中 + 'created_at' => now(), + 'updated_at' => now(), + ]); + + DB::table('nanny_orders')->insert([ + 'store_id' => $storeId, + 'customer_id' => $customerId, + 'nanny_id' => $nannyId, + 'order_no' => 'NO' . date('YmdHis'), + 'service_type'=> 1, + 'start_date' => now()->subDays(14)->toDateString(), + 'end_date' => now()->addDays(16)->toDateString(), + 'days' => 30, + 'price' => 12000.00, + 'status' => 2, // 已签约/服务中 + 'created_at' => now()->subDays(14), + 'updated_at' => now(), + ]); + + // ── 7. 服务订单 ─────────────────────────────────────────────────────── + $serviceOrders = [ + ['产后修复套餐', 2, 3980.00], + ['宝宝游泳抚触课程', 2, 1200.00], + ['气血能量房体验', 2, 680.00], + ]; + foreach ($serviceOrders as [$name, $status, $amount]) { + DB::table('service_orders')->insert([ + 'store_id' => $storeId, + 'customer_id' => $customerId, + 'order_no' => 'SO' . date('YmdHis') . rand(100, 999), + 'type' => 1, + 'items' => json_encode([['name' => $name, 'qty' => 1, 'price' => $amount]]), + 'total_amount' => $amount, + 'actual_amount' => $amount, + 'status' => $status, + 'pay_method' => 1, + 'paid_at' => now()->subDays(14), + 'created_at' => now()->subDays(14), + 'updated_at' => now(), + ]); + } + + // ── 8. 客户账户 + 流水 ──────────────────────────────────────────────── + $accountId = DB::table('customer_accounts')->insertGetId([ + 'store_id' => $storeId, + 'customer_id' => $customerId, + 'cash_balance' => 3200.00, + 'card_balance' => 8800.00, + 'points' => 1580, + 'created_at' => now(), + 'updated_at' => now(), + ]); + + $txs = [ + [1, 20000.00, 20000.00, '签约充值'], + [2, 3980.00, 16020.00, '产后修复套餐'], + [2, 1200.00, 14820.00, '宝宝游泳课程'], + [3, 500.00, 15320.00, '退款:项目未使用'], + [2, 680.00, 14640.00, '气血能量房体验'], + [2, 2640.00, 12000.00, '月嫂服务首期'], + ]; + foreach ($txs as $i => [$type, $amount, $balanceAfter, $desc]) { + DB::table('account_transactions')->insert([ + 'store_id' => $storeId, + 'customer_account_id' => $accountId, + 'customer_id' => $customerId, + 'type' => $type, + 'amount' => $amount, + 'balance_after' => $balanceAfter, + 'description' => $desc, + 'created_at' => now()->subDays(14 - $i * 2), + ]); + } + + // ── 9. 投诉反馈 ─────────────────────────────────────────────────────── + DB::table('complaints')->insert([ + [ + 'store_id' => $storeId, + 'customer_id' => $customerId, + 'type' => 1, + 'content' => '昨晚空调温度偏低,宝宝有点凉,希望能保持在26度左右', + 'status' => 2, + 'handle_result' => '已通知客房调整空调,确保室温维持在25-26℃,感谢您的反馈!', + 'handle_at' => now()->subDays(1), + 'created_at' => now()->subDays(2), + 'updated_at' => now()->subDays(1), + ], + [ + 'store_id' => $storeId, + 'customer_id' => $customerId, + 'type' => 2, + 'content' => '今日午餐的汤偏咸,建议减少盐量,产后饮食应清淡', + 'status' => 1, + 'created_at' => now()->subHours(5), + 'updated_at' => now()->subHours(5), + ], + ]); + + $this->command->info("✅ Demo 客户创建成功!"); + $this->command->info(" 手机号:13800138001 密码:123456"); + $this->command->info(" 姓名:李婉婷 状态:在住第14天"); + } +} diff --git a/client/src/views/home/index.vue b/client/src/views/home/index.vue index 1368108..1d2d859 100644 --- a/client/src/views/home/index.vue +++ b/client/src/views/home/index.vue @@ -16,56 +16,75 @@ onMounted(async () => { } catch { } finally { loading.value = false } }) -const customer = computed(() => homeData.value?.customer || store.info) -const todayMeals = computed(() => homeData.value?.today_meals || []) +const customer = computed(() => homeData.value?.customer || store.info) +const todayMeals = computed(() => homeData.value?.today_meals || []) const latestRecords = computed(() => homeData.value?.care_records || []) -const nannyOrder = computed(() => homeData.value?.nanny_order) +const nannyOrder = computed(() => homeData.value?.nanny_order) -const mealTypeLabel = { 1: '早餐', 2: '午餐', 3: '下午茶', 4: '晚餐', 5: '宵夜' } +// 膳食时间映射 +const mealTime = { 1: '07:30', 2: '12:00', 3: '15:00', 4: '18:00', 5: '21:00' } +const mealLabel = { 1: '早餐', 2: '午餐', 3: '下午茶', 4: '晚餐', 5: '宵夜' } + +// 入住天数 +const checkinDays = computed(() => { + const d = customer.value?.actual_date + if (!d) return null + const diff = Math.floor((Date.now() - new Date(d).getTime()) / 86400000) + return diff > 0 ? diff : null +}) const features = [ - { label: '月子餐', bg: '#fff0f4', color: '#f43f5e', icon: 'food-o', path: '/meal' }, - { label: '服务包', bg: '#eff6ff', color: '#3b82f6', icon: 'balance-list-o', path: '/service/orders' }, - { label: '护理记录', bg: '#fffbeb', color: '#f59e0b', icon: 'orders-o', path: '/care/records' }, - { label: '我的月嫂', bg: '#f5f3ff', color: '#8b5cf6', icon: 'user-circle-o', path: '/nanny' }, + { label: '月子餐', bg: '#fff0f4', color: '#f43f5e', icon: '🍱', path: '/meal' }, + { label: '服务包', bg: '#eff6ff', color: '#3b82f6', icon: '🛏', path: '/service/orders' }, + { label: '护理记录', bg: '#fffbeb', color: '#f59e0b', icon: '🩺', path: '/care/records' }, + { label: '我的月嫂', bg: '#f5f3ff', color: '#8b5cf6', icon: '👩', path: '/nanny' }, ] -const today = new Date().toLocaleDateString('zh-CN', { month: 'long', day: 'numeric' }) +const today = new Date().toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })