增加 企业微信通知 以及 工单通知

This commit is contained in:
iVampireSP.com 2022-10-31 19:03:38 +08:00
parent 93a3497b76
commit 04c090ca42
No known key found for this signature in database
GPG Key ID: 2F7B001CA27A8132
18 changed files with 1218 additions and 16 deletions

View File

@ -0,0 +1,33 @@
<?php
namespace App\Broadcasting;
use App\Models\User;
use Illuminate\Notifications\Notification;
class WeComRobotChannel
{
/**
* Create a new channel instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* 发送给定的通知。
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return void
*/
public function send($notifiable, Notification $notification)
{
// $message = $notification->toVoice($notifiable);
// 向 $notifiable 实例发送通知...
}
}

View File

@ -20,7 +20,7 @@ public function index(WorkOrder $workOrder)
return $this->notFound('无法找到对应的工单。');
}
$replies = Reply::workOrderId($workOrder->id)->simplePaginate(10);
$replies = Reply::workOrderId($workOrder->id)->simplePaginate(100);
return $this->success($replies);
}

View File

@ -12,7 +12,7 @@ class WorkOrderController extends Controller
public function index(WorkOrder $workOrder)
{
$workOrder = $workOrder->thisUser()->with(['user', 'module', 'host'])->simplePaginate(10);
$workOrder = $workOrder->thisUser()->with(['user', 'module', 'host'])->simplePaginate(100);
return $this->success($workOrder);
}

View File

@ -47,16 +47,16 @@ public function handle()
$response = $http->post('work-orders/' . $this->reply->workOrder->id . '/replies', $reply);
if ($response->successful()) {
$this->reply->is_pending = false;
$this->reply->update([
'is_pending' => false
]);
broadcast(new UserEvent($this->reply->workOrder->user_id, 'work-order.replied', $this->reply));
} else {
$this->reply->is_pending = true;
}
$this->reply->save();
$this->reply->update([
'is_pending' => true
]);
}
}
}

View File

@ -46,11 +46,12 @@ public function handle()
}
if (!$response->successful()) {
$this->workOrder->status = 'error';
$this->workOrder->update([
'status' => 'error'
]);
} else {
broadcast(new UserEvent($this->workOrder->user_id, 'work-order.updated', $this->workOrder));
}
$this->workOrder->save();
}
}

View File

@ -33,7 +33,8 @@ class Module extends Model implements AuthenticatableContract, AuthorizableContr
protected $hidden = [
'api_token',
'url'
'url',
'wecom_key'
];

View File

@ -0,0 +1,98 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Http;
use App\Broadcasting\WeComRobotChannel;
use App\Models\WorkOrder\Reply;
use App\Models\WorkOrder\WorkOrder;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Log;
class WorkOrderNotification extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return [WeComRobotChannel::class];
}
public function toGroup($notifiable)
{
$workOrder = $notifiable;
$reply = [];
if ($notifiable instanceof WorkOrder) {
$view = 'notifications.work_order.created';
$workOrder->load(['module', 'user']);
$module = $workOrder->module;
} elseif ($notifiable instanceof Reply) {
$view = 'notifications.work_order.reply';
$workOrder->load(['workOrder', 'user']);
$workOrder->workOrder->load('module');
$reply = $workOrder;
$workOrder = $workOrder->workOrder;
$module = $workOrder->module;
} else {
return;
}
// 取消隐藏字段
$module->makeVisible(['wecom_key']);
if ($module->wecom_key == null) {
return;
}
$wecom_key = $module->wecom_key;
// 隐藏字段
$module->makeHidden(['wecom_key']);
$body = Http::post('https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=' . $wecom_key, [
'msgtype' => 'markdown',
'markdown' => [
'content' => view($view, [
'workOrder' => $workOrder,
'user' => $workOrder->user,
'reply' => $reply,
'module' => $module,
])->render(),
],
]);
Log::info('企业微信机器人发送消息', [
'body' => $body->body(),
'status' => $body->status(),
]);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace App\Observers\WorkOrder;
use App\Models\WorkOrder\Reply;
use App\Notifications\WorkOrderNotification;
class ReplyObserver
{
/**
* Handle the Reply "created" event.
*
* @param \App\Models\WorkOrder\Reply $reply
* @return void
*/
public function created(Reply $reply)
{
//
return (new WorkOrderNotification())
->toGroup($reply);
}
/**
* Handle the Reply "updated" event.
*
* @param \App\Models\WorkOrder\Reply $reply
* @return void
*/
public function updated(Reply $reply)
{
//
}
/**
* Handle the Reply "deleted" event.
*
* @param \App\Models\WorkOrder\Reply $reply
* @return void
*/
public function deleted(Reply $reply)
{
//
}
/**
* Handle the Reply "restored" event.
*
* @param \App\Models\WorkOrder\Reply $reply
* @return void
*/
public function restored(Reply $reply)
{
//
}
/**
* Handle the Reply "force deleted" event.
*
* @param \App\Models\WorkOrder\Reply $reply
* @return void
*/
public function forceDeleted(Reply $reply)
{
//
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Observers\WorkOrder;
use App\Models\WorkOrder\WorkOrder;
use App\Notifications\WorkOrderNotification;
use Illuminate\Support\Facades\Log;
class WorkOrderObserver
{
/**
* Handle the WorkOrder "created" event.
*
* @param \App\Models\WorkOrder\WorkOrder $workOrder
* @return void
*/
public function created(WorkOrder $workOrder)
{
//
return (new WorkOrderNotification())
->toGroup($workOrder);
}
/**
* Handle the WorkOrder "updated" event.
*
* @param \App\Models\WorkOrder\WorkOrder $workOrder
* @return void
*/
public function updated(WorkOrder $workOrder)
{
Log::debug('workOrder updated', ['workOrder' => $workOrder]);
//
return (new WorkOrderNotification())
->toGroup($workOrder);
}
/**
* Handle the WorkOrder "deleted" event.
*
* @param \App\Models\WorkOrder\WorkOrder $workOrder
* @return void
*/
public function deleted(WorkOrder $workOrder)
{
//
}
/**
* Handle the WorkOrder "restored" event.
*
* @param \App\Models\WorkOrder\WorkOrder $workOrder
* @return void
*/
public function restored(WorkOrder $workOrder)
{
//
}
/**
* Handle the WorkOrder "force deleted" event.
*
* @param \App\Models\WorkOrder\WorkOrder $workOrder
* @return void
*/
public function forceDeleted(WorkOrder $workOrder)
{
//
}
}

View File

@ -3,7 +3,7 @@
namespace App\Providers;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
// use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
@ -24,6 +24,12 @@ public function register()
public function boot()
{
$this->generateInstanceId();
// $this->app->make(\Illuminate\Notifications\ChannelManager::class)->extend('your-channel', function () {
// return $this->app->make(App\Channels\YourChannel::class);
// });
//
// header('server: Cluster Ready!');

View File

@ -12,9 +12,9 @@ class EventServiceProvider extends ServiceProvider
* @var array
*/
protected $listen = [
\App\Events\ExampleEvent::class => [
\App\Listeners\ExampleListener::class,
],
// \App\Events\WorkOrderProcessed::class => [
// \App\Listeners\SendWorkOrderNotification::class,
// ],
];
/**
@ -26,4 +26,11 @@ public function shouldDiscoverEvents()
{
return false;
}
public function boot() {
parent::boot();
\App\Models\WorkOrder\WorkOrder::observe(\App\Observers\WorkOrder\WorkOrderObserver::class);
\App\Models\WorkOrder\Reply::observe(\App\Observers\WorkOrder\ReplyObserver::class);
}
}

View File

@ -134,6 +134,7 @@
$app->register(App\Providers\EventServiceProvider::class);
$app->register(\Anik\Form\FormRequestServiceProvider::class);
$app->register(App\Providers\RouteBindingServiceProvider::class);
$app->register(Illuminate\Notifications\NotificationServiceProvider::class);
// broadcast
$app->register(App\Providers\BroadcastServiceProvider::class);

View File

@ -17,6 +17,7 @@
"freyo/flysystem-qcloud-cos-v5": "^2.0",
"guzzlehttp/guzzle": "^7.5",
"hhxsv5/laravel-s": "~3.7.0",
"illuminate/notifications": "^9.34",
"illuminate/redis": "^9.28",
"jenssegers/mongodb": "^3.9",
"laravel/lumen-framework": "^9.0",

784
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "4eea65d15fe3433d2e3ac710207e819a",
"content-hash": "348fafe400e5a446c6c7d832810b8a01",
"packages": [
{
"name": "adbario/php-dot-notation",
@ -437,6 +437,87 @@
],
"time": "2021-08-28T21:56:17+00:00"
},
{
"name": "dflydev/dot-access-data",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
"reference": "0992cc19268b259a39e86f296da5f0677841f42c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c",
"reference": "0992cc19268b259a39e86f296da5f0677841f42c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
"scrutinizer/ocular": "1.6.0",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^3.14"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Dflydev\\DotAccessData\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dragonfly Development Inc.",
"email": "info@dflydev.com",
"homepage": "http://dflydev.com"
},
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Carlos Frutos",
"email": "carlos@kiwing.it",
"homepage": "https://github.com/cfrutos"
},
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com"
}
],
"description": "Given a deep data structure, access data by dot notation.",
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
"keywords": [
"access",
"data",
"dot",
"notation"
],
"support": {
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1"
},
"time": "2021-08-13T13:06:58+00:00"
},
{
"name": "doctrine/cache",
"version": "2.2.0",
@ -3197,6 +3278,138 @@
},
"time": "2022-08-09T13:29:29+00:00"
},
{
"name": "illuminate/mail",
"version": "v9.34.0",
"source": {
"type": "git",
"url": "https://github.com/illuminate/mail.git",
"reference": "de6b2b493654c33b5336d35755973911bcfa14b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/mail/zipball/de6b2b493654c33b5336d35755973911bcfa14b7",
"reference": "de6b2b493654c33b5336d35755973911bcfa14b7",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"illuminate/collections": "^9.0",
"illuminate/container": "^9.0",
"illuminate/contracts": "^9.0",
"illuminate/macroable": "^9.0",
"illuminate/support": "^9.0",
"league/commonmark": "^2.2",
"php": "^8.0.2",
"psr/log": "^1.0|^2.0|^3.0",
"symfony/mailer": "^6.0",
"tijsverkoyen/css-to-inline-styles": "^2.2.2"
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SES mail driver (^3.198.1).",
"symfony/http-client": "Required to use the Symfony API mail transports (^6.0).",
"symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).",
"symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "9.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Mail\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Mail package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2022-09-14T13:13:44+00:00"
},
{
"name": "illuminate/notifications",
"version": "v9.34.0",
"source": {
"type": "git",
"url": "https://github.com/illuminate/notifications.git",
"reference": "98d1e4e7966d267a3b59198a537eea05b074e028"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/notifications/zipball/98d1e4e7966d267a3b59198a537eea05b074e028",
"reference": "98d1e4e7966d267a3b59198a537eea05b074e028",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"illuminate/broadcasting": "^9.0",
"illuminate/bus": "^9.0",
"illuminate/collections": "^9.0",
"illuminate/container": "^9.0",
"illuminate/contracts": "^9.0",
"illuminate/filesystem": "^9.0",
"illuminate/mail": "^9.0",
"illuminate/queue": "^9.0",
"illuminate/support": "^9.0",
"php": "^8.0.2"
},
"suggest": {
"illuminate/database": "Required to use the database transport (^9.0)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "9.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Notifications\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Notifications package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2022-09-12T13:48:14+00:00"
},
{
"name": "illuminate/pagination",
"version": "v9.33.0",
@ -4146,6 +4359,206 @@
},
"time": "2022-09-08T13:45:54+00:00"
},
{
"name": "league/commonmark",
"version": "2.3.6",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "857afc47ce113454bd629037213378ba3219dd40"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/857afc47ce113454bd629037213378ba3219dd40",
"reference": "857afc47ce113454bd629037213378ba3219dd40",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-mbstring": "*",
"league/config": "^1.1.1",
"php": "^7.4 || ^8.0",
"psr/event-dispatcher": "^1.0",
"symfony/deprecation-contracts": "^2.1 || ^3.0",
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
"cebe/markdown": "^1.0",
"commonmark/cmark": "0.30.0",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
"erusev/parsedown": "^1.0",
"ext-json": "*",
"github/gfm": "0.29.0",
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21",
"scrutinizer/ocular": "^1.8.1",
"symfony/finder": "^5.3 | ^6.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0"
},
"suggest": {
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
}
},
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)",
"homepage": "https://commonmark.thephpleague.com",
"keywords": [
"commonmark",
"flavored",
"gfm",
"github",
"github-flavored",
"markdown",
"md",
"parser"
],
"support": {
"docs": "https://commonmark.thephpleague.com/",
"forum": "https://github.com/thephpleague/commonmark/discussions",
"issues": "https://github.com/thephpleague/commonmark/issues",
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
"source": "https://github.com/thephpleague/commonmark"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
"type": "tidelift"
}
],
"time": "2022-10-30T16:45:38+00:00"
},
{
"name": "league/config",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/config.git",
"reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e",
"reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"dflydev/dot-access-data": "^3.0.1",
"nette/schema": "^1.2",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.90",
"phpunit/phpunit": "^9.5.5",
"scrutinizer/ocular": "^1.8.1",
"unleashedtech/php-coding-standard": "^3.1",
"vimeo/psalm": "^4.7.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.2-dev"
}
},
"autoload": {
"psr-4": {
"League\\Config\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Define configuration arrays with strict schemas and access values with dot notation",
"homepage": "https://config.thephpleague.com",
"keywords": [
"array",
"config",
"configuration",
"dot",
"dot-access",
"nested",
"schema"
],
"support": {
"docs": "https://config.thephpleague.com/",
"issues": "https://github.com/thephpleague/config/issues",
"rss": "https://github.com/thephpleague/config/releases.atom",
"source": "https://github.com/thephpleague/config"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
}
],
"time": "2021-08-14T12:15:32+00:00"
},
{
"name": "league/flysystem",
"version": "3.5.2",
@ -4658,6 +5071,165 @@
],
"time": "2022-09-02T07:48:13+00:00"
},
{
"name": "nette/schema",
"version": "v1.2.2",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
"reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df",
"reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
"php": ">=7.1 <8.2"
},
"require-dev": {
"nette/tester": "^2.3 || ^2.4",
"phpstan/phpstan-nette": "^0.12",
"tracy/tracy": "^2.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "📐 Nette Schema: validating data structures against a given Schema.",
"homepage": "https://nette.org",
"keywords": [
"config",
"nette"
],
"support": {
"issues": "https://github.com/nette/schema/issues",
"source": "https://github.com/nette/schema/tree/v1.2.2"
},
"time": "2021-10-15T11:40:02+00:00"
},
{
"name": "nette/utils",
"version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "a6784d523c0e67409b5c64c3d951e9871ef64241"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/a6784d523c0e67409b5c64c3d951e9871ef64241",
"reference": "a6784d523c0e67409b5c64c3d951e9871ef64241",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2 <8.3"
},
"conflict": {
"nette/di": "<3.0.6"
},
"require-dev": {
"nette/tester": "~2.0",
"phpstan/phpstan": "^1.0",
"tracy/tracy": "^2.3"
},
"suggest": {
"ext-gd": "to use Image",
"ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
"ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
"ext-json": "to use Nette\\Utils\\Json",
"ext-mbstring": "to use Strings::lower() etc...",
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
"ext-xml": "to use Strings::length() etc. when mbstring is not available"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
"homepage": "https://nette.org",
"keywords": [
"array",
"core",
"datetime",
"images",
"json",
"nette",
"paginator",
"password",
"slugify",
"string",
"unicode",
"utf-8",
"utility",
"validation"
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v3.2.8"
},
"time": "2022-09-06T00:55:00+00:00"
},
{
"name": "nikic/fast-route",
"version": "v1.3.0",
@ -6714,6 +7286,77 @@
],
"time": "2022-10-26T21:42:49+00:00"
},
{
"name": "symfony/css-selector",
"version": "v6.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/0dd5e36b80e1de97f8f74ed7023ac2b837a36443",
"reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=8.1"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/css-selector/tree/v6.1.3"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-06-27T17:24:16+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.1.1",
@ -7482,6 +8125,86 @@
],
"time": "2022-10-28T18:06:36+00:00"
},
{
"name": "symfony/mailer",
"version": "v6.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
"reference": "7e19813c0b43387c55665780c4caea505cc48391"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/7e19813c0b43387c55665780c4caea505cc48391",
"reference": "7e19813c0b43387c55665780c4caea505cc48391",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"egulias/email-validator": "^2.1.10|^3",
"php": ">=8.1",
"psr/event-dispatcher": "^1",
"psr/log": "^1|^2|^3",
"symfony/event-dispatcher": "^5.4|^6.0",
"symfony/mime": "^5.4|^6.0",
"symfony/service-contracts": "^1.1|^2|^3"
},
"conflict": {
"symfony/http-kernel": "<5.4"
},
"require-dev": {
"symfony/http-client-contracts": "^1.1|^2|^3",
"symfony/messenger": "^5.4|^6.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Mailer\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailer/tree/v6.1.7"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-10-28T16:23:08+00:00"
},
{
"name": "symfony/mime",
"version": "v6.1.6",
@ -9034,6 +9757,65 @@
},
"time": "2022-09-25T08:09:36+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
"version": "2.2.5",
"source": {
"type": "git",
"url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
"reference": "4348a3a06651827a27d989ad1d13efec6bb49b19"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/4348a3a06651827a27d989ad1d13efec6bb49b19",
"reference": "4348a3a06651827a27d989ad1d13efec6bb49b19",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"php": "^5.5 || ^7.0 || ^8.0",
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2.x-dev"
}
},
"autoload": {
"psr-4": {
"TijsVerkoyen\\CssToInlineStyles\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Tijs Verkoyen",
"email": "css_to_inline_styles@verkoyen.eu",
"role": "Developer"
}
],
"description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.",
"homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
"support": {
"issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.5"
},
"time": "2022-09-12T13:28:28+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v5.4.1",

11
config/settings.php Normal file
View File

@ -0,0 +1,11 @@
<?php
return [
'wecom' => [
'robot_hook' => [
'default' => '4727b740-57dc-448c-a89a-840e28fb48dc',
'billing' => '50aa88b6-febe-4cf5-a18f-c714b3752548',
'cluster_ready' => '7de76311-280e-40eb-bfd0-c17c0e053e90',
],
]
];

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('modules', function (Blueprint $table) {
//
$table->string('wecom_key')->nullable()->comment('企业微信机器人 key');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('modules', function (Blueprint $table) {
//
// drop if exists
if (Schema::hasColumn('modules', 'wecom_key')) {
$table->dropColumn('wecom_key');
}
});
}
};

View File

@ -0,0 +1,71 @@
@php
$title = '';
@endphp
@switch ($workOrder->status)
@case('pending')
@php
$title = '工单挂起';
@endphp
@break
@case('open')
@php
$title = '工单投递成功,并且已开启';
@endphp
@break
@case('user_replied')
@php
$title = '工单挂起';
@endphp
@break
@case('closed')
@php
$title = '已结单';
@endphp
@break
@case('replied')
@php
$title = '工作人员已回复';
@endphp
@break
@case('on_hold')
@php
$title = '挂起';
@endphp
@break
@case('in_progress')
@php
$title = '正在处理中';
@endphp
@break
@case('error')
@php
$title = '投递失败';
@endphp
@break
@default
@php
$title = '状态更新';
@endphp
@break
@endswitch
## {{ $title }}
# {{ $module->name }}
## 客户 {{ $user->name }}
##### 邮箱 {{ $user->email }}
##### 余额 {{ $user->balance }} 元
# {{ $workOrder->id }}#{{ $workOrder->title }}
{{ $workOrder->content }}

View File

@ -0,0 +1,15 @@
## @if ($workOrder->is_pending)
回复投递中
@else
回复已投递
@endif
# {{ $module->name }}
## 客户 {{ $user->name }}
##### 邮箱 {{ $user->email }}
##### 余额 {{ $user->balance }} 元
# {{ $workOrder->id }}#{{ $workOrder->title }}
{{ $reply->content }}