From 93f923181c41ce7e96077f304efe6e980231f1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=B8=9C=E4=BA=91?= Date: Fri, 5 Sep 2025 19:02:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(invoice):=20=E6=B7=BB=E5=8A=A0=E5=8F=91?= =?UTF-8?q?=E7=A5=A8=E8=AF=A6=E6=83=85=E6=9F=A5=E8=AF=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 InvoiceInfo 类封装发票信息 - 新增 PointBalance 类封装积分余额信息 - 在 InvoiceRepoInterface 接口中添加 findOne 方法 - 在 InvoiceRepo 类中实现 findOne 方法,用于查询单张发票详情 - 添加单元测试验证 findOne 方法的功能 --- .../Invoice/Aggregate/Invoice/InvoiceInfo.php | 81 +++++++++++++++++++ .../Invoice/ValueObject/PointBalance.php | 20 +++++ .../Repository/InvoiceRepoInterface.php | 7 ++ src/Infrastructure/Repository/InvoiceRepo.php | 48 +++++++++++ .../Invoice/QueryInvoiceDetailTest.php | 23 ++++++ 5 files changed, 179 insertions(+) create mode 100644 src/Domain/Invoice/Aggregate/Invoice/InvoiceInfo.php create mode 100644 src/Domain/Invoice/Aggregate/Invoice/ValueObject/PointBalance.php create mode 100644 tests/Feature/Invoice/QueryInvoiceDetailTest.php diff --git a/src/Domain/Invoice/Aggregate/Invoice/InvoiceInfo.php b/src/Domain/Invoice/Aggregate/Invoice/InvoiceInfo.php new file mode 100644 index 0000000..05bd06e --- /dev/null +++ b/src/Domain/Invoice/Aggregate/Invoice/InvoiceInfo.php @@ -0,0 +1,81 @@ + + * Powered by PhpStorm + * Created on 2025/9/5 + */ +declare(strict_types=1); + +namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice; + +use Carbon\Carbon; +use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointBalance; + +final readonly class InvoiceInfo +{ + public function __construct( + private string $invoiceNo, + private string $uid, + private string $caseId, + private Address $address, + private InvoiceProduct $product, + private PointBalance $balance, + private string $receiver, + private Carbon $invoiceAt, + private Carbon $designedAt, + private string $patientName, + ) {} + + public function getInvoiceNo(): string + { + return $this->invoiceNo; + } + + public function getUid(): string + { + return $this->uid; + } + + public function getCaseId(): string + { + return $this->caseId; + } + + public function getAddress(): Address + { + return $this->address; + } + + public function getProduct(): InvoiceProduct + { + return $this->product; + } + + public function getBalance(): PointBalance + { + return $this->balance; + } + + public function getReceiver(): string + { + return $this->receiver; + } + + public function getInvoiceAt(): Carbon + { + return $this->invoiceAt; + } + + public function getDesignedAt(): Carbon + { + return $this->designedAt; + } + + public function getPatientName(): string + { + return $this->patientName; + } +} \ No newline at end of file diff --git a/src/Domain/Invoice/Aggregate/Invoice/ValueObject/PointBalance.php b/src/Domain/Invoice/Aggregate/Invoice/ValueObject/PointBalance.php new file mode 100644 index 0000000..31266cf --- /dev/null +++ b/src/Domain/Invoice/Aggregate/Invoice/ValueObject/PointBalance.php @@ -0,0 +1,20 @@ + + * Powered by PhpStorm + * Created on 2025/9/5 + */ +declare(strict_types=1); + +namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject; + +final readonly class PointBalance { + public function __construct( + public float $total, + public float $cost, + public float $remain, + ) {} +} \ No newline at end of file diff --git a/src/Domain/Invoice/Repository/InvoiceRepoInterface.php b/src/Domain/Invoice/Repository/InvoiceRepoInterface.php index a92b448..ef8a276 100644 --- a/src/Domain/Invoice/Repository/InvoiceRepoInterface.php +++ b/src/Domain/Invoice/Repository/InvoiceRepoInterface.php @@ -13,6 +13,7 @@ use GuzzleHttp\Exception\GuzzleException; use Psr\Http\Message\ResponseInterface; use Singularity\HDK\Pay\Application\Command\CreateInvoiceCmd; use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Invoice; +use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo; interface InvoiceRepoInterface { @@ -36,4 +37,10 @@ interface InvoiceRepoInterface * @throws GuzzleException */ public function send(string $invoiceNo): void; + + /** + * @param string $invoiceNo + * @return InvoiceInfo + */ + public function findOne(string $invoiceNo): InvoiceInfo; } \ No newline at end of file diff --git a/src/Infrastructure/Repository/InvoiceRepo.php b/src/Infrastructure/Repository/InvoiceRepo.php index 7e59ec4..ee84361 100644 --- a/src/Infrastructure/Repository/InvoiceRepo.php +++ b/src/Infrastructure/Repository/InvoiceRepo.php @@ -11,12 +11,16 @@ declare(strict_types=1); namespace Singularity\HDK\Pay\Infrastructure\Repository; +use Carbon\Carbon; use Hyperf\Codec\Json; use Psr\Http\Message\ResponseInterface; use Singularity\HDK\Core\Exceptions\ValidateException; use Singularity\HDK\Pay\Application\Command\CreateInvoiceCmd; use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Address; use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Invoice; +use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo; +use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct; +use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointBalance; use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceRepoInterface; final class InvoiceRepo extends AbstractRepo implements InvoiceRepoInterface @@ -82,4 +86,48 @@ final class InvoiceRepo extends AbstractRepo implements InvoiceRepoInterface return $this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo/pdf"); } + + /** + * @inheritDoc + */ + public function findOne(string $invoiceNo): InvoiceInfo + { + if (empty($invoiceNo)) { + throw new ValidateException(message: 'invoice no is required.'); + } + + $response = $this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo"); + $content = $response->getBody()->getContents(); + $result = Json::decode($content); + + return new InvoiceInfo( + invoiceNo: $result['invoice_no'], + uid: $result['uid'], + caseId: $result['case_id'], + address: new Address( + patientName: $result['patient_name'], + address: $result['address']['address'], + city: $result['address']['city'], + state: $result['address']['state'], + country: $result['address']['country'], + zipCode: $result['address']['zip_code'], + ), + product: new InvoiceProduct( + caseId: $result['case_id'], + uid: $result['uid'], + name: $result['product']['name'], + sku: $result['product']['sku'], + description: $result['product']['description'], + ), + balance: new PointBalance( + total: $result['balance']['total'], + cost: $result['balance']['cost'], + remain: $result['balance']['remain'], + ), + receiver: $result['receiver'], + invoiceAt: new Carbon($result['invoice_at']), + designedAt: new Carbon($result['designed_at']), + patientName: $result['patient_name'], + ); + } } \ No newline at end of file diff --git a/tests/Feature/Invoice/QueryInvoiceDetailTest.php b/tests/Feature/Invoice/QueryInvoiceDetailTest.php new file mode 100644 index 0000000..ee63e76 --- /dev/null +++ b/tests/Feature/Invoice/QueryInvoiceDetailTest.php @@ -0,0 +1,23 @@ + + * Powered by PhpStorm + * Created on 2025/9/5 + */ + +use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo; +use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceRepo; + +use function Hyperf\Support\make; + +it('should can query invoice detail', function () { + $repo = make(InvoiceRepo::class); + + $invoiceNo = '517268'; + $result = $repo->findOne($invoiceNo); + expect($result) + ->toBeInstanceOf(InvoiceInfo::class); +});