瀏覽代碼

fix: 财商打卡页内联表达式导致data-event-opts编译错误 + 修复模板编译器recyclableRender未定义

1. checkin.vue: 4处内联赋值改为methods调用,解决WXML data-event-opts编码异常

2. package.json: 升级vue-cli-plugin-uni到2.0.2-5010420260703001匹配7月版模板编译器

3. postinstall-fix.js: 新增templateLoader.js补丁,移除未定义的recyclableRender/components导出

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
liaoxg 1 月之前
父節點
當前提交
0186e5f4f9
共有 4 個文件被更改,包括 81 次插入26 次删除
  1. 15 15
      cfc-frontend/package-lock.json
  2. 1 1
      cfc-frontend/package.json
  3. 14 4
      cfc-frontend/pages/wealth-sub/checkin.vue
  4. 51 6
      cfc-frontend/postinstall-fix.js

+ 15 - 15
cfc-frontend/package-lock.json

@@ -9,7 +9,7 @@
       "version": "1.0.0",
       "hasInstallScript": true,
       "dependencies": {
-        "@dcloudio/vue-cli-plugin-uni": "^2.0.2-5000720260410001",
+        "@dcloudio/vue-cli-plugin-uni": "^2.0.2-5010420260703001",
         "@dcloudio/webpack-uni-mp-loader": "^2.0.2-5010520260709001",
         "postcss": "7.0.39",
         "regenerator-runtime": "^0.14.1",
@@ -2113,9 +2113,9 @@
       "license": "Apache-2.0"
     },
     "node_modules/@dcloudio/uni-stat": {
-      "version": "2.0.2-5000720260410001",
-      "resolved": "https://registry.npmjs.org/@dcloudio/uni-stat/-/uni-stat-2.0.2-5000720260410001.tgz",
-      "integrity": "sha512-3UOXmSGcuI0mvLPOlHKnaChbLvjETGFyXZSbkl5aGlvEHVe+uJwrTLDaRibzbjgEV7Nyk2d/FY2E2fYyxVjJtw==",
+      "version": "2.0.2-5010520260709001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stat/-/uni-stat-2.0.2-5010520260709001.tgz",
+      "integrity": "sha512-f0IY8FZX+x0hoLMhXjBqJtt8ldT9ASTxKos25QT8RMPvrsgOGt27xhRDFI7AFTQNpO/U/HWN2uZ8CPpgz15OZQ==",
       "license": "Apache-2.0"
     },
     "node_modules/@dcloudio/uni-template-compiler": {
@@ -2133,12 +2133,12 @@
       }
     },
     "node_modules/@dcloudio/vue-cli-plugin-uni": {
-      "version": "2.0.2-5000720260410001",
-      "resolved": "https://registry.npmjs.org/@dcloudio/vue-cli-plugin-uni/-/vue-cli-plugin-uni-2.0.2-5000720260410001.tgz",
-      "integrity": "sha512-V5DU8yXFbw8eKtUzvJXDaTBb736rs/pyKUrMwOIS74ccrw1Qfj/QX1capcwVvCBFzwDEpYeYRbEJ2ersoGDUng==",
+      "version": "2.0.2-5010520260709001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/vue-cli-plugin-uni/-/vue-cli-plugin-uni-2.0.2-5010520260709001.tgz",
+      "integrity": "sha512-NHEKIsHYGtuIszwRmqvkCkHYBYu4ev1MVEgTi9y8kMQZNu/RpqUuk+qliJIb9S6sKTGZObii/5fS+YEXSdMDGA==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@dcloudio/uni-stat": "^2.0.2-5000720260410001",
+        "@dcloudio/uni-stat": "^2.0.2-5010520260709001",
         "buffer-json": "^2.0.0",
         "clone-deep": "^4.0.1",
         "cross-env": "^5.2.0",
@@ -23116,9 +23116,9 @@
       "dev": true
     },
     "@dcloudio/uni-stat": {
-      "version": "2.0.2-5000720260410001",
-      "resolved": "https://registry.npmjs.org/@dcloudio/uni-stat/-/uni-stat-2.0.2-5000720260410001.tgz",
-      "integrity": "sha512-3UOXmSGcuI0mvLPOlHKnaChbLvjETGFyXZSbkl5aGlvEHVe+uJwrTLDaRibzbjgEV7Nyk2d/FY2E2fYyxVjJtw=="
+      "version": "2.0.2-5010520260709001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/uni-stat/-/uni-stat-2.0.2-5010520260709001.tgz",
+      "integrity": "sha512-f0IY8FZX+x0hoLMhXjBqJtt8ldT9ASTxKos25QT8RMPvrsgOGt27xhRDFI7AFTQNpO/U/HWN2uZ8CPpgz15OZQ=="
     },
     "@dcloudio/uni-template-compiler": {
       "version": "2.0.2-5010420260703001",
@@ -23134,11 +23134,11 @@
       }
     },
     "@dcloudio/vue-cli-plugin-uni": {
-      "version": "2.0.2-5000720260410001",
-      "resolved": "https://registry.npmjs.org/@dcloudio/vue-cli-plugin-uni/-/vue-cli-plugin-uni-2.0.2-5000720260410001.tgz",
-      "integrity": "sha512-V5DU8yXFbw8eKtUzvJXDaTBb736rs/pyKUrMwOIS74ccrw1Qfj/QX1capcwVvCBFzwDEpYeYRbEJ2ersoGDUng==",
+      "version": "2.0.2-5010520260709001",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/vue-cli-plugin-uni/-/vue-cli-plugin-uni-2.0.2-5010520260709001.tgz",
+      "integrity": "sha512-NHEKIsHYGtuIszwRmqvkCkHYBYu4ev1MVEgTi9y8kMQZNu/RpqUuk+qliJIb9S6sKTGZObii/5fS+YEXSdMDGA==",
       "requires": {
-        "@dcloudio/uni-stat": "^2.0.2-5000720260410001",
+        "@dcloudio/uni-stat": "^2.0.2-5010520260709001",
         "buffer-json": "^2.0.0",
         "clone-deep": "^4.0.1",
         "cross-env": "^5.2.0",

+ 1 - 1
cfc-frontend/package.json

@@ -38,7 +38,7 @@
     "yalc": "^1.0.0-pre.53"
   },
   "dependencies": {
-    "@dcloudio/vue-cli-plugin-uni": "^2.0.2-5000720260410001",
+    "@dcloudio/vue-cli-plugin-uni": "^2.0.2-5010420260703001",
     "@dcloudio/webpack-uni-mp-loader": "^2.0.2-5010520260709001",
     "postcss": "7.0.39",
     "regenerator-runtime": "^0.14.1",

+ 14 - 4
cfc-frontend/pages/wealth-sub/checkin.vue

@@ -85,7 +85,7 @@
     <view class="record-section">
       <view class="section-title-row">
         <text class="section-title">打卡记录</text>
-        <text class="section-subtitle" @click="showAllRecords = !showAllRecords">
+        <text class="section-subtitle" @click="toggleRecords">
           {{ showAllRecords ? '收起' : '查看全部' }}
         </text>
       </view>
@@ -114,7 +114,7 @@
     </view>
 
     <!-- 打卡弹窗 -->
-    <view class="dialog-mask" v-if="showDialog" @click="showDialog = false">
+    <view class="dialog-mask" v-if="showDialog" @click="closeDialog">
       <view class="dialog-card" @click.stop>
         <text class="dialog-title">{{ dialogType ? getTypeLabel(dialogType) : '' }}打卡</text>
         <view class="dialog-form">
@@ -140,12 +140,12 @@
                 :key="i"
                 class="mood-item"
                 :class="{ selected: formMood === m.value }"
-                @click="formMood = m.value">{{ m.icon }}</text>
+                @click="selectMood(m.value)">{{ m.icon }}</text>
             </view>
           </view>
         </view>
         <view class="dialog-actions">
-          <button class="dialog-btn cancel" @click="showDialog = false">取消</button>
+          <button class="dialog-btn cancel" @click="closeDialog">取消</button>
           <button class="dialog-btn confirm" @click="doCheckin">确认打卡</button>
         </view>
       </view>
@@ -320,6 +320,16 @@ export default {
       // 点击日期跳转到当天或者查看记录
     },
 
+    toggleRecords: function() {
+      this.showAllRecords = !this.showAllRecords
+    },
+    selectMood: function(value) {
+      this.formMood = value
+    },
+    closeDialog: function() {
+      this.showDialog = false
+    },
+
     showCheckinDialog: function(type) {
       this.dialogType = type
       this.formAmount = ''

+ 51 - 6
cfc-frontend/postinstall-fix.js

@@ -18,6 +18,42 @@
 const fs = require('fs');
 const path = require('path');
 
+/**
+ * Patch 2: templateLoader.js — remove undefined `recyclableRender` and `components` exports.
+ *
+ * Root cause: templateLoader.js hardcodes `export { render, staticRenderFns, recyclableRender, components }`
+ * but the template compiler (vue-template-compiler / @vue/component-compiler-utils) does NOT define
+ * `recyclableRender` or `components` in the output. This causes:
+ *   "Module parse failed: Export 'recyclableRender' is not defined"
+ *   "export 'components' was not found in './xxx.vue'"
+ *
+ * The fix removes the two undefined symbols from the export line.
+ */
+function patchTemplateLoader(filePath) {
+  let content = fs.readFileSync(filePath, 'utf8');
+
+  // Check if already patched
+  if (content.includes("export { render, staticRenderFns }") &&
+      !content.includes("recyclableRender")) {
+    console.log(`  ⏭️  ${filePath} (templateLoader already patched)`);
+    return true;
+  }
+
+  const oldExport = /export \{ render, staticRenderFns, recyclableRender, components \}/;
+  if (oldExport.test(content)) {
+    content = content.replace(
+      oldExport,
+      "export { render, staticRenderFns }"
+    );
+    fs.writeFileSync(filePath, content, 'utf8');
+    console.log(`  ✅ ${filePath}`);
+    return true;
+  }
+
+  console.log(`  ❌ ${filePath} (templateLoader unexpected format)`);
+  return false;
+}
+
 /** Find all remove-scoped.js files to patch */
 function findRemoveScopedFiles() {
   const files = [];
@@ -71,12 +107,21 @@ function patchFile(filePath) {
 const files = findRemoveScopedFiles();
 if (files.length === 0) {
   console.log('remove-scoped.js not found in any location, skipping patch');
-  process.exit(0);
+} else {
+  console.log(`Found ${files.length} remove-scoped.js to patch:`);
+  let patched = 0;
+  for (const f of files) {
+    if (patchFile(f)) patched++;
+  }
+  console.log(`Done: ${patched}/${files.length} patched`);
 }
 
-console.log(`Found ${files.length} remove-scoped.js to patch:`);
-let patched = 0;
-for (const f of files) {
-  if (patchFile(f)) patched++;
+// Patch 2: templateLoader.js
+const templateLoaderPath = path.join(__dirname, 'node_modules', '@dcloudio',
+  'vue-cli-plugin-uni', 'packages', 'vue-loader', 'lib', 'loaders', 'templateLoader.js');
+if (fs.existsSync(templateLoaderPath)) {
+  console.log('templateLoader.js found, applying patch:');
+  patchTemplateLoader(templateLoaderPath);
+} else {
+  console.log('templateLoader.js not found, skipping patch');
 }
-console.log(`Done: ${patched}/${files.length} patched`);