// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\api\model\groupon; use app\api\model\Goods as GoodsModel; use app\api\model\groupon\Goods as GrouponGoodsModel; use app\api\model\groupon\TaskUsers as TaskUsersModel; use app\api\service\User as UserService; use app\api\service\Goods as GoodsService; use app\common\model\groupon\Task as TaskModel; use app\common\enum\groupon\ActiveType as ActiveTypeEnum; use app\common\enum\groupon\TaskStatus as TaskStatusEnum; use cores\exception\BaseException; /** * 拼团拼单模型 * Class Task * @package app\api\model\groupon */ class Task extends TaskModel { /** * 隐藏字段 * @var array */ protected $hidden = [ 'actual_people', 'robot_people', 'is_delete', 'store_id', 'create_time', 'update_time', ]; /** * 我的拼团列表 * @return mixed|\think\Paginator * @throws BaseException * @throws \think\db\exception\DbException */ public function getMyList() { // 当前登录用户ID $userId = UserService::getCurrentLoginUserId(); // 砍价活动列表 $list = $this->where('user_id', '=', $userId) ->where('is_delete', '=', 0) ->order(['create_time' => 'desc']) ->paginate(15); // 设置商品数据 if (!$list->isEmpty()) { $list = GoodsService::setGoodsData($list, true, GoodsModel::getHidden(['goods_images'])); } return $list; } /** * 获取指定商品的凑团记录 * @param int $groupGoodsId 拼团商品ID * @param int $limit 限制的数量 * @return array|\think\Collection|\think\db\BaseQuery[] * @throws BaseException * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public static function getQuickJoinList(int $groupGoodsId, int $limit) { // 当前用户ID (凑团信息不能显示自己发起的团) $userId = UserService::getCurrentLoginUserId(false); // 查询列表数据 $query = (new static)->getNewQuery(); // $userId > 0 && $query->where('user_id', '<>', $userId); return $query->with(['user.avatar']) ->field(['(people - actual_people - robot_people) as surplus_people']) ->field(true) ->where('groupon_goods_id', '=', $groupGoodsId) ->where('end_time', '>=', time()) ->where('status', '=', TaskStatusEnum::NORMAL) ->where('is_delete', '=', 0) ->order(['surplus_people' => 'asc', 'end_time' => 'asc']) ->limit($limit) ->select(); } /** * 获取拼单详情 (详细) * @param int $taskId 拼单ID * @return Task|array * @throws BaseException * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getDetail(int $taskId) { // 获取拼单详情 $detail = static::getBasic($taskId); // 获取拼单的成员列表 $TaskUsersModel = new TaskUsersModel; $detail['users'] = $TaskUsersModel->getUserList($taskId); // 当前用户是否为发起人 $detail['is_leader'] = $this->getIsLeader($detail); // 当前用户是否已参团 $detail['is_join'] = $this->getIsjoin($detail); return $detail; } /** * 当前用户是否为发起人 * @param $detail * @return bool * @throws BaseException */ private function getIsLeader($detail): bool { $userId = UserService::getCurrentLoginUserId(false); return !empty($userId) && $userId == $detail['user_id']; } /** * 当前用户是否已参团 * @param $detail * @return bool * @throws BaseException */ private function getIsjoin($detail): bool { $userId = UserService::getCurrentLoginUserId(false); return $userId > 0 && TaskUsersModel::isJoin($detail['task_id'], $userId); } /** * 更新拼单信息 (用于订单付款后) * @param int $taskId 拼单ID * @param int $userId 用户ID * @param int $orderId 订单ID * @return bool * @throws BaseException */ public function updateTaskInfo(int $taskId, int $userId, int $orderId): bool { // 获取拼单详情 $model = static::getBasic($taskId); // 验证当前拼单是否允许加入新成员 if (!$this->checkToJoin($model, $userId, false)) { return false; } // 已拼人数 $model['actual_people'] = $model['actual_people'] + 1; $joinedPeople = $model['actual_people'] + $model['robot_people']; // 判断拼单状态 if ($joinedPeople >= $model['people']) { $model['complete_time'] = time(); $model['status'] = TaskStatusEnum::SUCCESS; } // 创建拼单成员 $this->createTaskUser($taskId, $userId, $orderId, false, $model['store_id']); // 保存拼单信息 return $model->save(); } /** * 新增拼单成员 * @param int $taskId * @param int $userId * @param int $orderId * @param bool $isLeader * @param int $storeId * @return void */ private function createTaskUser(int $taskId, int $userId, int $orderId, bool $isLeader, int $storeId): void { $model = new TaskUsersModel; $model->save([ 'task_id' => $taskId, 'order_id' => $orderId, 'user_id' => $userId, 'is_leader' => $isLeader, 'store_id' => $storeId, ]); } /** * 创建新拼单记录 * @param int $userId 用户ID * @param GrouponGoodsModel $goodsInfo 拼团商品信息 * @param int $stepPeople 阶梯团的人数 * @return false|int */ public function createTask(int $userId, int $orderId, GrouponGoodsModel $goodsInfo, int $stepPeople) { // 保存新的拼单记录 $people = $goodsInfo['active_type'] === ActiveTypeEnum::STEPS ? $stepPeople : $goodsInfo['people']; $status = $this->save([ 'groupon_goods_id' => $goodsInfo['groupon_goods_id'], 'goods_id' => $goodsInfo['goods_id'], 'active_type' => $goodsInfo['active_type'], 'people' => $people, 'actual_people' => 1, 'user_id' => $userId, 'start_time' => time(), 'end_time' => time() + ($goodsInfo['group_time'] * 60 * 60), 'status' => TaskStatusEnum::NORMAL, 'store_id' => $goodsInfo['store_id'], ]); // 创建拼单成员 $this->createTaskUser((int)$this['task_id'], $userId, $orderId, true, $goodsInfo['store_id']); return $status ? (int)$this['task_id'] : false; } }