129 lines
4.5 KiB
PHP
129 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace app\support;
|
|
|
|
use support\think\Db;
|
|
|
|
class EnterpriseCustomerService
|
|
{
|
|
public function generateCustomerCode(): string
|
|
{
|
|
do {
|
|
$code = 'ENT' . date('Ymd') . strtoupper(substr(bin2hex(random_bytes(4)), 0, 8));
|
|
} while (Db::name('enterprise_customers')->where('customer_code', $code)->find());
|
|
|
|
return $code;
|
|
}
|
|
|
|
public function generateAppKey(): string
|
|
{
|
|
do {
|
|
$key = 'ak_' . bin2hex(random_bytes(12));
|
|
} while (Db::name('enterprise_customer_apps')->where('app_key', $key)->find());
|
|
|
|
return $key;
|
|
}
|
|
|
|
public function generateAppSecret(): string
|
|
{
|
|
return 'sk_' . bin2hex(random_bytes(24));
|
|
}
|
|
|
|
public function encryptSecret(string $secret): string
|
|
{
|
|
$key = $this->secretKey();
|
|
$iv = random_bytes(16);
|
|
$cipher = openssl_encrypt($secret, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
|
if ($cipher === false) {
|
|
throw new \RuntimeException('应用密钥加密失败');
|
|
}
|
|
|
|
return base64_encode($iv . $cipher);
|
|
}
|
|
|
|
public function decryptSecret(string $cipherText): string
|
|
{
|
|
$raw = base64_decode($cipherText, true);
|
|
if ($raw === false || strlen($raw) <= 16) {
|
|
return '';
|
|
}
|
|
|
|
$iv = substr($raw, 0, 16);
|
|
$cipher = substr($raw, 16);
|
|
$secret = openssl_decrypt($cipher, 'AES-256-CBC', $this->secretKey(), OPENSSL_RAW_DATA, $iv);
|
|
|
|
return is_string($secret) ? $secret : '';
|
|
}
|
|
|
|
public function ensureVirtualUser(array $customer): int
|
|
{
|
|
$existingUserId = (int)($customer['user_id'] ?? 0);
|
|
if ($existingUserId > 0 && Db::name('users')->where('id', $existingUserId)->find()) {
|
|
return $existingUserId;
|
|
}
|
|
|
|
$now = date('Y-m-d H:i:s');
|
|
$mobile = 'ENT' . substr(hash('sha256', (string)($customer['customer_code'] ?? $customer['id'] ?? '')), 0, 20) . '@V';
|
|
$userId = (int)Db::name('users')->insertGetId([
|
|
'nickname' => (string)($customer['customer_name'] ?? '大客户'),
|
|
'avatar' => '',
|
|
'mobile' => $mobile,
|
|
'password' => '',
|
|
'status' => 'enabled',
|
|
'last_login_at' => null,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
|
|
Db::name('enterprise_customers')->where('id', $customer['id'])->update([
|
|
'user_id' => $userId,
|
|
'updated_at' => $now,
|
|
]);
|
|
|
|
return $userId;
|
|
}
|
|
|
|
public function formatCustomer(array $item): array
|
|
{
|
|
return [
|
|
'id' => (int)$item['id'],
|
|
'customer_code' => (string)$item['customer_code'],
|
|
'customer_name' => (string)$item['customer_name'],
|
|
'contact_name' => (string)($item['contact_name'] ?? ''),
|
|
'contact_mobile' => (string)($item['contact_mobile'] ?? ''),
|
|
'contact_email' => (string)($item['contact_email'] ?? ''),
|
|
'settlement_type' => (string)($item['settlement_type'] ?? 'monthly'),
|
|
'settlement_type_text' => '月结',
|
|
'user_id' => (int)($item['user_id'] ?? 0),
|
|
'webhook_url' => (string)($item['webhook_url'] ?? ''),
|
|
'webhook_enabled' => (bool)($item['webhook_enabled'] ?? false),
|
|
'status' => (string)($item['status'] ?? 'enabled'),
|
|
'status_text' => ($item['status'] ?? 'enabled') === 'enabled' ? '启用中' : '已停用',
|
|
'remark' => (string)($item['remark'] ?? ''),
|
|
'created_at' => (string)($item['created_at'] ?? ''),
|
|
'updated_at' => (string)($item['updated_at'] ?? ''),
|
|
];
|
|
}
|
|
|
|
public function formatApp(array $item): array
|
|
{
|
|
return [
|
|
'id' => (int)$item['id'],
|
|
'customer_id' => (int)$item['customer_id'],
|
|
'app_name' => (string)($item['app_name'] ?? ''),
|
|
'app_key' => (string)$item['app_key'],
|
|
'secret_last4' => (string)($item['secret_last4'] ?? ''),
|
|
'status' => (string)($item['status'] ?? 'enabled'),
|
|
'status_text' => ($item['status'] ?? 'enabled') === 'enabled' ? '启用中' : '已停用',
|
|
'last_used_at' => (string)($item['last_used_at'] ?? ''),
|
|
'created_at' => (string)($item['created_at'] ?? ''),
|
|
];
|
|
}
|
|
|
|
private function secretKey(): string
|
|
{
|
|
$seed = $_ENV['APP_KEY'] ?? $_ENV['JWT_SECRET'] ?? 'anxinyan-enterprise-secret-key';
|
|
return hash('sha256', (string)$seed, true);
|
|
}
|
|
}
|