26 changed files with 259 additions and 173 deletions
			
			
		- 
					1app/Admin/Controllers/AgentController.php
 - 
					7app/Admin/Controllers/AgentStatisticsController.php
 - 
					1app/Admin/Controllers/GuideController.php
 - 
					4app/Admin/Controllers/MiniProgramTemplateController.php
 - 
					1app/Admin/Controllers/OrderController.php
 - 
					1app/Admin/Controllers/OrderStatisticsController.php
 - 
					7app/Admin/Controllers/SupplierStatisticsController.php
 - 
					6app/Admin/Controllers/UserStatisticsController.php
 - 
					4app/Admin/Extensions/Grid/MiniProgramAuditStatus.php
 - 
					2app/Admin/Extensions/Grid/MiniProgramPull.php
 - 
					150app/Admin/Extensions/Grid/MiniProgramUpload.php
 - 
					17app/AdminAgent/Forms/LoadSupplierSpec.php
 - 
					3app/AdminGuide/Controllers/OrderController.php
 - 
					2app/AdminSupplier/Controllers/FinanceStatisticsController.php
 - 
					1app/AdminSupplier/Controllers/OrderController.php
 - 
					1app/AdminSupplier/Controllers/OrderStatisticsController.php
 - 
					4app/AdminSupplier/Controllers/ProductStatisticsController.php
 - 
					2app/Http/Controllers/Api/OrderController.php
 - 
					4app/Http/Controllers/Api/SpecialController.php
 - 
					6app/Http/Controllers/Api/TestController.php
 - 
					54app/Jobs/UploadMiniProgramQueue.php
 - 
					1app/Models/MiniProgramDraft.php
 - 
					1app/Models/MiniProgramTemplate.php
 - 
					143app/Service/UploadMiniProgram.php
 - 
					8resources/js/agent-spec-edit.js
 - 
					1upload.bat
 
@ -0,0 +1,54 @@ | 
				
			|||
<?php | 
				
			|||
 | 
				
			|||
namespace App\Jobs; | 
				
			|||
 | 
				
			|||
use App\Models\Agent; | 
				
			|||
use App\Models\MiniProgramTemplate; | 
				
			|||
use App\Service\UploadMiniProgram; | 
				
			|||
use Exception; | 
				
			|||
use GuzzleHttp\Exception\GuzzleException; | 
				
			|||
use Illuminate\Bus\Queueable; | 
				
			|||
use Illuminate\Contracts\Queue\ShouldQueue; | 
				
			|||
use Illuminate\Foundation\Bus\Dispatchable; | 
				
			|||
use Illuminate\Queue\InteractsWithQueue; | 
				
			|||
use Illuminate\Queue\SerializesModels; | 
				
			|||
 | 
				
			|||
