/** * 提现管理导出防崩溃与 PHP 8.0 兼容性回归测试 */ const fs = require('fs'); const path = require('path'); const assert = require('assert'); console.log('========================================================'); console.log(' 开始执行提现台账导出防崩溃与全链路加固测试'); console.log('========================================================\n'); // 1. 测试模型层 PHP 8.0 bcmath 防崩溃模拟 function simulateChargeRateFormat(value, chargeRate) { const rate = (value !== null && value !== undefined && value !== '') ? value : (chargeRate ?? 0); const safeRate = (!isNaN(rate) && rate !== '' && rate !== null && rate !== undefined) ? String(rate) : '0'; return (Number(safeRate) * 100).toFixed(1) + '%'; } function simulateRealAmount(amount, chargeFee) { const safeAmount = (!isNaN(amount) && amount !== '' && amount !== null) ? Number(amount) : 0; const safeFee = (!isNaN(chargeFee) && chargeFee !== '' && chargeFee !== null) ? Number(chargeFee) : 0; return Math.max(0, safeAmount - safeFee); } // 模拟各种异常输入,确保不抛出错误 assert.strictEqual(simulateChargeRateFormat(null, null), '0.0%'); assert.strictEqual(simulateChargeRateFormat('', ''), '0.0%'); assert.strictEqual(simulateChargeRateFormat(0, 0), '0.0%'); assert.strictEqual(simulateChargeRateFormat(undefined, 0.06), '6.0%'); assert.strictEqual(simulateRealAmount(null, null), 0); assert.strictEqual(simulateRealAmount('', ''), 0); assert.strictEqual(simulateRealAmount(100, 6), 94); assert.strictEqual(simulateRealAmount(10, 0.60), 9.4); console.log('[测试点 1] 模型层 PHP 8.0 bcmath 边界参数容错模拟断言通过'); // 2. 检查 application/admin/model/shopro/Withdraw.php 包含加固逻辑 const modelContent = fs.readFileSync(path.resolve(__dirname, '../../application/admin/model/shopro/Withdraw.php'), 'utf8'); assert(modelContent.includes('is_numeric($rate)'), 'getChargeRateFormatAttr 包含 is_numeric 校验'); assert(modelContent.includes('is_numeric($amount)'), 'getRealAmountAttr 包含 is_numeric 校验'); console.log('[测试点 2] Withdraw 模型源代码加固断言通过'); // 3. 检查 addons/shopro/library/Export.php 包含缓冲检查与下载退出 const exportContent = fs.readFileSync(path.resolve(__dirname, '../../addons/shopro/library/Export.php'), 'utf8'); assert(exportContent.includes('ob_get_level() > 0'), 'Export.php 包含 ob_get_level() 检查防 Notice'); assert(exportContent.includes("if ($this->config['save_type'] != 'save')"), 'Export.php 包含下载模式检查'); assert(exportContent.includes('exit;'), 'Export.php 下载完成安全退出'); console.log('[测试点 3] Export.php 缓冲区安全清理与下载模式防污染退出断言通过'); // 4. 检查 application/admin/controller/shopro/Withdraw.php 包含异常捕获、单 key 汇总、时间格式化 const controllerContent = fs.readFileSync(path.resolve(__dirname, '../../application/admin/controller/shopro/Withdraw.php'), 'utf8'); assert(controllerContent.includes('catch (\\Throwable $e)'), 'Withdraw.php 包含 \\Throwable 全局异常捕获'); assert(controllerContent.includes("(new WithdrawModel)->sheepFilter()"), 'Withdraw.php 使用全新实例查询防状态污染'); assert(controllerContent.includes("date('Y-m-d H:i:s'"), 'Withdraw.php 包含时间戳转格式化日期'); assert(controllerContent.includes("'id' => '合计: 共 ' . $total"), 'Withdraw.php 汇总行符合 Export.php 单 key 自动合并规范'); console.log('[测试点 4] Withdraw.php 控制器异常保护与导出规范断言通过'); // 5. 检查 public/assets/js/backend/shopro/withdraw.js 采用隐藏 iframe 下载 const jsContent = fs.readFileSync(path.resolve(__dirname, '../../public/assets/js/backend/shopro/withdraw.js'), 'utf8'); assert(jsContent.includes("document.createElement('iframe')"), 'withdraw.js 使用隐藏 iframe 触发下载'); assert(jsContent.includes('encodeURIComponent(search.search'), 'withdraw.js 对 search 参数进行安全 URI 编码'); assert(!jsContent.includes('window.location.href = `${Config.moduleurl}/shopro/withdraw/${type}'), '已移除直接 window.location 避免后台页面被替换'); console.log('[测试点 5] withdraw.js 前端静默下载与主页面安全隔离断言通过'); console.log('\n========================================================'); console.log(' 所有提现导出防崩溃加固测试全部通过![100% OK]'); console.log('========================================================');