CRMEB_PRO_M/app/controller/admin/v1/wechat/RoutineTemplate.php

432 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\admin\v1\wechat;
use app\controller\admin\AuthController;
use app\jobs\notice\template\RoutineTemplateJob;
use app\services\message\SystemNotificationServices;
use app\services\message\TemplateMessageServices;
use app\services\other\QrcodeServices;
use app\services\system\attachment\SystemAttachmentServices;
use crmeb\exceptions\AdminException;
use crmeb\services\{FileService, FormBuilder as Form, template\Template, UploadService, wechat\MiniProgram};
use crmeb\services\CacheService;
use think\exception\ValidateException;
use think\facade\App;
use think\facade\Route as Url;
use think\Request;
use function Swoole\Coroutine\batch;
/**
* Class RoutineTemplate
* @package app\controller\admin\v1\application\routine
*/
class RoutineTemplate extends AuthController
{
protected $cacheTag = 'system_routine';
/**
* 构造方法
* WechatTemplate constructor.
* @param App $app
* @param TemplateMessageServices $services
*/
public function __construct(App $app, TemplateMessageServices $services)
{
parent::__construct($app);
$this->services = $services;
}
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index()
{
$where = $this->request->getMore([
['name', ''],
['status', '']
]);
$where['type'] = 0;
$data = $this->services->getTemplateList($where);
$industry = CacheService::get($this->cacheTag . '_wechat_industry', function () {
try {
$cache = (new Template('wechat'))->getIndustry();
if (!$cache) return [];
return $cache->toArray();
} catch (\Exception $e) {
return $e->getMessage();
}
}, 0) ?: [];
!is_array($industry) && $industry = [];
$industry['primary_industry'] = isset($industry['primary_industry']) ? $industry['primary_industry']['first_class'] . ' | ' . $industry['primary_industry']['second_class'] : '未选择';
$industry['secondary_industry'] = isset($industry['secondary_industry']) ? $industry['secondary_industry']['first_class'] . ' | ' . $industry['secondary_industry']['second_class'] : '未选择';
$lst = [
'industry' => $industry,
'count' => $data['count'],
'list' => $data['list']
];
return $this->success($lst);
}
/**
* 显示创建资源表单页.
*
* @return \think\Response
*/
public function create()
{
$f = array();
$f[] = Form::input('tempkey', '模板编号');
$f[] = Form::input('tempid', '模板ID');
$f[] = Form::input('name', '模板名');
$f[] = Form::input('content', '回复内容')->type('textarea');
$f[] = Form::radio('status', '状态', 1)->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]);
return $this->makePostForm('添加模板消息', $f, Url::buildUrl('/app/routine'), 'POST');
}
/**
* 保存新建的资源
*
* @param \think\Request $request
* @return \think\Response
*/
public function save(Request $request)
{
$data = $this->request->postMore([
'tempkey',
'tempid',
'name',
'content',
['status', 0]
]);
if ($data['tempkey'] == '') return $this->fail('请输入模板编号');
if ($data['tempkey'] != '' && $this->services->getOne(['tempkey' => $data['tempkey']]))
return $this->fail('请输入模板编号已存在,请重新输入');
if ($data['tempid'] == '') return $this->fail('请输入模板ID');
if ($data['name'] == '') return $this->fail('请输入模板名');
if ($data['content'] == '') return $this->fail('请输入回复内容');
$data['add_time'] = time();
$this->services->save($data);
return $this->success('添加模板消息成功!');
}
/**
* 显示指定的资源
*
* @param int $id
* @return \think\Response
*/
public function read($id)
{
//
}
/**
* 显示编辑资源表单页.
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
if (!$id) return $this->fail('数据不存在');
$product = $this->services->get($id);
if (!$product) return $this->fail('数据不存在!');
$f = array();
$f[] = Form::input('tempkey', '模板编号', $product->getData('tempkey'))->disabled(1);
$f[] = Form::input('name', '模板名', $product->getData('name'))->disabled(1);
$f[] = Form::input('tempid', '模板ID', $product->getData('tempid'));
$f[] = Form::radio('status', '状态', $product->getData('status'))->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]);
return $this->makePostForm('编辑模板消息', $f, Url::buildUrl('/app/routine/' . $id), 'PUT');
}
/**
* 保存更新的资源
*
* @param \think\Request $request
* @param int $id
* @return \think\Response
*/
public function update(Request $request, $id)
{
$data = $this->request->postMore([
'tempid',
['status', 0]
]);
if ($data['tempid'] == '') return $this->fail('请输入模板ID');
if (!$id) return $this->fail('数据不存在');
$product = $this->services->get($id);
if (!$product) return $this->fail('数据不存在!');
$this->services->update($id, $data, 'id');
return $this->success('修改成功!');
}
/**
* 删除指定资源
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{
if (!$id) return $this->fail('数据不存在!');
if (!$this->services->delete($id))
return $this->fail('删除失败,请稍候再试!');
else
return $this->success('删除成功!');
}
/**
* 修改状态
* @param $id
* @param $status
* @return mixed
*/
public function set_status($id, $status)
{
if ($status == '' || $id == 0) return $this->fail('参数错误');
$this->services->update($id, ['status' => $status], 'id');
return $this->success($status == 0 ? '关闭成功' : '开启成功');
}
/**
* 同步订阅消息
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function syncSubscribe()
{
if (!sys_config('routine_appId') || !sys_config('routine_appsecret')) {
throw new AdminException('请先配置小程序appid、appSecret等参数');
}
$all = $this->services->getTemplateList(['status' => 1, 'type' => 0]);
$errMessage = [
'-1' => '系统繁忙,此时请稍候再试',
'40001' => 'AppSecret错误或者AppSecret不属于这个小程序请确认AppSecret 的正确性',
'40002' => '请确保grant_type字段值为client_credential',
'40013' => '不合法的AppID请检查AppID的正确性避免异常字符注意大小写',
'40125' => '小程序配置无效,请检查配置',
'41002' => '缺少appid参数',
'41004' => '缺少secret参数',
'43104' => 'appid与openid不匹配',
'45009' => '达到微信api每日限额上限',
'200011' => '此账号已被封禁,无法操作',
'200012' => '个人模版数已达上限上限25个',
];
if ($all['list']) {
$i = 0;
foreach ($all['list'] as $template) {
if (!$template['tempkey']) {
continue;
}
if (!isset($template['kid'])) {
return $this->fail('数据库模版表(template_message)缺少字段kid');
}
if (isset($template['kid']) && $template['kid']) {
continue;
}
RoutineTemplateJob::dispatch([$template, $errMessage]);
$i++;
}
/** @var SystemNotificationServices $systemNotificationServices */
$systemNotificationServices = app()->make(SystemNotificationServices::class);
//清空模版缓存
$systemNotificationServices->clearTemplateCache();
}
return $this->success($i ? '队列执行中,请稍后查看,小程序需要选择:生活服务/百货/超市/便利店类目' : '已同步成功,请不要重复同步');
}
/**
* 下载小程序
* @return mixed
*/
public function downloadTemp()
{
[$name, $is_live] = $this->request->postMore([
['name', ''],
['is_live', 0]
], true);
if (!sys_config('routine_appId', '')) {
throw new AdminException('请先在设置->系统设置->应用设置,配置小程序相关信息');
}
if (!file_exists(public_path() . 'statics/mp_view') || count(scandir(public_path() . 'statics/mp_view')) == 2) {
throw new AdminException('请先上传小程序打包文件,路径:' . public_path() . 'statics/mp_view');
}
try {
@unlink(public_path() . 'statics/download/routine.zip');
//拷贝源文件
/** @var FileService $fileService */
$fileService = app(FileService::class);
$fileService->copyDir(public_path() . 'statics/mp_view', public_path() . 'statics/download');
$baseUrl = sys_config('site_url');
batch([
'appId' => function () use ($name) {
try {
$this->updateConfigJson(sys_config('routine_appId'), $name != '' ? $name : sys_config('routine_name'));
} catch (\Throwable $e) {
}
return true;
},
'updateApp' => function () use ($is_live) {
$res1 = true;
//是否开启直播
if ($is_live == 0) {
//pages.json 替换直播组件
try {
$this->updateAppJson();
} catch (\Throwable $e) {
}
}
return $res1;
},
'updateProductDetail' => function () use ($is_live) {
$res1 = true;
//是否开启直播
if ($is_live == 0) {
//商品详情页 替换直播组件
try {
$this->updateProductDetailJson();
} catch (\Throwable $e) {
}
}
return $res1;
},
'url' => function () use ($baseUrl) {
//替换url
try {
$this->updateUrl($baseUrl);
} catch (\Throwable $e) {
}
return true;
}
]);
//压缩文件
$fileService->addZip(public_path() . 'statics/download', public_path() . 'statics/download/routine.zip', public_path() . 'statics/download');
$data['url'] = $baseUrl . '/statics/download/routine.zip';
return app('json')->success($data);
} catch (\Throwable $e) {
throw new AdminException($e->getMessage());
}
}
/**
* 替换url
* @param $url
*/
public function updateUrl($url)
{
$fileUrl = app()->getRootPath() . "public/statics/download/common/vendor.js";
$string = file_get_contents($fileUrl); //加载配置文件
$url = parse_url($url)['host'] ?? $url;
$string = str_replace('demo.crmeb.com', $url, $string); // 正则查找然后替换
$newFileUrl = app()->getRootPath() . "public/statics/download/common/vendor.js";
@file_put_contents($newFileUrl, $string); // 写入配置文件
}
/**
* 判断是否开启直播(弃用)
* @param int $iszhibo
*/
public function updateAppJson()
{
$fileUrl = app()->getRootPath() . "public/statics/download/app.json";
$string = file_get_contents($fileUrl); //加载配置文件
$pats = '/,
"plugins": {
"live-player-plugin": {
"version": "(.*?)",
"provider": "(.*?)"
}
}/';
$string = preg_replace($pats, '', $string); // 正则查找然后替换
$newFileUrl = app()->getRootPath() . "public/statics/download/app.json";
@file_put_contents($newFileUrl, $string); // 写入配置文件
}
/**
* 替换appid
* @param string $appid
* @param string $projectanme
*/
public function updateConfigJson($appId = '', $projectName = '')
{
$fileUrl = app()->getRootPath() . "public/statics/download/project.config.json";
$string = file_get_contents($fileUrl); //加载配置文件
// 替换appid
$appIdOld = '/"appid"(.*?),/';
$appIdNew = '"appid"' . ': ' . '"' . $appId . '",';
$string = preg_replace($appIdOld, $appIdNew, $string); // 正则查找然后替换
// 替换小程序名称
$projectNameOld = '/"projectname"(.*?),/';
$projectNameNew = '"projectname"' . ': ' . '"' . $projectName . '",';
$string = preg_replace($projectNameOld, $projectNameNew, $string); // 正则查找然后替换
$newFileUrl = app()->getRootPath() . "public/statics/download/project.config.json";
@file_put_contents($newFileUrl, $string); // 写入配置文件
}
/**
* 替换商品详情直播
*/
public function updateProductDetailJson()
{
$fileUrl = app()->getRootPath() . "public/statics/download/common/main.js";
$string = file_get_contents($fileUrl); //加载配置文件
$string = str_replace('requirePlugin("live-player-plugin")', 'null', $string);
$pats = '/onShow:function\(e\)\{(.*?)},/';
$string = preg_replace($pats, '', $string); // 正则查找然后替换
$newFileUrl = app()->getRootPath() . "public/statics/download/common/main.js";
@file_put_contents($newFileUrl, $string); // 写入配置文件
}
/**
* 获取下载小程序模版页面数据
* @return string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getDownloadInfo()
{
$data['routine_name'] = sys_config('routine_name', '');
$appid = sys_config('routine_appId', '');
if (!$appid) {
throw new AdminException('请先在设置->系统设置->应用设置,配置小程序相关信息');
}
$name = $data['routine_name'] . '.jpg';
/** @var QrcodeServices $qrcode */
$qrcode = app()->make(QrcodeServices::class);
$resForever = $qrcode->qrCodeForever(0, 'code');
$id = (int)$resForever['id'];
/** @var QrcodeServices $QrcodeService */
$QrcodeService = app()->make(QrcodeServices::class);
//生成小程序地址
$urlCode = $QrcodeService->getRoutineQrcodePath($id, 0, -1, $name);
if (!$urlCode) {
$qrcode->update($id, ['status' => 1, 'time' => time(), 'qrcode_url' => $urlCode]);
}
$data['code'] = $qrcode;
$data['appId'] = $appid;
$data['help'] = 'https://doc.crmeb.com/web/pro/crmebprov2/1192';
return $this->success($data);
}
}