class UploadMiniProgramQueue implements ShouldQueue | 
				
			|||
{ | 
				
			|||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | 
				
			|||
 | 
				
			|||
	private int $template_id; //小程序模板ID
 | 
				
			|||
	private int $agent_id; | 
				
			|||
 | 
				
			|||
	/** | 
				
			|||
	 * Create a new job instance. | 
				
			|||
	 * | 
				
			|||
	 * @param int $template_id 小程序模板ID | 
				
			|||
	 * @param int $agent_id 代理商ID | 
				
			|||
	 */ | 
				
			|||
    public function __construct(int $template_id, int $agent_id) | 
				
			|||
    { | 
				
			|||
        $this->template_id = $template_id; | 
				
			|||
        $this->agent_id = $agent_id; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
	/** | 
				
			|||
	 * Execute the job. | 
				
			|||
	 * | 
				
			|||
	 * @return void | 
				
			|||
	 * @throws Exception | 
				
			|||
	 */ | 
				
			|||
    public function handle() | 
				
			|||
    { | 
				
			|||
		$agent = Agent::find($this->agent_id); | 
				
			|||
		$template = MiniProgramTemplate::find($this->template_id); | 
				
			|||
 | 
				
			|||
		if (!$agent || !$template) return; | 
				
			|||
 | 
				
			|||
		try { | 
				
			|||
			new UploadMiniProgram($agent, $template); | 
				
			|||
		} catch (GuzzleException | \Exception $e) { | 
				
			|||
			throw new Exception($e->getMessage()); | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
@ -0,0 +1,143 @@ | 
				
			|||
<?php | 
				
			|||
 | 
				
			|||
namespace App\Service; | 
				
			|||
use App\Models\Agent; | 
				
			|||
use App\Models\MiniProgramTemplate; | 
				
			|||
use App\Models\MiniProgramUploadLog; | 
				
			|||
use EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Code\Client; | 
				
			|||
use Exception; | 
				
			|||
use GuzzleHttp\Exception\GuzzleException; | 
				
			|||
use Illuminate\Support\Facades\Redis; | 
				
			|||
use Illuminate\Support\Facades\Storage; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 上传小程序 | 
				
			|||
 * Class UploadMiniProgram | 
				
			|||
 * @package App\Service | 
				
			|||
 */ | 
				
			|||
class UploadMiniProgram | 
				
			|||
{ | 
				
			|||
	/** | 
				
			|||
	 * UploadMiniProgram constructor. | 
				
			|||
	 * @param Agent $agent | 
				
			|||
	 * @param MiniProgramTemplate $template | 
				
			|||
	 * @throws GuzzleException | 
				
			|||
	 * @throws Exception | 
				
			|||
	 */ | 
				
			|||
	public function __construct(Agent $agent, MiniProgramTemplate $template) | 
				
			|||
	{ | 
				
			|||
		try { | 
				
			|||
			$openPlatform = new OpenPlatform(); | 
				
			|||
			$refreshToken = $openPlatform->refreshToken($agent->appid); | 
				
			|||
			if (!$refreshToken) { | 
				
			|||
				throw new Exception('获取refresh_token失败'); | 
				
			|||
			} | 
				
			|||
			$miniProgram = $openPlatform->miniProgram($agent->appid, $refreshToken); | 
				
			|||
 | 
				
			|||
			/** @var Client $code */ | 
				
			|||
			$code = $miniProgram['code'] ?? null; | 
				
			|||
			if (!$code) { | 
				
			|||
				throw new Exception('获取code失败'); | 
				
			|||
			} | 
				
			|||
 | 
				
			|||
			$templateId = $template->template_id; | 
				
			|||
			$extJson = json_encode(['extAppid' => $agent->appid]); | 
				
			|||
			$version = $template->user_version; | 
				
			|||
			$description = $agent->company_name; | 
				
			|||
 | 
				
			|||
			//提交上传
 | 
				
			|||
			$commit = $code->commit($templateId, $extJson, $version, $description); | 
				
			|||
 | 
				
			|||
			if (!isset($commit['errcode'], $commit['errmsg']) || $commit['errcode'] != 0 || $commit['errmsg'] != 'ok') { | 
				
			|||
				throw new Exception($commit['errmsg'] ?? join(',', $commit)); | 
				
			|||
			} | 
				
			|||
 | 
				
			|||
			//提交审核,文档:https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/code/submit_audit.html
 | 
				
			|||
			$res = $code->submitAudit([]); | 
				
			|||
 | 
				
			|||
			$audit_err_code = $this->auditErrorCode(); | 
				
			|||
			if (isset($res['errcode'], $res['errmsg']) && $res['errcode'] == 0 && $res['errmsg'] == 'ok') { | 
				
			|||
				$filename = "mini_program_qrcode/{$agent->id}-{$agent->appid}-demo.jpg"; | 
				
			|||
 | 
				
			|||
				//保存上传记录
 | 
				
			|||
				MiniProgramUploadLog::insert([ | 
				
			|||
					'agent_id' => $agent->id, | 
				
			|||
					'appid' => $agent->appid, | 
				
			|||
					'user_version' => $template->user_version, | 
				
			|||
					'template_id' => $templateId, | 
				
			|||
					'qrcode' => $filename, | 
				
			|||
					'audit_id' => $res['auditid'], | 
				
			|||
					'created_at' => now(), | 
				
			|||
				]); | 
				
			|||
 | 
				
			|||
				//获取体验二维码并保存,30天内只获取一次
 | 
				
			|||
				$qrcode_path = Storage::path("mini_program_qrcode/{$agent->id}-{$agent->appid}-demo.jpg"); | 
				
			|||
				if (!file_exists($qrcode_path) || time() - filemtime($qrcode_path) < 86400 * 30) { | 
				
			|||
					$qrcode = $code->getQrCode(); | 
				
			|||
					Storage::put("public/$filename", $qrcode); | 
				
			|||
				} | 
				
			|||
 | 
				
			|||
				//设置域名,如果之前已经设置过了将记录下来,不再设置
 | 
				
			|||
				$host = env('APP_URL'); | 
				
			|||
				$redis_key = 'mini_program_set_host:' . substr(md5($host), 0, 10); | 
				
			|||
				if (!Redis::hget($redis_key, $agent->appid)) { | 
				
			|||
					/** @var \EasyWeChat\OpenPlatform\Authorizer\MiniProgram\Domain\Client $domain */ | 
				
			|||
					$domain = $miniProgram['domain']; | 
				
			|||
 | 
				
			|||
					$param = [ | 
				
			|||
						"action" => "add", | 
				
			|||
						"requestdomain" => [$host], | 
				
			|||
						"wsrequestdomain" => [str_replace('http', 'ws', $host)], | 
				
			|||
						"uploaddomain" => [$host], | 
				
			|||
						"downloaddomain" => [$host], | 
				
			|||
					]; | 
				
			|||
					$domain->modify($param); //服务器域名,服务器域名多次设置仅第一次成功,这里不校验返回结果正确性
 | 
				
			|||
					$res = $domain->setWebviewDomain([$host]); //业务域名
 | 
				
			|||
					if (!isset($res['errcode'], $res['errmsg']) || $res['errcode'] != 0 || $res['errmsg'] != 'ok') { | 
				
			|||
						throw new Exception("设置业务域名{$host}失败,原因:" . $res['errmsg'] ?? (is_array($res) ? join(',', $res) : '未知')); | 
				
			|||
					} | 
				
			|||
					Redis::hset($redis_key, $agent->appid, 1); | 
				
			|||
				} | 
				
			|||
 | 
				
			|||
				echo "上传成功,并已提交审核"; | 
				
			|||
			} else if (isset($audit_err_code[$res['errcode']])) { | 
				
			|||
				throw new Exception($audit_err_code[$res['errcode']]); | 
				
			|||
			} else { | 
				
			|||
				throw new Exception($res['errmsg'] ?? join(',', $res)); | 
				
			|||
			} | 
				
			|||
		} catch (Exception $e) { | 
				
			|||
			throw new Exception($agent->id . '-' . $agent->appid . $e->getMessage()); | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	private function auditErrorCode(): array | 
				
			|||
	{ | 
				
			|||
		return [ | 
				
			|||
			-1 => '系统繁忙', | 
				
			|||
			86000 => '不是由第三方代小程序进行调用', | 
				
			|||
			86001 => '不存在第三方的已经提交的代码', | 
				
			|||
			85006 => '标签格式错误', | 
				
			|||
			85007 => '页面路径错误', | 
				
			|||
			85008 => '当前小程序没有已经审核通过的类目,请添加类目成功后重试', | 
				
			|||
			85009 => '已经有正在审核的版本', | 
				
			|||
			85010 => 'item_list 有项目为空', | 
				
			|||
			85011 => '标题填写错误', | 
				
			|||
			85023 => '审核列表填写的项目数不在 1-5 以内', | 
				
			|||
			85077 => '小程序类目信息失效(类目中含有官方下架的类目,请重新选择类目)', | 
				
			|||
			86002 => '小程序还未设置昵称、头像、简介。请先设置完后再重新提交', | 
				
			|||
			85085 => '小程序提审数量已达本月上限,请点击查看《临时quota申请流程》', | 
				
			|||
			85086 => '提交代码审核之前需提前上传代码', | 
				
			|||
			85087 => '小程序已使用 api navigateToMiniProgram,请声明跳转 appid 列表后再次提交', | 
				
			|||
			87006 => '小游戏不能提交', | 
				
			|||
			86007 => '小程序禁止提交', | 
				
			|||
			85051 => 'version_desc或者preview_info超限', | 
				
			|||
			85092 => 'preview_info格式错误', | 
				
			|||
			85093 => 'preview_info 视频或者图片个数超限', | 
				
			|||
			85094 => '需提供审核机制说明信息', | 
				
			|||
			86009 => '服务商新增小程序代码提审能力被限制', | 
				
			|||
			86010 => '服务商迭代小程序代码提审能力被限制', | 
				
			|||
			9400001 => '该开发小程序已开通小程序直播权限,不支持发布版本。如需发版,请解绑开发小程序后再操作。', | 
				
			|||
			9402202 => '请勿频繁提交,待上一次操作完成后再提交', | 
				
			|||
		]; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
@ -0,0 +1 @@ | 
				
			|||
git push | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue