added table of co-woeker requests and new features 3
This commit is contained in:
@@ -3,12 +3,15 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\DB\Te\TableEngine;
|
use App\DB\Te\TableEngine;
|
||||||
|
use App\Exceptions\SmsBlockedException;
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Message;
|
use App\Models\Message;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Services\ConfigService;
|
use App\Services\ConfigService;
|
||||||
|
use App\Services\SmsBilling\SmsGatewayService;
|
||||||
|
use App\Services\SmsBilling\SmsWalletService;
|
||||||
use App\Services\SmsProfanityFilter;
|
use App\Services\SmsProfanityFilter;
|
||||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||||
|
|
||||||
@@ -53,12 +56,22 @@ class MassageController extends Controller
|
|||||||
$filter = app(SmsProfanityFilter::class);
|
$filter = app(SmsProfanityFilter::class);
|
||||||
$filter->assertClean((string) ($request->message ?? ''));
|
$filter->assertClean((string) ($request->message ?? ''));
|
||||||
|
|
||||||
foreach ($customers as $customer) {
|
$cfg = app(ConfigService::class);
|
||||||
// جایگزین کردن نام در پیام
|
$appName = trim((string) ($cfg->get('name_fa', '') ?: ''));
|
||||||
$message = str_replace('%name%', $customer->name, $request->message);
|
$rawMessage = $this->ensureAppNameFooter((string) ($request->message ?? ''), $appName);
|
||||||
|
|
||||||
// ارسال پیامک
|
// پیامک گروهی باید از گلوگاه billing رد شود و از اعتبار کم شود
|
||||||
$this->send($customer->mobile, $message);
|
$billingOk = SmsWalletService::isBillingOperational()
|
||||||
|
|| app(\App\Services\SmsBilling\SuperAdminSmsClient::class)->enabled();
|
||||||
|
if (! $billingOk) {
|
||||||
|
throw new UnprocessableEntityHttpException(
|
||||||
|
'پنل پیامک (billing) فعال نیست؛ ارسال گروهی بدون کسر اعتبار مجاز نیست.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($customers as $customer) {
|
||||||
|
$message = $this->applyCustomerNamePlaceholders($rawMessage, (string) $customer->name);
|
||||||
|
$this->sendBilledSms((string) $customer->mobile, $message, 'group_sms');
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(true);
|
return response()->json(true);
|
||||||
@@ -98,10 +111,8 @@ class MassageController extends Controller
|
|||||||
$appUrl = $cfg->resolvePublicSiteUrl($request);
|
$appUrl = $cfg->resolvePublicSiteUrl($request);
|
||||||
|
|
||||||
$message = str_replace(
|
$message = str_replace(
|
||||||
['%name%', '%نام%', '%app_name%', '%نام_اپ%', '%app_url%', '%لینک_اپ%', '%لینک%'],
|
['%app_name%', '%نام_اپ%', '%app_url%', '%لینک_اپ%', '%لینک%'],
|
||||||
[
|
[
|
||||||
(string) $customer->name,
|
|
||||||
(string) $customer->name,
|
|
||||||
$appName,
|
$appName,
|
||||||
$appName,
|
$appName,
|
||||||
$appUrl,
|
$appUrl,
|
||||||
@@ -110,6 +121,8 @@ class MassageController extends Controller
|
|||||||
],
|
],
|
||||||
$rawMessage
|
$rawMessage
|
||||||
);
|
);
|
||||||
|
$message = $this->applyCustomerNamePlaceholders($message, (string) $customer->name);
|
||||||
|
$message = $this->ensureAppNameFooter($message, $appName);
|
||||||
|
|
||||||
$this->send($customer->mobile, $message);
|
$this->send($customer->mobile, $message);
|
||||||
|
|
||||||
@@ -263,6 +276,39 @@ class MassageController extends Controller
|
|||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ارسال از گلوگاه پنل پیامک با کسر اجباری اعتبار؛ در صورت مسدودی/شکست، خطا برمیگردد.
|
||||||
|
*/
|
||||||
|
private function sendBilledSms(string $mobile, string $message, string $source): void
|
||||||
|
{
|
||||||
|
$text = trim($message);
|
||||||
|
if ($text === '') {
|
||||||
|
throw new UnprocessableEntityHttpException('متن پیامک خالی است.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$gateway = app(SmsGatewayService::class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = $gateway->sendOrThrow($mobile, $text, $source);
|
||||||
|
} catch (SmsBlockedException $e) {
|
||||||
|
throw new UnprocessableEntityHttpException(
|
||||||
|
'اعتبار پنل پیامک کافی نیست یا ارسال مسدود است.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $result->sent) {
|
||||||
|
throw new UnprocessableEntityHttpException(
|
||||||
|
$result->errorMessage ?: 'ارسال پیامک ناموفق بود؛ اعتبار کسر نشد.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::create([
|
||||||
|
'sms' => $text,
|
||||||
|
'receiver' => $mobile,
|
||||||
|
'platforms' => ($result->provider ?: 'sms') . ':' . $mobile,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
private function removeDuplicateNumbers(array $customers)
|
private function removeDuplicateNumbers(array $customers)
|
||||||
{
|
{
|
||||||
$uniqueCustomers = [];
|
$uniqueCustomers = [];
|
||||||
@@ -278,6 +324,46 @@ class MassageController extends Controller
|
|||||||
return $uniqueCustomers;
|
return $uniqueCustomers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* جایگزینی توکن نام مشتری با واریانتهای فارسی/انگلیسی و فاصله اختیاری.
|
||||||
|
* مثال: %name ، %name% ، ٪نام ، % نام ، ٪ نام
|
||||||
|
*/
|
||||||
|
private function applyCustomerNamePlaceholders(string $message, string $customerName): string
|
||||||
|
{
|
||||||
|
$patterns = [
|
||||||
|
'/[%٪]\s*name\s*[%٪]?/iu',
|
||||||
|
'/[%٪]\s*نام\s*[%٪]?/u',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
$replaced = preg_replace($pattern, $customerName, $message);
|
||||||
|
if (is_string($replaced)) {
|
||||||
|
$message = $replaced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** خط آخر پیام باید نام اپ باشد؛ اگر نبود اضافه میشود. */
|
||||||
|
private function ensureAppNameFooter(string $message, string $appName): string
|
||||||
|
{
|
||||||
|
$appName = trim($appName);
|
||||||
|
$trimmed = rtrim($message);
|
||||||
|
|
||||||
|
if ($appName === '') {
|
||||||
|
return $trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lines = preg_split('/\R/u', $trimmed) ?: [];
|
||||||
|
$last = trim((string) end($lines));
|
||||||
|
if ($last === $appName) {
|
||||||
|
return $trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $trimmed === '' ? $appName : ($trimmed . "\n" . $appName);
|
||||||
|
}
|
||||||
|
|
||||||
public function messagesTable(Request $request)
|
public function messagesTable(Request $request)
|
||||||
{
|
{
|
||||||
$records = Message::with(['person']);
|
$records = Message::with(['person']);
|
||||||
|
|||||||
Reference in New Issue
Block a user