Compare commits

...

12 Commits

Author SHA1 Message Date
李东云
fb3327b252 chore(release): 1.7.0 2025-09-04 17:26:12 +08:00
李东云
975a5ee301 feat(account): 增加积分日志详情查询功能并支持发票信息
- 新增 InvoiceRecord 类用于存储发票信息
- 在 PointLog 类中添加发票相关字段和方法
- 在 PointLogRepo 中实现积分日志详情查询接口
- 更新单元测试以覆盖新功能
2025-09-04 17:25:57 +08:00
李东云
580c2f6ca0 chore(release): 1.6.1 2025-09-04 15:45:09 +08:00
李东云
15c0ecb6fe feat(invoice): 添加发票下载和发送功能
- 在 InvoiceRepoInterface 中新增了 download 和 send 方法的接口
- 在 InvoiceRepo 类中实现了 download 和 send 方法
- 优化了 create 方法的文档注释
2025-09-04 15:44:56 +08:00
李东云
fb54e19366 chore(release): 1.6.0 2025-09-04 15:12:03 +08:00
李东云
366f1d64ad feat(invoice): 添加发票下载功能并优化测试
- 在 InvoiceRepo 中实现 download 方法,用于下载发票 PDF
- 在 CreateInvoiceTest 中添加发票下载测试用例
- 优化测试用例的编写方式,提高可读性
2025-09-04 15:11:39 +08:00
李东云
72f7d37382 feat(invoice): 添加发票发送功能并进行测试
- 在 InvoiceRepo 中添加 send 方法,用于发送发票邮件
- 在 CreateInvoiceTest 中添加测试用例,验证发票发送功能
2025-09-04 15:06:23 +08:00
李东云
2a40b3b219 chore(release): 1.5.3 2025-09-04 11:30:35 +08:00
李东云
86f375b18a refactor(PointLogRepo): 优化 getList 方法参数类型
- 将 $type 参数类型从 string 改为 PointType 枚举
- 使用 isset 和 null 合并条件表达式简化代码
2025-09-04 11:30:30 +08:00
李东云
8a70e35de7 refactor(invoice): 重构发票创建流程和积分日志接口
- 移除 CreateInvoiceCmd 中的 uid 字段
- 更新 InvoiceRepo 中的 create 方法,移除 URL 中的 uid
- 修改 PointLogRepo 中的 getList 方法,增加 type 参数并更新 API 调用
- 更新相关测试文件以适应这些变更
2025-09-04 11:28:26 +08:00
李东云
06a198714e chore(release): 1.5.2 2025-09-02 10:25:01 +08:00
李东云
c2358ae19b fix(AccountBalanceRepo): 修复积分余额过期时间解析
- 在 PointsBalance 类中,将 expiredAt 字段的类型从字符串改为 Carbon 对象
- 优化了对 expiredAt 字段的处理逻辑,增加了空值判断
2025-09-02 10:24:48 +08:00
13 changed files with 212 additions and 11 deletions

View File

