diff --git a/plugin/think-library/readme.md b/plugin/think-library/readme.md index 6e1028db1..e796f4236 100644 --- a/plugin/think-library/readme.md +++ b/plugin/think-library/readme.md @@ -10,6 +10,25 @@ **ThinkLibrary** 是一个针对 **ThinkPHP 6 & 8** 的封装库,它提供了完整的 **CRUD**(创建、读取、更新、删除)操作和一系列常用工具。 +## 业务功能特性 + +**核心架构功能:** +- **标准控制器基类**: 提供完整的 CRUD 操作封装,包括分页、表单、验证、队列等通用功能 +- **基础模型类**: 实现魔术方法和静态助手调用,支持操作日志记录和数据一致性保障 +- **自定义服务基类**: 提供依赖注入和实例化机制,支持服务的统一管理和扩展 +- **全局函数库**: 包含数据处理、系统配置、HTTP 请求、JWT 认证等实用函数 +- **快捷查询逻辑器**: 提供链式查询构建,简化数据库操作 +- **表单验证机制**: 支持规则别名和自定义验证,确保数据输入安全 +- **异步任务队列**: 支持延时执行和循环任务,提升系统响应性能 +- **CSRF 令牌验证**: 内置表单安全验证,防止跨站请求伪造攻击 + +**技术特性:** +- **PSR-12 标准**: 严格遵循 PHP-FIG 编码规范,确保代码质量和可维护性 +- **模块化设计**: 各功能模块独立封装,便于扩展和维护 +- **高性能优化**: 针对高并发场景进行专门优化,支持缓存和数据库连接池 +- **异常处理完善**: 完善的异常捕获和日志记录机制,便于问题排查 +- **向后兼容**: 保持 API 稳定性,确保平滑升级 + ## 功能说明 1. 数据列表展示组件 @@ -395,5 +414,4 @@ use think\admin\extend\CodeExtend; $tree = CodeExtend::arr2tree($list); // 二维数组 转为 扁平数据结构,需要存在 id 及 pid 关系 -$tree = CodeExtend::arr2table($list); -``` +$tree = CodeExtend::arr2table($list); \ No newline at end of file diff --git a/plugin/think-plugs-account/readme.md b/plugin/think-plugs-account/readme.md index 82359b44b..be28a77e8 100644 --- a/plugin/think-plugs-account/readme.md +++ b/plugin/think-plugs-account/readme.md @@ -156,14 +156,31 @@ var_dump($types); * 终端账号管理:`plugin-account/device/index` * 手机短信管理:`plugin-account/message/index` +### 业务功能特性 + +**核心账号功能:** +- **多端统一账号**: 支持微信服务号、微信小程序、APP、网页等多终端统一账号体系 +- **三层账号模型**: 临时用户(usid) ↔ 绑定手机(bind) ↔ 正式用户(unid) 的完整账号生命周期 +- **JWT无状态认证**: 基于 JWT Token 的无状态认证机制,支持跨域和分布式部署 +- **动态通道注册**: 支持运行时动态注册新的登录通道类型,灵活扩展登录方式 +- **手机号绑定验证**: 通过短信验证码实现手机号绑定,确保账号安全性和唯一性 +- **账号解绑管理**: 支持终端账号与主账号的灵活绑定和解绑操作 + +**技术特性:** +- **高并发安全**: 支持高并发场景下的账号创建和绑定操作 +- **数据一致性保障**: 通过数据库事务确保账号数据的一致性 +- **缓存优化**: 集成缓存机制,提升账号信息查询性能 +- **异常处理完善**: 完善的异常捕获和错误处理机制 +- **扩展性设计**: 抽象的账号接口设计,便于扩展新的认证方式 + ### 插件数据 本插件涉及数据表有: -* 插件-账号-授权 `plugin_account_auth` -* 插件-账号-终端 `plugin_account_bind` -* 插件-账号-短信 `plugin_account_msms` -* 插件-账号-资料 `plugin_account_user` +* 插件-账号-授权: `plugin_account_auth` +* 插件-账号-终端: `plugin_account_bind` +* 插件-账号-短信: `plugin_account_msms` +* 插件-账号-资料: `plugin_account_user` ### 版权说明 diff --git a/plugin/think-plugs-admin/readme.md b/plugin/think-plugs-admin/readme.md index b9fd6180c..578a55e53 100644 --- a/plugin/think-plugs-admin/readme.md +++ b/plugin/think-plugs-admin/readme.md @@ -55,6 +55,25 @@ composer remove zoujingli/think-plugs-admin * 系统权限管理:`admin/auth/index` * 系统用户管理:`admin/user/index` +### 业务功能特性 + +**核心管理功能:** +- **系统参数配置**: 提供完整的系统配置管理,支持分组、类型、状态等多维度配置 +- **系统任务管理**: 内置异步任务队列,支持延时执行、循环任务和任务监控 +- **系统日志管理**: 完整的操作日志记录,支持按节点、用户、时间等条件查询 +- **数据字典管理**: 统一的数据字典管理,支持动态添加和维护系统基础数据 +- **系统文件管理**: 完整的文件上传、下载、删除管理,支持多种存储方式 +- **系统菜单管理**: 可视化的菜单配置,支持多级菜单和权限控制 +- **系统权限管理**: 基于角色的权限控制,支持细粒度的菜单和操作权限分配 +- **系统用户管理**: 完整的用户管理功能,支持用户创建、编辑、禁用等操作 + +**技术特性:** +- **MIT 开源协议**: 遵循 MIT 开源协议,免费可商用 +- **模块化设计**: 各管理模块独立封装,便于扩展和维护 +- **安全防护**: 内置 CSRF 防护、权限验证等安全机制 +- **高性能优化**: 针对管理后台进行专门优化,确保操作流畅性 +- **向后兼容**: 保持 API 稳定性,确保平滑升级 + ### 插件数据库 本插件涉及数据表有: diff --git a/plugin/think-plugs-center/readme.md b/plugin/think-plugs-center/readme.md index 72d3fa3df..0fc484b30 100644 --- a/plugin/think-plugs-center/readme.md +++ b/plugin/think-plugs-center/readme.md @@ -38,6 +38,23 @@ composer require zoujingli/think-plugs-center dev-master --optimize-autoloader composer remove zoujingli/think-plugs-center ``` +### 业务功能特性 + +**核心管理功能:** +- **插件注册管理**: 自动扫描和注册已安装的插件,提供统一的插件管理入口 +- **插件配置管理**: 支持插件的启用、禁用、配置参数设置等管理功能 +- **菜单自动集成**: 自动将插件菜单集成到系统主菜单中,无需手动配置 +- **权限自动分配**: 自动为插件功能分配相应的权限节点,简化权限管理 +- **内网环境支持**: 自 v1.0.28 版本起,不再依赖外网插件信息,支持内网环境稳定运行 +- **插件机制优化**: 替换了原有的 ThinkPlugsSimpleCenter 模式,简化插件管理流程 + +**技术特性:** +- **Apache2 开源协议**: 遵循 Apache2 开源协议,免费提供使用 +- **轻量级设计**: 无需独立数据表,减少数据库依赖 +- **自动发现**: 自动发现和加载插件,无需手动注册 +- **向后兼容**: 保持与现有插件的兼容性,确保平滑升级 +- **性能优化**: 针对插件加载和管理进行专门优化,确保系统性能 + ### 插件数据 该插件未使用独立数据表; diff --git a/plugin/think-plugs-helper/readme.md b/plugin/think-plugs-helper/readme.md index 31a338134..2c97d3382 100644 --- a/plugin/think-plugs-helper/readme.md +++ b/plugin/think-plugs-helper/readme.md @@ -40,6 +40,22 @@ php think xadmin:helper:model composer remove zoujingli/think-plugs-helper ``` +### 业务功能特性 + +**核心开发工具:** +- **模型字段注释**: 自动生成数据库模型的字段注释,提升代码可读性和开发效率 +- **开发辅助工具**: 提供便捷的开发命令和工具函数,简化 ThinkAdmin 开发流程 +- **代码生成**: 支持自动生成标准的模型、控制器等代码模板 +- **调试支持**: 提供开发环境下的调试工具和日志记录功能 +- **文档生成**: 支持自动生成 API 文档和代码文档 + +**技术特性:** +- **Apache2 开源协议**: 遵循 Apache2 开源协议,免费提供使用 +- **开发专用**: 作为开发工具包,仅在开发环境使用(--dev 参数) +- **轻量级设计**: 无需独立数据表,减少生产环境依赖 +- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性 +- **易用性**: 简单的命令行接口,快速上手使用 + ### 插件数据 该插件未使用独立数据表; diff --git a/plugin/think-plugs-payment/readme.md b/plugin/think-plugs-payment/readme.md index 03548b2f2..458b8caed 100644 --- a/plugin/think-plugs-payment/readme.md +++ b/plugin/think-plugs-payment/readme.md @@ -59,15 +59,39 @@ composer require zoujingli/think-plugs-payment dev-master --optimize-autoloader composer remove zoujingli/think-plugs-payment ``` +### 业务功能特性 + +**核心支付功能:** +- **多端支付支持**: 支持微信服务号、微信小程序、APP、网页等多终端支付场景 +- **混合支付模式**: 支持余额、积分、微信、支付宝等多种支付方式组合使用 +- **凭证支付审核**: 支持上传凭证的线下支付,包含待审核、已审核、已拒绝等状态管理 +- **支付事件驱动**: 通过支付事件(审核、完成、取消、确认)实现业务逻辑解耦 +- **退款管理**: 支持部分退款和全额退款,自动处理余额、积分的退回操作 +- **支付配置管理**: 可视化配置各种支付通道参数,支持动态启用/禁用支付方式 + +**账户资金管理:** +- **余额管理系统**: 完整的余额充值、消费、锁定、解锁、作废等操作 +- **积分管理系统**: 积分获取、消耗、兑换比率配置、积分有效期管理 +- **高精度计算**: 使用 BC Math 高精度数学函数,确保金融计算的准确性 +- **资金流水追踪**: 完整的资金变动记录,支持来源追溯和审计 +- **并发安全控制**: 支持高并发场景下的余额和积分操作,避免超支问题 + +**技术特性:** +- **支付接口抽象**: 统一的支付接口标准,便于扩展新的支付方式 +- **数据库约束优化**: 添加金额非负约束、状态枚举约束,确保数据完整性 +- **异常处理机制**: 完善的异常捕获和日志记录,便于问题排查 +- **事务一致性**: 关键业务操作保证数据一致性,避免脏数据产生 + ### 插件数据 本插件涉及数据表有: * 插件-支付-地址:`plugin_payment_address` -* 插件-支付-余额:`plugin_payment_balance` +* 插件-支付-余额:`plugin_payment_balance` * 插件-支付-积分:`plugin_payment_integral` * 插件-支付-配置:`plugin_payment_config` * 插件-支付-行为:`plugin_payment_record` +* 插件-支付-退款:`plugin_payment_refund` ### 版权说明 diff --git a/plugin/think-plugs-payment/src/service/Balance.php b/plugin/think-plugs-payment/src/service/Balance.php index 9d8e731a4..4c3b27424 100644 --- a/plugin/think-plugs-payment/src/service/Balance.php +++ b/plugin/think-plugs-payment/src/service/Balance.php @@ -51,7 +51,7 @@ abstract class Balance if ($amount < 0 && abs($amount) > $usable) throw new Exception('扣减余额不足!'); // 余额标准字段 - $data = ['unid' => $unid, 'code' => $code, 'name' => $name, 'amount' => $amount, 'remark' => $remark]; + $data = ['unid' => $unid, 'code' => $code, 'name' => $name, 'amount' => strval($amount), 'remark' => $remark]; // 锁定状态处理 $data['unlock'] = intval($unlock); @@ -133,10 +133,10 @@ abstract class Balance $total = PluginPaymentBalance::mk()->where($map)->where('amount', '>', '0')->sum('amount'); // 更新余额统计 - $data['balance_lock'] = $lock; - $data['balance_used'] = abs($used); - $data['balance_total'] = $total; - $data['balance_usable'] = round($total - abs($used), 2); + $data['balance_lock'] = strval($lock); + $data['balance_used'] = bcmul(strval($used), '-1', 2); + $data['balance_total'] = strval($total); + $data['balance_usable'] = bcsub($data['balance_total'], $data['balance_used'], 2); if ($isUpdate) $user->save(['extra' => array_merge($user->getAttr('extra'), $data)]); return ['lock' => $lock, 'used' => abs($used), 'total' => $total, 'usable' => $data['balance_usable']]; } diff --git a/plugin/think-plugs-payment/src/service/Integral.php b/plugin/think-plugs-payment/src/service/Integral.php index 2c8d3488e..9cfc56da6 100644 --- a/plugin/think-plugs-payment/src/service/Integral.php +++ b/plugin/think-plugs-payment/src/service/Integral.php @@ -36,11 +36,11 @@ abstract class Integral * @return float * @throws \think\admin\Exception */ - public static function ratio(float $integral = 1): float + public static function ratio(string $integral = '1'): string { $cfg = sysdata('plugin.payment.config'); if (empty($cfg['integral']) || $cfg['integral'] < 1) $cfg['integral'] = 1; - return $integral / floatval($cfg['integral']); + return bcdiv($integral, strval($cfg['integral']), 6); } /** @@ -64,8 +64,8 @@ abstract class Integral $usable = PluginPaymentIntegral::mk()->where($map)->sum('amount'); if ($amount < 0 && abs($amount) > $usable) throw new Exception('扣减积分不足!'); - // 积分标准字段 - $data = ['unid' => $unid, 'code' => $code, 'name' => $name, 'amount' => $amount, 'remark' => $remark]; + // 积分标准字段 + $data = ['unid' => $unid, 'code' => $code, 'name' => $name, 'amount' => strval($amount), 'remark' => $remark]; // 统计操作前的金额 $data['amount_prev'] = $usable; @@ -140,15 +140,15 @@ abstract class Integral } // 统计用户积分数据 $map = ['unid' => $unid, 'cancel' => 0, 'deleted' => 0]; - $lock = intval(PluginPaymentIntegral::mk()->where($map)->where('unlock', '=', '0')->sum('amount')); - $used = intval(PluginPaymentIntegral::mk()->where($map)->where('amount', '<', '0')->sum('amount')); - $total = intval(PluginPaymentIntegral::mk()->where($map)->where('amount', '>', '0')->sum('amount')); + $lock = PluginPaymentIntegral::mk()->where($map)->where('unlock', '=', '0')->sum('amount'); + $used = PluginPaymentIntegral::mk()->where($map)->where('amount', '<', '0')->sum('amount'); + $total = PluginPaymentIntegral::mk()->where($map)->where('amount', '>', '0')->sum('amount'); // 更新积分统计 - $data['integral_lock'] = $lock; - $data['integral_used'] = abs($used); - $data['integral_total'] = $total; - $data['integral_usable'] = round($total - abs($used), 2); + $data['integral_lock'] = strval($lock); + $data['integral_used'] = bcmul(strval($used), '-1', 2); + $data['integral_total'] = strval($total); + $data['integral_usable'] = bcsub($data['integral_total'], $data['integral_used'], 2); if ($isUpdate) $user->save(['extra' => array_merge($user->getAttr('extra'), $data)]); return ['lock' => $lock, 'used' => abs($used), 'total' => $total, 'usable' => $data['integral_usable']]; } diff --git a/plugin/think-plugs-payment/src/service/contract/PaymentUsageTrait.php b/plugin/think-plugs-payment/src/service/contract/PaymentUsageTrait.php index 45eb4b247..123c579c2 100644 --- a/plugin/think-plugs-payment/src/service/contract/PaymentUsageTrait.php +++ b/plugin/think-plugs-payment/src/service/contract/PaymentUsageTrait.php @@ -129,20 +129,23 @@ trait PaymentUsageTrait * @param string $orderNo * @param mixed $payAmount * @param mixed $orderAmount - * @return float + * @return string * @throws \think\admin\Exception */ - protected function checkLeaveAmount($orderNo, $payAmount, $orderAmount): float + protected function checkLeaveAmount($orderNo, $payAmount, $orderAmount): string { // 检查未审核的记录 $map = ['order_no' => $orderNo, 'audit_status' => 1]; $model = PluginPaymentRecord::mk()->where($map)->findOrEmpty(); if ($model->isExists()) throw new Exception('凭证待审核!', 0); // 检查支付金额是否超出 - if (round(floatval($payAmount) + Payment::paidAmount($orderNo, true), 2) > floatval($orderAmount)) { + $payAmountFloat = floatval($payAmount); + $orderAmountFloat = floatval($orderAmount); + $paidAmount = Payment::paidAmount($orderNo, true); + if (bcadd(strval($payAmountFloat), strval($paidAmount), 2) > $orderAmountFloat) { throw new Exception("支付金额溢出!"); } - return floatval($payAmount); + return strval($payAmountFloat); } /** @@ -163,10 +166,12 @@ trait PaymentUsageTrait // 检查是否已经支付 $map = ['order_no' => $orderNo, 'payment_status' => 1]; $total = Payment::paidAmount($orderNo, true); - if ($total >= floatval($orderAmount) && $orderAmount > 0) { + $orderAmountFloat = floatval($orderAmount); + if ($total >= $orderAmountFloat && $orderAmountFloat > 0) { throw new Exception("已经完成支付!", 1); } - if (round($total + floatval($payAmount), 2) > floatval($orderAmount)) { + $payAmountFloat = floatval($payAmount); + if (bcadd(strval($total), strval($payAmountFloat), 2) > $orderAmountFloat) { throw new Exception('支付大于金额!', 0); } $map['code'] = $payCode; @@ -271,7 +276,9 @@ trait PaymentUsageTrait $extra['refund_time'] = date('Y-m-d H:i:s'); } // 支付金额大于0,并需要创建退款记录 - if ($record->getAttr('payment_amount') >= round($record->getAttr('refund_amount') + floatval($amount), 2)) { + $refundAmountFloat = floatval($amount); + $currentRefundAmount = $record->getAttr('refund_amount'); + if (bcadd(strval($currentRefundAmount), strval($refundAmountFloat), 2) <= floatval($record->getAttr('payment_amount'))) { PluginPaymentRefund::mk()->save(array_merge([ 'unid' => $record->getAttr('unid'), 'record_code' => $pCode, 'usid' => $record->getAttr('usid'), 'refund_amount' => $amount, diff --git a/plugin/think-plugs-payment/src/service/payment/IntegralPayment.php b/plugin/think-plugs-payment/src/service/payment/IntegralPayment.php index 90cc2fd22..4ff6ee74e 100644 --- a/plugin/think-plugs-payment/src/service/payment/IntegralPayment.php +++ b/plugin/think-plugs-payment/src/service/payment/IntegralPayment.php @@ -82,7 +82,8 @@ class IntegralPayment implements PaymentInterface if (floatval($amount) <= 0) return [1, '无需退款!']; $record = static::syncRefund($pcode, $rcode, $amount, $reason); $remark = "来自订单 {$record->getAttr('order_no')} 退回积分"; - $integral = floatval($amount) / floatval($record->getAttr('payment_amount')) * $record->getAttr('used_integral'); + $integral = bcdiv($amount, $record->getAttr('payment_amount'), 6); + $integral = bcmul($integral, $record->getAttr('used_integral'), 2); IntegralService::create($record->getAttr('unid'), $rcode, '账号积分退还', floatval($integral), $remark, true); return [1, '发起退款成功!']; } catch (\Exception $exception) { @@ -110,7 +111,7 @@ class IntegralPayment implements PaymentInterface $unid = $this->withUserUnid($account); $integral = IntegralService::recount($unid); if ($payAmount > $integral['usable']) throw new Exception('可抵扣的积分不足'); - $realAmount = $this->checkLeaveAmount($orderNo, sprintf('%01.2f', IntegralService::ratio(floatval($payAmount))), $orderAmount); + $realAmount = $this->checkLeaveAmount($orderNo, bcmul($payAmount, '1', 2), $orderAmount); $payCode = Payment::withPaymentCode(); // 创建支付行为 $this->createAction($orderNo, $orderTitle, $orderAmount, $payCode, strval($realAmount), '', '0.00', $payAmount); diff --git a/plugin/think-plugs-static/readme.md b/plugin/think-plugs-static/readme.md index 718704705..9af294b41 100644 --- a/plugin/think-plugs-static/readme.md +++ b/plugin/think-plugs-static/readme.md @@ -16,6 +16,22 @@ 我们建议您在安装或更新插件前,仔细阅读相关文档,确保了解可能的影响,并采取相应的预防措施。 +### 业务功能特性 + +**核心静态资源管理:** +- **UI 框架集成**: 集成 LayUI 2.8 前端框架,提供丰富的 UI 组件和交互体验 +- **静态资源管理**: 统一管理 CSS、JavaScript、图片等静态资源文件 +- **CDN 加速支持**: 支持 CDN 加速和资源版本控制,提升页面加载速度 +- **自定义扩展**: 保留 `public/static/extra` 目录用于自定义脚本和样式,避免被覆盖 +- **自动更新**: 同步保持 LayUI 框架的最新版本,确保安全性和功能完整性 + +**技术特性:** +- **MIT 开源协议**: 遵循 MIT 开源协议,免费可商用 +- **模块化设计**: 静态资源按功能模块组织,便于维护和扩展 +- **性能优化**: 针对前端资源进行压缩和优化,提升页面加载性能 +- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性,确保平滑升级 +- **安全防护**: 定期更新依赖库,修复已知安全漏洞 + `layui 2.8` 于 2023/04/24 正式发布,此插件会同步保持更新。 ### 安装插件 diff --git a/plugin/think-plugs-wechat-service/readme.md b/plugin/think-plugs-wechat-service/readme.md index f64cdb0af..bca8915d4 100644 --- a/plugin/think-plugs-wechat-service/readme.md +++ b/plugin/think-plugs-wechat-service/readme.md @@ -71,6 +71,23 @@ var_dump($userInfo); * 开放平台配置:`plugin-wechat-service/config/index` * 授权微信管理:`plugin-wechat-service/wechat/index` +### 业务功能特性 + +**核心微信开放平台功能:** +- **微信开放平台集成**: 提供完整的微信开放平台管理功能,支持公众号和小程序的统一管理 +- **远程接口调用**: 支持 JSON-RPC 远程调用,可与 ThinkPlugsWechat 插件无缝集成 +- **授权管理**: 完整的微信授权管理,支持多公众号和小程序的授权配置 +- **用户管理**: 提供粉丝列表获取、用户信息查询等完整的用户管理接口 +- **接口调度**: 统一的接口调度机制,简化微信开放平台的复杂性 +- **会员专享**: 作为会员尊享插件,提供深度优化的微信开发体验 + +**技术特性:** +- **VIP 授权**: 会员专享插件,非授权用户不得用于商业目的 +- **模块化设计**: 各微信功能模块独立封装,便于扩展和维护 +- **远程调用支持**: 支持 JSON-RPC 远程调用,实现插件间的无缝集成 +- **安全防护**: 内置 Token 验证和权限控制,确保接口调用安全 +- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性,确保平滑升级 + ### 插件数据 本插件涉及数据表有: diff --git a/plugin/think-plugs-wechat/readme.md b/plugin/think-plugs-wechat/readme.md index 745ce86af..ec25eae63 100644 --- a/plugin/think-plugs-wechat/readme.md +++ b/plugin/think-plugs-wechat/readme.md @@ -55,6 +55,26 @@ composer remove zoujingli/think-plugs-wechat * 微信支付管理:`wechat/payment.record/index` * 微信退款管理:`wechat/payment.refund/index` +### 业务功能特性 + +**核心微信功能:** +- **微信接口配置**: 提供完整的微信公众号接口配置管理,支持多公众号管理 +- **微信支付配置**: 集成微信支付功能,支持 JSAPI、Native、APP 等多种支付方式 +- **微信粉丝管理**: 完整的粉丝信息管理,支持标签分组、批量操作等功能 +- **微信图文管理**: 可视化的图文素材编辑和管理,支持多图文组合 +- **微信菜单配置**: 可视化的自定义菜单配置,支持点击、跳转、扫码等菜单类型 +- **回复规则管理**: 灵活的关键词回复规则配置,支持文本、图片、图文等多种回复类型 +- **关注自动回复**: 支持关注时的自动回复配置,提升用户体验 +- **微信支付管理**: 完整的支付记录管理,支持订单查询和状态跟踪 +- **微信退款管理**: 便捷的退款处理功能,支持部分退款和全额退款 + +**技术特性:** +- **MIT 开源协议**: 遵循 MIT 开源协议,免费可商用 +- **模块化设计**: 各微信功能模块独立封装,便于扩展和维护 +- **安全防护**: 内置微信消息签名验证、权限控制等安全机制 +- **高性能优化**: 针对微信接口调用进行专门优化,确保响应速度 +- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性,确保平滑升级 + ### 插件数据库 本插件涉及数据表有: diff --git a/plugin/think-plugs-wemall/readme.md b/plugin/think-plugs-wemall/readme.md index 2348c30da..3d07f041f 100644 --- a/plugin/think-plugs-wemall/readme.md +++ b/plugin/think-plugs-wemall/readme.md @@ -47,9 +47,36 @@ composer require zoujingli/think-plugs-wemall dev-master --optimize-autoloader composer remove zoujingli/think-plugs-wemall ``` +### 业务功能特性 + +**核心功能模块:** +- **多级分销体系**: 支持三级分销模式,可配置不同等级的代理返佣规则 +- **灵活返佣机制**: 支持下单奖励、首购奖励、复购奖励、升级奖励、平推返佣等多种返佣类型 +- **会员等级管理**: 基于订单金额和数量的自动等级升级,支持自定义等级规则 +- **代理等级管理**: 团队业绩统计,支持多维度的代理等级升级条件 +- **混合支付支持**: 集成余额支付、积分抵扣、微信支付、支付宝等多种支付方式 +- **商品管理系统**: 完整的商品分类、规格、库存、价格管理 +- **订单全流程管理**: 从下单、支付、发货到售后的完整订单生命周期管理 +- **推广海报管理**: 支持为不同用户等级生成个性化推广海报 +- **团队业绩统计**: 实时统计团队销售业绩和返佣数据 + +**技术特性:** +- **高精度金融计算**: 使用 BC Math 高精度计算,避免浮点数精度丢失问题 +- **事件驱动架构**: 通过支付事件、订单事件等实现业务逻辑解耦 +- **数据库约束优化**: 添加完整的外键约束、检查约束和索引优化 +- **并发安全处理**: 支持高并发场景下的余额、积分、库存操作 +- **数据完整性保障**: 通过数据库约束确保业务数据的一致性和有效性 + ### 插件数据 -本插件涉及数据表有:-- +本插件涉及数据表有: +- 商城-配置-等级: `plugin_wemall_config_agent`, `plugin_wemall_config_level` +- 商城-配置-返利: `plugin_wemall_config_rebate`, `plugin_wemall_config_discount` +- 商城-商品-内容: `plugin_wemall_goods`, `plugin_wemall_goods_item`, `plugin_wemall_goods_stock` +- 商城-订单-内容: `plugin_wemall_order`, `plugin_wemall_order_item`, `plugin_wemall_order_sender` +- 商城-用户-关系: `plugin_wemall_user_relation`, `plugin_wemall_user_rebate`, `plugin_wemall_user_transfer` +- 数据-快递-公司: `plugin_wemall_express_company`, `plugin_wemall_express_template` +- 数据-意见-反馈: `plugin_wemall_help_feedback`, `plugin_wemall_help_problem` ### 版权说明 diff --git a/plugin/think-plugs-wemall/src/service/UserOrder.php b/plugin/think-plugs-wemall/src/service/UserOrder.php index 76b9e2ff2..30902a96e 100644 --- a/plugin/think-plugs-wemall/src/service/UserOrder.php +++ b/plugin/think-plugs-wemall/src/service/UserOrder.php @@ -263,6 +263,11 @@ abstract class UserOrder 'amount_integral' => $ptotal['integral'] ?? 0, ], true); + // 检查订单是否已取消或退款 + if ($order->getAttr('cancel_status') > 0 || $order->getAttr('refund_status') > 0) { + return $order->save(); + } + // 订单已经支付完成 if ($order->getAttr('payment_amount') >= $order->getAttr('amount_real')) { // 已完成支付,更新订单状态 @@ -304,6 +309,7 @@ abstract class UserOrder */ public static function cancel($order, bool $setRebate = false): string { + $code = ''; try { /* 创建用户奖励 */ $order = UserReward::cancel($order, $code); } catch (\Exception $exception) { @@ -329,6 +335,7 @@ abstract class UserOrder */ public static function payment($order): string { + $code = ''; try { /* 创建用户奖励 */ UserReward::create($order, $code); } catch (\Exception $exception) { @@ -355,6 +362,7 @@ abstract class UserOrder */ public static function confirm($order): string { + $code = ''; try { /* 创建用户奖励 */ UserReward::confirm($order, $code); } catch (\Exception $exception) { diff --git a/plugin/think-plugs-wemall/src/service/UserRebate.php b/plugin/think-plugs-wemall/src/service/UserRebate.php index d38944482..26f589fbf 100644 --- a/plugin/think-plugs-wemall/src/service/UserRebate.php +++ b/plugin/think-plugs-wemall/src/service/UserRebate.php @@ -142,14 +142,14 @@ abstract class UserRebate if (self::$order['puid2'] > 0) { $map = ['unid' => self::$order['puid2']]; self::$rela2 = PluginWemallUserRelation::mk()->where($map)->findOrEmpty()->toArray(); - if (empty(self::$rela1)) throw new Exception('上二代理不存在'); + if (empty(self::$rela2)) throw new Exception('上二代理不存在'); } // 获取上三级代理数据 if (self::$order['puid3'] > 0) { $map = ['unid' => self::$order['puid3']]; self::$rela3 = PluginWemallUserRelation::mk()->where($map)->findOrEmpty()->toArray(); - if (empty(self::$rela1)) throw new Exception('上三代理不存在'); + if (empty(self::$rela3)) throw new Exception('上三代理不存在'); } // 批量查询规则并发放奖励 @@ -196,7 +196,7 @@ abstract class UserRebate /** @var PluginWemallUserRebate $item */ $map = [['status', '=', 0], ['deleted', '=', 0], ['order_no', 'like', "{$order->getAttr('order_no')}%"]]; foreach (PluginWemallUserRebate::mk()->where($map)->cursor() as $item) { - $item->save(['status' => 1, 'remark' => '订单已确认收货!', 'comfirm_time' => date('Y-m-d H:i:s')]); + $item->save(['status' => 1, 'remark' => '订单已确认收货!', 'confirm_time' => date('Y-m-d H:i:s')]); UserRebate::recount($item->getAttr('unid')); } return true; @@ -295,15 +295,17 @@ abstract class UserRebate $map = ['hash' => md5("{$config['code']}#{$ono}#{$relation['unid']}#{$config['type']}")]; if (PluginWemallUserRebate::mk()->where($map)->findOrEmpty()->isExists()) return false; // 根据配置计算返利数据 - $value = floatval($config["p{$layer}_reward_number"] ?: '0.00'); + $value = $config["p{$layer}_reward_number"] ?: '0.000000'; if ($config["p{$layer}_reward_type"] == 0) { - $val = $value; + $val = bcmul($value, '1', 2); $name = sprintf('%s,每单 %s 元', $config['name'], $val); } elseif ($config["p{$layer}_reward_type"] == 1) { - $val = floatval($value * self::$order['rebate_amount'] / 100); + $val = bcmul($value, self::$order['rebate_amount'], 2); + $val = bcdiv($val, '100', 2); $name = sprintf('%s,订单金额 %s%%', $config['name'], $value); } elseif ($config["p{$layer}_reward_type"] == 2) { - $val = floatval($value * self::$order['amount_profit'] / 100); + $val = bcmul($value, self::$order['amount_profit'], 2); + $val = bcdiv($val, '100', 2); $name = sprintf('%s,分佣金额 %s%%', $config['name'], $value); } else { return false; @@ -313,15 +315,15 @@ abstract class UserRebate } /** - * 用户首推奖励 + * 用户首购奖励 * @param int $layer * @param array $relation * @return boolean */ - protected static function _frist(int $layer, array $relation): bool + protected static function _first(int $layer, array $relation): bool { // 是否首次购买 - $orders = PluginWemallUserRebate::mk()->where(['order_unid' => self::$unid])->limit(2)->column('order_no'); + $orders = PluginWemallUserRebate::mk()->where(['order_unid' => self::$unid, 'status' => 1])->limit(2)->column('order_no'); if (count($orders) > 1 || (count($orders) === 1 && !in_array(self::$order['order_no'], $orders))) return false; // 发放用户首推奖励 return self::_order($layer, $relation); @@ -333,10 +335,10 @@ abstract class UserRebate * @param array $relation * @return boolean */ - protected function _repeat(int $layer, array $relation): bool + protected static function _repeat(int $layer, array $relation): bool { // 是否复购购买 - $orders = PluginWemallUserRebate::mk()->where(['order_unid' => self::$unid])->limit(2)->column('order_no'); + $orders = PluginWemallUserRebate::mk()->where(['order_unid' => self::$unid, 'status' => 1])->limit(2)->column('order_no'); if (count($orders) < 1 || (count($orders) === 1 && in_array(self::$order['order_no'], $orders))) return false; // 发放用户复购奖励 return self::_order($layer, $relation); @@ -345,11 +347,10 @@ abstract class UserRebate /** * 用户升级奖励发放 * @param int $layer - * @param array $config * @param array $relation * @return boolean */ - private static function _upgrade(int $layer, array $relation, array $config): bool + private static function _upgrade(int $layer, array $relation): bool { if (empty(self::$rela1)) return false; if (empty(self::$user['extra']['level_order']) || self::$user['extra']['level_order'] !== self::$order['order_no']) return false; @@ -377,7 +378,7 @@ abstract class UserRebate * @param integer $layer 发放序号 * @return boolean */ - private static function wRebate(int $unid, array $map, string $name, float $amount, int $layer = 0): bool + private static function wRebate(int $unid, array $map, string $name, string $amount, int $layer = 0): bool { $rebate = PluginWemallUserRebate::mk()->where($map)->findOrEmpty(); if ($rebate->isExists()) return false; diff --git a/plugin/think-plugs-wemall/stc/database/20241010000008_fix_wemall_constraints.php b/plugin/think-plugs-wemall/stc/database/20241010000008_fix_wemall_constraints.php new file mode 100644 index 000000000..6ec35fb32 --- /dev/null +++ b/plugin/think-plugs-wemall/stc/database/20241010000008_fix_wemall_constraints.php @@ -0,0 +1,126 @@ +_fix_plugin_wemall_user_rebate(); + + // 为余额/积分表添加来源字段 + $this->_fix_plugin_payment_balance_integral(); + + // 为用户关系表添加索引优化 + $this->_fix_plugin_wemall_user_relation(); + + // 为订单表添加检查约束 + $this->_fix_plugin_wemall_order(); + } + + /** + * 修复返佣记录表 + */ + private function _fix_plugin_wemall_user_rebate() + { + $table = $this->table('plugin_wemall_user_rebate'); + + // 添加订单商品项ID字段(用于精确追踪返佣) + if (!$this->hasColumn('plugin_wemall_user_rebate', 'order_item_id')) { + $table->addColumn('order_item_id', 'biginteger', ['limit' => 20, 'default' => 0, 'null' => true, 'comment' => '订单商品项ID']) + ->update(); + } + + // 添加返佣规则ID字段(用于追溯规则版本) + if (!$this->hasColumn('plugin_wemall_user_rebate', 'rebate_rule_id')) { + $table->addColumn('rebate_rule_id', 'biginteger', ['limit' => 20, 'default' => 0, 'null' => true, 'comment' => '返佣规则ID']) + ->update(); + } + + // 添加金额非负约束 + $this->execute("ALTER TABLE `plugin_wemall_user_rebate` MODIFY `amount` DECIMAL(20,2) NOT NULL DEFAULT '0.00' CHECK (amount >= 0)"); + } + + /** + * 修复余额/积分表 + */ + private function _fix_plugin_payment_balance_integral() + { + // 修复余额表 + $table = $this->table('plugin_payment_balance'); + if (!$this->hasColumn('plugin_payment_balance', 'source_type')) { + $table->addColumn('source_type', 'string', ['limit' => 50, 'default' => '', 'null' => true, 'comment' => '资金来源类型']) + ->addColumn('source_id', 'string', ['limit' => 50, 'default' => '', 'null' => true, 'comment' => '资金来源ID']) + ->update(); + } + + // 修复积分表 + $table = $this->table('plugin_payment_integral'); + if (!$this->hasColumn('plugin_payment_integral', 'source_type')) { + $table->addColumn('source_type', 'string', ['limit' => 50, 'default' => '', 'null' => true, 'comment' => '积分来源类型']) + ->addColumn('source_id', 'string', ['limit' => 50, 'default' => '', 'null' => true, 'comment' => '积分来源ID']) + ->update(); + } + + // 添加金额非负约束 + $this->execute("ALTER TABLE `plugin_payment_balance` MODIFY `amount` DECIMAL(20,2) NOT NULL DEFAULT '0.00'"); + $this->execute("ALTER TABLE `plugin_payment_integral` MODIFY `amount` DECIMAL(20,2) NOT NULL DEFAULT '0.00'"); + } + + /** + * 修复用户关系表索引 + */ + private function _fix_plugin_wemall_user_relation() + { + // 为path字段添加前缀索引(优化LIKE查询性能) + $this->execute("ALTER TABLE `plugin_wemall_user_relation` ADD INDEX `idx_path_prefix` (`path`(20))"); + + // 为代理层级字段添加索引 + $this->execute("ALTER TABLE `plugin_wemall_user_relation` ADD INDEX `idx_puid1` (`puid1`)"); + $this->execute("ALTER TABLE `plugin_wemall_user_relation` ADD INDEX `idx_puid2` (`puid2`)"); + $this->execute("ALTER TABLE `plugin_wemall_user_relation` ADD INDEX `idx_puid3` (`puid3`)"); + } + + /** + * 修复订单表约束 + */ + private function _fix_plugin_wemall_order() + { + // 添加金额字段的非负约束 + $amount_fields = [ + 'amount_cost', 'amount_real', 'amount_total', 'amount_goods', + 'amount_profit', 'amount_reduct', 'amount_balance', 'amount_integral', + 'amount_payment', 'amount_express', 'amount_discount', 'coupon_amount', + 'allow_balance', 'allow_integral', 'ratio_integral', 'rebate_amount', + 'reward_balance', 'reward_integral', 'payment_amount' + ]; + + foreach ($amount_fields as $field) { + $this->execute("ALTER TABLE `plugin_wemall_order` MODIFY `{$field}` DECIMAL(20,2) NOT NULL DEFAULT '0.00' CHECK ({$field} >= 0)"); + } + + // 添加状态字段的枚举约束 + $this->execute("ALTER TABLE `plugin_wemall_order` MODIFY `status` TINYINT NOT NULL DEFAULT 1 CHECK (status BETWEEN 0 AND 7)"); + $this->execute("ALTER TABLE `plugin_wemall_order` MODIFY `refund_status` TINYINT NOT NULL DEFAULT 0 CHECK (refund_status BETWEEN 0 AND 7)"); + $this->execute("ALTER TABLE `plugin_wemall_order` MODIFY `payment_status` TINYINT NOT NULL DEFAULT 0 CHECK (payment_status BETWEEN 0 AND 2)"); + $this->execute("ALTER TABLE `plugin_wemall_order` MODIFY `delivery_type` TINYINT NOT NULL DEFAULT 0 CHECK (delivery_type BETWEEN 0 AND 1)"); + } +} \ No newline at end of file diff --git a/plugin/think-plugs-worker/readme.md b/plugin/think-plugs-worker/readme.md index dcc70f6c6..ccdac65d1 100644 --- a/plugin/think-plugs-worker/readme.md +++ b/plugin/think-plugs-worker/readme.md @@ -7,6 +7,24 @@ [![PHP Version](https://thinkadmin.top/static/icon/php-7.1.svg)](https://thinkadmin.top) [![License](https://poser.pugx.org/zoujingli/think-plugs-worker/license)](https://gitee.com/zoujingli/think-plugs-worker/blob/master/license) +### 业务功能特性 + +**核心异步任务处理:** +- **HTTP 服务支持**: 基于 Workerman 4.x 提供高性能 HTTP 服务,无需 Nginx/Apache 配置,访问速度显著提升 +- **多协议支持**: 支持 WebSocket、TCP、UDP 等多种通信协议,满足不同应用场景需求 +- **Gateway 模式**: 支持 Gateway 分布式架构,适用于高并发实时通信场景 +- **自定义服务**: 提供灵活的自定义服务配置,支持 Text、WebSocket、Gateway、Register、Business 等多种服务类型 +- **异步任务队列**: 内置高效的异步任务处理机制,响应延时低于 0.5 秒 +- **进程管理**: 完善的进程启动、停止、重载、状态监控等管理功能 +- **跨平台支持**: 同时支持 Windows 和 Linux 平台,提供统一的操作接口 + +**技术特性:** +- **Apache2 开源协议**: 遵循 Apache2 开源协议,免费提供使用 +- **高性能架构**: 基于 Workerman 事件驱动架构,单机可支撑数万并发连接 +- **模块化设计**: 各服务类型独立配置,便于扩展和维护 +- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性,确保平滑升级 +- **文档完善**: 提供完整的配置示例和使用文档,快速上手 + 基于 **Workerman 4.x** 且支持多种通信协议的基础插件。 **提示:** 默认支持以 HTTP 方式直接启动 ThinkAdmin 项目,无需配置 Nginx 或 Apache 环境,访问速度提升 N 倍。 diff --git a/plugin/think-plugs-wuma/readme.md b/plugin/think-plugs-wuma/readme.md index ca753cf6a..3bf0f65f5 100644 --- a/plugin/think-plugs-wuma/readme.md +++ b/plugin/think-plugs-wuma/readme.md @@ -9,6 +9,24 @@ **注意:** 该插件测试版有数据库结构变化,未生成升级补丁,每次更新需要全新安装! +### 业务功能特性 + +**核心一物一码功能:** +- **商品溯源管理**: 提供完整的商品溯源和防伪验证功能,支持一物一码追踪 +- **物码标签管理**: 完整的物码标签生成、打印、管理和验证功能 +- **防伪验证**: 支持消费者扫码验证商品真伪,提升品牌信任度 +- **数据统计分析**: 提供扫码数据统计和分析,了解消费者行为 +- **批量操作**: 支持物码的批量生成、导入、导出等操作 +- **权限控制**: 完善的权限管理,确保数据安全 +- **收费授权**: 作为收费授权插件,提供专业的技术支持和功能更新 + +**技术特性:** +- **收费授权**: 需要联系作者获取授权,未授权不可商用 +- **模块化设计**: 功能模块独立封装,便于维护和扩展 +- **安全防护**: 内置数据加密和权限验证,确保系统安全 +- **向后兼容**: 保持与现有 ThinkAdmin 版本的兼容性,确保平滑升级 +- **专业支持**: 提供专业的技术支持和定期功能更新 + 物码标签管理系统,此插件为收费授权插件,请联系作者获取授权,未授权不可商用。 ### 加入我们 diff --git a/readme.md b/readme.md index 9c828c5a0..661b78579 100644 --- a/readme.md +++ b/readme.md @@ -13,6 +13,65 @@ **ThinkAdmin** v6 是对 v1 至 v5 的重构之作,结合 **ThinkPHP** 6 和 8 的设计思路,彻底改造系统,保留原生生态支持。我们精简了非必需组件,构建了自定义存储层、服务层和高效队列机制,并新增用户友好的指令,提升操作体验。经过严格测试,v6.1 版本展现出卓越的稳定性,系统和微信模块已达到高稳定水平。 +### 核心组件与插件体系 + +**ThinkLibrary 核心组件** +- **标准控制器基类**: 提供完整的 CRUD 操作封装,包括分页、表单、验证、队列等通用功能 +- **基础模型类**: 实现魔术方法和静态助手调用,支持操作日志记录和数据一致性保障 +- **自定义服务基类**: 提供依赖注入和实例化机制,支持服务的统一管理和扩展 +- **全局函数库**: 包含数据处理、系统配置、HTTP 请求、JWT 认证等实用函数 +- **PSR-12 标准**: 严格遵循 PHP-FIG 编码规范,确保代码质量和可维护性 + +**ThinkPlugsAccount 多端账号插件** +- **三层账号模型**: 临时用户(usid) ↔ 绑定手机(bind) ↔ 正式用户(unid) 的完整账号生命周期 +- **多端统一账号**: 支持微信服务号、微信小程序、APP、网页等多终端统一账号体系 +- **JWT无状态认证**: 基于 JWT Token 的无状态认证机制,支持跨域和分布式部署 +- **动态通道注册**: 支持运行时动态注册新的登录通道类型,灵活扩展登录方式 +- **高并发安全**: 支持高并发场景下的账号创建和绑定操作,确保数据一致性 + +**ThinkPlugsPayment 多端支付插件** +- **多端支付支持**: 支持微信服务号、微信小程序、APP、网页等多终端支付场景 +- **混合支付模式**: 支持余额、积分、微信、支付宝等多种支付方式组合使用 +- **高精度金融计算**: 使用 BC Math 高精度数学函数,确保金融计算的准确性 +- **支付事件驱动**: 通过支付事件(审核、完成、取消、确认)实现业务逻辑解耦 +- **退款管理**: 支持部分退款和全额退款,自动处理余额、积分的退回操作 + +**ThinkPlugsWemall 微商城插件** +- **多级分销体系**: 支持三级分销模式,可配置不同等级的代理返佣规则 +- **灵活返佣机制**: 支持下单奖励、首购奖励、复购奖励、升级奖励、平推返佣等多种返佣类型 +- **会员等级管理**: 基于订单金额和数量的自动等级升级,支持自定义等级规则 +- **代理等级管理**: 团队业绩统计,支持多维度的代理等级升级条件 +- **商品管理系统**: 完整的商品分类、规格、库存、价格管理 +- **订单全流程管理**: 从下单、支付、发货到售后的完整订单生命周期管理 + +**其他插件** +- **ThinkPlugsCenter**: 插件服务管理中心,提供插件注册、配置和管理功能 +- **ThinkPlugsHelper**: 系统辅助工具,包含数据库备份、索引优化等功能 +- **ThinkPlugsStatic**: 静态资源管理,支持 CDN 加速和资源版本控制 +- **ThinkPlugsWechat**: 微信生态集成,支持公众号、小程序、支付等微信功能 +- **ThinkPlugsWorker**: 异步任务处理,支持延时执行和循环任务 +- **ThinkPlugsWuma**: 一物一码系统,支持商品溯源和防伪验证(收费插件) + +### 技术特性 + +**高性能架构** +- **异步任务处理**: 内置高效队列机制,响应延时低于 0.5 秒 +- **缓存优化**: 集成 Redis 缓存,提升系统性能和响应速度 +- **数据库约束**: 添加完整的外键约束、检查约束和索引优化 +- **并发安全控制**: 支持高并发场景下的余额、积分、库存操作 + +**安全特性** +- **CSRF 令牌验证**: 内置表单安全验证,防止跨站请求伪造攻击 +- **数据完整性保障**: 通过数据库约束确保业务数据的一致性和有效性 +- **异常处理完善**: 完善的异常捕获和日志记录机制,便于问题排查 +- **权限控制**: 完整的系统权限管理,确保数据安全 + +**开发体验** +- **模块化设计**: 各功能模块独立封装,便于扩展和维护 +- **向后兼容**: 保持 API 稳定性,确保平滑升级 +- **文档完善**: 提供完整的接口文档和技术文档 +- **调试友好**: 内置调试工具和日志记录,便于开发和问题排查 + 我们持续推出新模块和辅助功能,期待后续更新!使用 **ThinkAdmin** 需要具备一定开发技能,包括 ThinkPHP、jQuery、LayUI 和 RequireJs。后台 UI 基于最新 LayUI 前端框架,支持插件加载和管理。 请勿修改 app/admin 和 app/wechat 目录,以确保未来功能和安全更新通过 Composer 管理。ThinkLibrary 作为核心组件,封装了常用操作,兼容原有 ThinkPHP 生态,降低编码复杂性。