| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479 |
- <?php
- namespace app\common\service;
- use think\db\Where;
- use think\facade\Db;
- use think\facade\Log;
- class CompanyPackageService
- {
- /**
- * 验证企业套餐购买资格
- */
- public function validateCompanyPurchase($userId, $packagePriceId, $quantity)
- {
- try {
- // 1. 获取套餐信息
- $package = Db::table('ba_package_price')
- ->alias('pp')
- ->leftJoin('ba_package p', 'p.id = pp.package_id')
- ->where('pp.id', $packagePriceId)
- ->field('pp.*, p.name as package_name')
- ->find();
- if (!$package) {
- throw new \Exception('套餐不存在');
- }
- // 2. 如果是企业套餐,检查用户是否属于企业
- if ($package['type'] == 2) { // 企业套餐
- $companyInfo = $this->getUserCompany($userId);
- if (!$companyInfo) {
- throw new \Exception('只有企业成员才能购买企业套餐');
- }
- // 3. 检查日期卡的最低购买数量
- if ($package['is_date_card'] == 1 && $quantity < $package['min_quantity']) {
- throw new \Exception('企业日期卡至少需要购买' . $package['min_quantity'] . '份');
- }
- return [
- 'valid' => true,
- 'company_id' => $companyInfo['id'],
- 'company_name' => $companyInfo['name'],
- 'min_quantity' => $package['min_quantity']
- ];
- }
- return ['valid' => true, 'company_id' => null];
- } catch (\Throwable $e) {
- Log::error('验证企业套餐购买资格失败: ' . $e->getMessage());
- throw $e;
- }
- }
- /**
- * 获取用户所在企业
- */
- public function getUserCompany($userId)
- {
- // 检查用户是否是企业创建人
- $company = Db::table('ba_company')
- ->where('creator_id', $userId)
- ->where('status', 1)
- ->field('id, name,creator_id')
- ->find();
- if ($company) {
- return $company;
- }
- // 检查是否是成员
- $member = Db::table('ba_company_member')
- ->alias('cm')
- ->leftJoin('ba_company c', 'c.id = cm.company_id')
- ->where('cm.user_id', $userId)
- ->where('cm.status', 1)
- ->where('c.status', 1)
- ->field('c.id, c.name')
- ->find();
- return $member;
- }
- /**
- * 处理企业套餐购买(创建席位记录)
- */
- public function processCompanyPackagePurchase($orderId, $companyId, $packagePriceId, $quantity, $cardType, $unitValue, $pointsValue)
- {
- Db::startTrans();
- try {
- // 1. 获取或创建企业套餐席位记录
- $seatsRecord = Db::table('ba_company_package_seats')
- ->where('company_id', $companyId)
- ->where('package_price_id', $packagePriceId)
- ->find();
- if ($seatsRecord) {
- // 更新现有记录
- $updateData = [
- 'total_seats' => Db::raw('total_seats + ' . $quantity),
- 'available_seats' => Db::raw('available_seats + ' . $quantity),
- 'is_shared' => $cardType < 3 ? 1 : 0, // 次卡/积分卡为共享资源
- 'update_time' => date('Y-m-d H:i:s')
- ];
- // 如果是次卡,累加次数
- if ($cardType == 1) {
- $updateData['total_times'] = Db::raw('total_times + ' . ($unitValue * $quantity));
- $updateData['remaining_times'] = Db::raw('remaining_times + ' . ($unitValue * $quantity));
- }
- // 如果是积分卡,累加积分
- if ($cardType == 2) {
- $updateData['total_points'] = Db::raw('total_points + ' . ($pointsValue * $quantity));
- $updateData['remaining_points'] = Db::raw('remaining_points + ' . ($pointsValue * $quantity));
- }
- Db::table('ba_company_package_seats')
- ->where('id', $seatsRecord['id'])
- ->update($updateData);
- $seatsId = $seatsRecord['id'];
- } else {
- // 创建新记录
- $seatsData = [
- 'company_id' => $companyId,
- 'package_price_id' => $packagePriceId,
- 'product_id' => $this->getProductIdByPackage($packagePriceId),
- 'total_seats' => $cardType < 3 ? 1000 : $quantity,
- 'assigned_seats' => 0,
- 'available_seats' => $cardType < 3 ? 1000 : $quantity,
- 'is_shared' => $cardType < 3 ? 1 : 0, // 次卡/积分卡为共享资源
- 'card_type' => $cardType,
- 'total_times' => $cardType == 1 ? $unitValue * $quantity : 0,
- 'remaining_times' => $cardType == 1 ? $unitValue * $quantity : 0,
- 'total_points' => $cardType == 2 ? $pointsValue * $quantity : 0,
- 'remaining_points' => $cardType == 2 ? $pointsValue * $quantity : 0,
- 'status' => 1,
- 'create_time' => date('Y-m-d H:i:s'),
- 'update_time' => date('Y-m-d H:i:s')
- ];
- $seatsId = Db::table('ba_company_package_seats')->insertGetId($seatsData);
- }
- // 2. 获取购买者ID
- $buyerId = $this->getOrderBuyerId($orderId);
- // 3. 查询订单商品
- $orderItems = Db::table('ba_order_item')
- ->where('order_id', $orderId)
- ->where('package_price_id', $packagePriceId)
- ->select();
- foreach ($orderItems as $item) {
- if ($cardType >= 3) {
- // 日期卡:为每个购买的数量创建独立的分配记录
- for ($i = 0; $i < $quantity; $i++) {
- $allocationData = [
- 'order_item_id' => $item['id'],
- 'order_id' => $orderId,
- 'package_price_id' => $packagePriceId,
- 'product_id' => $item['product_id'],
- 'buyer_id' => $buyerId,
- 'company_id' => $companyId,
- 'assigned_to_user_id' => null, // 初始不分配
- 'assigned_by_user_id' => $buyerId,
- 'record_type' => 2, // 购买记录
- 'is_general' => 0,
- 'seat_index' => $i + 1, // 席位索引
- 'allocation_status' => 0, // 未分配
- 'allocation_time' => null,
- 'start_time' => null,
- 'end_time' => null,
- 'expire_time' => $this->calculateEndTime($cardType, date('Y-m-d H:i:s')), // 冗余字段
- 'remaining_times' => 0, // 日期卡没有次数
- 'remaining_points' => 0, // 日期卡没有积分
- 'is_used' => 0,
- 'create_time' => date('Y-m-d H:i:s'),
- 'update_time' => date('Y-m-d H:i:s')
- ];
- $allocationId = Db::table('ba_company_package_allocation')->insertGetId($allocationData);
- }
- } else {
- // 次卡和积分卡:
- // 1. 创建通用记录(用于管理总资源)
- $generalAllocationData = [
- 'order_item_id' => $item['id'],
- 'order_id' => $orderId,
- 'package_price_id' => $packagePriceId,
- 'product_id' => $item['product_id'],
- 'buyer_id' => $buyerId,
- 'company_id' => $companyId,
- 'assigned_to_user_id' => null, // 通用记录不分配
- 'assigned_by_user_id' => $buyerId,
- 'record_type' => 0, // 通用记录
- 'is_general' => 1, // 是通用记录
- 'seat_index' => 0,
- 'allocation_status' => 0, // 状态:通用记录
- 'allocation_time' => null,
- 'start_time' => null,
- 'end_time' => null,
- 'expire_time' => null,
- 'remaining_times' => $cardType == 1 ? $unitValue * $quantity : 0,
- 'remaining_points' => $cardType == 2 ? $pointsValue * $quantity : 0,
- 'is_used' => 0,
- 'create_time' => date('Y-m-d H:i:s'),
- 'update_time' => date('Y-m-d H:i:s')
- ];
- $generalAllocationId = Db::table('ba_company_package_allocation')->insertGetId($generalAllocationData);
- // 2. 为购买者创建独立的分配记录
- $buyerAllocationData = [
- 'order_item_id' => $item['id'],
- 'order_id' => $orderId,
- 'package_price_id' => $packagePriceId,
- 'product_id' => $item['product_id'],
- 'buyer_id' => $buyerId,
- 'company_id' => $companyId,
- 'assigned_to_user_id' => $buyerId,
- 'assigned_by_user_id' => $buyerId,
- 'record_type' => 1, // 用户分配记录
- 'is_general' => 0,
- 'seat_index' => 0,
- 'parent_id' => $generalAllocationId, // 关联通用记录
- 'allocation_status' => 0, // 未分配
- 'allocation_time' => date('Y-m-d H:i:s'),
- 'start_time' => date('Y-m-d H:i:s'),
- 'end_time' => null,
- 'expire_time' => null,
- 'remaining_times' => $cardType == 1 ? $unitValue : 0,
- 'remaining_points' => $cardType == 2 ? $pointsValue : 0,
- 'is_used' => 0,
- 'create_time' => date('Y-m-d H:i:s'),
- 'update_time' => date('Y-m-d H:i:s')
- ];
- $buyerAllocationId = Db::table('ba_company_package_allocation')->insertGetId($buyerAllocationData);
- // 3. 将购买者添加到授权列表
- $seats = Db::table('ba_company_package_seats')
- ->where('id', $seatsId)
- ->find();
- $authorizedUsers = json_decode($seats['authorized_users'] ?? '[]', true);
- if (!in_array($buyerId, $authorizedUsers)) {
- $authorizedUsers[] = $buyerId;
- Db::table('ba_company_package_seats')
- ->where('id', $seatsId)
- ->update([
- 'authorized_users' => json_encode($authorizedUsers),
- 'assigned_member_count' => Db::raw('assigned_member_count + 1')
- ]);
- }
- }
- // 更新订单商品的分配记录ID(对于日期卡,记录第一个分配记录的ID)
- if ($cardType >= 3) {
- // 获取第一个分配记录ID
- $firstAllocation = Db::table('ba_company_package_allocation')
- ->where('order_item_id', $item['id'])
- ->where('record_type', 2)
- ->order('seat_index', 'asc')
- ->find();
- if ($firstAllocation) {
- Db::table('ba_order_item')
- ->where('id', $item['id'])
- ->update(['allocation_id' => $firstAllocation['id']]);
- }
- } else {
- // 次卡/积分卡使用购买者分配记录ID
- Db::table('ba_order_item')
- ->where('id', $item['id'])
- ->update(['allocation_id' => $buyerAllocationId]);
- }
- }
- Db::commit();
- return true;
- } catch (\Throwable $e) {
- Db::rollback();
- Log::error('处理企业套餐购买失败: ' . $e->getMessage());
- throw $e;
- }
- }
- /**
- * 获取可分配的企业套餐列表(区分类型)
- */
- public function getAvailableCompanyPackages($companyId, $operatorId)
- {
- try {
- // 获取用户角色(创建者或成员)
- $isCreator = Db::table('ba_company')
- ->where('id', $companyId)
- ->where('creator_id', $operatorId)
- ->count() > 0;
- // 获取企业所有套餐席位
- $seats = Db::table('ba_company_package_seats')
- ->alias('cs')
- ->leftJoin('ba_package_price pp', 'pp.id = cs.package_price_id')
- ->leftJoin('ba_product p', 'p.id = cs.product_id')
- ->leftJoin('ba_company_package_allocation pcs', 'pcs.package_price_id = pp.id')
- ->where('cs.company_id', $companyId)
- ->where('pcs.buyer_id', $operatorId)
- // ->where('cs.available_seats', '>', 0)
- ->where('cs.status', 1)
- ->field('cs.*, pp.spec_name, pp.card_type, pp.type as package_type, p.name as product_name, p.type as product_type, p.link,pp.image')
- ->group('pcs.package_price_id')
- ->select();
- // 获取企业所有成员(包括创建者)
- $allMembers = $this->getAllCompanyMembers($companyId);
- // 处理数据
- $result = [];
- foreach ($seats as $seat) {
- // 获取该套餐已分配的成员
- $allocatedMembers = $this->getAllocatedMembersForPackage($companyId, $seat['package_price_id']);
- // 获取该套餐已分配的成员ID列表
- $allocatedMemberIds = array_column($allocatedMembers, 'user_id');
- // 筛选未分配的成员
- $unallocatedMembers = [];
- foreach ($allMembers as $member) {
- if (!in_array($member['user_id'], $allocatedMemberIds)) {
- $unallocatedMembers[] = $member;
- }
- }
- // 组织返回数据
- $seatItem = [
- 'seats_id' => $seat['id'],
- 'product_id' => $seat['product_id'],
- 'product_name' => $seat['product_name'],
- 'product_type' => $seat['product_type'], // 1:网页,2:软件
- 'product_link' => $seat['link'],
- 'product_image' => $seat['image'],
- 'package_price_id' => $seat['package_price_id'],
- 'spec_name' => $seat['spec_name'],
- 'card_type' => $seat['card_type'],
- 'card_type_text' => $this->getCardTypeText($seat['card_type']),
- 'package_type' => $seat['package_type'], // 1个人,2企业
- 'total_seats' => $seat['total_seats'],
- 'assigned_seats' => $seat['assigned_seats'],
- 'available_seats' => $seat['available_seats'],
- // 次卡和积分卡相关
- 'total_times' => $seat['total_times'],
- 'remaining_times' => $seat['remaining_times'],
- 'total_points' => $seat['total_points'],
- 'remaining_points' => $seat['remaining_points'],
- 'end_time' => $seat['end_time'],
- // 已分配成员信息
- 'allocated_members' => $allocatedMembers,
- // 未分配成员信息
- 'unallocated_members' => $unallocatedMembers,
- // 统计信息
- 'allocated_count' => count($allocatedMembers),
- 'unallocated_count' => count($unallocatedMembers),
- 'total_members' => count($allMembers)
- ];
- $result[] = $seatItem;
- }
- return [
- 'packages' => $result,
- 'is_creator' => $isCreator,
- 'total_members' => count($allMembers)
- ];
- } catch (\Throwable $e) {
- Log::error('获取可分配企业套餐失败: ' . $e->getMessage());
- return [
- 'packages' => [],
- 'is_creator' => false,
- 'total_members' => 0
- ];
- }
- }
- /**
- * 获取企业所有成员(包括创建者)
- */
- private function getAllCompanyMembers($companyId)
- {
- $members = [];
- // 1. 获取企业创建者
- $company = Db::table('ba_company')
- ->where('id', $companyId)
- ->field('id, name as company_name, creator_id')
- ->find();
- if ($company && $company['creator_id']) {
- // 获取创建者用户信息
- $creator = Db::table('ba_user')
- ->where('id', $company['creator_id'])
- ->field('id as user_id, nickname as member_name, avatar, email, mobile')
- ->find();
- if ($creator) {
- $creator['is_creator'] = 1;
- $creator['role'] = 1; // 创建者/管理员
- $members[] = $creator;
- }
- }
- // 2. 获取企业成员表中的成员
- $companyMembers = Db::table('ba_company_member')
- ->alias('cm')
- ->leftJoin('ba_user u', 'u.id = cm.user_id')
- ->where('cm.company_id', $companyId)
- ->where('cm.status', 1)
- ->field('
- cm.id as member_id,
- cm.user_id,
- COALESCE(cm.name, u.nickname) as member_name,
- COALESCE(cm.email, u.email) as email,
- u.avatar,
- u.mobile,
- cm.role
- ')
- ->select()
- ->toArray();
- // 过滤掉重复的成员(创建者可能也在成员表中)
- foreach ($companyMembers as $member) {
- // 检查是否已经是创建者
- $isCreator = false;
- foreach ($members as $existingMember) {
- if ($existingMember['user_id'] == $member['user_id']) {
- $isCreator = true;
- break;
- }
- }
- if (!$isCreator) {
- $member['is_creator'] = 0;
- $members[] = $member;
- }
- }
- return $members;
- }
- /**
- * 获取指定套餐已分配的成员
- */
- private function getAllocatedMembersForPackage($companyId, $packagePriceId)
- {
- // 获取套餐信息,判断卡类型
- $package = Db::table('ba_package_price')
- ->where('id', $packagePriceId)
- ->field('card_type')
- ->find();
- if (!$package) {
- return [];
- }
- $cardType = $package['card_type'];
- if ($cardType >= 3) {
- // 日期卡:从分配记录中获取已分配成员
- return Db::table('ba_company_package_allocation')
- ->alias('cpa')
- ->leftJoin('ba_user u', 'u.id = cpa.assigned_to_user_id')
- ->leftJoin('ba_company_member cm', 'cm.user_id = cpa.assigned_to_user_id AND cm.company_id = cpa.company_id')
- ->where('cpa.company_id', $companyId)
- ->where('cpa.package_price_id', $packagePriceId)
- ->where('cpa.allocation_status', 1) // 已分配
- ->whereNotNull('cpa.assigned_to_user_id')
- ->field('
- cpa.assigned_to_user_id as user_id,
- COALESCE(cm.name, u.nickname) as member_name,
- COALESCE(cm.email, u.email) as email,
- u.avatar,
- u.mobile,
- cpa.id as allocation_id,
- cpa.allocation_time,
- cpa.start_time,
- cpa.end_time,
- cpa.remaining_times,
- cpa.remaining_points
- ')
- ->select()
- ->toArray();
- } else {
- // 次卡/积分卡:从席位表的授权用户列表中获取
- $seats = Db::table('ba_company_package_seats')
- ->where('company_id', $companyId)
- ->where('package_price_id', $packagePriceId)
- ->field('authorized_users')
- ->find();
- if (!$seats || empty($seats['authorized_users'])) {
- return [];
- }
- $authorizedUserIds = json_decode($seats['authorized_users'], true);
- if (empty($authorizedUserIds)) {
- return [];
- }
- // 获取授权用户的详细信息
- $where[]=['cp.record_type','<>',0];
- $user=Db::table('ba_user')
- ->alias('u')
- // 使用字符串条件替代闭包
- ->leftJoin('ba_company_member cm', 'cm.user_id = u.id AND cm.company_id = ' . $companyId)
- ->leftJoin('ba_company_package_allocation cp', 'u.id = cp.assigned_to_user_id')
- ->whereIn('u.id', $authorizedUserIds)
- ->where('cp.allocation_status',1)
- ->where($where)
- ->where('cp.package_price_id',$packagePriceId)
- ->field('
- u.id as user_id,
- COALESCE(cm.name, u.nickname) as member_name,
- COALESCE(cm.email, u.email) as email,
- u.avatar,
- cp.id as allocation_id,
- u.mobile,
- cm.role
- ')
- ->select()
- ->toArray();
- // dump($user);die;
- return $user;
- }
- }
- /**
- * 分配套餐给企业成员
- */
- public function allocatePackage($seatsId, $assignedToUserId, $operatorId, $remark = '')
- {
- Db::startTrans();
- try {
- // 1. 获取席位信息
- $seats = Db::table('ba_company_package_seats')
- ->where('id', $seatsId)
- ->lock(true)
- ->find();
- if (!$seats || $seats['available_seats'] <= 0) {
- throw new \Exception('没有可用席位');
- }
- // 2. 检查是否是日期卡
- if ($seats['card_type'] < 3) {
- throw new \Exception('非日期卡类型,请使用assignPackagePermission方法');
- }
- // 3. 检查权限(只有创建者可以分配其他人的,成员只能分配自己的)
- $isCreator = Db::table('ba_company')
- ->where('id', $seats['company_id'])
- ->where('creator_id', $operatorId)
- ->count() > 0;
- // 4. 获取一个未分配的购买记录
- $availableAllocation = Db::table('ba_company_package_allocation')
- ->where('company_id', $seats['company_id'])
- ->where('package_price_id', $seats['package_price_id'])
- ->where('record_type', 2) // 购买记录
- ->whereIn('allocation_status', [0,2]) // 未分配
- ->where('assigned_to_user_id', null) // 未指定用户
- ->lock(true)
- ->order('seat_index', 'asc') // 按席位索引排序
- ->find();
- if (!$availableAllocation) {
- throw new \Exception('没有可分配的套餐记录');
- }
- // 如果不是创建者,检查是否是购买者
- if (!$isCreator && $availableAllocation['buyer_id'] != $operatorId) {
- throw new \Exception('您只能分配自己购买的套餐');
- }
- // 5. 检查成员是否属于该企业
- $isMember = Db::table('ba_company_member')
- ->where('company_id', $seats['company_id'])
- ->where('user_id', $assignedToUserId)
- ->where('status', 1)
- ->count() > 0;
- if (!$isMember) {
- throw new \Exception('该用户不是企业成员');
- }
- // 6. 检查该成员是否已分配此套餐(日期卡只能分配给一个成员)
- if ($seats['card_type'] >= 3) { // 日期卡
- $alreadyAllocated = Db::table('ba_company_package_allocation')
- ->where('company_id', $seats['company_id'])
- ->where('package_price_id', $seats['package_price_id'])
- ->where('assigned_to_user_id', $assignedToUserId)
- ->where('allocation_status', 1)
- ->count();
- if ($alreadyAllocated > 0) {
- throw new \Exception('该成员已分配此套餐,如需再次分配请重新购买');
- }
- }
- // 7. 执行分配
- $now = date('Y-m-d H:i:s');
- // 计算到期时间
- $endTime = $this->calculateEndTime($seats['card_type'], $now);
- // 更新分配记录
- Db::table('ba_company_package_allocation')
- ->where('id', $availableAllocation['id'])
- ->update([
- 'assigned_to_user_id' => $assignedToUserId,
- 'assigned_by_user_id' => $operatorId,
- 'allocation_status' => 1,
- 'allocation_time' => $now,
- 'start_time' => $now,
- 'end_time' => $endTime,
- 'expire_time' => $endTime, // 更新冗余字段
- 'update_time' => $now
- ]);
- // 8.更新席位表
- Db::table('ba_company_package_seats')
- ->where('id', $seatsId)
- ->update([
- 'assigned_seats' => Db::raw('assigned_seats + 1'),
- 'available_seats' => Db::raw('available_seats - 1'),
- 'update_time' => $now
- ]);
- // 9. 检查是否所有席位都已分配
- $unallocatedCount = Db::table('ba_company_package_allocation')
- ->where('order_item_id', $availableAllocation['order_item_id'])
- ->where('allocation_status', 0)
- ->where('record_type', 2)
- ->count();
- if ($unallocatedCount == 0) {
- // 所有席位都已分配,更新订单商品
- Db::table('ba_order_item')
- ->where('id', $availableAllocation['order_item_id'])
- ->update([
- 'is_allocated' => 1,
- 'company_id' => $seats['company_id']
- ]);
- }
- // 10. 为用户创建产品使用记录
- $userProductService = new UserProductService();
- $userProductService->createCompanyProductUsage($availableAllocation, $assignedToUserId, $seats['card_type']);
- // 11. 记录分配日志
- Db::table('ba_allocation_log')->insert([
- 'allocation_id' => $availableAllocation['id'],
- 'action' => 1, // 分配
- 'operator_id' => $operatorId,
- 'to_user_id' => $assignedToUserId,
- 'remark' => $remark,
- 'create_time' => $now
- ]);
- Db::commit();
- return [
- 'success' => true,
- 'allocation_id' => $availableAllocation['id'],
- 'message' => '分配成功'
- ];
- } catch (\Throwable $e) {
- Db::rollback();
- Log::error('分配套餐失败: ' . $e->getMessage());
- throw $e;
- }
- }
- /**
- * 取消分配(日期卡独占席位模式)
- */
- public function cancelAllocation($allocationId, $operatorId, $remark = '')
- {
- Db::startTrans();
- try {
- // 1. 获取分配记录
- $allocation = Db::table('ba_company_package_allocation')
- ->where('id', $allocationId)
- ->where('record_type', 2) // 购买记录
- ->where('allocation_status', 1) // 已分配
- ->lock(true)
- ->find();
- if (!$allocation) {
- throw new \Exception('分配记录不存在或未分配');
- }
- // 2. 检查权限
- $isCreator = Db::table('ba_company')
- ->where('id', $allocation['company_id'])
- ->where('creator_id', $operatorId)
- ->count() > 0;
- if (!$isCreator && $allocation['assigned_by_user_id'] != $operatorId) {
- throw new \Exception('您没有取消分配的权限');
- }
- // 3. 获取席位信息
- $seats = Db::table('ba_company_package_seats')
- ->where('company_id', $allocation['company_id'])
- ->where('package_price_id', $allocation['package_price_id'])
- ->find();
- if (!$seats) {
- throw new \Exception('企业套餐席位不存在');
- }
- // 4. 执行取消分配
- $now = date('Y-m-d H:i:s');
- // 更新分配记录状态
- Db::table('ba_company_package_allocation')
- ->where('id', $allocationId)
- ->update([
- 'assigned_to_user_id' => null,
- 'allocation_status' => 2,
- 'cancel_allocation_time' => $now,
- 'update_time' => $now
- ]);
- // 5. 更新席位表
- Db::table('ba_company_package_seats')
- ->where('id', $seats['id'])
- ->update([
- 'assigned_seats' => Db::raw('assigned_seats - 1'),
- 'available_seats' => Db::raw('available_seats + 1'),
- 'update_time' => $now
- ]);
- // 6. 检查是否还有已分配的记录
- $allocatedCount = Db::table('ba_company_package_allocation')
- ->where('order_item_id', $allocation['order_item_id'])
- ->where('allocation_status', 1)
- ->count();
- if ($allocatedCount == 0) {
- // 没有已分配的记录,更新订单商品
- Db::table('ba_order_item')
- ->where('id', $allocation['order_item_id'])
- ->update([
- 'is_allocated' => 0,
- 'allocation_id' => null
- ]);
- }
- // 7. 删除对应的用户产品使用记录
- Db::table('ba_user_product_usage')
- ->where('user_id', $allocation['assigned_to_user_id'])
- ->where('package_price_id', $allocation['package_price_id'])
- ->where('company_id', $allocation['company_id'])
- ->where('package_type', 2) // 企业套餐
- ->delete();
- // 8. 记录取消分配日志
- Db::table('ba_allocation_log')->insert([
- 'allocation_id' => $allocationId,
- 'action' => 2, // 取消分配
- 'operator_id' => $operatorId,
- 'from_user_id' => $allocation['assigned_to_user_id'],
- 'remark' => $remark,
- 'create_time' => $now
- ]);
- Db::commit();
- return true;
- } catch (\Throwable $e) {
- Db::rollback();
- Log::error('取消分配失败: ' . $e->getMessage());
- throw $e;
- }
- }
- /**
- * 分配次卡/积分卡使用权限给成员(授权访问共享资源池)
- */
- public function assignPackagePermission($seatsId, $memberUserId, $allocatorId, $remark = '')
- {
- Db::startTrans();
- try {
- // 1. 获取席位信息
- $seats = Db::table('ba_company_package_seats')
- ->where('id', $seatsId)
- ->lock(true)
- ->find();
- if (!$seats) {
- throw new \Exception('企业套餐不存在');
- }
- // 2. 检查权限(只有企业创建者或购买者可以分配)
- $canAssign = $this->checkAssignPermission($allocatorId, $seats['company_id'], $seatsId);
- if (!$canAssign) {
- throw new \Exception('没有分配权限');
- }
- // 3. 检查成员是否属于企业
- if (!$this->isCompanyMember($memberUserId, $seats['company_id'])) {
- throw new \Exception('该用户不是企业成员');
- }
- // 4. 检查是否已经是次卡或积分卡
- if (!in_array($seats['card_type'], [1, 2])) {
- throw new \Exception('只有次卡和积分卡支持权限分配');
- }
- // 5. 检查该成员是否已被授权
- $authorizedUsers = json_decode($seats['authorized_users'] ?? '[]', true);
- if (in_array($memberUserId, $authorizedUsers)) {
- throw new \Exception('该成员已被授权使用此套餐');
- }
- // 6. 查找通用记录
- $generalRecord = Db::table('ba_company_package_allocation')
- ->where('company_id', $seats['company_id'])
- ->where('package_price_id', $seats['package_price_id'])
- ->where('record_type', 0) // 通用记录
- ->where('is_general', 1) // 是通用记录
- ->order('id', 'asc')
- ->find();
- if (!$generalRecord) {
- throw new \Exception('未找到套餐购买记录');
- }
- // 7. 将成员添加到授权列表
- $authorizedUsers[] = $memberUserId;
- Db::table('ba_company_package_seats')
- ->where('id', $seatsId)
- ->update([
- 'authorized_users' => json_encode($authorizedUsers),
- 'assigned_member_count' => Db::raw('assigned_member_count + 1'),
- 'assigned_seats' => Db::raw('assigned_seats + 1'),
- 'available_seats' => Db::raw('available_seats - 1'),
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- // 8. 检查是否存在已取消的分配记录
- $now = date('Y-m-d H:i:s');
- $allocationId = 0;
- // 查找该用户对于此套餐的已取消分配记录
- $canceledAllocation = Db::table('ba_company_package_allocation')
- ->where('company_id', $seats['company_id'])
- ->where('package_price_id', $seats['package_price_id'])
- ->where('assigned_to_user_id', $memberUserId)
- ->where('record_type', 1) // 用户分配记录
- ->where('allocation_status', 2) // 已取消状态
- ->order('cancel_allocation_time', 'desc') // 取最新的取消记录
- ->find();
- if ($canceledAllocation) {
- // 8.1 更新已取消的记录为已分配状态
- Db::table('ba_company_package_allocation')
- ->where('id', $canceledAllocation['id'])
- ->update([
- 'order_item_id' => $generalRecord['order_item_id'],
- 'order_id' => $generalRecord['order_id'],
- 'package_price_id' => $seats['package_price_id'],
- 'product_id' => $seats['product_id'],
- 'buyer_id' => $generalRecord['buyer_id'],
- 'company_id' => $seats['company_id'],
- 'assigned_to_user_id' => $memberUserId,
- 'assigned_by_user_id' => $allocatorId,
- 'record_type' => 1, // 用户分配记录
- 'is_general' => 0,
- 'parent_id' => $generalRecord['id'],
- 'allocation_status' => 1, // 更新为已分配
- 'allocation_time' => $now,
- 'cancel_allocation_time' => null, // 清除取消时间
- 'start_time' => $now,
- 'end_time' => null,
- 'expire_time' => null,
- 'remaining_times' => $seats['remaining_times'],
- 'remaining_points' => $seats['remaining_points'],
- 'is_used' => 0,
- 'usage_count' => $canceledAllocation['usage_count'] ?? 0, // 保留原有使用次数
- 'update_time' => $now
- ]);
- $allocationId = $canceledAllocation['id'];
- Log::info('复用已取消的分配记录', [
- 'allocation_id' => $allocationId,
- 'member_user_id' => $memberUserId,
- 'package_price_id' => $seats['package_price_id'],
- 'company_id' => $seats['company_id']
- ]);
- } else {
- // 8.2 创建新的分配记录
- $newAllocationData = [
- 'order_item_id' => $generalRecord['order_item_id'],
- 'order_id' => $generalRecord['order_id'],
- 'package_price_id' => $seats['package_price_id'],
- 'product_id' => $seats['product_id'],
- 'buyer_id' => $generalRecord['buyer_id'],
- 'company_id' => $seats['company_id'],
- 'assigned_to_user_id' => $memberUserId,
- 'assigned_by_user_id' => $allocatorId,
- 'record_type' => 1, // 用户分配记录
- 'is_general' => 0,
- 'seat_index' => 0,
- 'parent_id' => $generalRecord['id'], // 关联通用记录
- 'allocation_status' => 1, // 已分配
- 'allocation_time' => $now,
- 'start_time' => $now,
- 'end_time' => null,
- 'expire_time' => null,
- 'remaining_times' => $seats['remaining_times'],
- 'remaining_points' => $seats['remaining_points'],
- 'is_used' => 0,
- 'usage_count' => 0,
- 'create_time' => $now,
- 'update_time' => $now
- ];
- $allocationId = Db::table('ba_company_package_allocation')->insertGetId($newAllocationData);
- Log::info('创建新的分配记录', [
- 'allocation_id' => $allocationId,
- 'member_user_id' => $memberUserId,
- 'package_price_id' => $seats['package_price_id'],
- 'company_id' => $seats['company_id']
- ]);
- }
- // 9. 为用户创建产品使用记录
- $userProductService = new UserProductService();
- $orderItem = Db::table('ba_order_item')->where('id', $generalRecord['order_item_id'])->find();
- if ($orderItem) {
- $package = Db::table('ba_package_price')->where('id', $seats['package_price_id'])->find();
- if ($package) {
- $userProductService->createCompanyProductUsage($canceledAllocation, $memberUserId, $seats['card_type']);
- }
- }
- // 10. 记录分配日志
- Db::table('ba_allocation_log')->insert([
- 'allocation_id' => $allocationId,
- 'action' => 1, // 分配
- 'operator_id' => $allocatorId,
- 'to_user_id' => $memberUserId,
- 'remark' => $remark ?: '分配次卡/积分卡使用权限',
- 'create_time' => $now
- ]);
- Db::commit();
- return [
- 'success' => true,
- 'allocation_id' => $allocationId,
- 'message' => '分配成功'
- ];
- } catch (\Throwable $e) {
- Db::rollback();
- throw $e;
- }
- }
- /**
- * 检查分配权限
- */
- private function checkAssignPermission($userId, $companyId, $seatsId = null)
- {
- // 1. 检查是否是公司创建者
- $isCreator = Db::table('ba_company')
- ->where('id', $companyId)
- ->where('creator_id', $userId)
- ->count() > 0;
- if ($isCreator) {
- return true;
- }
- // 2. 检查是否是购买者(对于该套餐)
- if ($seatsId) {
- $isBuyer = Db::table('ba_company_package_allocation')
- // ->where('seats_id', $seatsId)
- ->where('buyer_id', $userId)
- ->count() > 0;
- if ($isBuyer) {
- return true;
- }
- }
- // 3. 检查是否是管理员(根据企业成员表)
- $isAdmin = Db::table('ba_company_member')
- ->where('company_id', $companyId)
- ->where('user_id', $userId)
- ->where('role', 1) // 1=管理员
- ->where('status', 1)
- ->count() > 0;
- return $isAdmin;
- }
- /**
- * 检查用户是否是企业成员
- */
- private function isCompanyMember($userId, $companyId)
- {
- // 检查是否是创建者
- $isCreator = Db::table('ba_company')
- ->where('id', $companyId)
- ->where('creator_id', $userId)
- ->count() > 0;
- if ($isCreator) {
- return true;
- }
- // 检查是否是成员
- $isMember = Db::table('ba_company_member')
- ->where('company_id', $companyId)
- ->where('user_id', $userId)
- ->where('status', 1)
- ->count() > 0;
- return $isMember;
- }
- /**
- * 自动分配席位给购买者
- */
- public function autoAllocateToBuyer($buyerId, $companyId, $packagePriceId, $orderId)
- {
- try {
- Log::info('开始自动分配席位给购买者', [
- 'buyer_id' => $buyerId,
- 'company_id' => $companyId,
- 'package_price_id' => $packagePriceId,
- 'order_id' => $orderId
- ]);
- // 1. 检查购买者是否已分配此套餐
- $alreadyAllocated = Db::table('ba_company_package_allocation')
- ->where('company_id', $companyId)
- ->where('package_price_id', $packagePriceId)
- ->where('assigned_to_user_id', $buyerId)
- ->where('allocation_status', 1) // 已分配
- ->count();
- Log::info('检查购买者是否已分配此套餐结果', [
- 'already_allocated' => $alreadyAllocated
- ]);
- if ($alreadyAllocated > 0) {
- Log::info('购买者已分配此套餐,跳过自动分配', [
- 'buyer_id' => $buyerId,
- 'company_id' => $companyId,
- 'package_price_id' => $packagePriceId
- ]);
- return false; // 已分配,跳过
- }
- // 2. 获取可用的席位ID(从席位表中获取)
- $seats = Db::table('ba_company_package_seats')
- ->where('company_id', $companyId)
- ->where('package_price_id', $packagePriceId)
- ->where('available_seats', '>', 0)
- ->find();
- Log::info('查询可用席位结果', [
- 'seats' => $seats ? $seats['id'] : null,
- 'available_seats' => $seats ? $seats['available_seats'] : 0
- ]);
- if (!$seats) {
- Log::error('没有可用席位进行自动分配', [
- 'company_id' => $companyId,
- 'package_price_id' => $packagePriceId
- ]);
- return false;
- }
- // 3. 获取一个未分配的分配记录
- $allocation = Db::table('ba_company_package_allocation')
- ->where('order_id', $orderId)
- ->where('company_id', $companyId)
- ->where('package_price_id', $packagePriceId)
- ->where('allocation_status', 0) // 未分配
- ->order('id', 'asc')
- ->find();
- Log::info('查询未分配记录结果', [
- 'allocation' => $allocation ? $allocation['id'] : null,
- 'order_id' => $orderId
- ]);
- if (!$allocation) {
- // 尝试查找任何属于该订单的未分配记录
- $allocation = Db::table('ba_company_package_allocation')
- ->where('order_id', $orderId)
- ->where('allocation_status', 0)
- ->order('id', 'asc')
- ->find();
- Log::info('二次查询未分配记录结果', [
- 'allocation' => $allocation ? $allocation['id'] : null
- ]);
- if (!$allocation) {
- Log::error('没有找到未分配的分配记录', [
- 'order_id' => $orderId,
- 'company_id' => $companyId,
- 'package_price_id' => $packagePriceId
- ]);
- return false;
- }
- }
- // 4. 获取套餐信息(用于卡类型判断)
- $package = Db::table('ba_package_price')
- ->where('id', $packagePriceId)
- ->find();
- if (!$package) {
- Log::error('套餐信息不存在', ['package_price_id' => $packagePriceId]);
- return false;
- }
- Db::startTrans();
- try {
- // 5. 执行分配
- $now = date('Y-m-d H:i:s');
- // 更新分配记录
- Db::table('ba_company_package_allocation')
- ->where('id', $allocation['id'])
- ->update([
- 'assigned_to_user_id' => $buyerId,
- 'assigned_by_user_id' => $buyerId,
- 'allocation_status' => 1,
- 'allocation_time' => $now,
- 'start_time' => $now,
- 'end_time' => $this->calculateEndTime($package['card_type'], $now),
- 'update_time' => $now
- ]);
- // 更新席位表
- Db::table('ba_company_package_seats')
- ->where('id', $seats['id'])
- ->update([
- 'assigned_seats' => Db::raw('assigned_seats + 1'),
- 'available_seats' => Db::raw('available_seats - 1'),
- 'update_time' => $now
- ]);
- // 更新订单商品
- Db::table('ba_order_item')
- ->where('id', $allocation['order_item_id'])
- ->update([
- 'is_allocated' => 1,
- 'company_id' => $companyId
- ]);
- // 6. 记录分配日志
- Db::table('ba_allocation_log')->insert([
- 'allocation_id' => $allocation['id'],
- 'action' => 1, // 分配
- 'operator_id' => $buyerId,
- 'to_user_id' => $buyerId,
- 'remark' => '购买后自动分配给购买者',
- 'create_time' => $now
- ]);
- // 7. 根据卡类型创建用户产品记录
- $userProductService = new UserProductService();
- // 所有卡类型都需要创建使用记录
- // if ($package['card_type'] >= 3) { // 日期卡
- // 日期卡分配时创建使用记录
- $userProductService->createCompanyProductUsage($allocation, $buyerId, $package['card_type']);
- // } else { // 次卡(1)和积分卡(2)
- // // 获取订单商品信息
- // $orderItem = Db::table('ba_order_item')
- // ->where('id', $allocation['order_item_id'])
- // ->find();
- //
- // if ($orderItem) {
- // // 创建用户产品记录(次卡/积分卡)
- // $userProductService->createUserProductRecord($buyerId, $orderItem, $package);
- // }
- // }
- Db::commit();
- Log::info('企业套餐自动分配给购买者成功', [
- 'buyer_id' => $buyerId,
- 'company_id' => $companyId,
- 'package_price_id' => $packagePriceId,
- 'allocation_id' => $allocation['id']
- ]);
- return true;
- } catch (\Throwable $e) {
- Db::rollback();
- Log::error('企业套餐自动分配给购买者失败: ' . $e->getMessage());
- throw $e;
- }
- } catch (\Throwable $e) {
- Log::error('自动分配企业套餐给购买者失败: ' . $e->getMessage());
- return false;
- }
- }
- /**
- * 计算到期时间
- */
- private function calculateEndTime($cardType, $startTime)
- {
- $start = strtotime($startTime);
- 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; // 次卡和积分卡没有固定到期时间
- }
- }
- /**
- * 获取卡类型文本
- */
- private function getCardTypeText($type)
- {
- $map = [
- 1 => '次卡',
- 2 => '积分卡',
- 3 => '日卡',
- 4 => '周卡',
- 5 => '季卡',
- 6 => '月卡',
- 7 => '年卡'
- ];
- return $map[$type] ?? '其他';
- }
- private function getProductIdByPackage($packagePriceId) {
- // 实现获取产品ID的逻辑
- $package = Db::table('ba_package_price')->where('id', $packagePriceId)->find();
- $product = Db::table('ba_product')->where('package_id', $package['package_id'])->find();
- return $product ? $product['id'] : 0;
- }
- private function getOrderBuyerId($orderId) {
- $order = Db::table('ba_order')->where('id', $orderId)->find();
- return $order ? $order['user_id'] : 0;
- }
- /**
- * 取消次卡/积分卡权限分配
- */
- public function cancelPackagePermission($allocationId, $operatorId, $remark = '')
- {
- Db::startTrans();
- try {
- // 1. 获取分配记录
- $allocation = Db::table('ba_company_package_allocation')
- ->where('id', $allocationId)
- ->where('record_type', 1) // 用户分配记录
- ->where('allocation_status', 1) // 已分配
- ->lock(true)
- ->find();
- if (!$allocation) {
- throw new \Exception('分配记录不存在或未分配');
- }
- // 2. 检查权限
- $canCancel = $this->checkAssignPermission($operatorId, $allocation['company_id']);
- if (!$canCancel) {
- throw new \Exception('您没有取消分配的权限');
- }
- // 3. 获取席位信息
- $seats = Db::table('ba_company_package_seats')
- ->where('company_id', $allocation['company_id'])
- ->where('package_price_id', $allocation['package_price_id'])
- ->find();
- if (!$seats) {
- throw new \Exception('企业套餐席位不存在');
- }
- // 4. 从授权列表中移除用户
- $authorizedUsers = json_decode($seats['authorized_users'] ?? '[]', true);
- $key = array_search($allocation['assigned_to_user_id'], $authorizedUsers);
- if ($key !== false) {
- unset($authorizedUsers[$key]);
- $authorizedUsers = array_values($authorizedUsers); // 重新索引数组
- // 更新席位表
- Db::table('ba_company_package_seats')
- ->where('id', $seats['id'])
- ->update([
- 'authorized_users' => json_encode($authorizedUsers),
- 'assigned_member_count' => Db::raw('assigned_member_count - 1'),
- 'assigned_seats' => Db::raw('assigned_seats - 1'),
- 'available_seats' => Db::raw('available_seats + 1'),
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- }
- // 5. 更新分配记录状态
- $now = date('Y-m-d H:i:s');
- Db::table('ba_company_package_allocation')
- ->where('id', $allocationId)
- ->update([
- 'allocation_status' => 2, // 已取消
- 'cancel_allocation_time' => $now,
- 'update_time' => $now
- ]);
- // 6. 删除对应的用户产品使用记录
- $del=Db::table('ba_user_product_usage')
- ->where('user_id', $allocation['assigned_to_user_id'])
- ->where('package_price_id', $allocation['package_price_id'])
- ->where('company_id', $allocation['company_id'])
- ->where('package_type', 2) // 企业套餐
- ->delete();
- // 7. 记录取消分配日志
- Db::table('ba_allocation_log')->insert([
- 'allocation_id' => $allocationId,
- 'action' => 2, // 取消分配
- 'operator_id' => $operatorId,
- 'from_user_id' => $allocation['assigned_to_user_id'],
- 'remark' => $remark ?: '取消次卡/积分卡使用权限',
- 'create_time' => $now
- ]);
- Db::commit();
- return true;
- } catch (\Throwable $e) {
- Db::rollback();
- Log::error('取消次卡/积分卡权限失败: ' . $e->getMessage());
- throw $e;
- }
- }
- /**
- * 使用企业次卡/积分卡(从共享资源池扣除)
- */
- public function useSharedCompanyPackage($userId, $packagePriceId, $useQuantity, $productId = null, $remark = '')
- {
- Db::startTrans();
- try {
- // 1. 获取用户所在企业
- $companyInfo = $this->getUserCompany($userId);
- if (!$companyInfo) {
- throw new \Exception('您不属于任何企业');
- }
- // 2. 获取套餐信息
- $package = Db::table('ba_package_price')
- ->where('id', $packagePriceId)
- ->find();
- if (!$package) {
- throw new \Exception('套餐不存在');
- }
- // 3. 检查卡类型是否为次卡或积分卡
- if (!in_array($package['card_type'], [1, 2])) {
- throw new \Exception('只有次卡和积分卡支持此使用方式');
- }
- // 4. 获取企业套餐席位信息,检查用户是否被授权
- $seats = Db::table('ba_company_package_seats')
- ->where('company_id', $companyInfo['id'])
- ->where('package_price_id', $packagePriceId)
- ->lock(true)
- ->find();
- if (!$seats) {
- throw new \Exception('企业套餐不存在');
- }
- // 检查用户是否在授权列表中
- $authorizedUsers = json_decode($seats['authorized_users'] ?? '[]', true);
- if (!in_array($userId, $authorizedUsers)) {
- throw new \Exception('您未被授权使用此套餐');
- }
- // 5. 检查共享资源池是否足够
- if ($package['card_type'] == 1) { // 次卡
- if ($seats['remaining_times'] < $useQuantity) {
- throw new \Exception('剩余次数不足,剩余:' . $seats['remaining_times'] . '次');
- }
- } elseif ($package['card_type'] == 2) { // 积分卡
- if ($seats['remaining_points'] < $useQuantity) {
- throw new \Exception('剩余积分不足,剩余:' . $seats['remaining_points'] . '积分');
- }
- }
- // 6. 获取用户的分配记录
- $userAllocation = Db::table('ba_company_package_allocation')
- ->where('company_id', $companyInfo['id'])
- ->where('package_price_id', $packagePriceId)
- ->where('assigned_to_user_id', $userId)
- ->where('allocation_status', 1)
- ->order('id', 'asc')
- ->find();
- if (!$userAllocation) {
- throw new \Exception('未找到您的分配记录');
- }
- // 7. 扣减共享池资源
- if ($package['card_type'] == 1) { // 次卡
- Db::table('ba_company_package_seats')
- ->where('id', $seats['id'])
- ->dec('remaining_times', $useQuantity)
- ->update();
- $remainingTimesAfter = $seats['remaining_times'] - $useQuantity;
- $remainingPointsAfter = $seats['remaining_points'];
- } else { // 积分卡
- Db::table('ba_company_package_seats')
- ->where('id', $seats['id'])
- ->dec('remaining_points', $useQuantity)
- ->update();
- $remainingTimesAfter = $seats['remaining_times'];
- $remainingPointsAfter = $seats['remaining_points'] - $useQuantity;
- }
- // 8. 更新分配记录的使用状态
- Db::table('ba_company_package_allocation')
- ->where('id', $userAllocation['id'])
- ->update([
- 'is_used' => 1,
- 'usage_count' => Db::raw('usage_count + ' . $useQuantity),
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- // 9. 记录使用明细
- $usageData = [
- 'allocation_id' => $userAllocation['id'],
- 'company_id' => $companyInfo['id'],
- 'package_price_id' => $packagePriceId,
- 'user_id' => $userId,
- 'card_type' => $package['card_type'],
- 'used_quantity' => $useQuantity,
- 'remaining_times_after' => $remainingTimesAfter,
- 'remaining_points_after' => $remainingPointsAfter,
- 'product_id' => $productId,
- 'usage_time' => date('Y-m-d H:i:s'),
- 'remark' => $remark,
- 'create_time' => date('Y-m-d H:i:s')
- ];
- $usageId = Db::table('ba_company_package_usage')->insertGetId($usageData);
- Db::commit();
- return [
- 'success' => true,
- 'usage_id' => $usageId,
- 'remaining_times' => $remainingTimesAfter,
- 'remaining_points' => $remainingPointsAfter,
- 'message' => '使用成功'
- ];
- } catch (\Throwable $e) {
- Db::rollback();
- Log::error('使用企业次卡/积分卡失败: ' . $e->getMessage());
- throw $e;
- }
- }
- }
|