Compare commits

...

14 Commits

Author SHA1 Message Date
李东云
7e0d711e99 chore(release): 1.9.4 2025-09-19 15:35:43 +08:00
李东云
eb44b6e3b6 fix(product): 修复产品列表中点数显示问题
- 在 RechargeProductsDto 类中,修改了 bonus_rate_pct 的计算方式
- 使用 round 函数对结果进行四舍五入,提高精度
- 调整 scale 参数为3,增加小数位数- 这些修改提高了点数计算的准确性,解决了产品列表中的点数显示问题
2025-09-19 15:35:27 +08:00
李东云
3af39e4254 chore(release): 1.9.3 2025-09-19 10:17:29 +08:00
李东云
8bbc8ed629 feat(PointType): 添加 ScanToModel 作为点类型
在 PointType 枚举中添加了新的点类型 ScanToModel,以支持新的扫描建模功能。
2025-09-19 10:17:21 +08:00
李东云
48e6fafe8e chore(release): 1.9.2 2025-09-19 09:45:32 +08:00
李东云
874a6f4fa9 feat(Account): 添加新的积分类型
- 新增 ScanToModel 积分类型
- 用于奖励完成扫描取模的用户
2025-09-19 09:45:18 +08:00
李东云
8ac850fc62 chore(release): 1.9.1 2025-09-17 20:35:04 +08:00
李东云
8f8f7b08b0 fix(account): 修复初始账户命令和测试
- 修改 InitialAccountCmd 类的属性和方法
- 更新 addPointsBalance 方法的参数和返回值
- 调整测试数据和测试逻辑以适应新的命令结构
2025-09-17 20:34:51 +08:00
李东云
203dd34353 chore(release): 1.9.0 2025-09-17 20:04:00 +08:00
李东云
87b09ef34c feat(account): 添加初始化账户余额功能
- 新增 InitialAccountCmd 类用于处理初始账户命令
- 在 AccountRepoInterface 接口中添加 initial 方法
- 实现 AccountBalanceRepo 类中的 initial 方法
- 添加单元测试 InitialAccountBalanceTest 以验证初始化功能
2025-09-17 20:03:45 +08:00
李东云
a59d979076 chore(release): 1.8.2 2025-09-17 14:41:12 +08:00
李东云
686d835a91 fix(ProductRepo): 修复产品仓库中的数组为空的处理逻辑
- 优化了 one_time、package 和 plan 数据的处理方式
- 使用 array_map 函数替代循环,提高代码可读性
- 增加空值合并运算符 ??,提高代码健壮性
-调整代码格式,提高代码整洁度
2025-09-17 14:40:56 +08:00
李东云
65b060e5d3 chore(release): 1.8.1 2025-09-06 03:06:53 +08:00
李东云
3b12216344 feat(PointLog): 添加获取病人姓名的方法并更新相关代码
- 在 PointLog 类中添加 patientName属性和 getPatientName() 方法
- 更新 PointLogRepo 类,从数据库中获取并设置 patient_name 字段
2025-09-06 03:06:43 +08:00
11 changed files with 260 additions and 61 deletions

View File

