| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481 |
- <?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;
- }
- }
- }
|