更新
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service\prescriptionai;
|
||||
|
||||
use DomainException;
|
||||
use think\facade\Db;
|
||||
|
||||
/** Save-response recovery for new clients; contains hashes, never prescription content. */
|
||||
final class PrescriptionAiRequest
|
||||
{
|
||||
private static function key(array $params, int $actorId): ?string
|
||||
{
|
||||
$key = $params['request_key'] ?? '';
|
||||
if (!PrescriptionAiStore::enabled() || $key === '') {
|
||||
return null;
|
||||
}
|
||||
if (!is_string($key) || !preg_match('/^[a-zA-Z0-9_-]{16,64}$/D', $key)) {
|
||||
throw new DomainException('保存请求标识无效');
|
||||
}
|
||||
return hash('sha256', $actorId . ':' . $key);
|
||||
}
|
||||
|
||||
private static function fingerprint(array $params): string
|
||||
{
|
||||
unset($params['request_key']);
|
||||
return hash('sha256', PrescriptionAiPolicy::canonical($params));
|
||||
}
|
||||
|
||||
public static function replay(array $params, int $actorId, bool $reserve = false): ?int
|
||||
{
|
||||
$key = self::key($params, $actorId);
|
||||
if ($key === null) {
|
||||
return null;
|
||||
}
|
||||
$hash = self::fingerprint($params);
|
||||
if ($reserve) {
|
||||
Db::name('prescription_ai_request')->extra('IGNORE')->insert([
|
||||
'request_key' => $key, 'actor_id' => $actorId, 'request_hash' => $hash,
|
||||
'prescription_id' => 0, 'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
$row = Db::name('prescription_ai_request')->where('request_key', $key)->lock($reserve)->find();
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
if ((int) $row['actor_id'] !== $actorId || !hash_equals($row['request_hash'], $hash)) {
|
||||
throw new DomainException('请求标识已用于其他处方内容,请重新保存');
|
||||
}
|
||||
if ((int) $row['prescription_id'] > 0) {
|
||||
$exists = Db::name('tcm_prescription')->where('id', $row['prescription_id'])
|
||||
->where('creator_id', $actorId)->whereNull('delete_time')->count();
|
||||
if (!$exists) {
|
||||
throw new DomainException('此保存请求对应处方已删除,请重新开方');
|
||||
}
|
||||
return (int) $row['prescription_id'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function complete(array $params, int $actorId, int $prescriptionId): void
|
||||
{
|
||||
$key = self::key($params, $actorId);
|
||||
if ($key !== null) {
|
||||
Db::name('prescription_ai_request')->where('request_key', $key)->update(['prescription_id' => $prescriptionId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user