init
- 框架初始化 - 安装插件 - 修复PHP8.4报错
This commit is contained in:
227
application/admin/controller/shopro/notification/Config.php
Normal file
227
application/admin/controller/shopro/notification/Config.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\shopro\notification;
|
||||
|
||||
use app\admin\controller\shopro\Common;
|
||||
use app\admin\model\shopro\notification\Config as ConfigModel;
|
||||
use app\admin\controller\shopro\notification\traits\Notification as NotificationTraits;
|
||||
use addons\shopro\facade\Wechat;
|
||||
|
||||
class Config extends Common
|
||||
{
|
||||
use NotificationTraits;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new ConfigModel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 消息通知配置
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (!$this->request->isAjax()) {
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
$receiver_type = $this->request->param('receiver_type');
|
||||
|
||||
$notifications = $this->getNotificationsByReceiverType($receiver_type);
|
||||
|
||||
$groupConfigs = $this->getGroupConfigs();
|
||||
foreach ($notifications as $key => &$notification) {
|
||||
$currentConfigs = $groupConfigs[$notification['event']] ?? [];
|
||||
foreach ($notification['channels'] as $channel) {
|
||||
$notification['configs'][$channel] = [
|
||||
'status' => isset($currentConfigs[$channel]) ? $currentConfigs[$channel]['status'] : 'disabled',
|
||||
'send_num' => isset($currentConfigs[$channel]) ? $currentConfigs[$channel]['send_num'] : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('获取成功', null, $notifications);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function detail()
|
||||
{
|
||||
$event = $this->request->param('event');
|
||||
$channel = $this->request->param('channel');
|
||||
if (!$event || !$channel) {
|
||||
error_stop('参数错误');
|
||||
}
|
||||
|
||||
$notification = $this->getNotificationByEvent($event);
|
||||
|
||||
$notification = $this->formatNotification($notification, $event, $channel);
|
||||
|
||||
$this->success('获取成功', null, $notification);
|
||||
}
|
||||
|
||||
|
||||
// 编辑配置
|
||||
public function edit($id = null)
|
||||
{
|
||||
if (!$this->request->isAjax()) {
|
||||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
$event = $this->request->param('event');
|
||||
$channel = $this->request->param('channel');
|
||||
if ($channel == 'Email') {
|
||||
$content = $this->request->param('content', '');
|
||||
} else {
|
||||
$content = $this->request->param('content/a', []);
|
||||
}
|
||||
$type = $this->request->param('type', 'default');
|
||||
if (!$event || !$channel) {
|
||||
error_stop('参数错误');
|
||||
}
|
||||
|
||||
$config = $this->model->where('event', $event)->where('channel', $channel)->find();
|
||||
|
||||
if (!$config) {
|
||||
$config = $this->model;
|
||||
$config->event = $event;
|
||||
$config->channel = $channel;
|
||||
}
|
||||
|
||||
if (in_array($channel, ['WechatOfficialAccount', 'WechatMiniProgram']) && $type == 'default') {
|
||||
// 自动组装微信默认模板
|
||||
$content['fields'] = $this->formatWechatTemplateFields($event, $channel, $content['fields']);
|
||||
}
|
||||
|
||||
$config->type = $type;
|
||||
$config->content = $content;
|
||||
$config->save();
|
||||
|
||||
$this->success('设置成功');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 配置状态
|
||||
public function setStatus($event, $channel)
|
||||
{
|
||||
$event = $this->request->param('event');
|
||||
$channel = $this->request->param('channel');
|
||||
$status = $this->request->param('status', 'disabled');
|
||||
|
||||
if (!$event || !$channel) {
|
||||
$this->error('参数错误');
|
||||
}
|
||||
|
||||
$config = $this->model->where('event', $event)->where('channel', $channel)->find();
|
||||
if (!$config) {
|
||||
$config = $this->model;
|
||||
$config->event = $event;
|
||||
$config->channel = $channel;
|
||||
$config->type = 'default';
|
||||
}
|
||||
$config->status = $status;
|
||||
$config->save();
|
||||
|
||||
$this->success('设置成功');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 自动获取微信模板 id
|
||||
*/
|
||||
public function getTemplateId()
|
||||
{
|
||||
$event = $this->request->param('event');
|
||||
$channel = $this->request->param('channel');
|
||||
$is_delete = $this->request->param('is_delete', 0);
|
||||
$template_id = $this->request->param('template_id', '');
|
||||
if (!$event || !$channel) {
|
||||
error_stop('参数错误');
|
||||
}
|
||||
|
||||
$notification = $this->getNotificationByEvent($event);
|
||||
|
||||
$template = $notification['template'][$channel] ?? null;
|
||||
if (!$template) {
|
||||
$this->error('模板不存在');
|
||||
}
|
||||
|
||||
// 请求微信接口
|
||||
switch ($channel) {
|
||||
case 'WechatMiniProgram': // 小程序订阅消息
|
||||
$requestParams['tid'] = $template['tid'];
|
||||
$requestParams['kid'] = $template['kid'];
|
||||
$requestParams['sceneDesc'] = $template['scene_desc'];
|
||||
if (!$requestParams['tid'] || !$requestParams['kid']) {
|
||||
$this->error('缺少模板参数');
|
||||
}
|
||||
$wechat = Wechat::miniProgram()->subscribe_message;
|
||||
$delete_method = 'deleteTemplate';
|
||||
$result_key = 'priTmplId';
|
||||
break;
|
||||
// case 'WechatOfficialAccount': // 公众号模板消息
|
||||
// $requestParams['template_id'] = $template['temp_no'];
|
||||
// if (!$requestParams['template_id']) {
|
||||
// $this->error('缺少模板参数,获取失败');
|
||||
// }
|
||||
// $wechat = Wechat::officialAccount()->template_message; // 微信管理
|
||||
// $result_key = 'template_id';
|
||||
// $delete_method = 'deletePrivateTemplate';
|
||||
// break;
|
||||
case 'WechatOfficialAccount': // 新版公众号模板消息
|
||||
$requestParams['template_id'] = $template['temp_no'];
|
||||
$requestParams['keywords'] = $template['keywords'];
|
||||
|
||||
if (!$requestParams['template_id']) {
|
||||
$this->error('公众号类目模板库目前不完善,请自行在公众号后台->模板消息->选择模板配置');
|
||||
}
|
||||
if (!$requestParams['keywords']) {
|
||||
$this->error('缺少模板关键字,获取失败');
|
||||
}
|
||||
|
||||
$wechat = new \addons\shopro\library\easywechatPlus\WechatOfficialTemplate(Wechat::officialAccount());
|
||||
|
||||
$result_key = 'template_id';
|
||||
$delete_method = 'deletePrivateTemplate';
|
||||
break;
|
||||
case 'WechatOfficialAccountBizsend': // 公众号订阅消息(待补充)
|
||||
$requestParams['tid'] = $template['tid'];
|
||||
$requestParams['kid'] = $template['kid'];
|
||||
if (!$requestParams['tid'] || !$requestParams['kid']) {
|
||||
$this->error('缺少模板参数,获取失败');
|
||||
}
|
||||
$wechat = Wechat::officialAccount()->subscribe_message; // 微信管理
|
||||
$result_key = 'priTmplId';
|
||||
$delete_method = 'deleteTemplate';
|
||||
break;
|
||||
default:
|
||||
$this->error('当前发送渠道不能获取模板');
|
||||
break;
|
||||
}
|
||||
|
||||
$result = $wechat->addTemplate(...array_values($requestParams));
|
||||
|
||||
if ($result['errcode'] != 0) {
|
||||
$this->error('获取失败: errcode:' . $result['errcode'] . '; errmsg:' . $result['errmsg']);
|
||||
} else {
|
||||
if ($is_delete) {
|
||||
// 删除传入的老模板
|
||||
if ($template_id) {
|
||||
$deleteResult = $wechat->{$delete_method}($template_id);
|
||||
}
|
||||
// 删除数据库的老模板
|
||||
$config = $this->model->where('event', $event)->where('channel', $channel)->find();
|
||||
$template_id = $config ? ($config->content['template_id'] ?? null) : null;
|
||||
if ($template_id) {
|
||||
$deleteResult = $wechat->{$delete_method}($template_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('获取成功', null, ($result[$result_key] ?? null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\shopro\notification;
|
||||
|
||||
use app\admin\controller\shopro\Common;
|
||||
use app\admin\model\shopro\notification\Notification as NotificationModel;
|
||||
use app\admin\model\shopro\Admin;
|
||||
|
||||
class Notification extends Common
|
||||
{
|
||||
|
||||
protected $noNeedRight = ['index', 'read', 'delete', 'notificationType'];
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new NotificationModel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取管理员的消息列表
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$admin = auth_admin();
|
||||
$admin = Admin::where('id', $admin['id'])->find();
|
||||
|
||||
$notifiable_type = $admin->getNotifiableType();
|
||||
$notifications = NotificationModel::sheepFilter(false)
|
||||
->where('notifiable_type', $notifiable_type)
|
||||
->where('notifiable_id', $admin['id'])
|
||||
->order('createtime', 'desc')
|
||||
->paginate($this->request->param('list_rows', 10));
|
||||
|
||||
$this->success('消息列表', null, $notifications);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 指定消息标记已读
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
$admin = auth_admin();
|
||||
$admin = Admin::where('id', $admin['id'])->find();
|
||||
|
||||
$notifiable_type = $admin->getNotifiableType();
|
||||
$notification = NotificationModel::sheepFilter()
|
||||
->where('notifiable_type', $notifiable_type)
|
||||
->where('notifiable_id', $admin['id'])
|
||||
->where('id', $id)
|
||||
->find();
|
||||
|
||||
if (!$notification) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$notification->read_time = time();
|
||||
$notification->save();
|
||||
|
||||
$this->success('已读成功', null, $notification);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除已读消息
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$admin = auth_admin();
|
||||
$admin = Admin::where('id', $admin['id'])->find();
|
||||
|
||||
// 将已读的消息全部删除
|
||||
$notifiable_type = $admin->getNotifiableType();
|
||||
NotificationModel::sheepFilter()
|
||||
->where('notifiable_type', $notifiable_type)
|
||||
->where('notifiable_id', $admin['id'])
|
||||
->whereNotNull('read_time')
|
||||
->delete();
|
||||
|
||||
$this->success('删除成功');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 消息类别,以及未读消息数
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function notificationType()
|
||||
{
|
||||
$admin = auth_admin();
|
||||
|
||||
$notificationType = NotificationModel::$notificationType;
|
||||
|
||||
$newType = [];
|
||||
foreach ($notificationType as $type => $name) {
|
||||
// 未读消息数
|
||||
$unread_num = NotificationModel::where('notifiable_type', 'admin')->where('notifiable_id', $admin['id'])
|
||||
->notificationType($type)
|
||||
->where('read_time', null)
|
||||
->order('createtime', 'desc')->count();
|
||||
|
||||
$newType[] = [
|
||||
'label' => $name,
|
||||
'value' => $type,
|
||||
'unread_num' => $unread_num
|
||||
];
|
||||
}
|
||||
|
||||
$result = [
|
||||
'unread_num' => array_sum(array_column($newType, 'unread_num')),
|
||||
'notification_type' => $newType
|
||||
];
|
||||
|
||||
$this->success('消息类型', null, $result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\shopro\notification\traits;
|
||||
|
||||
/**
|
||||
* 消息通知,额外方法
|
||||
*/
|
||||
trait Notification
|
||||
{
|
||||
|
||||
protected $notificationTypes = [
|
||||
\addons\shopro\notification\order\OrderNew::class,
|
||||
\addons\shopro\notification\order\OrderDispatched::class,
|
||||
\addons\shopro\notification\order\aftersale\OrderAftersaleChange::class,
|
||||
\addons\shopro\notification\order\aftersale\OrderAdminAftersaleChange::class,
|
||||
\addons\shopro\notification\order\OrderRefund::class,
|
||||
\addons\shopro\notification\order\OrderApplyRefund::class,
|
||||
// 商品
|
||||
\addons\shopro\notification\goods\StockWarning::class,
|
||||
// 钱包
|
||||
\addons\shopro\notification\wallet\CommissionChange::class,
|
||||
\addons\shopro\notification\wallet\MoneyChange::class,
|
||||
\addons\shopro\notification\wallet\ScoreChange::class,
|
||||
// 活动
|
||||
\addons\shopro\notification\activity\GrouponFail::class,
|
||||
\addons\shopro\notification\activity\GrouponFinish::class,
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 根据接收人类型,获取消息类型
|
||||
*
|
||||
* @param array|string $receiverType
|
||||
* @return array
|
||||
*/
|
||||
protected function getNotificationsByReceiverType($receiverType = 'user')
|
||||
{
|
||||
$receiverType = is_array($receiverType) ? $receiverType : [$receiverType];
|
||||
|
||||
$notifications = $this->getNotifications();
|
||||
|
||||
$receiverNotifications = [];
|
||||
foreach ($notifications as $notification) {
|
||||
if (in_array($notification['receiver_type'], $receiverType)) {
|
||||
$receiverNotifications[] = $notification;
|
||||
}
|
||||
}
|
||||
|
||||
return $receiverNotifications;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据事件类型获取消息
|
||||
*
|
||||
* @param string $event
|
||||
* @return void
|
||||
*/
|
||||
protected function getNotificationByEvent($event)
|
||||
{
|
||||
$notifications = $this->getNotifications();
|
||||
|
||||
$notifications = array_column($notifications, null, 'event');
|
||||
return $notifications[$event] ?? null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 按照事件类型获取配置分组
|
||||
*
|
||||
* @param string $event
|
||||
* @return array
|
||||
*/
|
||||
protected function getGroupConfigs($event = null)
|
||||
{
|
||||
// 获取所有配置
|
||||
$configs = $this->model->select();
|
||||
$newConfigs = [];
|
||||
foreach ($configs as $config) {
|
||||
$newConfigs[$config['event']][$config['channel']] = $config;
|
||||
}
|
||||
|
||||
return $event ? ($newConfigs[$event] ?? []) : $newConfigs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有消息类型
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getNotifications()
|
||||
{
|
||||
$types = [];
|
||||
foreach ($this->notificationTypes as $key => $class_name) {
|
||||
$class = new $class_name();
|
||||
$currentFields = $class->returnField;
|
||||
$currentFields['event'] = $class->event;
|
||||
$currentFields['receiver_type'] = $class->receiver_type;
|
||||
$currentFields['template'] = $class->template;
|
||||
|
||||
$types[] = $currentFields;
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 格式化详情返回结果
|
||||
*
|
||||
* @param array $notification
|
||||
* @param string $event
|
||||
* @param string $channel
|
||||
* @return array
|
||||
*/
|
||||
protected function formatNotification($notification, $event, $channel)
|
||||
{
|
||||
$currentConfigs = $this->getGroupConfigs($event);
|
||||
$currentConfig = $currentConfigs[$channel] ?? null;
|
||||
|
||||
if (in_array($channel, ['WechatOfficialAccount', 'WechatMiniProgram', 'WechatOfficialAccountBizsend'])) {
|
||||
$currentTemplate = $notification['template'][$channel] ?? [];
|
||||
unset($notification['template']);
|
||||
$notification['wechat'] = $currentTemplate;
|
||||
}
|
||||
|
||||
$notification['type'] = $currentConfig['type'] ?? 'default';
|
||||
$content = $currentConfig['content'] ?? null;
|
||||
if (!is_array($content)) {
|
||||
$notification['content_text'] = $content;
|
||||
}
|
||||
if ($content && is_array($content)) {
|
||||
$contentFields = [];
|
||||
if (isset($content['fields']) && $content['fields']) { // 判断数组是否存在 fields 设置
|
||||
$contentFields = array_column($content['fields'], null, 'field');
|
||||
}
|
||||
|
||||
$tempFields = array_column($notification['fields'], null, 'field');
|
||||
$configField = array_merge($tempFields, $contentFields);
|
||||
|
||||
$content['fields'] = array_values($configField);
|
||||
$notification['content'] = $content;
|
||||
} else {
|
||||
$notification['content'] = [
|
||||
'template_id' => '',
|
||||
'fields' => $notification['fields']
|
||||
];
|
||||
}
|
||||
|
||||
unset($notification['fields']);
|
||||
|
||||
return $notification;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 格式化微信公众号,小程序默认模板时 自动配置 模板字段
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function formatWechatTemplateFields($event, $channel, $fields)
|
||||
{
|
||||
$notification = $this->getNotificationByEvent($event);
|
||||
|
||||
$channelFields = $notification['template'][$channel]['fields'] ?? [];
|
||||
$channelFields = array_column($channelFields, null, 'field');
|
||||
|
||||
foreach ($fields as $key => &$field) {
|
||||
$field_name = $field['field'] ?? '';
|
||||
if ($field_name && isset($channelFields[$field_name])) {
|
||||
$field['template_field'] = $channelFields[$field_name]['template_field'] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user