where('order_item_id', $orderItem['id']) ->where('user_id', $userId) ->lock(true) ->find(); if ($existing) { Db::commit(); Log::info('用户产品记录已存在,跳过创建', [ 'order_item_id' => $orderItem['id'], 'user_id' => $userId, 'existing_id' => $existing['id'] ]); return $existing['id']; } // 2. 创建使用记录(原有逻辑) $usageData = [ 'user_id' => $userId, 'order_id' => $orderItem['order_id'], 'order_item_id' => $orderItem['id'], 'product_id' => $orderItem['product_id'], 'package_price_id' => $orderItem['package_price_id'], 'package_type' => $package['type'], 'card_type' => $package['card_type'], 'start_time' => date('Y-m-d H:i:s'), 'status' => 1, 'create_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s') ]; // 3. 根据卡类型和购买数量计算初始值 $quantity = $orderItem['quantity'] ?? 1; switch ($package['card_type']) { case 1: // 次卡 $unitValue = $package['unit_value'] ?? 0; $usageData['remaining_times'] = $unitValue * $quantity; break; case 2: // 积分卡 $pointsValue = $package['points_value'] ?? 0; $usageData['remaining_points'] = $pointsValue * $quantity; break; case 3: // 日卡 $usageData['end_time'] = date('Y-m-d 23:59:59', strtotime('+1 day')); break; case 4: // 周卡 $usageData['end_time'] = date('Y-m-d 23:59:59', strtotime('+7 days')); break; case 5: // 季卡 $usageData['end_time'] = date('Y-m-d 23:59:59', strtotime('+90 days')); break; case 6: // 月卡 $usageData['end_time'] = date('Y-m-d 23:59:59', strtotime('+30 days')); break; case 7: // 年卡 $usageData['end_time'] = date('Y-m-d 23:59:59', strtotime('+365 days')); break; } $usageId = Db::table('ba_user_product_usage')->insertGetId($usageData); // 4. 如果是个人套餐,同时更新ba_user_product表 if ($package['type'] == 1) { $this->updateUserProductTable($userId, $orderItem, $package, $usageData); } Db::commit(); Log::info('用户产品记录创建成功', [ 'usage_id' => $usageId, 'user_id' => $userId, 'order_item_id' => $orderItem['id'] ]); return $usageId; } catch (\Throwable $e) { Db::rollback(); Log::error('创建用户产品记录失败: ' . $e->getMessage()); throw $e; } } /** * 更新用户产品表(兼容原有表) */ private function updateUserProductTable($userId, $orderItem, $package, $usageData) { try { // 检查是否已有记录 $userProduct = Db::table('ba_user_product') ->where('user_id', $userId) ->where('product_id', $orderItem['product_id']) ->where('package_price_id', $orderItem['package_price_id']) ->find(); if ($userProduct) { // 更新现有记录 $updateData = [ 'update_time' => date('Y-m-d H:i:s') ]; // 根据卡类型累加 if ($package['card_type'] == 1) { // 次卡 $updateData['remaining_times'] = Db::raw('remaining_times + ' . $usageData['remaining_times']); } elseif ($package['card_type'] == 2) { // 积分卡 $updateData['remaining_points'] = Db::raw('remaining_points + ' . $usageData['remaining_points']); } elseif ($package['card_type'] >= 3) { // 日期卡 // 日期卡取最新的结束时间 if (empty($userProduct['expire_time']) || strtotime($usageData['end_time']) > strtotime($userProduct['expire_time'])) { $updateData['expire_time'] = $usageData['end_time']; } } Db::table('ba_user_product') ->where('id', $userProduct['id']) ->update($updateData); } else { // 创建新记录 $newData = [ 'user_id' => $userId, 'product_id' => $orderItem['product_id'], 'package_price_id' => $orderItem['package_price_id'], 'remaining_points' => $usageData['remaining_points'] ?? 0, 'remaining_times' => $usageData['remaining_times'] ?? 0, 'expire_time' => $usageData['end_time'] ?? null, 'create_time' => date('Y-m-d H:i:s') ]; Db::table('ba_user_product')->insert($newData); } } catch (\Throwable $e) { Log::error('更新用户产品表失败: ' . $e->getMessage()); // 这里不抛出异常,因为这是辅助功能,主功能不受影响 } } /** * 企业套餐分配时创建用户产品记录 */ public function createCompanyProductUsage($allocationRecord, $assignedToUserId,$card_type) { try { // 从分配记录创建用户产品使用记录 $usageData = [ 'user_id' => $assignedToUserId, 'order_id' => $allocationRecord['order_id'], 'order_item_id' => $allocationRecord['order_item_id'], 'product_id' => $allocationRecord['product_id'], 'package_price_id' => $allocationRecord['package_price_id'], 'package_type' => 2, // 企业套餐 'card_type' => $card_type, 'company_id' => $allocationRecord['company_id'], 'allocation_id' => $allocationRecord['id'], 'is_allocated' => 1, 'start_time' => date('Y-m-d H:i:s'), 'status' => 1, 'create_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s') ]; // 设置有效期和剩余量 if ($card_type >= 3) { // 日期卡 $usageData['end_time'] = $this->calculateEndTime($card_type); } elseif ($card_type == 1) { // 次卡 $usageData['remaining_times'] = $allocationRecord['remaining_times']; } elseif ($card_type == 2) { // 积分卡 $usageData['remaining_points'] = $allocationRecord['remaining_points']; } return Db::table('ba_user_product_usage')->insertGetId($usageData); } catch (\Throwable $e) { Log::error('创建企业产品使用记录失败: ' . $e->getMessage()); throw $e; } } /** * 获取我的产品列表(整合个人套餐和企业套餐) */ public function getUserProducts($userId) { try { // 1. 查询个人套餐(直接从使用记录表) $personalProducts = Db::table('ba_user_product_usage') ->alias('upu') ->leftJoin('ba_product p', 'p.id = upu.product_id') ->leftJoin('ba_package_price pp', 'pp.id = upu.package_price_id') ->where('upu.user_id', $userId) ->where('upu.package_type', 1) // 个人套餐 ->where('upu.status', 1) // 有效 ->field('upu.*, p.name as product_name, p.type as product_type, p.link, pp.spec_name, pp.type as package_type, pp.card_type,pp.image') ->select() ->toArray(); // 2. 查询已分配给用户的企业套餐 $companyProducts = Db::table('ba_user_product_usage') ->alias('upu') ->leftJoin('ba_product p', 'p.id = upu.product_id') ->leftJoin('ba_package_price pp', 'pp.id = upu.package_price_id') ->leftJoin('ba_company_package_allocation cpa', 'cpa.id = upu.allocation_id') ->where('upu.user_id', $userId) ->where('upu.package_type', 2) // 企业套餐 ->where('upu.status', 1) // 有效 ->where('upu.is_allocated', 1) // 已分配 ->field('upu.*, p.name as product_name, p.type as product_type, p.link, pp.spec_name, pp.type as package_type, pp.card_type, cpa.assigned_by_user_id,pp.image') ->select() ->toArray(); // 3. 合并结果 $allProducts = array_merge($personalProducts, $companyProducts); // 4. 按产品ID和套餐规格ID分组,合并相同产品(只合并次卡和积分卡) $groupedProducts = []; foreach ($allProducts as $product) { $key = $product['product_id'] . '_' . $product['package_price_id']; // 日期卡不合并,每次分配单独显示 if ($product['card_type'] >= 3) { $groupedProducts[] = $this->formatProductItem($product, false); continue; } // 次卡和积分卡合并 if (!isset($groupedProducts[$key])) { $groupedProducts[$key] = $this->formatProductItem($product, true); } else { // 累加剩余次数/积分 $groupedProducts[$key]['remaining_times'] += $product['remaining_times']; $groupedProducts[$key]['remaining_points'] += $product['remaining_points']; $groupedProducts[$key]['total_quantity'] += 1; } } // 5. 处理合并后的数组 $result = []; foreach ($groupedProducts as $product) { $result[] = $product; } return $result; } catch (\Throwable $e) { Log::error('获取用户产品列表失败: ' . $e->getMessage()); return []; } } /** * 格式化产品项 */ private function formatProductItem($product, $isMerged = false) { $item = [ 'product_id' => $product['product_id'], 'product_name' => $product['product_name'], 'product_type' => $product['product_type'] ?? 1, // 默认1:网页 'product_link' => $product['link'] ?? '', 'image' => $product['image'] ?? '', 'package_spec' => $product['spec_name'], 'package_type' => $product['package_type'], 'package_type_text' => $product['package_type'] == 1 ? '个人套餐' : '企业套餐', 'card_type' => $product['card_type'], 'card_type_text' => $this->getCardTypeText($product['card_type']), 'total_quantity' => $isMerged ? 1 : 1, 'effective_end_time' => $product['end_time'] ?? null, 'remaining_times' => $product['remaining_times'] ?? 0, 'remaining_points' => $product['remaining_points'] ?? 0, 'display_info' => $this->getDisplayInfo($product), 'usage_id' => $product['id'], 'start_time' => $product['start_time'] ?? null, 'last_use_time' => $product['last_use_time'] ?? null, 'status' => $product['status'] ?? 1, 'buy_time' => $product['create_time'] ]; // 企业套餐特有字段 if ($product['package_type'] == 2) { $item['is_allocated'] = $product['is_allocated'] ?? 0; $item['company_id'] = $product['company_id'] ?? null; $item['allocation_id'] = $product['allocation_id'] ?? null; // 获取企业套餐的席位信息(如果有) if ($item['company_id']) { $seatsInfo = Db::name('company_package_seats') ->where('company_id', $item['company_id']) ->where('package_price_id', $product['package_price_id']) ->find(); if ($seatsInfo) { $item['total_seats'] = $seatsInfo['total_seats']; $item['assigned_seats'] = $seatsInfo['assigned_seats']; $item['available_seats'] = $seatsInfo['available_seats']; } else { $item['total_seats'] = 0; $item['assigned_seats'] = 0; $item['available_seats'] = 0; } } else { $item['total_seats'] = null; $item['assigned_seats'] = null; $item['available_seats'] = null; } } else { // 个人套餐没有席位信息 $item['is_allocated'] = 0; $item['company_id'] = null; $item['allocation_id'] = null; $item['total_seats'] = null; $item['assigned_seats'] = null; $item['available_seats'] = null; } return $item; } /** * 获取显示信息 */ private function getDisplayInfo($product) { if ($product['card_type'] >= 3) { // 日期卡 $endTime = $product['end_time'] ?? null; return $endTime ? '到期: ' . date('Y-m-d', strtotime($endTime)) : '永久有效'; } elseif ($product['card_type'] == 1) { // 次卡 $remainingTimes = $product['remaining_times'] ?? 0; return '剩余次数: ' . $remainingTimes; } elseif ($product['card_type'] == 2) { // 积分卡 $remainingPoints = $product['remaining_points'] ?? 0; return '剩余积分: ' . $remainingPoints; } return ''; } /** * 获取卡类型文本 */ private function getCardTypeText($type) { $map = [ 1 => '次卡', 2 => '积分卡', 3 => '日卡', 4 => '周卡', 5 => '季卡', 6 => '月卡', 7 => '年卡' ]; return $map[$type] ?? '其他'; } /** * 计算到期时间 */ private function calculateEndTime($cardType) { $start = time(); switch ($cardType) { case 3: // 日卡 return date('Y-m-d 23:59:59', strtotime('+1 day', $start)); case 4: // 周卡 return date('Y-m-d 23:59:59', strtotime('+7 days', $start)); case 5: // 季卡 return date('Y-m-d 23:59:59', strtotime('+90 days', $start)); case 6: // 月卡 return date('Y-m-d 23:59:59', strtotime('+30 days', $start)); case 7: // 年卡 return date('Y-m-d 23:59:59', strtotime('+365 days', $start)); default: return null; } } }