@@ -1,4 +1,41 @@
# 版本更新日志
## [1.7.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.6.1...v1.7.0) (2025-09-04)
### ✨ Features | 新功能
* **account:** 增加积分日志详情查询功能并支持发票信息 ([975a5ee](http://124.126.16.154:8888/singularity/hdk-pay/commit/975a5ee30110f27ceba0ef11fba751639189d57b))
### [1.6.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.6.0...v1.6.1) (2025-09-04)
### ✨ Features | 新功能
* **invoice:** 添加发票下载和发送功能 ([15c0ecb](http://124.126.16.154:8888/singularity/hdk-pay/commit/15c0ecb6fe8f227b09c4d4618ffb2f5560e4b261))
## [1.6.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.3...v1.6.0) (2025-09-04)
### ✨ Features | 新功能
* **invoice:** 添加发票下载功能并优化测试 ([366f1d6](http://124.126.16.154:8888/singularity/hdk-pay/commit/366f1d64add68d1bb8a9b3e5f17b23963a91d3bc))
* **invoice:** 添加发票发送功能并进行测试 ([72f7d37](http://124.126.16.154:8888/singularity/hdk-pay/commit/72f7d37382752047ed4c15809f16c3f1d07e16e0))
### [1.5.3](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.2...v1.5.3) (2025-09-04)
### ♻️ Code Refactoring | 代码重构
* **invoice:** 重构发票创建流程和积分日志接口 ([8a70e35](http://124.126.16.154:8888/singularity/hdk-pay/commit/8a70e35de72d269bbbd0b5e05c3fa4bccdf1878c))
* **PointLogRepo:** 优化 getList 方法参数类型 ([86f375b](http://124.126.16.154:8888/singularity/hdk-pay/commit/86f375b18a0c3213e405b6fcaec20224979dd991))
### [1.5.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.1...v1.5.2) (2025-09-02)
### 🐛 Bug Fixes | Bug 修复
* **AccountBalanceRepo:** 修复积分余额过期时间解析 ([c2358ae](http://124.126.16.154:8888/singularity/hdk-pay/commit/c2358ae19b072dc0f84a76949ce748f9ce15da4f))
### [1.5.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.0...v1.5.1) (2025-09-01)

View File

@@ -70,5 +70,5 @@
"url": "https://mirrors.aliyun.com/composer/"
}
},
"version": "1.5.1"
"version": "1.7.0"
}

View File

@@ -13,7 +13,6 @@ namespace Singularity\HDK\Pay\Application\Command;
final readonly class CreateInvoiceCmd {
public function __construct(
public string $uid,
public string $caseId,
public bool $setFreqInvAddr,
public string $receiver,

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog;
use Carbon\Carbon;
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\ValueObject\InvoiceRecord;
use Singularity\HDK\Pay\Domain\AggregateRoot;
final class PointLog extends AggregateRoot
@@ -25,6 +26,8 @@ final class PointLog extends AggregateRoot
private readonly string $operator,
private readonly string $description,
private readonly Carbon $date,
private readonly bool $invoiceable,
private readonly ?InvoiceRecord $invoiceRecord,
) {}
public function getDescription(): string
@@ -67,4 +70,19 @@ final class PointLog extends AggregateRoot
{
return $this->id;
}
public function getInvoiceNo(): ?string
{
return $this->invoiceRecord?->invoiceNo;
}
public function getInvoiceReceiver(): ?string
{
return $this->invoiceRecord?->receiver;
}
public function getInvoiceable(): bool
{
return $this->invoiceable;
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* InvoiceRecord.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/9/4
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\ValueObject;
final class InvoiceRecord
{
public function __construct(
public string $invoiceNo,
public string $receiver,
) {}
}

View File

@@ -19,4 +19,9 @@ interface PointLogRepoInterface
*/
public function getList(string $uid): array;
/**
* @param string $caseId
* @return PointLog
*/
public function getDetail(string $caseId): PointLog;
}

View File

@@ -9,6 +9,8 @@
namespace Singularity\HDK\Pay\Domain\Invoice\Repository;
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;
@@ -17,6 +19,21 @@ interface InvoiceRepoInterface
/**
* @param CreateInvoiceCmd $cmd
* @return Invoice
* @throws GuzzleException
*/
public function create(CreateInvoiceCmd $cmd): Invoice;
/**
* @param string $invoiceNo
* @return ResponseInterface
* @throws GuzzleException
*/
public function download(string $invoiceNo): ResponseInterface;
/**
* @param string $invoiceNo
* @return void
* @throws GuzzleException
*/
public function send(string $invoiceNo): void;
}

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Carbon\Carbon;
use Hyperf\Codec\Json;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
@@ -41,7 +42,7 @@ final class AccountBalanceRepo extends AbstractRepo implements AccountRepoInterf
cost: $pointBalance['cost'],
amount: $pointBalance['amount'],
version: $pointBalance['version'],
expiredAt: $pointBalance['expired_at'],
expiredAt: isset($pointBalance['expired_at']) ? new Carbon($pointBalance['expired_at']): null,
),
array: $result['point_balance'],
),
@@ -63,7 +64,7 @@ final class AccountBalanceRepo extends AbstractRepo implements AccountRepoInterf
cost: $result['cost'],
amount: $result['amount'],
version: $result['version'],
expiredAt: $result['expired_at'],
expiredAt: isset($result['expired_at']) ? new Carbon($result['expired_at']): null,
);
}
}

View File

@@ -12,6 +12,8 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
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;
@@ -19,10 +21,13 @@ use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceRepoInterface;
final class InvoiceRepo extends AbstractRepo implements InvoiceRepoInterface
{
/**
* @inheritDoc
*/
public function create(CreateInvoiceCmd $cmd): Invoice
{
$response = $this->requestService->requestPost(
url: "/rpc/v2/account/$cmd->uid/logs/points/$cmd->caseId/invoices",
url: "/rpc/v2/account/logs/points/$cmd->caseId/invoices",
data: [
'set_freq_addr' => $cmd->setFreqInvAddr,
'receiver' => $cmd->receiver,
@@ -54,4 +59,27 @@ final class InvoiceRepo extends AbstractRepo implements InvoiceRepoInterface
receiver: $result['receiver'],
);
}
/**
* @inheritDoc
*/
public function send(string $invoiceNo): void
{
if (empty($invoiceNo)) {
throw new ValidateException(message: 'invoice no is required.');
}
$this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo/email");
}
/**
* @inheritDoc
*/
public function download(string $invoiceNo): ResponseInterface
{
if (empty($invoiceNo)) {
throw new ValidateException(message: 'invoice no is required.');
}
return $this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo/pdf");
}
}

View File

@@ -12,15 +12,25 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Codec\Json;
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\PointLog;
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\ValueObject\InvoiceRecord;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
use Singularity\HDK\Pay\Domain\Account\Repository\PointLogRepoInterface;
final class PointLogRepo extends AbstractRepo implements PointLogRepoInterface
{
public function getList(string $uid): array
/**
* @param string $uid
* @param PointType|null $type
* @return array{}|PointLog[]
* @throws GuzzleException
*/
public function getList(string $uid, ?PointType $type = null): array
{
$response = $this->requestService->requestGet(url: "/rpc/v2/account/$uid/logs/points");
$type = isset($type) ? $type->value : 'all';
$response = $this->requestService->requestGet(url: "/rpc/v2/account/$uid/balance/$type/logs");
$content = $response->getBody()->getContents();
$result = Json::decode($content);
@@ -35,7 +45,43 @@ final class PointLogRepo extends AbstractRepo implements PointLogRepoInterface
operator: $item['operator'],
description: $item['description'],
date: new Carbon($item['date']),
invoiceable: $item['invoiceable'],
invoiceRecord: isset($item['invoice_record'])
? new InvoiceRecord(
invoiceNo: $item['invoice_record']['invoice_no'],
receiver: $item['invoice_record']['receiver'],
)
: null,
);
}, $result);
}
/**
* @inheritDoc
*/
public function getDetail(string $caseId): PointLog
{
$response = $this->requestService->requestGet(url: "/rpc/v2/account/logs/points/$caseId");
$content = $response->getBody()->getContents();
$result = Json::decode($content);
return new PointLog(
id: $result['id'],
caseId: $result['case_id'],
uid: $result['uid'],
credits: $result['credits'],
source: $result['source'],
operator: $result['operator'],
description: $result['description'],
date: new Carbon($result['date']),
invoiceable: $result['invoiceable'],
invoiceRecord: isset($result['invoice_record'])
? new InvoiceRecord(
$result['invoice_record']['invoice_no'],
$result['invoice_record']['receiver'],
)
: null,
);
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* QueryPointLogListTest.php@Pay
* QueryPointLogTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
@@ -23,3 +23,12 @@ it('should can query point log list', function () {
->each
->toBeInstanceOf(PointLog::class);
});
it('should can query a point log', function () {
$case_id = '68b6ac37a6440';
$repo = make(PointLogRepo::class);
$log = $repo->getDetail($case_id);
expect($log)
->toBeInstanceOf(PointLog::class);
});

View File

@@ -8,6 +8,7 @@
* Created on 2025/8/29
*/
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\Infrastructure\Repository\InvoiceRepo;
@@ -19,7 +20,6 @@ it('should can create invoice', function () {
$invoice = $repo->create(
new CreateInvoiceCmd(
uid: '61dbe752d4caa',
caseId: '68affb136c01d',
setFreqInvAddr: true,
receiver: "dongyun.li@luxcreo.ai",
@@ -35,3 +35,24 @@ it('should can create invoice', function () {
expect($invoice)
->toBeInstanceOf(Invoice::class);
});
it('should can send invoice email to receiver', function () {
$repo = make(InvoiceRepo::class);
expect(
(function () use ($repo) {
$invoice_no = '517268';
$repo->send($invoice_no);
return true;
})(),
)->not->toThrow(Throwable::class);
});
it('should can download invoice pdf', function () {
$repo = make(InvoiceRepo::class);
$invoice_no = '517268';
$response = $repo->download($invoice_no);
expect($response)->toBeInstanceOf(ResponseInterface::class);
});

View File

@@ -29,7 +29,7 @@ test('能够正常创建 Stripe 订单', function () {
service: 1
);
expect($order)->toBeInstanceOf(Order::class);
});
})->skip();
test('能够正常获取 Stripe 配置信息', function () {
/** @var StripeRpc $service */
@@ -40,4 +40,4 @@ test('能够正常获取 Stripe 配置信息', function () {
->toBeInstanceOf(StripeConfiguration::class)
->toHaveKeys(['id', 'pk'])
->and($configures->resolve())->toBeArray();
});
})->skip();