Compare commits

...

63 Commits

Author SHA1 Message Date
李东云
e92a6f46a4 chore(release): 1.11.1 2025-11-27 16:01:04 +08:00
李东云
e0748e444b chore(release): 1.11.0 2025-11-27 11:52:19 +08:00
李东云
244dd1220a feat(invoice): 添加发票金额和货币支持
- 在 CreateInvoiceCmd 中新增 price 和 currencySymbol 字段
- 在 Invoice 聚合根中集成 Money 对象并添加相关方法
- 更新 InvoiceRepo 以处理价格数据的序列化与反序列化
- 在测试中增加对新字段的验证
2025-11-27 11:51:46 +08:00
李东云
8a9971bc59 chore(release): 1.10.0 2025-11-25 16:01:52 +08:00
李东云
4c5dde9020 feat(invoice): 引入点数价格值对象并更新发票产品结构
- 新增 PointPrice 值对象用于表示金额与货币符号
- 修改 InvoiceProduct 结构以支持多个 PointPrice 实例
- 更新 InvoiceProductRepo 以映射数据库中的价格数据
- 在测试中验证 prices 字段的正确性和类型安全
2025-11-25 16:01:25 +08:00
李东云
1cb20a7c7e test(product): 移除测试中的 only 标记
- 移除了 QueryPointRateTest 中两个测试用例的 only 标记
- 确保所有测试用例都能正常执行
- 避免因 only 标记导致其他测试被跳过
2025-11-25 15:30:06 +08:00
李东云
028721feb1 chore(deps): 移除 Carbon 依赖包
- 从 composer.json 中移除了 nesbot/carbon 依赖
- 保留了 swoole/ide-helper 依赖包
- 更新了依赖包列表格式以保持整洁
2025-11-25 14:54:22 +08:00
李东云
bd00102081 chore(release): 1.9.7 2025-10-30 15:19:26 +08:00
李东云
7763b088df feat(account): 添加4D X无限奖励积分类型
- 在PointType枚举中新增FourDXUnlimitedBonusCredits类型
- 更新values方法以包含新的积分类型值
2025-10-30 15:19:18 +08:00
李东云
cd56a6214b chore(release): 1.9.6 2025-09-19 16:48:36 +08:00
李东云
31559fdf5d refactor(Domain): 重构 ExchangeRepoInterface 接口
-将 getRate 方法的 $uid 参数类型从 string 改为 ?string
2025-09-19 16:48:31 +08:00
李东云
41d768ba82 chore(release): 1.9.5 2025-09-19 16:42:28 +08:00
李东云
c552dd8ed0 refactor(ProductRepo): 优化 getRate 方法参数处理
- 将 getRate 方法的 $uid 参数变更为可选参数
- 使用 array_filter 过滤空值,避免在请求中发送不必要的参数
- 增加了两个单元测试用例,分别测试不带 uid 和带 uid 的情况
2025-09-19 16:41:26 +08:00
李东云
e7e1c7f6c9 refactor(domain): 更新汇率接口并添加 UID 参数
- 在 ExchangeRepoInterface 中添加了 uid 参数
- 在 ProductRepo 中实现了 getRate 方法,增加了 uid 参数
- 更新了单元测试,添加了 uid 参数
2025-09-19 16:39:09 +08:00
李东云
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
李东云
7354abb99a chore(release): 1.8.0 2025-09-05 19:02:29 +08:00
李东云
93f923181c feat(invoice): 添加发票详情查询功能
- 新增 InvoiceInfo 类封装发票信息
- 新增 PointBalance 类封装积分余额信息
- 在 InvoiceRepoInterface 接口中添加 findOne 方法
- 在 InvoiceRepo 类中实现 findOne 方法,用于查询单张发票详情
- 添加单元测试验证 findOne 方法的功能
2025-09-05 19:02:13 +08:00
李东云
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
李东云
5a4edf9258 chore(release): 1.5.1 2025-09-01 17:25:38 +08:00
李东云
d17a67f58e feat(RechargeProductRepoInterface): 添加查找 FTAI 产品的方法
- 在 RechargeProductRepoInterface接口中添加了 findFtaiProduct 方法
- 新方法用于根据 UID 和点数类型查找 FTAI 产品
- 引入了 PointType 枚举类
2025-09-01 17:25:20 +08:00
李东云
23aa9b68bf chore(release): 1.5.0 2025-09-01 17:18:31 +08:00
李东云
48f44f4c4c feat(product): 支持查询 FTAI 产品
- 新增 findFtaiProduct 方法,用于查询 FTAI 产品信息
- 修改 RechargeProductsDto 以支持 FTAI 产品的特殊逻辑
- 更新 ProductItem 实体,允许 effect 属性为 null
- 调整产品价格的处理方式,确保精度正确
-增加 FTAI 产品查询的单元测试
2025-09-01 17:18:01 +08:00
李东云
25612823a5 chore(release): 1.4.1 2025-08-29 11:28:58 +08:00
李东云
c8681a6d54 refactor(invoice): 移除 getCaseProduct 方法中未使用的参数
- 从 InvoiceProductRepoInterface 和 InvoiceProductRepo 中移除了 getCaseProduct 方法的 $uid 参数
- 更新了 QueryCaseInvoiceProductTest 中的测试用例,移除了 $uid 相关的代码- 调整了 API 请求的路径,从 "/rpc/v2/account/$uid/logs/points/$caseId/product" 改为 "/rpc/v2/invoice/$caseId/product"
2025-08-29 11:28:43 +08:00
李东云
c8f3acd62b chore(release): 1.4.0 2025-08-29 04:02:57 +08:00
李东云
d3b861a7f7 feat(invoice): 添加查询用户常用发票地址功能
- 新增 FrequentAddress 类表示常用地址
- 添加 FrequentAddressRepoInterface 接口和 FrequentAddressRepo 实现类
- 在 ConfigProvider 中注册 FrequentAddressRepo
- 编写单元测试验证查询功能
2025-08-29 04:02:48 +08:00
李东云
630d4ba7a4 refactor(invoice): 重构发票相关类的命名空间
-将 ValueObject 目录下的类移动到 Invoice 目录下
- 更新相关的命名空间
- 修改使用这些类的文件,以适应新的命名空间
2025-08-29 03:50:47 +08:00
李东云
b3317c5f8d feat(invoice): 添加创建发票功能
- 新增 CreateInvoiceCmd 类作为创建发票的命令对象
- 创建 Address 类表示发票地址信息
- 实现 Invoice 类作为发票的领域模型
- 添加 InvoiceRepoInterface 接口和 InvoiceRepo 实现类,用于处理发票创建逻辑
- 编写 CreateInvoiceTest测试用例验证发票创建功能
2025-08-29 01:42:42 +08:00
李东云
66a468e702 refactor(invoice): 更新 InvoiceProduct 类的位置
- 将 InvoiceProduct 类从 ValueObject 目录移动到 Aggregate/ValueObject 目录
- 更新类的命名空间以反映新的目录结构
2025-08-29 01:05:32 +08:00
李东云
dd212ad8a2 feat(invoice): 新增发票商品查询功能
- 添加 InvoiceProductRepoInterface 接口用于获取发票商品信息
- 实现 InvoiceProductRepo 类,通过 API 请求获取发票商品数据
- 创建 InvoiceProduct 类作为发票商品的价值对象
- 在 ConfigProvider 中注册 InvoiceProductRepo
- 添加单元测试 QueryCaseInvoiceProductTest 验证功能正确性
2025-08-28 18:52:49 +08:00
李东云
0d4f561ef0 chore(release): 1.3.1 2025-08-27 17:04:54 +08:00
李东云
aa8742923c refactor(account): 优化点数日志仓库接口和实现类
- 在 PointLogRepoInterface 中添加了空行,提高代码可读性
- 在 PointLogRepo 中移除了未使用的 PointType 引用,减少冗余代码
2025-08-27 17:04:40 +08:00
李东云
738d225fd8 chore(release): 1.3.0 2025-08-27 11:31:41 +08:00
李东云
38ce644c73 feat(account): 添加积分日志相关功能
- 新增 PointLog 类用于表示积分日志实体
- 添加 PointAction 枚举类,定义积分操作类型
- 实现 PointLogRepoInterface 接口,提供积分日志查询功能
- 在 ConfigProvider 中注册 PointLogRepo
- 编写单元测试以验证积分日志查询功能
2025-08-27 11:30:48 +08:00
李东云
f2a51fa1da refactor(Account): 重构账户相关类的命名空间
- 将 AccountBalance 和 PointsBalance 类移动到新的命名空间
- 更新相关文件中的 use 语句以适应新的命名空间
- 此改动仅影响文件组织结构,不改变类的功能或接口
2025-08-27 11:06:52 +08:00
李东云
59b5118b93 chore(release): 1.2.7 2025-08-26 16:09:03 +08:00
李东云
c468fdda0e build: 更新发布流程以使用阿里云镜像源
- 修改 /etc/apt/sources.list 文件,将 Debian 官方镜像源替换为阿里云镜像源
- 更新 security.debian.org 为阿里云镜像源
- 这些更改旨在提高构建过程中的下载速度和可靠性
2025-08-26 16:08:50 +08:00
李东云
24709acf09 chore(release): 1.2.6 2025-08-26 16:02:42 +08:00
李东云
f141989a8d refactor(Order): 重构订单资源以支持经典订单解析
- 新增 parseClassicOrder 方法用于解析经典订单
- 修改 toArray 方法,根据订单类型选择性调用 parseClassicOrder
- 引入 Money库以处理金额和货币
2025-08-26 16:02:31 +08:00
48 changed files with 2251 additions and 538 deletions