@@ -1,4 +1,53 @@
# 版本更新日志
### [1.9.4](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.3...v1.9.4) (2025-09-19)
### 🐛 Bug Fixes | Bug 修复
* **product:** 修复产品列表中点数显示问题 ([eb44b6e](http://124.126.16.154:8888/singularity/hdk-pay/commit/eb44b6e3b6e9a2e3f757076d0d4438163e7d1f51))
### [1.9.3](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.2...v1.9.3) (2025-09-19)
### ✨ Features | 新功能
* **PointType:** 添加 ScanToModel 作为点类型 ([8bbc8ed](http://124.126.16.154:8888/singularity/hdk-pay/commit/8bbc8ed629e5c15e42db0adf758505e531ff3dca))
### [1.9.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.1...v1.9.2) (2025-09-19)
### ✨ Features | 新功能
* **Account:** 添加新的积分类型 ([874a6f4](http://124.126.16.154:8888/singularity/hdk-pay/commit/874a6f4fa96b09a4c6c652b6d285d4b6631a3c66))
### [1.9.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.0...v1.9.1) (2025-09-17)
### 🐛 Bug Fixes | Bug 修复
* **account:** 修复初始账户命令和测试 ([8f8f7b0](http://124.126.16.154:8888/singularity/hdk-pay/commit/8f8f7b08b03d9b810bb09ce4b1f15a27cbd43e68))
## [1.9.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.8.2...v1.9.0) (2025-09-17)
### ✨ Features | 新功能
* **account:** 添加初始化账户余额功能 ([87b09ef](http://124.126.16.154:8888/singularity/hdk-pay/commit/87b09ef34cd3427816ef2c357406a74975ada8a9))
### [1.8.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.8.1...v1.8.2) (2025-09-17)
### 🐛 Bug Fixes | Bug 修复
* **ProductRepo:** 修复产品仓库中的数组为空的处理逻辑 ([686d835](http://124.126.16.154:8888/singularity/hdk-pay/commit/686d835a9130d60768eef37a3c9a67c6526cb418))
### [1.8.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.8.0...v1.8.1) (2025-09-05)
### ✨ Features | 新功能
* **PointLog:** 添加获取病人姓名的方法并更新相关代码 ([3b12216](http://124.126.16.154:8888/singularity/hdk-pay/commit/3b1221634419f0ca39359e36c0363602b075b9b8))
## [1.8.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.7.0...v1.8.0) (2025-09-05)

View File

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

View File

@@ -0,0 +1,40 @@
<?php
/**
* InitialAccountCmd.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/9/17
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Application\Command;
use Carbon\Carbon;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
final class InitialAccountCmd
{
public array $pointsBalances;
public function __construct(
public readonly string $uid,
) {}
public function addPointsBalance(
PointType $type,
float $basic = 0.0,
float $bonus = 0.0,
?Carbon $expiredAt = null,
?string $version = null,
): array {
return $this->pointsBalances[] = [
'type' => $type->value,
'basic' => $basic,
'bonus' => $bonus,
'expired_at' => $expiredAt->toDateTimeString(),
'version' => $version,
];
}
}

View File

@@ -54,17 +54,19 @@ final class RechargeProductsDto extends AbstractDto
if (!$is_ftai) {
$result += [
'total_points' => $effect->getPointTotal(),
'bonus_rate_pct' => (float)(bcmul(
num1: $effect->getPointTotal() == 0
? '0'
: bcdiv(
(string)$effect->pointBonus,
(string)$effect->getPointTotal(),
3,
),
num2: '100',
scale: 0,
)),
'bonus_rate_pct' => round(
(float)(bcmul(
num1: $effect->getPointTotal() == 0
? '0'
: bcdiv(
(string)$effect->pointBonus,
(string)$effect->getPointTotal(),
3,
),
num2: '100',
scale: 3,
)),
),
'point' => [
'total' => $effect->getPointTotal(),
'number' => $effect->pointBasic,

View File

@@ -25,11 +25,17 @@ final class PointLog extends AggregateRoot
private readonly string $source,
private readonly string $operator,
private readonly string $description,
private readonly string $patientName,
private readonly Carbon $date,
private readonly bool $invoiceable,
private readonly ?InvoiceRecord $invoiceRecord,
) {}
public function getPatientName(): string
{
return $this->patientName;
}
public function getDescription(): string
{
return $this->description;

View File

@@ -16,11 +16,15 @@ enum PointType: string
case EMA = 'ema';
case FtaiAligner = 'aligner';
case FtaiRetainer = 'retainer';
case Aligner4D = 'aligner-4d';
case NightguardAi = 'nightguard-ai';
case ScanToModel = 'scan-to-model';
public static function values(): array
{
return [
@@ -30,6 +34,7 @@ enum PointType: string
self::FtaiRetainer->value,
self::Aligner4D->value,
self::NightguardAi->value,
self::ScanToModel->value
];
}
}

View File

@@ -11,13 +11,29 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Account\Repository;
use Singularity\HDK\Pay\Application\Command\InitialAccountCmd;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
interface AccountRepoInterface
{
/**
* @param string $uid
* @return AccountBalance
*/
public function getAccount(string $uid): AccountBalance;
/**
* @param string $uid
* @param PointType $pointType
* @return PointsBalance
*/
public function getPointBalance(string $uid, PointType $pointType): PointsBalance;
/**
* @param InitialAccountCmd $cmd
* @return void
*/
public function initial(InitialAccountCmd $cmd): void;
}

View File

@@ -13,6 +13,7 @@ namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Carbon\Carbon;
use Hyperf\Codec\Json;
use Singularity\HDK\Pay\Application\Command\InitialAccountCmd;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
@@ -67,4 +68,17 @@ final class AccountBalanceRepo extends AbstractRepo implements AccountRepoInterf
expiredAt: isset($result['expired_at']) ? new Carbon($result['expired_at']): null,
);
}
/**
* @inheritDoc
*/
public function initial(InitialAccountCmd $cmd): void
{
$uid = $cmd->uid;
$this->requestService->requestPost(
url: "/rpc/v2/account/$uid/balance",
data: $cmd->pointsBalances
);
}
}

View File

@@ -44,6 +44,7 @@ final class PointLogRepo extends AbstractRepo implements PointLogRepoInterface
source: $item['source'],
operator: $item['operator'],
description: $item['description'],
patientName: $item['patient_name'],
date: new Carbon($item['date']),
invoiceable: $item['invoiceable'],
invoiceRecord: isset($item['invoice_record'])
@@ -74,6 +75,7 @@ final class PointLogRepo extends AbstractRepo implements PointLogRepoInterface
source: $result['source'],
operator: $result['operator'],
description: $result['description'],
patientName: $result['patient_name'],
date: new Carbon($result['date']),
invoiceable: $result['invoiceable'],
invoiceRecord: isset($result['invoice_record'])

View File

@@ -45,7 +45,7 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
id: $result['one_time']['id'],
description: $result['one_time']['name'],
unitPrice: new Money(
amount:bcmul((string)$result['one_time']['price'], '100'),
amount: bcmul((string)$result['one_time']['price'], '100'),
currency: new Currency($result['one_time']['currency']),
),
productType: ProductType::oneTime,
@@ -55,20 +55,23 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
pointBonus: $result['one_time']['point']['bonus'],
),
),
packages: array_map(fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
packages: array_map(
fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
),
productType: ProductType::pack,
effect: new RechargeEffect(
pointType: PointType::LuxPoint,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
),
productType: ProductType::pack,
effect: new RechargeEffect(
pointType: PointType::LuxPoint,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
), $result['package']),
$result['package'] ?? [],
),
);
}
@@ -99,29 +102,35 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
),
)
: null,
plans: array_map(fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
plans: array_map(
fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
),
productType: ProductType::plan,
),
productType: ProductType::plan,
), $result['plan']),
packages: array_map(fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
$result['plan'] ?? [],
),
packages: array_map(
fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
),
productType: ProductType::plan,
effect: new RechargeEffect(
pointType: $pointType,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
),
productType: ProductType::plan,
effect: new RechargeEffect(
pointType: $pointType,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
), $result['package']),
$result['package'] ?? [],
),
);
}
@@ -144,7 +153,7 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
id: $result['one_time']['id'],
description: $result['one_time']['name'],
unitPrice: new Money(
amount:bcmul((string)$result['one_time']['price'], '100'),
amount: bcmul((string)$result['one_time']['price'], '100'),
currency: new Currency($result['one_time']['currency']),
),
productType: ProductType::oneTime,
@@ -171,20 +180,23 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
),
)
: null,
plans: array_map(fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
plans: array_map(
fn(array $item) => new ProductItem(
id: $item['id'],
description: $item['name'],
unitPrice: new Money(
amount: bcmul((string)$item['price'], '100'),
currency: new Currency($item['currency']),
),
productType: ProductType::plan,
effect: new RechargeEffect(
pointType: PointType::EMA,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
),
productType: ProductType::plan,
effect: new RechargeEffect(
pointType: PointType::EMA,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
), $result['plan']),
$result['plan'] ?? [],
),
);
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* InitialAccountBalanceTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/9/17
*/
use Carbon\Carbon;
use Singularity\HDK\Pay\Application\Command\InitialAccountCmd;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
use function Hyperf\Support\make;
it('should initial account balance', function () {
$uid = uniqid('TDD');
$data = [
[
'type' => 'aligner',
'basic' => 0,
'bonus' => 40,
'expired_at' => Carbon::now()->addYear(),
'version' => 'trial',
],
[
'type' => 'ema',
'basic' => 0,
'bonus' => 1,
'expired_at' => Carbon::now()->addYear(),
'version' => 'Trial',
],
];
$cmd = new InitialAccountCmd($uid);
foreach ($data as $point_balance) {
$cmd->addPointsBalance(
type: PointType::from($point_balance['type']),
basic: $point_balance['basic'],
bonus: $point_balance['bonus'],
expiredAt:$point_balance['expired_at'],
version: $point_balance['version'],
);
}
$repo = make(AccountBalanceRepo::class);
$repo->initial($cmd);
expect(true)->toBeTrue();
});