// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\store\model\goods; use think\Paginator; use think\db\exception\DbException; use app\job\controller\goods\Collector as GoodsCollectorJob; use app\common\model\goods\Collector as CollectorModel; use app\common\enum\goods\CollectorStatus as GoodsCollectorStatusEnum; use cores\exception\BaseException; /** * 商品采集记录模型 * Class Collector * @package app\store\model\goods */ class Collector extends CollectorModel { /** * 获取采集记录 * @param array $param * @return Paginator * @throws DbException */ public function getList(array $param = []): \think\Paginator { return $this->where($this->getFilter($param)) ->where('is_delete', '=', 0) ->order(['create_time' => 'desc', $this->getPk()]) ->paginate(10); } /** * 获取查询条件 * @param array $param * @return array */ private function getFilter(array $param = []): array { // 默认查询参数 $params = $this->setQueryDefaultValue($param, ['goods_type' => -1, 'status' => -1]); // 检索查询条件 $filter = []; $params['status'] > -1 && $filter[] = ['status', '=', (int)$params['status']]; return $filter; } /** * 执行采集任务` * @param array $form * @return bool * @throws BaseException */ public function batch(array $form): bool { $urls = $this->getUrls($form); // 验证采集的商品数量是否合法 $this->checkLimit($urls); // 新增商品采集记录 $recordId = $this->addRecord(\count($urls)); // 调度计划任务 $this->dispatchJob($urls, $recordId, $form); return true; } /** * 获取采集商品url列表 * @param array $form * @return false|string[] */ private function getUrls(array $form) { return array_filter(explode("\n", $form['urls'])); } /** * 调度队列服务执行商品采集 * @param array $urls 商品url列表 * @param int $recordId 商品采集记录ID * @return void */ private function dispatchJob(array $urls, int $recordId, array $form) { // 分批每次采集1条 $limit = 1; // 根据商品总数量计算需要的队列任务数量 $jobCount = \count($urls) / $limit; // 逐次发布队列任务 for ($i = 0; $i < $jobCount; $i++) { $data = array_slice($urls, $i * $limit, $limit); GoodsCollectorJob::dispatch([ 'urls' => $data, 'form' => $form, 'recordId' => $recordId, 'storeId' => self::$storeId, ]); } } /** * 新增商品采集记录 * @param int $totalCount 商品总数量 * @return int */ private function addRecord(int $totalCount): int { $this->save([ 'total_count' => $totalCount, 'start_time' => \time(), 'fail_log' => [], 'status' => GoodsCollectorStatusEnum::NORMAL, 'store_id' => self::$storeId ]); return (int)$this['id']; } /** * 验证采集的商品数量是否合法 * @param array $urls * @return void * @throws BaseException */ private function checkLimit(array $urls): void { // 判断商品数据是否为空 if (empty($urls)) { throwError('很抱歉,采集的商品数量不能为空'); } // 判断商品数量是否超出100条 if (\count($urls) > 100) { throwError('很抱歉,一次性采集最多不能超过100个商品'); } } /** * 删除记录 * @return bool */ public function setDelete(): bool { // if ($this['status'] == GoodsCollectorStatusEnum::NORMAL) { // $this->error = '很抱歉,当前任务没有结束不能删除'; // return false; // } return $this->save(['is_delete' => 1]); } }