Files
littleTiger/application/common/logic/saas/MiniappLogic.php

527 lines
20 KiB
PHP
Raw Permalink Normal View History

2019-02-28 19:48:21 +08:00
<?php
/**
* tpshop
* ============================================================================
* * 版权所有 2015-2027 深圳搜豹网络科技有限公司,并保留所有权利。
* 网站地址: http://www.tp-shop.cn
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用 .
* 不允许对程序代码以任何形式任何目的的再发布。
* 采用TP5助手函数可实现单字母函数M D U等,也可db::name方式,可双向兼容
* ============================================================================
* @Author: lhb
*/
namespace app\common\logic\saas;
use app\common\model\saas\AppService;
use app\common\model\saas\Miniapp;
use app\common\model\saas\UserMiniapp;
use think\Validate;
use app\common\model\saas\Users;
use app\common\model\saas\ExtendService;
use app\common\model\saas\MiniappTemplate;
use app\common\logic\saas\wechat\MiniApp3rd;
/**
* 微信小程序逻辑处理
*/
class MiniappLogic
{
/**
* 绑定/解绑体验者
* @param string $wechatId 用户微信号
* @param string $operate 操作码 'unbind''bind'
*/
public function bindTester($miniappId, $userId, $wechatId, $operate)
{
if (!$miniapp = Miniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1])) {
return ['status' => -1, 'msg' => '小程序不存在'];
}
$miniApp3rd = new MiniApp3rd($miniapp);
if ($operate == 'unbind') {
$return = $miniApp3rd->unbindTester($wechatId);
} else {
$return = $miniApp3rd->bindTester($wechatId);
}
if ($return === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$testers = $miniapp->testers;
if ($operate == 'unbind') {
foreach ($testers as $k => $tester) {
if ($wechatId == $tester) {
unset($testers[$k]);
break;
}
}
} else {
if (!in_array($wechatId, $testers)) {
$testers[] = $wechatId;
}
}
$miniapp->save(['testers' => $testers]);
return ['status' => 1, 'msg' => ($operate == 'unbind' ? '解绑成功' : '绑定成功')];
}
/**
* 设置服务器域名
*/
public function setServerDomains($miniappId, $userId, $domains)
{
if (!$miniapp = Miniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1])) {
return ['status' => -1, 'msg' => '小程序不存在'];
}
//$domains['requestdomain'];
//$domains['wsrequestdomain'];
//$domains['uploaddomain'];
//$domains['downloaddomain'];
foreach ($domains as &$domain) {
$domain = explode(',', $domain);
foreach ($domain as $k => $url) {
$domain[$k] = urldecode($url);
}
}
$miniApp3rd = new MiniApp3rd($miniapp);
$return = $miniApp3rd->modifyDomain('set', $domains);
if ($return === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$domains = $miniApp3rd->getDomain();
if ($domains === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$msg = '';
$return = $miniApp3rd->setWebViewDomain();
if ($return === false) {
if ($miniApp3rd->getErrCode() == 89231) {
$msg = '这是个人小程序web-view部分功能没法使用';
} else {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
}
Miniapp::update(['domains' => $domains], ['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1]);
return ['status' => 1, 'msg' => '设置成功'.$msg];
}
/**
* 重置域名
*/
public function resetServerDomains($miniappId, $userId)
{
$appService = AppService::get(['miniapp_id' => $miniappId], 'app');
if (!$appService || $appService->install_status != AppService::INSTALL_DONE) {
return ['status' => -1, 'msg' => '请先关联应用或购买应用服务或安装应用'];
}
$url = $appService->app->miniapp_domain;
$domains['requestdomain'] = 'https://'.$url;
$domains['wsrequestdomain'] = 'wss://'.$url;
$domains['uploaddomain'] = 'https://'.$url;
$domains['downloaddomain'] = 'https://'.$url;
return $this->setServerDomains($miniappId, $userId, $domains);
}
private function validateCommitMiniappData($data, $miniapp)
{
$validate = new Validate([
'store_name' => 'require|min:1',
]);
if (!$validate->check($data)) {
return ['status' => -1, 'msg' => $validate->getError()];
}
$domains = $miniapp->domains;
if (!$domains || !$domains['requestdomain'] || !$domains['wsrequestdomain'] || !$domains['uploaddomain'] || !$domains['downloaddomain']) {
return ['status' => -1, 'msg' => '域名信息不全,请先设置服务器域名'];
} elseif (!in_array($data['request_url'], $domains['requestdomain']) || !in_array($data['request_url'], $domains['uploaddomain'])) {
//目前只用了requestdomain和uploaddomain
return ['status' => -1, 'msg' => '所填域名不在服务器域名配置中'];
}
return ['status' => 1, 'msg' => '验证成功'];
}
/**
* 提交小程序,使小程序进入体验版
* @param $miniappId
* @param $data array 提交的数据
* @return array
*/
public function commitMiniapp($miniappId, $userId, $data)
{
if (!$miniapp = Miniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1], 'appService')) {
return ['status' => -1, 'msg' => '小程序不存在'];
}
if (!$miniapp->app_service || $miniapp->app_service->install_status != AppService::INSTALL_DONE) {
return ['status' => -1, 'msg' => '请先安装应用'];
}
$orgRequestUrl = $miniapp->app_service->app->miniapp_domain;
$data['request_url'] = 'https://'.$orgRequestUrl;
$data['store_name'] = tpCache("shop_info.store_name");
$data['store_logo'] = tpCache("shop_info.store_logo");
$data['version'] = 'v3.0.0';
$data['description'] = 'app_service_id:'.$miniapp->app_service->service_id;
$return = $this->validateCommitMiniappData($data, $miniapp);
if ($return['status'] != 1) {
return $return;
}
$template = MiniappTemplate::get(['is_on_sale' => 1, 'app_id' => $miniapp->app_service->app_id]);
if (! $template) {
return ['status' => -1, 'msg' => '所选模板不存在或已下线'];
}
$extCfg = json_encode([
'extAppid' => $miniapp->appid,
'ext' => [
'store_name' => $data['store_name'],
'store_logo' => $data['store_logo'],
'request_url' => $data['request_url'],
'default_url' => $miniapp->app_service->app->miniapp_domain,
'is_refactor' => $miniapp->app_service->app->miniapp_domain == $orgRequestUrl,
'saas_app' => $miniapp->app_service->domain
],
], JSON_UNESCAPED_UNICODE);
$miniApp3rd = new MiniApp3rd($miniapp);
$return = $miniApp3rd->commit($template['miniapp_tpl_id'], $extCfg, $data['version'], $data['description']);
if ($return === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$data['name'] = $template->name;
$data['template_version'] = $template->template_version;
$data['user_id'] = $miniapp->user_id;
$data['miniapp_id'] = $miniapp->miniapp_id;
$data['ext_config'] = $extCfg;
$data['add_time'] = time();
$data['status'] = UserMiniapp::STATUS_TEST;
//只能有一个体验版
$userMiniapp = UserMiniapp::get(['user_id' => $userId, 'miniapp_id' => $miniapp->miniapp_id, 'status' => UserMiniapp::STATUS_TEST]);
if ($userMiniapp) {
$userMiniapp->save($data);
} else {
UserMiniapp::create($data);
}
return ['status' => 1, 'msg' => '提交成功'];
}
/**
* 检查提交审核的表单
*/
private function checkAuditForm($miniapp, $data)
{
/* 检查题目合法性 */
if (!$data['title'] || count($data['title']) > 32) {
return ['status' => -1, 'msg' => '标题长度取值范围为 1~32'];
}
/* 检查tag合法性 */
if ($data['tag']) {
$tags = explode(' ', $data['tag']);
if (count($tags) > 10) {
return ['status' => -1, 'msg' => '标签不能多于10个'];
}
foreach ($tags as $tag) {
if (count($tag) > 20) {
return ['status' => -1, 'msg' => '标签长度不超过20'];
}
}
}
/* 检查服务类目合法性 */
$miniApp3rd = new MiniApp3rd($miniapp);
$categories = $miniapp->categories ?: [];
if (!$categories) {
$categories = $miniApp3rd->getCategory();
if ($categories === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
if (!$categories) {
return ['status' => -1, 'msg' => '服务类目为空'];
}
Miniapp::update(['categories' => $categories], ['miniapp_id' => $miniapp->miniapp_id]);
}
$category = [];
$isFindCategory = false;
foreach ($categories as $category) {
$category['second_id'] = isset($category['second_id']) ? $category['second_id'] : '';
$category['third_id'] = isset($category['third_id']) ? $category['third_id'] : '';
if ($category['first_id'] == $data['first_id']
&& $category['second_id'] == $data['second_id']
&& $category['third_id'] == $data['third_id']) {
$isFindCategory = true;
break;
}
}
if (!$isFindCategory) {
return ['status' => -1, 'msg' => '服务类目不在已设置的范围内'];
}
/* 提交审核的参数 */
$data['first_class'] = $category['first_class'];
$data['second_class'] = isset($category['second_class']) ? $category['second_class'] : '';
$data['third_class'] = isset($category['third_class']) ? $category['third_class'] : '';
$data['address'] = 'pages/index/index/index'; //目前只固定为首页,还没做定制,可从getPage获取
$data = array_allow_keys($data, ['address', 'tag', 'first_class', 'second_class', 'third_class', 'first_id', 'second_id', 'third_id', 'title']);
return ['status' => 1, 'msg' => '检查成功', 'result' => $data];
}
/**
* 提交审核
* @param $miniappId int 小程序id
* @param $data array 提交的数据title,tag,first_id,second_id,third_id
* @return array
*/
public function submitAudit($miniappId, $userId, $data)
{
/* 检查小程序数据是否完整 */
if (!$miniapp = Miniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1])) {
return ['status' => -1, 'msg' => '小程序不存在'];
}
if (!$miniappTest = UserMiniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'status' => UserMiniapp::STATUS_TEST])) {
return ['status' => -1, 'msg' => '该体验版本不存在,不能提交审核'];
}
/**
$miniappService = ExtendService::get(['user_id' => $userId, 'extend_id' => $miniappTest->template_id, 'extend_type' => EXTEND_MINIAPP]);
if (!$miniappService) {
return ['status' => -1, 'msg' => '该小程序模板尚未购买'];
} elseif ($miniappService->status != ExtendService::STATUS_NORMAL) {
return ['status' => -1, 'msg' => '该小程序模板已过期'];
}
**/
/* 检查是否有已经提交的审核 */
$miniappAudit = UserMiniapp::get(['miniapp_id' => $miniapp->miniapp_id, 'status' => ['in', [UserMiniapp::STATUS_AUDITING, UserMiniapp::STATUS_AUDIT_DONG]]]);
if ($miniappAudit) {
return ['status' => -1, 'msg' => '已有在审核中的版本或审核通过尚未发布的版本'];
}
/* 检查提交审核的参数 */
$return = $this->checkAuditForm($miniapp, $data);
if ($return['status'] != 1) {
return $return;
}
/* 提交审核 */
$itemList[] = $return['result']; //目前只能设置一个页面的配置
$miniApp3rd = new MiniApp3rd($miniapp);
$auditId = $miniApp3rd->submitAudit($itemList);
if ($auditId === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$miniappTest->save([
'audit_id' => $auditId,
'status' => UserMiniapp::STATUS_AUDITING,
'audit_time' => time(),
]);
return ['status' => 1, 'msg' => '提交审核成功'];
}
/**
* 发布小程序
*/
public function releaseMiniapp($miniappId, $userId)
{
if (!$miniapp = Miniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1])) {
return ['status' => -1, 'msg' => '小程序不存在'];
}
$miniApp3rd = new MiniApp3rd($miniapp);
if ($miniApp3rd->release() === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
//同步一下可访问状态,不处理错误
$miniApp3rd->changeVisitStatus($miniapp->is_show_release);
//以前上线的已无效
UserMiniapp::update(['status' => UserMiniapp::STATUS_INVALID], [
'miniapp_id' => $miniapp->miniapp_id,
'status' => UserMiniapp::STATUS_ON_RELEASE
]);
//审核通过的改为已上线
UserMiniapp::update(['status' => UserMiniapp::STATUS_ON_RELEASE, 'release_time' => time()], [
'miniapp_id' => $miniapp->miniapp_id,
'status' => UserMiniapp::STATUS_AUDIT_DONG
]);
return ['status' => 1, 'msg' => '发布成功'];
}
/**
* 设置可见(可访问)状态
* @param $status int|boolean 设置访问状态
* @return array
*/
public function setVisitStatus($miniappId, $userId, $status)
{
$miniapp = Miniapp::get(['user_id' => $userId, 'miniapp_id' => $miniappId, 'is_auth' => 1]);
if (!$miniapp) {
return ['status' => -1, 'msg' => '小程序尚未授权'];
}
$status = $status ? 1 : 0;
$miniApp3rd = new MiniApp3rd($miniapp);
if ($miniApp3rd->changeVisitStatus($status) === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$miniapp->save(['is_show_release' => $status]);
return ['status' => 1, 'msg' => '设置成功'];
}
/**
* 获取各版本的信息
* @param $miniapp
* @return array
*/
public function getVersionsInfo($miniapp)
{
// 体验版本
$test = UserMiniapp::where(['miniapp_id' => $miniapp->miniapp_id, 'status' => UserMiniapp::STATUS_TEST])->order('add_time desc')->find();
// 审核版本
$auditStatus = [UserMiniapp::STATUS_AUDITING, UserMiniapp::STATUS_AUDIT_DONG, UserMiniapp::STATUS_AUDIT_FAIL];
$audit = UserMiniapp::where(['miniapp_id' => $miniapp->miniapp_id, 'status' => ['in', $auditStatus]])->order('audit_time desc')->find();
if ($audit && $audit->status == UserMiniapp::STATUS_AUDITING) { //正在审核
$miniApp3rd = new MiniApp3rd($miniapp);
$result = $miniApp3rd->getAuditStatus($audit->audit_id);
if ($result === false) {
return ['status' => -1, 'msg' => $miniApp3rd->getError()];
}
$statusMap = [0 => UserMiniapp::STATUS_AUDIT_DONG, 1 => UserMiniapp::STATUS_AUDIT_FAIL, 2 => UserMiniapp::STATUS_AUDITING];
$returnStatus = $statusMap[$result['status']];
if ($returnStatus != 1) {
$audit->status = $returnStatus;
$audit->audit_fail_reason = $result['reason'];
$audit->save();
}
}
// 发布版本
$release = UserMiniapp::where(['miniapp_id' => $miniapp->miniapp_id, 'status' => UserMiniapp::STATUS_ON_RELEASE])->order('release_time desc')->find();
return ['status' => 1, 'msg' => '获取成功', 'result' => [
'test' => $test,
'audit' => $audit,
'release' => $release
]];
}
private function checkTemplateForm($data)
{
$validate = new Validate([
['price','require|number','价格必填|价格格式不正确'],
['miniapp_tpl_id', 'require|number','模板id必须|模板id必须为数字'],
['name', 'require|min:1', '模板名称必须|模板名称非空'],
['template_version', 'require|min:1', '模板名称必须|模板名称非空'],
['app_id', 'require|>:0','app_id必须|app_id不能为空'],
]);
if (!$validate->check($data)) {
return ['status' => -1, 'msg' => $validate->getError()];
}
return ['status' => 1, 'msg' => '验证成功'];
}
/**
* 添加模板
*/
public function addTemplate($data)
{
$return = $this->checkTemplateForm($data);
if ($return['status'] != 1) {
return $return;
}
if ($template = MiniappTemplate::get($data['miniapp_tpl_id'])) {
return ['status' => -1, 'msg' => '小程序模板id已存在'];
}
$template = MiniappTemplate::create($data);
return ['status' => 1, 'msg' => '添加成功', 'result' => $template->template_id];
}
/**
* 编辑模板
*/
public function editTemplate($data)
{
$return = $this->checkTemplateForm($data);
if ($return['status'] != 1) {
return $return;
}
if (!$template = MiniappTemplate::get(['template_id' => $data['template_id']])) {
return ['status' => -1, 'msg' => '模板不存在'];
}
if (MiniappTemplate::get(['template_id' => ['<>', $data['template_id']], 'miniapp_tpl_id' => $data['miniapp_tpl_id']])) {
return ['status' => -1, 'msg' => '小程序模板id已存在'];
}
$template->save($data);
return ['status' => 1, 'msg' => '编辑成功', 'result' => $template->template_id];
}
/**
* 删除模板
*/
public function deleteTemplate($templateId)
{
if (!$template = MiniappTemplate::get(['template_id' => $templateId])) {
return ['status' => -1, 'msg' => '模板不存在'];
}
if (ExtendService::get(['extend_id' => $template->template_id, 'extend_type' => EXTEND_MINIAPP, 'status' => ExtendService::STATUS_NORMAL])) {
return ['status' => -1, 'msg' => '该模板已有用户在使用'];
}
$template->delete();
return ['status' => 1, 'msg' => '删除成功'];
}
/**
* 更新小程序信息
*/
public function updateMiniapp($userId, $miniappId)
{
if (!$miniapp = Miniapp::get(['miniapp_id' => $miniappId, 'user_id' => $userId])) {
return ['status' => -1, 'msg' => '小程序不存在'];
}
$logic = new Wx3rdLogic;
$return = $logic->getAuthUserInfo($miniapp->appid);
if ($return['status'] != 1) {
return $return;
}
$miniapp->save($return['result']);
if ($user = Users::get(['user_id' => $miniapp->user_id])) {
if (!$user->head_img && $miniapp->head_img) {
$user->save(['head_img' => $miniapp->head_img]); //更新头像
}
}
return ['status' => 1, 'msg' => '更新成功'];
}
}