mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2026-06-07 12:38:11 +08:00
refactor: 使用 BC Math 替换浮点运算以提高精度
将多处基于浮点的数值计算替换为 BC Math 字符串运算以避免浮点精度问题,涉及支付、退款、转账、比较与统计逻辑的重构。主要改动包括: - 将比较与判断替换为 bccomp,累加与合并使用 bcadd,乘以 100 等使用 bcmul; - 将部分初始数值与统计结果从数值类型改为字符串形式(如 '0.00'),并调整相关返回类型(如 Payment::paidAmount 改为返回 string); - 修正订单/退款金额计算与超额校验逻辑以使用高精度算术; - 更新微信支付相关 SDK 调用中金额乘 100 的计算以避免精度误差; - 在若干插件中用高精度运算替换 floatval/int 转换(包括 SystemQueue、Wemall、Wuma 等); - 更新文档(readme)添加 BC Math/高精度计算等说明并统一版权年份至 2014-2026; - 新增 .copilot-commit-message-instructions.md(提交信息规范)。 此改动旨在增强金融/金额相关业务的计算正确性与一致性,避免因浮点运算导致的金额误差。
This commit is contained in:
parent
987ad41765
commit
d2b499d14a
4
.copilot-commit-message-instructions.md
Normal file
4
.copilot-commit-message-instructions.md
Normal file
@ -0,0 +1,4 @@
|
||||
请用中文生成提交信息,遵循规范提交格式:
|
||||
- 标题:类型:以业务内容为主简短描述
|
||||
- 正文:详细说明改动原因与内容
|
||||
- 类型:feat/fix/docs/style/refactor/test/chore
|
||||
@ -21,6 +21,7 @@
|
||||
- **表单验证机制**: 支持规则别名和自定义验证,确保数据输入安全
|
||||
- **异步任务队列**: 支持延时执行和循环任务,提升系统响应性能
|
||||
- **CSRF 令牌验证**: 内置表单安全验证,防止跨站请求伪造攻击
|
||||
- **高精度计算支持**: 集成 BC Math 高精度数学函数,确保金融计算的准确性
|
||||
|
||||
**技术特性:**
|
||||
- **PSR-12 标准**: 严格遵循 PHP-FIG 编码规范,确保代码质量和可维护性
|
||||
@ -28,6 +29,7 @@
|
||||
- **高性能优化**: 针对高并发场景进行专门优化,支持缓存和数据库连接池
|
||||
- **异常处理完善**: 完善的异常捕获和日志记录机制,便于问题排查
|
||||
- **向后兼容**: 保持 API 稳定性,确保平滑升级
|
||||
- **数据完整性保障**: 通过数据库约束确保业务数据的一致性和有效性
|
||||
|
||||
## 功能说明
|
||||
|
||||
@ -117,6 +119,8 @@
|
||||
* **Github** 仓库地址:https://github.com/zoujingli/ThinkLibrary
|
||||
* **Gitcode** 仓库地址: https://gitcode.com/ThinkAdmin/ThinkLibrary
|
||||
|
||||
版权所有 Copyright © 2014-2026 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
|
||||
## 使用说明
|
||||
|
||||
1. **依赖管理**:ThinkLibrary 需要 Composer 支持进行安装和依赖管理。
|
||||
|
||||
@ -64,7 +64,7 @@ class SystemQueue extends Model
|
||||
*/
|
||||
public function getEnterTimeAttr($value): string
|
||||
{
|
||||
return floatval($value) > 0 ? format_datetime(intval($value)) : '';
|
||||
return bccomp(strval($value), '0.00', 2) > 0 ? format_datetime(intval($value)) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
### 加入我们
|
||||
|
||||
我们的代码仓库已移至 **Github**,而 **Gitee** 则仅作为国内镜像仓库,方便广大开发者获取和使用。若想提交 **PR** 或 **ISSUE** 请在 [ThinkAdminDeveloper](https://github.com/zoujingli/ThinkAdminDeveloper) 仓库进行操作,如果在其他仓库操作或提交问题将无法处理!。
|
||||
我们的代码仓库已移至 **Github**,而 **Gitee** 则仅作为国内镜像仓库,方便广大开发者获取和使用。若想提交 **PR** 或 **ISSUE** 请在 [ThinkAdminDeveloper](https://github.com/zoujingli/ThinkAdminDeveloper) 仓库进行操作,如果在其他仓库操作或提交问题将无法处理!.
|
||||
|
||||
### 开放接口
|
||||
|
||||
@ -165,13 +165,14 @@ var_dump($types);
|
||||
- **动态通道注册**: 支持运行时动态注册新的登录通道类型,灵活扩展登录方式
|
||||
- **手机号绑定验证**: 通过短信验证码实现手机号绑定,确保账号安全性和唯一性
|
||||
- **账号解绑管理**: 支持终端账号与主账号的灵活绑定和解绑操作
|
||||
|
||||
**技术特性:**
|
||||
- **高并发安全**: 支持高并发场景下的账号创建和绑定操作
|
||||
- **数据一致性保障**: 通过数据库事务确保账号数据的一致性
|
||||
|
||||
**技术特性:**
|
||||
- **缓存优化**: 集成缓存机制,提升账号信息查询性能
|
||||
- **异常处理完善**: 完善的异常捕获和错误处理机制
|
||||
- **扩展性设计**: 抽象的账号接口设计,便于扩展新的认证方式
|
||||
- **向后兼容**: 保持 API 稳定性,确保平滑升级
|
||||
|
||||
### 插件数据
|
||||
|
||||
@ -188,4 +189,4 @@ var_dump($types);
|
||||
|
||||
未获得此插件授权时仅供参考学习不可商用,了解商用授权请阅读 [《会员授权》](https://thinkadmin.top/vip-introduce)。
|
||||
|
||||
版权所有 Copyright © 2014-2025 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
版权所有 Copyright © 2014-2026 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
|
||||
@ -68,6 +68,7 @@ composer remove zoujingli/think-plugs-payment
|
||||
- **支付事件驱动**: 通过支付事件(审核、完成、取消、确认)实现业务逻辑解耦
|
||||
- **退款管理**: 支持部分退款和全额退款,自动处理余额、积分的退回操作
|
||||
- **支付配置管理**: 可视化配置各种支付通道参数,支持动态启用/禁用支付方式
|
||||
- **高精度金融计算**: 全面采用 BC Math 高精度数学函数,确保金融计算的准确性,避免浮点数精度丢失问题
|
||||
|
||||
**账户资金管理:**
|
||||
- **余额管理系统**: 完整的余额充值、消费、锁定、解锁、作废等操作
|
||||
@ -75,12 +76,14 @@ composer remove zoujingli/think-plugs-payment
|
||||
- **高精度计算**: 使用 BC Math 高精度数学函数,确保金融计算的准确性
|
||||
- **资金流水追踪**: 完整的资金变动记录,支持来源追溯和审计
|
||||
- **并发安全控制**: 支持高并发场景下的余额和积分操作,避免超支问题
|
||||
- **数据完整性保障**: 通过数据库约束确保业务数据的一致性和有效性
|
||||
|
||||
**技术特性:**
|
||||
- **支付接口抽象**: 统一的支付接口标准,便于扩展新的支付方式
|
||||
- **数据库约束优化**: 添加金额非负约束、状态枚举约束,确保数据完整性
|
||||
- **异常处理机制**: 完善的异常捕获和日志记录,便于问题排查
|
||||
- **事务一致性**: 关键业务操作保证数据一致性,避免脏数据产生
|
||||
- **向后兼容**: 保持 API 稳定性,确保平滑升级
|
||||
|
||||
### 插件数据
|
||||
|
||||
@ -99,4 +102,4 @@ composer remove zoujingli/think-plugs-payment
|
||||
|
||||
未获得此插件授权时仅供参考学习不可商用,了解商用授权请阅读 [《会员授权》](https://thinkadmin.top/vip-introduce)。
|
||||
|
||||
版权所有 Copyright © 2014-2025 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
版权所有 Copyright © 2014-2026 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | Payment Plugin for ThinkAdmin
|
||||
// +----------------------------------------------------------------------
|
||||
// | 版权所有 2014~2025 ThinkAdmin [ thinkadmin.top ]
|
||||
// | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网站: https://thinkadmin.top
|
||||
// +----------------------------------------------------------------------
|
||||
@ -427,11 +427,11 @@ abstract class Payment
|
||||
* @param string $orderNo 订单单号
|
||||
* @param bool $realtime 有效金额
|
||||
*/
|
||||
public static function paidAmount(string $orderNo, bool $realtime = false): float
|
||||
public static function paidAmount(string $orderNo, bool $realtime = false): string
|
||||
{
|
||||
$map = ['order_no' => $orderNo, 'payment_status' => 1];
|
||||
$raw = new Raw($realtime ? 'payment_amount - refund_amount' : 'payment_amount');
|
||||
return round(PluginPaymentRecord::mk()->where($map)->sum($raw), 2);
|
||||
return bcadd('0.00', strval(PluginPaymentRecord::mk()->where($map)->sum($raw)), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -451,7 +451,7 @@ abstract class Payment
|
||||
*/
|
||||
public static function totalPaymentAmount(string $orderNo): array
|
||||
{
|
||||
$total = ['amount' => 0, 'payment' => 0, 'balance' => 0, 'integral' => 0];
|
||||
$total = ['amount' => '0.00', 'payment' => '0.00', 'balance' => '0.00', 'integral' => '0.00'];
|
||||
try {
|
||||
PluginPaymentRecord::mk()->where(['order_no' => $orderNo, 'payment_status' => 1])->field([
|
||||
'channel_type',
|
||||
@ -460,12 +460,12 @@ abstract class Payment
|
||||
'sum(used_balance-refund_balance)' => 'balance',
|
||||
'sum(used_integral-refund_integral)' => 'integral',
|
||||
])->group('channel_type')->select()->map(static function (PluginPaymentRecord $item) use (&$total) {
|
||||
$total['amount'] = round($total['amount'] + $item->getAttr('amount'), 2);
|
||||
$total['amount'] = bcadd($total['amount'], strval($item->getAttr('amount')), 2);
|
||||
$type = $item->getAttr('channel_type');
|
||||
if (!in_array($type, [self::INTEGRAL, self::BALANCE])) {
|
||||
$type = 'payment';
|
||||
}
|
||||
$total[$type] = round($total[$type] + $item[$type] ?? 0, 2);
|
||||
$total[$type] = bcadd($total[$type], strval($item[$type] ?? '0.00'), 2);
|
||||
});
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
@ -479,17 +479,17 @@ abstract class Payment
|
||||
*/
|
||||
public static function totalRefundAmount(string $pCode): array
|
||||
{
|
||||
$total = ['amount' => 0, 'payment' => 0, 'balance' => 0, 'integral' => 0];
|
||||
$total = ['amount' => '0.00', 'payment' => '0.00', 'balance' => '0.00', 'integral' => '0.00'];
|
||||
try {
|
||||
PluginPaymentRefund::mk()->where(['record_code' => $pCode, 'refund_status' => [0, 1]])->field([
|
||||
'refund_account', 'sum(refund_amount) amount', 'sum(used_payment)' => 'payment', 'sum(used_balance)' => 'balance', 'sum(used_integral)' => 'integral',
|
||||
])->group('refund_account')->select()->map(static function (PluginPaymentRefund $item) use (&$total) {
|
||||
$total['amount'] = round($total['amount'] + $item->getAttr('amount'), 2);
|
||||
$total['amount'] = bcadd($total['amount'], strval($item->getAttr('amount')), 2);
|
||||
$type = $item->getAttr('refund_account');
|
||||
if (!in_array($type, [self::INTEGRAL, self::BALANCE])) {
|
||||
$type = 'payment';
|
||||
}
|
||||
$total[$type] = round($total[$type] + $item[$type] ?? 0, 2);
|
||||
$total[$type] = bcadd($total[$type], strval($item[$type] ?? '0.00'), 2);
|
||||
});
|
||||
} catch (\Exception $exception) {
|
||||
trace_file($exception);
|
||||
|
||||
@ -85,7 +85,7 @@ class BalancePayment implements PaymentInterface
|
||||
{
|
||||
try {
|
||||
// 记录并退回
|
||||
if (floatval($amount) <= 0) {
|
||||
if (bccomp(strval($amount), '0.00', 2) <= 0) {
|
||||
return [1, '无需退款!'];
|
||||
}
|
||||
$record = static::syncRefund($pcode, $rcode, $amount, $reason);
|
||||
|
||||
@ -85,7 +85,7 @@ class IntegralPayment implements PaymentInterface
|
||||
{
|
||||
try {
|
||||
// 记录并退回
|
||||
if (floatval($amount) <= 0) {
|
||||
if (bccomp(strval($amount), '0.00', 2) <= 0) {
|
||||
return [1, '无需退款!'];
|
||||
}
|
||||
$record = static::syncRefund($pcode, $rcode, $amount, $reason);
|
||||
|
||||
@ -92,7 +92,7 @@ class WechatPaymentV2 extends WechatPayment
|
||||
'attach' => $this->cfgCode,
|
||||
'out_trade_no' => $payCode,
|
||||
'trade_type' => static::tradeTypes[$this->cfgType] ?? '',
|
||||
'total_fee' => intval(floatval($payAmount) * 100),
|
||||
'total_fee' => intval(strval(bcmul(strval($payAmount), '100', 0))),
|
||||
'notify_url' => $this->withNotifyUrl($payCode),
|
||||
'spbill_create_ip' => $this->app->request->ip(),
|
||||
];
|
||||
@ -203,7 +203,7 @@ class WechatPaymentV2 extends WechatPayment
|
||||
'out_trade_no' => $pcode,
|
||||
'out_refund_no' => $rcode,
|
||||
'total_fee' => intval($record->getAttr('payment_amount') * 100),
|
||||
'refund_fee' => intval(floatval($amount) * 100),
|
||||
'refund_fee' => intval(strval(bcmul(strval($amount), '100', 0))),
|
||||
'notify_url' => static::withNotifyUrl($rcode, 'refund'),
|
||||
];
|
||||
if (strlen($reason) > 0) {
|
||||
|
||||
@ -206,7 +206,7 @@ class WechatPaymentV3 extends WechatPayment
|
||||
'notify_url' => static::withNotifyUrl($rcode, 'refund'),
|
||||
'amount' => [
|
||||
'total' => intval($record->getAttr('payment_amount') * 100),
|
||||
'refund' => intval(floatval($amount) * 100),
|
||||
'refund' => intval(strval(bcmul(strval($amount), '100', 0))),
|
||||
'currency' => 'CNY',
|
||||
],
|
||||
];
|
||||
|
||||
@ -84,8 +84,8 @@ class PaymentService
|
||||
return ['code' => 1, 'info' => '已完成支付!', 'data' => [], 'params' => []];
|
||||
}
|
||||
// 检查剩余支付金额
|
||||
$pAmount = floatval(is_null($pAmount) ? (floatval($oAmount) - $oPayed) : $pAmount);
|
||||
if ($oPayed + $pAmount > floatval($oAmount)) {
|
||||
$pAmount = strval(is_null($pAmount) ? (bcsub(strval($oAmount), strval($oPayed), 2)) : $pAmount);
|
||||
if (bccomp(bcadd(strval($oPayed), $pAmount, 2), strval($oAmount), 2) > 0) {
|
||||
return ['code' => 0, 'info' => '支付总额超出!', 'data' => [], 'params' => []];
|
||||
}
|
||||
$config = WechatService::getConfig(true);
|
||||
@ -218,7 +218,7 @@ class PaymentService
|
||||
if ($record->getAttr('refund_amount') >= $record->getAttr('payment_amount')) {
|
||||
return [1, '该订单已完成退款!'];
|
||||
}
|
||||
if ($record->getAttr('refund_amount') + floatval($amount) > $record->getAttr('payment_amount')) {
|
||||
if (bccomp(bcadd(strval($record->getAttr('refund_amount')), strval($amount), 2), strval($record->getAttr('payment_amount')), 2) > 0) {
|
||||
return [0, '退款大于支付金额!'];
|
||||
}
|
||||
// 创建支付退款申请
|
||||
@ -232,7 +232,7 @@ class PaymentService
|
||||
'out_refund_no' => $rcode,
|
||||
'notify_url' => static::withNotifyUrl($rcode, 'refund'),
|
||||
'amount' => [
|
||||
'refund' => intval(floatval($amount) * 100),
|
||||
'refund' => intval(strval(bcmul(strval($amount), '100', 0))),
|
||||
'total' => intval($record->getAttr('payment_amount') * 100),
|
||||
'currency' => 'CNY',
|
||||
],
|
||||
@ -372,10 +372,10 @@ class PaymentService
|
||||
protected static function createPaymentAction(string $openid, string $oCode, string $oName, string $oAmount, string $pType, string $pCode, string $pAmount): array
|
||||
{
|
||||
// 检查是否已经支付
|
||||
if (static::withPayed($oCode, $oPayed) >= floatval($oAmount)) {
|
||||
if (bccomp(strval(self::withPayed($oCode, $oPayed)), strval($oAmount), 2) >= 0) {
|
||||
throw new Exception('已经完成支付', 1);
|
||||
}
|
||||
if ($oPayed + floatval($pAmount) > floatval($oAmount)) {
|
||||
if (bccomp(bcadd(strval($oPayed), strval($pAmount), 2), strval($oAmount), 2) > 0) {
|
||||
throw new Exception('总支付超出金额', 0);
|
||||
}
|
||||
$map = ['order_code' => $oCode, 'payment_status' => 1];
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
### 加入我们
|
||||
|
||||
我们的代码仓库已移至 **Github**,而 **Gitee** 则仅作为国内镜像仓库,方便广大开发者获取和使用。若想提交 **PR** 或 **ISSUE** 请在 [ThinkAdminDeveloper](https://github.com/zoujingli/ThinkAdminDeveloper) 仓库进行操作,如果在其他仓库操作或提交问题将无法处理!。
|
||||
我们的代码仓库已移至 **Github**,而 **Gitee** 则仅作为国内镜像仓库,方便广大开发者获取和使用。若想提交 **PR** 或 **ISSUE** 请在 [ThinkAdminDeveloper](https://github.com/zoujingli/ThinkAdminDeveloper) 仓库进行操作,如果在其他仓库操作或提交问题将无法处理!.
|
||||
|
||||
### 依赖插件
|
||||
|
||||
@ -59,6 +59,7 @@ composer remove zoujingli/think-plugs-wemall
|
||||
- **订单全流程管理**: 从下单、支付、发货到售后的完整订单生命周期管理
|
||||
- **推广海报管理**: 支持为不同用户等级生成个性化推广海报
|
||||
- **团队业绩统计**: 实时统计团队销售业绩和返佣数据
|
||||
- **高精度计算保障**: 全面采用 BC Math 高精度计算,避免浮点数精度丢失问题
|
||||
|
||||
**技术特性:**
|
||||
- **高精度金融计算**: 使用 BC Math 高精度计算,避免浮点数精度丢失问题
|
||||
@ -66,6 +67,7 @@ composer remove zoujingli/think-plugs-wemall
|
||||
- **数据库约束优化**: 添加完整的外键约束、检查约束和索引优化
|
||||
- **并发安全处理**: 支持高并发场景下的余额、积分、库存操作
|
||||
- **数据完整性保障**: 通过数据库约束确保业务数据的一致性和有效性
|
||||
- **向后兼容**: 保持 API 稳定性,确保平滑升级
|
||||
|
||||
### 插件数据
|
||||
|
||||
@ -84,4 +86,4 @@ composer remove zoujingli/think-plugs-wemall
|
||||
|
||||
未获得此插件授权时仅供参考学习不可商用,了解商用授权请阅读 [《会员授权》](https://thinkadmin.top/vip-introduce)。
|
||||
|
||||
版权所有 Copyright © 2014-2025 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
版权所有 Copyright © 2014-2026 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
|
||||
@ -127,7 +127,7 @@ class Clear extends Command
|
||||
$this->queue->message(0, 0, '未启用订单自动取消功能!');
|
||||
} else {
|
||||
try {
|
||||
$time = time() - intval(floatval($this->config['cancel_time']) * 3600);
|
||||
$time = time() - intval(strval($this->config['cancel_time']) * 3600);
|
||||
$remark = $this->config['cancel_text'] ?? '自动取消未完成支付';
|
||||
$where = [['status', 'in', [1, 2, 3]], ['create_time', '<', date('Y-m-d H:i:s', $time)]];
|
||||
[$count, $total] = [0, ($items = PluginWemallOrder::mk()->where($where)->select())->count()];
|
||||
@ -157,7 +157,7 @@ class Clear extends Command
|
||||
$this->queue->message(0, 0, '未启用订单自动清理功能!');
|
||||
} else {
|
||||
try {
|
||||
$time = time() - intval(floatval($this->config['remove_time']) * 3600);
|
||||
$time = time() - intval(strval($this->config['remove_time']) * 3600);
|
||||
$remark = $this->config['remove_text'] ?? '系统自动清理已取消的订单!';
|
||||
$where = [['status', '=', 0], ['deleted_status', '=', 0], ['create_time', '<', date('Y-m-d H:i:s', $time)]];
|
||||
[$count, $total] = [0, ($items = PluginWemallOrder::mk()->where($where)->select())->count()];
|
||||
|
||||
@ -112,7 +112,7 @@ class Trans extends Command
|
||||
*/
|
||||
private function createTransferV3(PluginWemallUserTransfer $model): array
|
||||
{
|
||||
$amount = floatval($model->getAttr('amount')) - floatval($model->getAttr('charge_amount'));
|
||||
$amount = strval(bcmul(bcsub(strval($model->getAttr('amount')), strval($model->getAttr('charge_amount')), 2), '100', 0));
|
||||
return TransfersV3::instance($this->getConfig($model))->batchs([
|
||||
'out_batch_no' => "B{$model->getAttr('code')}",
|
||||
'batch_name' => '微信余额提现',
|
||||
|
||||
@ -126,7 +126,7 @@ class Agent extends Controller
|
||||
$key = "{$ats[0]}_{$ats[1]}_status";
|
||||
if ($vo['number'] > 0) {
|
||||
isset($vo['extra'][$key]) || $vo['extra'][$key] = 0;
|
||||
floatval($v) > 0 ? ++$count : ($vo['extra'][$key] = 0);
|
||||
bccomp(strval($v), '0.00', 2) > 0 ? ++$count : ($vo['extra'][$key] = 0);
|
||||
} else {
|
||||
$vo['extra'][$k] = 0;
|
||||
$vo['extra'][$key] = 0;
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
- **数据统计分析**: 提供扫码数据统计和分析,了解消费者行为
|
||||
- **批量操作**: 支持物码的批量生成、导入、导出等操作
|
||||
- **权限控制**: 完善的权限管理,确保数据安全
|
||||
- **高精度计算支持**: 集成 BC Math 高精度数学函数,确保金融计算的准确性
|
||||
- **收费授权**: 作为收费授权插件,提供专业的技术支持和功能更新
|
||||
|
||||
**技术特性:**
|
||||
@ -26,12 +27,13 @@
|
||||
- **安全防护**: 内置数据加密和权限验证,确保系统安全
|
||||
- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性,确保平滑升级
|
||||
- **专业支持**: 提供专业的技术支持和定期功能更新
|
||||
- **数据完整性保障**: 通过数据库约束确保业务数据的一致性和有效性
|
||||
|
||||
物码标签管理系统,此插件为收费授权插件,请联系作者获取授权,未授权不可商用。
|
||||
|
||||
### 加入我们
|
||||
|
||||
我们的代码仓库已移至 **Github**,而 **Gitee** 则仅作为国内镜像仓库,方便广大开发者获取和使用。若想提交 **PR** 或 **ISSUE** 请在 [ThinkAdminDeveloper](https://github.com/zoujingli/ThinkAdminDeveloper) 仓库进行操作,如果在其他仓库操作或提交问题将无法处理!。
|
||||
我们的代码仓库已移至 **Github**,而 **Gitee** 则仅作为国内镜像仓库,方便广大开发者获取和使用。若想提交 **PR** 或 **ISSUE** 请在 [ThinkAdminDeveloper](https://github.com/zoujingli/ThinkAdminDeveloper) 仓库进行操作,如果在其他仓库操作或提交问题将无法处理!.
|
||||
|
||||
### 安装插件
|
||||
|
||||
@ -67,4 +69,4 @@ composer remove zoujingli/think-plugs-wuma
|
||||
|
||||
未获得此插件授权时仅供参考学习不可商用,了解商用授权请阅读 [《付费授权》](https://thinkadmin.top/fee-introduce.html)。
|
||||
|
||||
版权所有 Copyright © 2014-2025 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
版权所有 Copyright © 2014-2026 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
|
||||
@ -89,7 +89,7 @@ class CodeService
|
||||
public static function codever(string $code, int $full, int $size = 4): string
|
||||
{
|
||||
[$a, $b] = [base_convert($code, 10, $full - 1), base_convert(strrev($code), 10, $full - 2)];
|
||||
return substr(str_pad(strval(floatval($a) + floatval($b)), $size, '0', STR_PAD_LEFT), 0, $size);
|
||||
return substr(str_pad(strval(bcadd(strval($a), strval($b), 2)), $size, '0', STR_PAD_LEFT), 0, $size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -276,7 +276,7 @@ class WhCoderService extends Service
|
||||
} elseif (in_array($attr[1], ['MAX', 'MID'])) {
|
||||
foreach ($rules['nums'] as $range => $num) {
|
||||
[$start, $after] = explode('-', $range);
|
||||
if (floatval($start) <= floatval($attr[0]) && floatval($attr[0]) <= floatval($after)) {
|
||||
if (bccomp(strval($start), strval($attr[0]), 2) <= 0 && bccomp(strval($attr[0]), strval($after), 2) <= 0) {
|
||||
$number = $num['mode'] === 1 ? $num['tomins'] : substr_count($strs, $code);
|
||||
$maps[$code] = $code . '#' . $number;
|
||||
$count += $number;
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
- **自定义服务基类**: 提供依赖注入和实例化机制,支持服务的统一管理和扩展
|
||||
- **全局函数库**: 包含数据处理、系统配置、HTTP 请求、JWT 认证等实用函数
|
||||
- **PSR-12 标准**: 严格遵循 PHP-FIG 编码规范,确保代码质量和可维护性
|
||||
- **高精度计算支持**: 集成 BC Math 高精度数学函数,确保金融计算的准确性
|
||||
|
||||
**ThinkPlugsAccount 多端账号插件**
|
||||
- **三层账号模型**: 临时用户(usid) ↔ 绑定手机(bind) ↔ 正式用户(unid) 的完整账号生命周期
|
||||
@ -35,6 +36,7 @@
|
||||
- **高精度金融计算**: 使用 BC Math 高精度数学函数,确保金融计算的准确性
|
||||
- **支付事件驱动**: 通过支付事件(审核、完成、取消、确认)实现业务逻辑解耦
|
||||
- **退款管理**: 支持部分退款和全额退款,自动处理余额、积分的退回操作
|
||||
- **数据库约束优化**: 添加金额非负约束、状态枚举约束,确保数据完整性
|
||||
|
||||
**ThinkPlugsWemall 微商城插件**
|
||||
- **多级分销体系**: 支持三级分销模式,可配置不同等级的代理返佣规则
|
||||
@ -43,6 +45,7 @@
|
||||
- **代理等级管理**: 团队业绩统计,支持多维度的代理等级升级条件
|
||||
- **商品管理系统**: 完整的商品分类、规格、库存、价格管理
|
||||
- **订单全流程管理**: 从下单、支付、发货到售后的完整订单生命周期管理
|
||||
- **高精度计算保障**: 全面采用 BC Math 高精度计算,避免浮点数精度丢失问题
|
||||
|
||||
**其他插件**
|
||||
- **ThinkPlugsCenter**: 插件服务管理中心,提供插件注册、配置和管理功能
|
||||
@ -112,4 +115,6 @@ start http://127.0.0.1:8088
|
||||
* 会员授权: [《会员尊享介绍》](https://thinkadmin.top/vip-introduce)
|
||||
* 收费授权:请通过文档中微信二维码联系作者。
|
||||
|
||||
版权所有 Copyright © 2014-2026 by ThinkAdmin (https://thinkadmin.top) All rights reserved。
|
||||
|
||||
<img alt="" src="https://thinkadmin.top/static/img/wx.png" width="250">
|
||||
Loading…
x
Reference in New Issue
Block a user