fix(order): 修复订单JS缺少闭合括号导致语法错误及页面打开空白问题
这个提交包含在:
@@ -42,8 +42,12 @@ class Order extends Common
|
||||
if (!$this->request->isAjax()) {
|
||||
if (sheep_config('shop.platform.WechatMiniProgram.status')) { // 如果开启了小程序平台
|
||||
// 设置小程序发货信息管理,消息通知跳转地址,有缓存, 不会每次都设置
|
||||
$uploadshoppingInfo = new \addons\shopro\library\easywechatPlus\WechatMiniProgramShop(Wechat::miniProgram());
|
||||
$uploadshoppingInfo->checkAndSetMessageJumpPath();
|
||||
try {
|
||||
$uploadshoppingInfo = new \addons\shopro\library\easywechatPlus\WechatMiniProgramShop(Wechat::miniProgram());
|
||||
$uploadshoppingInfo->checkAndSetMessageJumpPath();
|
||||
} catch (\Throwable $e) {
|
||||
\think\Log::error('WechatMiniProgram checkAndSetMessageJumpPath error: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$exportConfig = (new \addons\shopro\library\Export())->getConfig();
|
||||
|
||||
@@ -611,7 +611,7 @@
|
||||
</template>
|
||||
</el-popover>
|
||||
{if $auth->check('shopro/order/order/changeFee')}
|
||||
<el-button v-if="scope.row?.btns.includes('change_fee')" type="primary" link
|
||||
<el-button v-if="scope.row.btns?.includes('change_fee')" type="primary" link
|
||||
@click="onChangeFee(scope.row)">改价</el-button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -883,6 +883,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||
}, function (ret, res) { })
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
if (parent && parent.Layer && typeof parent.Layer.getFrameIndex === 'function') {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
function assert(condition, testName, detail = '') {
|
||||
if (condition) {
|
||||
console.log(` [PASS] ${testName}`);
|
||||
passed++;
|
||||
} else {
|
||||
console.error(` [FAIL] ${testName} - ${detail}`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("========================================================");
|
||||
console.log(" 订单页面 JS 语法与模板渲染健壮性 TDD 自动化测试");
|
||||
console.log("========================================================\n");
|
||||
|
||||
// 1. 验证 order.js 文件存在与语法解析
|
||||
const orderJsPath = path.resolve(__dirname, '../public/assets/js/backend/shopro/order/order.js');
|
||||
assert(fs.existsSync(orderJsPath), 'order.js 文件存在');
|
||||
|
||||
const orderJsContent = fs.readFileSync(orderJsPath, 'utf-8');
|
||||
|
||||
// 语法检查
|
||||
let syntaxOk = false;
|
||||
let syntaxErrorMsg = '';
|
||||
try {
|
||||
new vm.Script(orderJsContent, { filename: 'order.js' });
|
||||
syntaxOk = true;
|
||||
} catch (e) {
|
||||
syntaxErrorMsg = e.message;
|
||||
}
|
||||
assert(syntaxOk, 'order.js 语法解析无 SyntaxError', syntaxErrorMsg);
|
||||
|
||||
// 2. 验证 order.js 结构与闭合完整性
|
||||
const dummyDefine = function (deps, factory) {
|
||||
const $ = () => ({});
|
||||
const Backend = { api: {} };
|
||||
const Table = {};
|
||||
const Form = {};
|
||||
return factory($, undefined, Backend, Table, Form);
|
||||
};
|
||||
|
||||
let moduleLoaded = false;
|
||||
let controllerObj = null;
|
||||
try {
|
||||
const sandbox = {
|
||||
define: dummyDefine,
|
||||
console: console,
|
||||
location: { search: '?ref=addtabs' },
|
||||
window: {},
|
||||
Fast: { api: { ajax: () => {}, open: () => {}, fixurl: (u) => u } },
|
||||
Vue: {
|
||||
ref: (v) => ({ value: v }),
|
||||
reactive: (o) => o,
|
||||
onMounted: () => {},
|
||||
getCurrentInstance: () => ({ proxy: { $refs: {} } })
|
||||
},
|
||||
createApp: () => {}
|
||||
};
|
||||
vm.createContext(sandbox);
|
||||
controllerObj = vm.runInContext(orderJsContent, sandbox);
|
||||
if (controllerObj && typeof controllerObj.index === 'function' && typeof controllerObj.detail === 'function') {
|
||||
moduleLoaded = true;
|
||||
}
|
||||
} catch (e) {
|
||||
syntaxErrorMsg = e.message;
|
||||
}
|
||||
assert(moduleLoaded, 'order.js 成功执行并导出包含 index 和 detail 的 Controller 对象', syntaxErrorMsg);
|
||||
|
||||
// 3. 验证 detail 中的 onConfirm 闭合与 onBack 独立存在
|
||||
const onConfirmPattern = /function onConfirm\(\)\s*\{[\s\S]*?proxy\.\$refs\['formRef'\]\.validate[\s\S]*?\}\);\s*\}\s*function onBack\(\)/;
|
||||
assert(onConfirmPattern.test(orderJsContent), 'detail 中的 onConfirm 函数具有独立完整的闭合大括号,不侵入包裹后续方法');
|
||||
|
||||
// 4. 验证 index.html 模板中的按钮健壮性
|
||||
const orderIndexPath = path.resolve(__dirname, '../application/admin/view/shopro/order/order/index.html');
|
||||
assert(fs.existsSync(orderIndexPath), 'order/index.html 视图文件存在');
|
||||
const orderIndexContent = fs.readFileSync(orderIndexPath, 'utf-8');
|
||||
|
||||
const unsafeBtnMatch = orderIndexContent.includes('scope.row?.btns.includes');
|
||||
assert(!unsafeBtnMatch, 'order/index.html 中避免 scope.row?.btns.includes 引起的潜在 TypeError 崩溃');
|
||||
|
||||
console.log(`\n测试统计: 通过 ${passed}, 失败 ${failed}`);
|
||||
if (failed > 0) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户