572 lines
22 KiB
PHP
572 lines
22 KiB
PHP
<?php
|
||
|
||
namespace addon\aliapp\model;
|
||
|
||
use app\model\BaseModel;
|
||
use think\Exception;
|
||
use think\facade\Db;
|
||
use app\model\NewBaseModel;
|
||
|
||
/**
|
||
* Common: 支付宝小程序相关操作
|
||
* Author: wu-hui
|
||
* Time: 2022/12/29 15:10
|
||
* Class AliPayApplet
|
||
* @package addon\aliapp\model
|
||
*/
|
||
class AliPayApplet extends BaseModel
|
||
{
|
||
|
||
protected $site_id;
|
||
// 小程序模板信息
|
||
private $templateInfo = [];
|
||
// 小程序投放的端:com.alipay.alipaywallet=支付宝端。com.alipay.iot.xpaas=支付宝IoT端。
|
||
private $bundle_id = 'com.alipay.alipaywallet';
|
||
public $version = '';
|
||
|
||
public function __construct($siteId)
|
||
{
|
||
$this->site_id = $siteId;
|
||
$this->templateInfo = config('alipay.templateInfo');
|
||
$this->version = config('alipay.version');
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 小程序发布记录 查询集合
|
||
* Author: wu-hui
|
||
* Time: 2022/12/29 18:38
|
||
* @return Db
|
||
*/
|
||
private function appletReleaseSelectCollection($type)
|
||
{
|
||
return Db::name('applet_release')
|
||
->where('site_id', $this->site_id)
|
||
->where('type', $type);
|
||
}
|
||
|
||
/**
|
||
* Common: 获取已发布的最新版本
|
||
* Author: wu-hui
|
||
* Time: 2023/01/03 16:41
|
||
* @return string
|
||
*/
|
||
public function newestVersion(): string
|
||
{
|
||
$version = (string)$this->appletReleaseSelectCollection(1)
|
||
->order(['create_time' => 'desc', 'id' => 'desc'])
|
||
->value('version');
|
||
|
||
return !empty($version) ? $version : '0.0.0';
|
||
}
|
||
|
||
/**
|
||
* Common: 判断:当前版本是否为最新版本
|
||
* Author: wu-hui
|
||
* Time: 2023/01/03 17:07
|
||
* @return bool
|
||
*/
|
||
public function isNewestVersion($app_version=''): bool
|
||
{
|
||
$user_version=$this->newestVersion();
|
||
if($app_version && $user_version=='0.0.0'){
|
||
return true;
|
||
}else if(empty($app_version)){
|
||
return (boolean)version_compare($this->version, $user_version, '>');
|
||
}else{
|
||
return (boolean)version_compare($app_version, $user_version, '>');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Common: 发布流程处理 —— 开始处理
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 10:49
|
||
* @param $type
|
||
* @param $id
|
||
* @return array
|
||
*/
|
||
public function publishingInit($type, $id,$app_version='')
|
||
{
|
||
try {
|
||
// 根据操作类型获取对应信息
|
||
$config = $this->publishingConfig($type);
|
||
[$params, $textParams, $extra] = $this->publishingParams($type, $id,$app_version);
|
||
// 发起请求
|
||
$result = (new MinCode($this->site_id))->requestApi($config['api'], $params, $textParams);
|
||
$result = $result[$config['result_key']] ?? ['code' => 0];
|
||
if ($result['code'] == 10000) {
|
||
$res = $this->resultProcessing($type, $id, $result, $extra);
|
||
if ($res) return success(0, $res);
|
||
else return $this->success();
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
} catch (\Exception $e) {
|
||
return $this->error('', $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Common: 发布流程处理 —— 根据操作类型获取配置信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 10:09
|
||
* @param $type
|
||
* @return string[]
|
||
* @throws Exception
|
||
*/
|
||
private function publishingConfig($type): array
|
||
{
|
||
$list = [
|
||
'delete' => [
|
||
'api' => 'alipay.open.mini.version.delete', // 请求接口
|
||
'result_key' => 'alipay_open_mini_version_delete_response',// 返回结果字段名称
|
||
],
|
||
'release_experience_version' => [
|
||
'api' => 'alipay.open.mini.experience.create',
|
||
'result_key' => 'alipay_open_mini_experience_create_response',
|
||
],
|
||
'cancel_experience_version' => [
|
||
'api' => 'alipay.open.mini.experience.cancel',
|
||
'result_key' => 'alipay_open_mini_experience_cancel_response',
|
||
],
|
||
'see_experience_version' => [
|
||
'api' => 'alipay.open.mini.experience.query',
|
||
'result_key' => 'alipay_open_mini_experience_query_response',
|
||
],
|
||
'audit_submit' => [
|
||
'api' => 'alipay.open.mini.version.audit.apply',
|
||
'result_key' => 'alipay_open_mini_version_audit_apply_response',
|
||
],
|
||
'audit_cancel' => [
|
||
'api' => 'alipay.open.mini.version.audit.cancel',
|
||
'result_key' => 'alipay_open_mini_version_audit_cancel_response',
|
||
],
|
||
'audited_cancel' => [
|
||
'api' => 'alipay.open.mini.version.audited.cancel',
|
||
'result_key' => 'alipay_open_mini_version_audited_cancel_response',
|
||
],
|
||
'version_online' => [
|
||
'api' => 'alipay.open.mini.version.online',
|
||
'result_key' => 'alipay_open_mini_version_online_response',
|
||
],
|
||
'version_gray_online' => [
|
||
'api' => 'alipay.open.mini.version.gray.online',
|
||
'result_key' => 'alipay_open_mini_version_gray_online_response',
|
||
],
|
||
'version_gray_cancel' => [
|
||
'api' => 'alipay.open.mini.version.gray.cancel',
|
||
'result_key' => 'alipay_open_mini_version_gray_cancel_response',
|
||
],
|
||
'version_offline' => [
|
||
'api' => 'alipay.open.mini.version.offline',
|
||
'result_key' => 'alipay_open_mini_version_offline_response',
|
||
],
|
||
'version_rollback' => [
|
||
'api' => 'alipay.open.mini.version.rollback',
|
||
'result_key' => 'alipay_open_mini_version_rollback_response',
|
||
],
|
||
'version_upload' => [
|
||
'api' => 'alipay.open.mini.version.upload',
|
||
'result_key' => 'alipay_open_mini_version_upload_response',
|
||
],
|
||
];
|
||
if ($list[$type]) return $list[$type];
|
||
else throw new Exception('无效的操作!');
|
||
}
|
||
|
||
/**
|
||
* Common: 发布流程处理 —— 根据操作类型生成接口请求参数
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 10:32
|
||
* @param $type
|
||
* @param $id
|
||
* @param $app_version
|
||
* @return array[]
|
||
* @throws Exception
|
||
*/
|
||
private function publishingParams($type, $id,$app_version='')
|
||
{
|
||
$params = $textParams = $extra = [];
|
||
// 根据类型进行对应的操作
|
||
switch ($type) {
|
||
case 'delete':
|
||
case 'release_experience_version':
|
||
case 'cancel_experience_version':
|
||
case 'see_experience_version':
|
||
case 'audit_cancel':
|
||
case 'audited_cancel':
|
||
case 'version_online':
|
||
case 'version_gray_cancel':
|
||
case 'version_offline':
|
||
case 'version_rollback':
|
||
$params = [
|
||
'app_version' => $this->getVersion($id),
|
||
'bundle_id' => $this->bundle_id,
|
||
];
|
||
break;
|
||
case 'audit_submit':
|
||
$version = $this->getVersion($id);
|
||
$textParams = [
|
||
'region_type' => 'CHINA',
|
||
'version_desc' => "发布{$version}版本",
|
||
'app_version' => $version, //商家自定义版本
|
||
'bundle_id' => $this->bundle_id,
|
||
'speed_up' => 'false',
|
||
'auto_online' => 'auto_online'
|
||
];
|
||
break;
|
||
case 'version_gray_online':
|
||
$params = [
|
||
'app_version' => $this->getVersion($id),
|
||
'gray_strategy' => 'p10',// 枚举支持:p10、p30、p50
|
||
'bundle_id' => $this->bundle_id,
|
||
];
|
||
break;
|
||
case 'version_upload':
|
||
// $res = event('getDivideAccounts', ['site_id' => $this->site_id], true);
|
||
// if ($res) {
|
||
// $micode = new MinCode($this->site_id);
|
||
// $request = $micode->requestApi('alipay.trade.royalty.relation.batchquery', ['out_request_no' => date('YmdHisw')])['alipay_trade_royalty_relation_batchquery_response'];
|
||
// if ($request['code'] != 10000) {
|
||
// throw new Exception('分账状态异常:' . $request['sub_msg']);
|
||
// }
|
||
// }
|
||
if($app_version){
|
||
$this->version=$app_version;
|
||
}
|
||
// 获取最新版本
|
||
$isNewestVersion = (new AliPayApplet($this->site_id))->isNewestVersion($app_version);
|
||
if (!$isNewestVersion) throw new Exception('当前版本为最新版本,请勿重复发布!');
|
||
// 获取默认门店id
|
||
$storeInfo = Db::name('store')
|
||
->where('site_id', $this->site_id)
|
||
->where('is_default', 1)
|
||
->field('store_id,store_id,store_name')
|
||
->find();
|
||
if (empty($storeInfo)) throw new Exception('默认门店不存在,请添加后进行操作!');
|
||
// 判断:是否存在小程序配置信息
|
||
$hasAccount = Db::name('uni_account')->where(['site_id' => $this->site_id, 'app_type' => 'aliapp'])->value('appid');
|
||
if ($hasAccount <= 0) throw new Exception('请先配置小程序!');
|
||
$extra = ['appid' => $hasAccount];
|
||
$ext = [
|
||
'extEnable' => true,
|
||
'ext' => [
|
||
'site_id' => $this->site_id,
|
||
'store_id' => $storeInfo['store_id'],
|
||
],
|
||
'window' => [
|
||
'defaultTitle' => $storeInfo['store_name']
|
||
],
|
||
];
|
||
$params = [
|
||
'template_version' => $this->templateInfo['template_version'],// 小程序模板版本号
|
||
'ext' => json_encode($ext),//自定义参数
|
||
'template_id' => $this->templateInfo['template_id'],// 小程序模板 APPID
|
||
'app_version' => $this->version,//商家小程序版本号
|
||
'bundle_id' => $this->bundle_id,
|
||
];
|
||
break;
|
||
default:
|
||
throw new Exception('无效的操作!');
|
||
}
|
||
return [$params, $textParams, $extra];
|
||
}
|
||
|
||
/**
|
||
* Common: 发布流程处理 —— 根据id获取版本信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 10:18
|
||
* @param $id
|
||
* @return mixed
|
||
* @throws Exception
|
||
*/
|
||
private function getVersion($id)
|
||
{
|
||
$version = Db::name('applet_release')->where('id', $id)->value('version');
|
||
if (!$version) throw new Exception('版本不存在!');
|
||
return $version;
|
||
}
|
||
|
||
/**
|
||
* Common: 发布流程处理 —— 请求结果处理
|
||
* Author: wu-hui
|
||
* Time: 2023/01/04 10:46
|
||
* @param $type
|
||
* @param $id
|
||
* @param $result
|
||
* @return string
|
||
* @throws \think\db\exception\DbException
|
||
*/
|
||
private function resultProcessing($type, $id, $result, $extra = [])
|
||
{
|
||
$returnData = '';
|
||
switch ($type) {
|
||
case 'delete':
|
||
Db::name('applet_release')->where('id', $id)->delete();
|
||
break; // 删除版本
|
||
case 'release_experience_version':
|
||
$this->appletReleaseSelectCollection(1)->update(['is_experience_version' => 0]);
|
||
Db::name('applet_release')->where('id', $id)->update(['is_experience_version' => 1]);
|
||
break;// 发布体验版本
|
||
case 'cancel_experience_version':
|
||
Db::name('applet_release')->where('id', $id)->update(['is_experience_version' => 0]);
|
||
break;// 取消体验版发布
|
||
case 'see_experience_version':
|
||
$statusText = [
|
||
'expVersionPackged' => '体验版打包成功',
|
||
'expVersionPackaging' => '体验版打包中',
|
||
'notExpVersion' => '非体验版',
|
||
];
|
||
$returnData = $statusText[$result['status']];
|
||
break;// 体验版状态查看
|
||
case 'audit_submit':
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => 'AUDITING']);
|
||
break;// 提交审核
|
||
case 'audit_cancel':
|
||
case 'audited_cancel':
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => 'INIT']);
|
||
break;// 撤销审核 & 退回开发
|
||
case 'version_online':
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => 'RELEASE']);
|
||
break;//上架
|
||
case 'version_gray_online':
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => 'GRAY']);
|
||
break;//灰度上架
|
||
case 'version_gray_cancel':
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => 'WAIT_RELEASE']);
|
||
break;//结束灰度
|
||
case 'version_offline':
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => 'OFFLINE']);
|
||
break;// 下架
|
||
case 'version_rollback':
|
||
$this->versionSee($id);
|
||
break;// 回滚
|
||
case 'version_upload':
|
||
$version = config('alipay.templateInfo.template_version');
|
||
$data = [
|
||
'site_id' => $this->site_id,
|
||
'appid' => $extra['appid'],
|
||
'version' => $version,
|
||
'type' => 1,
|
||
'ali_create_status' => $result['create_status'],
|
||
'version_status' => 'INIT',
|
||
'create_time' => time(),
|
||
];
|
||
Db::name('applet_release')->insert($data);
|
||
break;// 发布新版本
|
||
}
|
||
return $returnData;
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 版本管理 —— 所有版本同步
|
||
* Author: wu-hui
|
||
* Time: 2022/12/30 9:58
|
||
* @return array
|
||
* @throws \Exception
|
||
*/
|
||
public function versionSynchronization()
|
||
{
|
||
$params = [
|
||
'bundle_id' => $this->bundle_id,
|
||
// 版本状态:INIT=开发中,AUDITING=审核中,AUDIT_REJECT=审核驳回,WAIT_RELEASE=待上架,BASE_AUDIT_PASS=准入不可营销,GRAY=灰度中,RELEASE=已上架,OFFLINE=已下架,AUDIT_OFFLINE: 已下架
|
||
'version_status' => 'INIT,AUDITING,AUDIT_REJECT,WAIT_RELEASE,BASE_AUDIT_PASS,GRAY,RELEASE,OFFLINE,AUDIT_OFFLINE',
|
||
];
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.open.mini.version.list.query', $params);
|
||
$result = $result['alipay_open_mini_version_list_query_response'];
|
||
if ($result['code'] == 10000) {
|
||
// 同步版本信息
|
||
$appVersionInfos = $result['app_version_infos'] ?? [];
|
||
$hasList = $this->appletReleaseSelectCollection(1)->column('version', 'id');
|
||
$hasListIds = array_flip($hasList);
|
||
$insertData = [];
|
||
$updateData = [];
|
||
foreach ($appVersionInfos as $val) {
|
||
if (!in_array($val['app_version'], $hasList)) {
|
||
$insertData[] = [
|
||
'site_id' => $this->site_id,
|
||
'version' => $val['app_version'],
|
||
'type' => 1,
|
||
'ali_create_status' => 0,
|
||
'version_status' => $val['version_status'],
|
||
'create_time' => strtotime($val['create_time']),
|
||
];
|
||
} else {
|
||
$updateData[] = [
|
||
'id' => $hasListIds[$val['app_version']],
|
||
'version_status' => $val['version_status'],
|
||
];
|
||
}
|
||
}
|
||
Db::name('applet_release')->insertAll($insertData);
|
||
(new NewBaseModel(['table_name' => 'applet_release']))->saveAll($updateData);
|
||
|
||
return $this->success();
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Common: 版本管理 —— 查询小程序版本构建状态
|
||
* Author: wu-hui
|
||
* Time: 2022/12/29 17:45
|
||
* @param $version
|
||
* @param $id
|
||
* @return array|mixed
|
||
* @throws \think\db\exception\DbException
|
||
*/
|
||
public function versionBuildQuery($version, $id)
|
||
{
|
||
$params = [
|
||
'app_version' => $version,
|
||
'bundle_id' => $this->bundle_id,
|
||
];
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.open.mini.version.build.query', $params);
|
||
$result = $result['alipay_open_mini_version_build_query_response'];
|
||
|
||
if ($result['code'] == 10000) {
|
||
Db::name('applet_release')->where('id', $id)->update(['ali_create_status' => $result['create_status']]);
|
||
|
||
return $result['create_status'];
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Common: 版本管理 —— 版本详情查询
|
||
* Author: wu-hui
|
||
* Time: 2022/12/30 16:54
|
||
* @param $id
|
||
* @return array
|
||
* @throws \think\db\exception\DbException
|
||
*/
|
||
public function versionSee($id)
|
||
{
|
||
$version = Db::name('applet_release')->where('id', $id)->value('version');
|
||
if (!$version) $this->error('', '版本不存在!');
|
||
$params = [
|
||
'app_version' => $version,
|
||
'bundle_id' => $this->bundle_id,
|
||
];
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.open.mini.version.detail.query', $params);
|
||
$result = $result['alipay_open_mini_version_detail_query_response'];
|
||
if ($result['code'] == 10000) {
|
||
Db::name('applet_release')->where('id', $id)->update(['version_status' => $result['status']]);
|
||
|
||
return success(0, '版本详情', $result);
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Common: 生成小程序推广二维码
|
||
* Author: wu-hui
|
||
* Time: 2023/01/03 14:12
|
||
* @return array
|
||
*/
|
||
public function qrcodeCreate()
|
||
{
|
||
$cacheName = 'alipay_open_app_qrcode_create_response_' . $this->site_id;
|
||
// 缓存操作
|
||
$result = cache($cacheName);
|
||
if ($result) {
|
||
return $this->success($result);
|
||
} else {
|
||
// 获取默认门店id
|
||
$storeId = (int)Db::name('store')
|
||
->where('site_id', $this->site_id)
|
||
->where('is_default', 1)
|
||
->value('store_id');
|
||
if ($storeId <= 0) $this->error('', '默认门店不存在,请添加后进行操作!');
|
||
$params = [
|
||
'url_param' => 'pages/index/index',// 访问页面路径
|
||
'query_param' => 'site_id=' . $this->site_id . '&store_id=' . $storeId,// 小程序的启动参数
|
||
'describe' => '小程序预览',//对应的二维码描述
|
||
'color' => '',
|
||
'size' => 'l',// 合成后图片的大小(s -- 8cm, m -- 12cm, l -- 30cm)
|
||
];
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.open.app.qrcode.create', $params);
|
||
$result = $result['alipay_open_app_qrcode_create_response'];
|
||
// 返回结果
|
||
if ($result['code'] == 10000) {
|
||
cache($cacheName, $result);
|
||
return $this->success($result);
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
}
|
||
|
||
public function queryTestQrcode($version)
|
||
{
|
||
|
||
$params['app_version'] = $this->version;//$version;
|
||
// (new MinCode($this->site_id))->requestApi('alipay.open.mini.experience.create', $params);
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.open.mini.experience.query', $params);
|
||
$result = $result['alipay_open_mini_experience_query_response'];
|
||
// 返回结果
|
||
if ($result['code'] == 10000) {
|
||
return $this->success($result);
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Common: 登录 —— 获取用户基本信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/05 13:33
|
||
* @param string $code
|
||
* @param string $grantType
|
||
* @param string $refreshToken
|
||
* @return array
|
||
*/
|
||
public function loginBaseInfo($code = '', $grantType = 'authorization_code', $refreshToken = '')
|
||
{
|
||
// authorization_code=换取授权令牌access_token;refresh_token=刷新获取新授权令牌。
|
||
$textParams = [
|
||
'grant_type' => $grantType
|
||
];
|
||
if ($grantType == 'refresh_token') $textParams['refresh_token'] = $refreshToken;
|
||
else if ($grantType == 'authorization_code') $textParams['code'] = $code;
|
||
// 发起请求
|
||
$result = (new MinCode($this->site_id))->requestApi('alipay.system.oauth.token', [], $textParams);
|
||
$result = $result['alipay_system_oauth_token_response'] ?? $result['error_response'];
|
||
// 返回结果
|
||
if (array_key_exists('user_id', $result)||array_key_exists('open_id',$result)) {
|
||
if(isset($result['open_id'])){
|
||
$result['user_id']=$result['open_id'];
|
||
}
|
||
return $this->success($result);
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Common: 登录 —— 获取用户详细信息
|
||
* Author: wu-hui
|
||
* Time: 2023/01/05 14:04
|
||
* @param $authToken
|
||
* @return array
|
||
*/
|
||
public function loginDetailsInfo($authToken)
|
||
{
|
||
// 发起请求
|
||
$result = (new MinCode($this->site_id))->requestMemberApi($authToken, 'alipay.user.info.share');
|
||
$result = $result['alipay_user_info_share_response'] ?? $result['error_response'];
|
||
// 返回结果
|
||
if ($result['code'] == 10000) {
|
||
|
||
return $this->success($result);
|
||
} else {
|
||
return $this->error('', $result['sub_msg']);
|
||
}
|
||
}
|
||
} |