View File

@@ -17,6 +17,8 @@ jobs:
ls ${{ gitea.workspace }}
- name: Zip files in the repository
run: |
sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list
sed -i 's|security.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list
apt-get update
apt-get install zip
zip -r dist.zip *

View File

@@ -1,4 +1,214 @@
# 版本更新日志
### [1.11.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.11.0...v1.11.1) (2025-11-27)
## [1.11.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.10.0...v1.11.0) (2025-11-27)
### ✨ Features | 新功能
* **invoice:** 添加发票金额和货币支持 ([244dd12](http://124.126.16.154:8888/singularity/hdk-pay/commit/244dd1220a2c19197ef08f41a82bcb273d0900e8))
## [1.10.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.7...v1.10.0) (2025-11-25)
### 🚀 Chore | 构建/工程依赖/工具
* **deps:** 移除 Carbon 依赖包 ([028721f](http://124.126.16.154:8888/singularity/hdk-pay/commit/028721feb1079eaa4fe80f20066912d46634f3df))
### ✅ Tests | 测试
* **product:** 移除测试中的 only 标记 ([1cb20a7](http://124.126.16.154:8888/singularity/hdk-pay/commit/1cb20a7c7e2c1a26c7b72669e6885d39f8d16005))
### ✨ Features | 新功能
* **invoice:** 引入点数价格值对象并更新发票产品结构 ([4c5dde9](http://124.126.16.154:8888/singularity/hdk-pay/commit/4c5dde9020364573d0e9673138620d967149e9f0))
### [1.9.7](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.6...v1.9.7) (2025-10-30)
### ✨ Features | 新功能
* **account:** 添加4D X无限奖励积分类型 ([7763b08](http://124.126.16.154:8888/singularity/hdk-pay/commit/7763b088dff711f2d95e65ec8437000322931f50))
### [1.9.6](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.5...v1.9.6) (2025-09-19)
### ♻️ Code Refactoring | 代码重构
* **Domain:** 重构 ExchangeRepoInterface 接口 ([31559fd](http://124.126.16.154:8888/singularity/hdk-pay/commit/31559fdf5ddec048680f520563fa7de56eae3e90))
### [1.9.5](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.4...v1.9.5) (2025-09-19)
### ♻️ Code Refactoring | 代码重构
* **domain:** 更新汇率接口并添加 UID 参数 ([e7e1c7f](http://124.126.16.154:8888/singularity/hdk-pay/commit/e7e1c7f6c946fa171cdbf8049f1d90864a043685))
* **ProductRepo:** 优化 getRate 方法参数处理 ([c552dd8](http://124.126.16.154:8888/singularity/hdk-pay/commit/c552dd8ed0b00f58fefa47c02219ce4de972e85c))
### [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)
### ✨ Features | 新功能
* **invoice:** 添加发票详情查询功能 ([93f9231](http://124.126.16.154:8888/singularity/hdk-pay/commit/93f923181c41ce7e96077f304efe6e980231f1f6))
## [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)
### ✨ Features | 新功能
* **RechargeProductRepoInterface:** 添加查找 FTAI 产品的方法 ([d17a67f](http://124.126.16.154:8888/singularity/hdk-pay/commit/d17a67f58ee2772191e30eb52c09923f43425989))
## [1.5.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.4.1...v1.5.0) (2025-09-01)
### ✨ Features | 新功能
* **product:** 支持查询 FTAI 产品 ([48f44f4](http://124.126.16.154:8888/singularity/hdk-pay/commit/48f44f4c4ceef95e7315ce52924ea3729f8214f5))
### [1.4.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.4.0...v1.4.1) (2025-08-29)
### ♻️ Code Refactoring | 代码重构
* **invoice:** 移除 getCaseProduct 方法中未使用的参数 ([c8681a6](http://124.126.16.154:8888/singularity/hdk-pay/commit/c8681a6d5445b8b9177a236e41aee25d63d50315))
## [1.4.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.3.1...v1.4.0) (2025-08-28)
### ♻️ Code Refactoring | 代码重构
* **invoice:** 更新 InvoiceProduct 类的位置 ([66a468e](http://124.126.16.154:8888/singularity/hdk-pay/commit/66a468e702a0b550ce7445c66164b10b4edcc41a))
* **invoice:** 重构发票相关类的命名空间 ([630d4ba](http://124.126.16.154:8888/singularity/hdk-pay/commit/630d4ba7a427bc7bece24093f783634d3e707b2f))
### ✨ Features | 新功能
* **invoice:** 新增发票商品查询功能 ([dd212ad](http://124.126.16.154:8888/singularity/hdk-pay/commit/dd212ad8a26f03f2b6e204e5485120e267ba73a2))
* **invoice:** 添加创建发票功能 ([b3317c5](http://124.126.16.154:8888/singularity/hdk-pay/commit/b3317c5f8d65aae811130f4af9d09cce514047ff))
* **invoice:** 添加查询用户常用发票地址功能 ([d3b861a](http://124.126.16.154:8888/singularity/hdk-pay/commit/d3b861a7f75281168ec16562aec290f1904fda7e))
### [1.3.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.3.0...v1.3.1) (2025-08-27)
### ♻️ Code Refactoring | 代码重构
* **account:** 优化点数日志仓库接口和实现类 ([aa87429](http://124.126.16.154:8888/singularity/hdk-pay/commit/aa8742923c38ae90386c83b8a280a47dacc3537b))
## [1.3.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.7...v1.3.0) (2025-08-27)
### ♻️ Code Refactoring | 代码重构
* **Account:** 重构账户相关类的命名空间 ([f2a51fa](http://124.126.16.154:8888/singularity/hdk-pay/commit/f2a51fa1da67d5169761bc47cbe2b6da605051ae))
### ✨ Features | 新功能
* **account:** 添加积分日志相关功能 ([38ce644](http://124.126.16.154:8888/singularity/hdk-pay/commit/38ce644c7351740641901a0497351f45c0119339))
### [1.2.7](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.6...v1.2.7) (2025-08-26)
### 📦‍ Build System | 打包构建
* 更新发布流程以使用阿里云镜像源 ([c468fdd](http://124.126.16.154:8888/singularity/hdk-pay/commit/c468fdda0e4fd8bf5b2253527b368362ccb81954))
### [1.2.6](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.5...v1.2.6) (2025-08-26)
### ♻️ Code Refactoring | 代码重构
* **Order:** 重构订单资源以支持经典订单解析 ([f141989](http://124.126.16.154:8888/singularity/hdk-pay/commit/f141989a8d7c6055d0d740619cc0660a1ea0ef7f))
### [1.2.5](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.4...v1.2.5) (2025-08-26)

View File

@@ -36,8 +36,7 @@
"firebase/php-jwt": "^6.8.0",
"hyperf/testing": "^3.1",
"friendsofhyperf/pest-plugin-hyperf": "3.1.*",
"swoole/ide-helper": "^4.8.13",
"nesbot/carbon": "^2.0"
"swoole/ide-helper": "^4.8.13"
},
"minimum-stability": "beta",
"prefer-stable": true,
@@ -70,5 +69,5 @@
"url": "https://mirrors.aliyun.com/composer/"
}
},
"version": "1.2.5"
"version": "1.11.1"
}

987
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
<?php
/**
* CreateInvoiceCmd.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Application\Command;
use Money\Money;
final readonly class CreateInvoiceCmd
{
public function __construct(
public string $caseId,
public bool $setFreqInvAddr,
public string $receiver,
public string $patientName,
public string $address,
public string $city,
public string $state,
public string $country,
public string $zipCode,
public Money $price,
public string $currencySymbol,
) {}
}

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

@@ -43,28 +43,38 @@ final class RechargeProductsDto extends AbstractDto
$effect = $product->effect;
$price = $product->unitPrice;
return [
$result = [
'id' => $product->id,
'name' => $product->description,
'currency' => $price->getCurrency()->getCode(),
'price' => (float)$price->getAmount(),
'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,
)),
'point' => [
'total' => $effect->getPointTotal(),
'number' => $effect->pointBasic,
'bonus' => $effect->pointBonus,
],
'price' => (float)bcdiv($price->getAmount(), '100', 2),
];
$is_ftai = empty($effect);
if (!$is_ftai) {
$result += [
'total_points' => $effect->getPointTotal(),
'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,
'bonus' => $effect->pointBonus,
],
];
}
return $result;
}
}

View File

@@ -7,11 +7,19 @@ namespace Singularity\HDK\Pay;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Framework\Logger\StdoutLogger;
use Singularity\HDK\Pay\Domain\Account\Repository\AccountRepoInterface;
use Singularity\HDK\Pay\Domain\Account\Repository\PointLogRepoInterface;
use Singularity\HDK\Pay\Domain\Invoice\Repository\FrequentAddressRepoInterface;
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceProductRepoInterface;
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceRepoInterface;
use Singularity\HDK\Pay\Domain\Product\Repository\ExchangeRepoInterface;
use Singularity\HDK\Pay\Domain\Product\Repository\RechargeProductRepoInterface;
use Singularity\HDK\Pay\Domain\Transaction\Repository\OrderRepoInterface;
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
use Singularity\HDK\Pay\Infrastructure\Repository\FrequentAddressRepo;
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceProductRepo;
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceRepo;
use Singularity\HDK\Pay\Infrastructure\Repository\OrderRepo;
use Singularity\HDK\Pay\Infrastructure\Repository\PointLogRepo;
use Singularity\HDK\Pay\Infrastructure\Repository\ProductRepo;
/**
@@ -30,11 +38,22 @@ class ConfigProvider
'dependencies' => [
StdoutLoggerInterface::class => StdoutLogger::class,
// Command
// Repo
// account
AccountRepoInterface::class => AccountBalanceRepo::class,
PointLogRepoInterface::class => PointLogRepo::class,
// product
ExchangeRepoInterface::class => ProductRepo::class,
RechargeProductRepoInterface::class => ProductRepo::class,
// transaction
OrderRepoInterface::class => OrderRepo::class,
// invoice
InvoiceProductRepoInterface::class => InvoiceProductRepo::class,
InvoiceRepoInterface::class => InvoiceRepo::class,
FrequentAddressRepoInterface::class => FrequentAddressRepo::class,
],
// 合并到 config/autoload/annotations.php 文件
'annotations' => [

View File

@@ -9,9 +9,7 @@
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Account\Aggregate;
use Singularity\HDK\Pay\Domain\Account\Aggregate\ValueObject\PointsBalance;
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\Account;
/**
* Singularity\HDK\Pay\Domain\Account\Aggregate\AccountBalance@Pay
@@ -27,7 +25,7 @@ final readonly class AccountBalance
{
/**
* @param string $uid
* @param TPointsBalances $pointsBalances
* @param PointsBalance $pointsBalances
*/
public function __construct(
private string $uid,

View File

@@ -9,7 +9,7 @@
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\ValueObject;
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\Account;
use Carbon\Carbon;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;

View File

@@ -0,0 +1,94 @@
<?php
/**
* PointLog.php@LuxPay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/21
*/
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
{
public function __construct(
private readonly int $id,
private readonly string $caseId,
private readonly string $uid,
private readonly float $credits,
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;
}
public function getSource(): string
{
return $this->source;
}
public function getDate(): Carbon
{
return $this->date;
}
public function getUid(): string
{
return $this->uid;
}
public function getCredits(): float
{
return $this->credits;
}
public function getOperator(): string
{
return $this->operator;
}
public function getCaseId(): ?string
{
return $this->caseId;
}
public function getId(): ?int
{
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

@@ -0,0 +1,35 @@
<?php
/**
* PointAction.php@LuxPay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/21
*/
namespace Singularity\HDK\Pay\Domain\Account\Enum;
enum PointAction
{
case Initial;
case Deduct;
case Refund;
case Increase;
case Clear;
public static function tryFrom(string $action): ?PointAction
{
return match (strtolower($action)) {
'initial' => self::Initial,
'deduct' => self::Deduct,
'refund' => self::Refund,
'increase' => self::Increase,
'clear' => self::Clear,
default => null,
};
}
}

View File

@@ -21,6 +21,10 @@ enum PointType: string
case Aligner4D = 'aligner-4d';
case NightguardAi = 'nightguard-ai';
case ScanToModel = 'scan-to-model';
case FourDXUnlimitedBonusCredits = 'aligner-4d-u';
public static function values(): array
{
return [
@@ -30,6 +34,8 @@ enum PointType: string
self::FtaiRetainer->value,
self::Aligner4D->value,
self::NightguardAi->value,
self::ScanToModel->value,
self::FourDXUnlimitedBonusCredits->value,
];
}
}

View File

@@ -11,13 +11,29 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Account\Repository;
use Singularity\HDK\Pay\Domain\Account\Aggregate\AccountBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\ValueObject\PointsBalance;
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

@@ -0,0 +1,27 @@
<?php
/**
* PointLogRepoInterface.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/27
*/
namespace Singularity\HDK\Pay\Domain\Account\Repository;
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\PointLog;
interface PointLogRepoInterface
{
/**
* @param string $uid
* @return PointLog[]
*/
public function getList(string $uid): array;
/**
* @param string $caseId
* @return PointLog
*/
public function getDetail(string $caseId): PointLog;
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* QueryFreqAddrDto.php@LuxPay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address;
use Singularity\HDK\Pay\Domain\AggregateRoot;
final class FrequentAddress extends AggregateRoot
{
public function __construct(
private readonly string $uid,
private readonly string $address,
private readonly string $city,
private readonly string $state,
private readonly string $country,
private readonly string $zipCode,
) {}
public function getUid(): string
{
return $this->uid;
}
public function getAddress(): string
{
return $this->address;
}
public function getCity(): string
{
return $this->city;
}
public function getState(): string
{
return $this->state;
}
public function getCountry(): string
{
return $this->country;
}
public function getZipCode(): string
{
return $this->zipCode;
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* Address.php@LuxPay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/28
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
final readonly class Address {
public function __construct(
private string $patientName,
private string $address,
private string $city,
private string $state,
private string $country,
private string $zipCode,
) {}
public function getPatientName(): string
{
return $this->patientName;
}
public function getAddress(): string
{
return $this->address;
}
public function getCity(): string
{
return $this->city;
}
public function getState(): string
{
return $this->state;
}
public function getCountry(): string
{
return $this->country;
}
public function getZipCode(): string
{
return $this->zipCode;
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* InvoiceDto.php@LuxPay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/28
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
use Money\Money;
use Singularity\HDK\Pay\Domain\AggregateRoot;
final class Invoice extends AggregateRoot
{
public function __construct(
private readonly string $invoiceNo,
private readonly string $uid,
private readonly string $caseId,
private readonly Address $address,
private readonly bool $setFreqInvAddr,
private readonly string $receiver,
private readonly Money $price,
private readonly string $currencySymbol,
) {}
public function getAmount(): float
{
return (float)bcdiv($this->price->getAmount(), '100', 2);
}
public function getCurrencyCode(): string
{
return $this->price->getCurrency()->getCode();
}
public function getCurrencySymbol(): string
{
return $this->currencySymbol;
}
public function getInvoiceNo(): string
{
return $this->invoiceNo;
}
public function getUid(): string
{
return $this->uid;
}
public function getCaseId(): string
{
return $this->caseId;
}
public function isSetFreqInvAddr(): bool
{
return $this->setFreqInvAddr;
}
public function getReceiver(): string
{
return $this->receiver;
}
public function getPatientName(): string
{
return $this->address->getPatientName();
}
public function getAddress(): string
{
return $this->address->getAddress();
}
public function getCity(): string
{
return $this->address->getCity();
}
public function getState(): string
{
return $this->address->getState();
}
public function getCountry(): string
{
return $this->address->getCountry();
}
public function getZipCode(): string
{
return $this->address->getZipCode();
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* InvoiceInfo.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* 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;
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* InvoiceProduct.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/28
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointPrice;
final readonly class InvoiceProduct {
/**
* @param string $caseId
* @param string $uid
* @param string $name
* @param string $sku
* @param string $description
* @param PointPrice[] $prices
*/
public function __construct(
public string $caseId,
public string $uid,
public string $name,
public string $sku,
public string $description,
public array $prices,
) {}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* PointBalance.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* 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,
) {}
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* PointPrice.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/11/25
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject;
use Money\Money;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
final readonly class PointPrice
{
public function __construct(
public Money $price,
public string $currencySymbol,
) {}
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* FrequentAddressRepoInterface.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
namespace Singularity\HDK\Pay\Domain\Invoice\Repository;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address\FrequentAddress;
interface FrequentAddressRepoInterface
{
/**
* @param string $uid
* @return FrequentAddress
*/
public function findByUser(string $uid): FrequentAddress;
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* InvoiceProductRepoInterface.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/28
*/
namespace Singularity\HDK\Pay\Domain\Invoice\Repository;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
interface InvoiceProductRepoInterface
{
/**
* @param string $caseId
* @return InvoiceProduct
*/
public function getCaseProduct(string $caseId): InvoiceProduct;
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* InvoiceRepoInterface.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
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;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo;
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;
/**
* @param string $invoiceNo
* @return InvoiceInfo
*/
public function findOne(string $invoiceNo): InvoiceInfo;
}

View File

@@ -22,6 +22,6 @@ final class ProductItem
public string $description,
public Money $unitPrice,
public ProductType $productType,
public RechargeEffect $effect,
public ?RechargeEffect $effect = null,
) {}
}

View File

@@ -16,7 +16,8 @@ interface ExchangeRepoInterface
/**
* @param PointType $source
* @param PointType $target
* @param string|null $uid
* @return float
*/
public function getRate(PointType $source, PointType $target): float;
public function getRate(PointType $source, PointType $target, ?string $uid = null): float;
}

View File

@@ -9,6 +9,7 @@
namespace Singularity\HDK\Pay\Domain\Product\Repository;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
use Singularity\HDK\Pay\Domain\Product\Aggregate\RechargeProduct;
interface RechargeProductRepoInterface
@@ -23,4 +24,11 @@ interface RechargeProductRepoInterface
* @return RechargeProduct
*/
public function findEmaProduct(string $uid): RechargeProduct;
/**
* @param string $uid
* @param PointType $pointType
* @return RechargeProduct
*/
public function findFtaiProduct(string $uid, PointType $pointType): RechargeProduct;
}

View File

@@ -11,9 +11,11 @@ declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Carbon\Carbon;
use Hyperf\Codec\Json;
use Singularity\HDK\Pay\Domain\Account\Aggregate\AccountBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\ValueObject\PointsBalance;
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;
use Singularity\HDK\Pay\Domain\Account\Repository\AccountRepoInterface;
@@ -41,7 +43,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 +65,20 @@ 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,
);
}
/**
* @inheritDoc
*/
public function initial(InitialAccountCmd $cmd): void
{
$uid = $cmd->uid;
$this->requestService->requestPost(
url: "/rpc/v2/account/$uid/balance",
data: $cmd->pointsBalances
);
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* FrequentAddressRepo.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Hyperf\Codec\Json;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address\FrequentAddress;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
use Singularity\HDK\Pay\Domain\Invoice\Repository\FrequentAddressRepoInterface;
use Singularity\HDK\Pay\Infrastructure\Repository\AbstractRepo;
final class FrequentAddressRepo extends AbstractRepo implements FrequentAddressRepoInterface
{
/**
* @inheritDoc
*/
public function findByUser(string $uid): FrequentAddress
{
$response = $this->requestService->requestGet("/rpc/v2/account/$uid/inv-addr");
$content = $response->getBody()->getContents();
$result = Json::decode($content);
return new FrequentAddress(
uid: $result['uid'],
address: $result['address'],
city: $result['city'],
state: $result['state'],
country: $result['country'],
zipCode: $result['zip']
);
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* InvoiceProductRepo.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/28
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Hyperf\Codec\Json;
use Money\Currency;
use Money\Money;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointPrice;
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceProductRepoInterface;
final class InvoiceProductRepo extends AbstractRepo implements InvoiceProductRepoInterface
{
/**
* @inheritDoc
*/
public function getCaseProduct(string $caseId): InvoiceProduct
{
$response = $this->requestService->requestGet("/rpc/v2/invoice/$caseId/product");
$content = $response->getBody()->getContents();
$result = Json::decode($content);
return new InvoiceProduct(
caseId: $result['case_id'],
uid: $result['uid'],
name: $result['name'],
sku: $result['sku'],
description: $result['description'],
prices: array_map(
callback: fn(array $price) => new PointPrice(
price: new Money(
amount: bcmul((string)$price['amount'], '100', 2),
currency: new Currency($price['currency']),
),
currencySymbol: $price['symbol'],
),
array: $result['prices'],
),
);
}
}

View File

@@ -0,0 +1,149 @@
<?php
/**
* InvoiceRepo.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
declare(strict_types=1);
namespace Singularity\HDK\Pay\Infrastructure\Repository;
use Carbon\Carbon;
use Hyperf\Codec\Json;
use Money\Currency;
use Money\Money;
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
{
/**
* @inheritDoc
*/
public function create(CreateInvoiceCmd $cmd): Invoice
{
$money = $cmd->price;
$response = $this->requestService->requestPost(
url: "/rpc/v2/account/logs/points/$cmd->caseId/invoices",
data: [
'set_freq_addr' => $cmd->setFreqInvAddr,
'receiver' => $cmd->receiver,
'patient_name' => $cmd->patientName,
'address' => $cmd->address,
'city' => $cmd->city,
'state' => $cmd->state,
'country' => $cmd->country,
'zip' => $cmd->zipCode,
'price' => [
'amount' => (float)bcmul($money->getAmount(), '100', 2),
'currency' => [
'code' => $money->getCurrency()->getCode(),
'symbol' => $cmd->currencySymbol,
],
],
],
);
$content = $response->getBody()->getContents();
$result = Json::decode($content);
$price = $result['price'];
return new Invoice(
invoiceNo: $result['invoice_no'],
uid: $result['uid'],
caseId: $result['case_id'],
address: new Address(
patientName: $result['patient_name'],
address: $result['address'],
city: $result['city'],
state: $result['state'],
country: $result['country'],
zipCode: $result['zip'],
),
setFreqInvAddr: $result['set_freq_addr'],
receiver: $result['receiver'],
price: new Money(
bcmul((string)$price['amount'], '100', 2),
new Currency($price['code']),
),
currencySymbol: $price['symbol'],
);
}
/**
* @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");
}
/**
* @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'],
);
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* PointLogRepo.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/27
*/
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
{
/**
* @param string $uid
* @param PointType|null $type
* @return array{}|PointLog[]
* @throws GuzzleException
*/
public function getList(string $uid, ?PointType $type = null): array
{
$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);
return array_map(function ($item) {
return new PointLog(
id: $item['id'],
caseId: $item['case_id'],
uid: $item['uid'],
credits: $item['credits'],
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'])
? 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'],
patientName: $result['patient_name'],
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

@@ -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: $result['one_time']['price'],
amount: bcmul((string)$result['one_time']['price'], '100'),
currency: new Currency($result['one_time']['currency']),
),
productType: ProductType::oneTime,
@@ -55,20 +55,82 @@ 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: $item['price'],
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'] ?? [],
),
);
}
public function findFtaiProduct(string $uid, PointType $pointType): RechargeProduct
{
$response = $this->requestService->requestGet(
url: '/rpc/v2/products/ftai',
params: ['uid' => $uid, 'type' => $pointType->value],
);
$content = $response->getBody()->getContents();
$result = Json::decode($content);
return new RechargeProduct(
oneTime: isset($result['one_time'])
? new ProductItem(
id: $result['one_time']['id'],
description: $result['one_time']['name'],
unitPrice: new Money(
amount: bcmul((string)$result['one_time']['price'], '100'),
currency: new Currency($result['one_time']['currency']),
),
productType: ProductType::oneTime,
effect: new RechargeEffect(
pointType: $pointType,
pointBasic: $result['one_time']['point']['number'],
pointBonus: $result['one_time']['point']['bonus'],
),
)
: 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']),
),
productType: ProductType::plan,
),
), $result['package']),
$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'],
),
),
$result['package'] ?? [],
),
);
}
@@ -91,7 +153,7 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
id: $result['one_time']['id'],
description: $result['one_time']['name'],
unitPrice: new Money(
amount: $result['one_time']['price'],
amount: bcmul((string)$result['one_time']['price'], '100'),
currency: new Currency($result['one_time']['currency']),
),
productType: ProductType::oneTime,
@@ -107,7 +169,7 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
id: $result['renew']['id'],
description: $result['renew']['name'],
unitPrice: new Money(
amount: $result['renew']['price'],
amount: bcmul((string)$result['renew']['price'], '100'),
currency: new Currency($result['renew']['currency']),
),
productType: ProductType::renew,
@@ -118,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: $item['price'],
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::LuxPoint,
pointBasic: $item['point']['number'],
pointBonus: $item['point']['bonus'],
),
), $result['plan']),
$result['plan'] ?? [],
),
);
}
@@ -141,10 +206,11 @@ final class ProductRepo extends AbstractRepo implements RechargeProductRepoInter
* @return float
* @throws GuzzleException
*/
public function getRate(PointType $source, PointType $target): float
public function getRate(PointType $source, PointType $target, ?string $uid = null): float
{
$response = $this->requestService->requestGet(
url: "/rpc/v2/products/$target->value/exchange-rate/$source->value",
params: array_filter(['uid' => $uid]),
);
$content = $response->getBody()->getContents();

View File

@@ -2,9 +2,9 @@
namespace Singularity\HDK\Pay\Resource\V2;
use App\Model\ServiceProvider;
use Carbon\Carbon;
use Hyperf\Resource\Json\JsonResource;
use Money\Currency;
use Money\Money;
use Singularity\HDK\Pay\Enum\OrderStatus;
use stdClass;
@@ -48,6 +48,9 @@ class Order extends JsonResource
*/
public function toArray(): array
{
if (empty($this->resource['order_no'])) {
return $this->parseClassicOrder();
}
return [
'order_no' => $this->order_no,
'state' => $this->state,
@@ -65,6 +68,25 @@ class Order extends JsonResource
];
}
private function parseClassicOrder(): array
{
return [
'order_no' => $this->orderNo,
'state' => $this->state,
'transaction_id' => $this->transactionId,
'uid' => $this->uid,
'method' => $this->payment,
'description' => $this->goodsName,
'total_amount' => new Money($this->amount['amount'], new Currency($this->amount['currency'])),
'currency' => $this->amount['currency'],
'items' => [],
'external' => [],
'remark' => $this->remark,
'notification' => $this->notification ?? [],
'more_details' => [],
];
}
public function __get($key)
{
return $this->resource->{$key} ?? $this->resource[$key];

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();
});

View File

@@ -8,7 +8,7 @@
* Created on 2025/8/18
*/
use Singularity\HDK\Pay\Domain\Account\Aggregate\AccountBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
use function Hyperf\Support\make;

View File

@@ -8,7 +8,7 @@
* Created on 2025/8/18
*/
use Singularity\HDK\Pay\Domain\Account\Aggregate\ValueObject\PointsBalance;
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;

View File

@@ -0,0 +1,34 @@
<?php
/**
* QueryPointLogTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/27
*/
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\PointLog;
use Singularity\HDK\Pay\Infrastructure\Repository\PointLogRepo;
use function Hyperf\Support\make;
it('should can query point log list', function () {
$uid = '61a74db54f387';
$repo = make(PointLogRepo::class);
$list = $repo->getList($uid);
expect($list)
->not->toBeEmpty()
->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

@@ -0,0 +1,61 @@
<?php
/**
* CreateInvoiceTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
use Money\Money;
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;
use function Hyperf\Support\make;
it('should can create invoice', function () {
$repo = make(InvoiceRepo::class);
$invoice = $repo->create(
new CreateInvoiceCmd(
caseId: '68affb136c01d',
setFreqInvAddr: true,
receiver: "dongyun.li@luxcreo.ai",
patientName: "Ms. Jennifer Durgan",
address: "12345 Magnolia Boulevard NortheastApartment 5678 Suite 910",
city: "Springfield",
state: "Illinois",
country: "United States",
zipCode: "67890-1234",
price: Money::EUR('19900'),
currencySymbol: '€'
),
);
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

@@ -0,0 +1,29 @@
<?php
/**
* QueryCaseInvoiceProductTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/28
*/
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointPrice;
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceProductRepo;
use function Hyperf\Support\make;
it('should can query case invoice product', function () {
/** @var InvoiceProductRepo $invoiceProductRepo */
$invoiceProductRepo = make(InvoiceProductRepo::class);
$caseId = '68affb136c01d';
$result = $invoiceProductRepo->getCaseProduct(caseId: $caseId);
expect($result)->toBeInstanceOf(InvoiceProduct::class)
->prices->toBeArray()
->each->toBeInstanceOf(PointPrice::class);
});

View File

@@ -0,0 +1,23 @@
<?php
/**
* QueryFreqAddrTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* Powered by PhpStorm
* Created on 2025/8/29
*/
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address\FrequentAddress;
use Singularity\HDK\Pay\Infrastructure\Repository\FrequentAddressRepo;
use function Hyperf\Support\make;
it('should can query frequent invoice address', function () {
$uid = '61dbe752d4caa';
$addrRepo = make(FrequentAddressRepo::class);
$freq_addr = $addrRepo->findByUser($uid);
expect($freq_addr)->toBeInstanceOf(FrequentAddress::class);
});

View File

@@ -0,0 +1,23 @@
<?php
/**
* QueryInvoiceDetailTest.php@Pay
*
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
* 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);
});

View File

@@ -19,6 +19,20 @@ it('can query point rate', function () {
$from = PointType::FtaiAligner;
$to = PointType::LuxPoint;
$rate = $repo->getRate($from, $to);
$uid = 'cn3321';
$rate = $repo->getRate($from, $to, $uid);
expect($rate)->toBeFloat();
});
it('can query point rate with uid', function () {
$repo = make(ProductRepo::class);
$from = PointType::FtaiAligner;
$to = PointType::LuxPoint;
$uid = 'cn3321';
$rate = $repo->getRate($from, $to, $uid);
expect($rate)->toBeFloat();
});

View File

@@ -9,6 +9,7 @@
*/
use Pest\Expectation;
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
use Singularity\HDK\Pay\Domain\Product\Aggregate\Entities\ProductItem;
use Singularity\HDK\Pay\Domain\Product\Aggregate\RechargeProduct;
use Singularity\HDK\Pay\Infrastructure\Repository\ProductRepo;
@@ -44,3 +45,19 @@ it('should can query EMA products', function () {
)
->and($products->getPlans())->each->toBeInstanceOf(ProductItem::class);
});
it('should can query FTAI products', function () {
$repo = make(ProductRepo::class);
$uid = '61efabc21e5a2';
$products = $repo->findFtaiProduct($uid, PointType::FtaiAligner);
expect($products)
->toBeInstanceOf(RechargeProduct::class)
->when(
$products->getOneTime() !== null,
fn(Expectation $expectation) => $expectation
->and($products->getOneTime())->toBeInstanceOf(ProductItem::class),
)
->and($products->getPackages())->each->toBeInstanceOf(ProductItem::class)
->and($products->getPlans())->each->toBeInstanceOf(ProductItem::class);
});

View File

@@ -32,4 +32,4 @@ test(
);
expect($goods)->toBeInstanceOf(Goods::class);
}
);
)->skip();

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();