guoziyun преди 9 месеца
родител
ревизия
c4ddd72a99

+ 33 - 25
oms/dist/src/scripts/active-user-daily-notify.ts.js

@@ -186,7 +186,7 @@ const sendAndRecordMessage = async (uid, fcmToken, template, messageData, strate
         errorMessage = errorInfo ? errorInfo.code : error.message;
         if (isInvalidToken) {
             // 如果是无效令牌错误,清空该用户的 fmToken
-            await userModel_1.User.findByIdAndUpdate(uid, { fmToken: null });
+            await userModel_1.User.findOneAndUpdate({ uid: uid }, { fmToken: null });
             console.warn(`[FCM] 检测到无效令牌,自动清除 UID ${uid} 的 fmToken。`);
             errorMessage += " (Token cleared)";
         }
@@ -209,10 +209,12 @@ const sendAndRecordMessage = async (uid, fcmToken, template, messageData, strate
 /**
  * 脚本的入口方法,用于筛选用户并发送每日FCM通知。
  * 此方法通过cron外部调用。
+ *
+ * @returns {Promise<void>} 返回一个 Promise,当所有任务(包括定时任务)完成后解决。
  */
 async function run() {
     console.log("脚本开始:发送活跃用户每日通知...");
-    // 在启动所有定时任务之前,首先建立数据库连接
+    // 在启动所有任务之前,首先建立数据库连接
     await (0, database_1.connectToDatabase)();
     try {
         const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
@@ -223,16 +225,18 @@ async function run() {
             versionName: { $in: ["5.8.0-debug"] },
             //   versionName: { $in: ["5.8.0", "5.8.0-debug"] },
         })
-            .select("_id fmToken lang cc")
+            .select("_id uid fmToken lang cc")
             .lean();
         if (activeUsers.length === 0) {
             console.log("未找到符合条件的用户,脚本结束。");
+            await (0, database_1.disconnectFromDatabase)();
             return;
         }
         console.log(`找到 ${activeUsers.length} 位活跃用户。`);
         const strategy = await messageStrategyModel_1.MessageStrategy.findOne({ name: strategyName }).populate("templates");
         if (!strategy || !strategy.templates || strategy.templates.length < 2) {
             console.error(`未找到策略 '${strategyName}' 或其绑定的消息模板,或模板数量不足2个。`);
+            await (0, database_1.disconnectFromDatabase)();
             return;
         }
         const templates = strategy.templates;
@@ -240,6 +244,7 @@ async function run() {
         const todaysArtworks = await getTodaysArtworksForFCM();
         if (todaysArtworks.length < 2) {
             console.warn("今日用于FCM消息推送的画作数量不足2个,无法执行双消息策略。脚本结束。");
+            await (0, database_1.disconnectFromDatabase)();
             return;
         }
         const artwork1Id = todaysArtworks[0];
@@ -269,33 +274,36 @@ async function run() {
             data1.bigger = "true";
             data1.action = "go/art";
             data1.param = artwork1Id;
-            await sendAndRecordMessage(user._id, fcmToken, messageData.template1, data1, strategy._id, strategy.name);
+            await sendAndRecordMessage(user.uid, fcmToken, messageData.template1, data1, strategy._id, strategy.name);
         }
         console.log("第一批消息发送完成。");
-        // --- 设置单个定时器,延迟30分钟后发送第二批消息 ---
-        setTimeout(async () => {
-            console.log("\n定时任务触发:开始发送第二批消息...");
-            for (const messageData of messagesToSend) {
-                const user = messageData.user;
-                const userLang = getUserLanguage(user);
-                const fcmToken = user.fmToken;
-                const data2 = getMessageDataFromTemplate(messageData.template2, userLang);
-                data2.image = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artwork2Id}.png`;
-                data2.bigger = "true";
-                data2.action = "go/art";
-                data2.param = artwork2Id;
-                await sendAndRecordMessage(user._id, fcmToken, messageData.template2, data2, strategy._id, strategy.name);
-            }
-            console.log("第二批消息发送完成。");
-        }, 30 * 60 * 1000);
-        console.log("脚本执行完毕。第二批消息将在30分钟后发送。");
+        // 返回一个 Promise,该 Promise 将在 30 分钟后执行并完成所有后续操作
+        return new Promise((resolve) => {
+            setTimeout(async () => {
+                console.log("\n定时任务触发:开始发送第二批消息...");
+                for (const messageData of messagesToSend) {
+                    const user = messageData.user;
+                    const userLang = getUserLanguage(user);
+                    const fcmToken = user.fmToken;
+                    const data2 = getMessageDataFromTemplate(messageData.template2, userLang);
+                    data2.image = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artwork2Id}.png`;
+                    data2.bigger = "true";
+                    data2.action = "go/art";
+                    data2.param = artwork2Id;
+                    await sendAndRecordMessage(user.uid, fcmToken, messageData.template2, data2, strategy._id, strategy.name);
+                }
+                console.log("第二批消息发送完成。");
+                // 所有任务完成后,安全地断开数据库连接
+                await (0, database_1.disconnectFromDatabase)();
+                resolve();
+            }, 30 * 60 * 1000);
+        });
     }
     catch (error) {
         console.error("脚本执行过程中发生致命错误:", error);
-    }
-    finally {
-        // 脚本执行完毕,您可以在这里调用数据库断开连接
-        await (0, database_1.disconnectFromDatabase)(); // 在退出前断开数据库连接
+        // 如果在第一阶段发生错误,确保断开数据库连接
+        await (0, database_1.disconnectFromDatabase)();
+        throw error;
     }
 }
 // 这个 if 块确保只有在直接运行此文件时才调用 run() 函数

+ 1 - 1
oms/public/app/index.html

@@ -9,5 +9,5 @@
   <style>body,html{width:100%;height:100%}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}body{margin:0;color:#000000d9;font-size:14px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-variant:tabular-nums;line-height:1.5715;background-color:#fff;font-feature-settings:"tnum"}html{--antd-wave-shadow-color:#1890ff;--scroll-bar:0}</style><link rel="stylesheet" href="styles-LXBSU6DF.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles-LXBSU6DF.css"></noscript></head>
   <body>
     <app-root></app-root>
-  <script src="polyfills-B6TNHZQ6.js" type="module"></script><script src="main-2PI2FCIZ.js" type="module"></script></body>
+  <script src="polyfills-B6TNHZQ6.js" type="module"></script><script src="main-Z77RP2VA.js" type="module"></script></body>
 </html>

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
oms/public/app/main-Z77RP2VA.js


+ 37 - 28
oms/src/scripts/active-user-daily-notify.ts.ts

@@ -173,7 +173,7 @@ const sendAndRecordMessage = async (uid: string, fcmToken: string, template: IMe
 
     if (isInvalidToken) {
       // 如果是无效令牌错误,清空该用户的 fmToken
-      await User.findByIdAndUpdate(uid, { fmToken: null });
+      await User.findOneAndUpdate({ uid: uid }, { fmToken: null });
       console.warn(`[FCM] 检测到无效令牌,自动清除 UID ${uid} 的 fmToken。`);
       errorMessage += " (Token cleared)";
     } else {
@@ -195,11 +195,13 @@ const sendAndRecordMessage = async (uid: string, fcmToken: string, template: IMe
 /**
  * 脚本的入口方法,用于筛选用户并发送每日FCM通知。
  * 此方法通过cron外部调用。
+ *
+ * @returns {Promise<void>} 返回一个 Promise,当所有任务(包括定时任务)完成后解决。
  */
-export async function run() {
+export async function run(): Promise<void> {
   console.log("脚本开始:发送活跃用户每日通知...");
 
-  // 在启动所有定时任务之前,首先建立数据库连接
+  // 在启动所有任务之前,首先建立数据库连接
   await connectToDatabase();
 
   try {
@@ -212,11 +214,12 @@ export async function run() {
       versionName: { $in: ["5.8.0-debug"] },
       //   versionName: { $in: ["5.8.0", "5.8.0-debug"] },
     })
-      .select("_id fmToken lang cc")
+      .select("_id uid fmToken lang cc")
       .lean<IUser[]>();
 
     if (activeUsers.length === 0) {
       console.log("未找到符合条件的用户,脚本结束。");
+      await disconnectFromDatabase();
       return;
     }
     console.log(`找到 ${activeUsers.length} 位活跃用户。`);
@@ -224,6 +227,7 @@ export async function run() {
     const strategy = await MessageStrategy.findOne({ name: strategyName }).populate("templates");
     if (!strategy || !strategy.templates || strategy.templates.length < 2) {
       console.error(`未找到策略 '${strategyName}' 或其绑定的消息模板,或模板数量不足2个。`);
+      await disconnectFromDatabase();
       return;
     }
     const templates = strategy.templates as IMessageTemplate[];
@@ -232,6 +236,7 @@ export async function run() {
     const todaysArtworks = await getTodaysArtworksForFCM();
     if (todaysArtworks.length < 2) {
       console.warn("今日用于FCM消息推送的画作数量不足2个,无法执行双消息策略。脚本结束。");
+      await disconnectFromDatabase();
       return;
     }
     const artwork1Id = todaysArtworks[0];
@@ -265,35 +270,39 @@ export async function run() {
       data1.action = "go/art";
       data1.param = artwork1Id;
 
-      await sendAndRecordMessage(user._id, fcmToken, messageData.template1, data1, strategy._id, strategy.name);
+      await sendAndRecordMessage(user.uid, fcmToken, messageData.template1, data1, strategy._id, strategy.name);
     }
     console.log("第一批消息发送完成。");
 
-    // --- 设置单个定时器,延迟30分钟后发送第二批消息 ---
-    setTimeout(async () => {
-      console.log("\n定时任务触发:开始发送第二批消息...");
-      for (const messageData of messagesToSend) {
-        const user = messageData.user;
-        const userLang = getUserLanguage(user);
-        const fcmToken = user.fmToken as string;
-
-        const data2 = getMessageDataFromTemplate(messageData.template2, userLang);
-        data2.image = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artwork2Id}.png`;
-        data2.bigger = "true";
-        data2.action = "go/art";
-        data2.param = artwork2Id;
-
-        await sendAndRecordMessage(user._id, fcmToken, messageData.template2, data2, strategy._id, strategy.name);
-      }
-      console.log("第二批消息发送完成。");
-    }, 30 * 60 * 1000);
-
-    console.log("脚本执行完毕。第二批消息将在30分钟后发送。");
+    // 返回一个 Promise,该 Promise 将在 30 分钟后执行并完成所有后续操作
+    return new Promise<void>((resolve) => {
+      setTimeout(async () => {
+        console.log("\n定时任务触发:开始发送第二批消息...");
+        for (const messageData of messagesToSend) {
+          const user = messageData.user;
+          const userLang = getUserLanguage(user);
+          const fcmToken = user.fmToken as string;
+
+          const data2 = getMessageDataFromTemplate(messageData.template2, userLang);
+          data2.image = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artwork2Id}.png`;
+          data2.bigger = "true";
+          data2.action = "go/art";
+          data2.param = artwork2Id;
+
+          await sendAndRecordMessage(user.uid, fcmToken, messageData.template2, data2, strategy._id, strategy.name);
+        }
+        console.log("第二批消息发送完成。");
+
+        // 所有任务完成后,安全地断开数据库连接
+        await disconnectFromDatabase();
+        resolve();
+      }, 30 * 60 * 1000);
+    });
   } catch (error) {
     console.error("脚本执行过程中发生致命错误:", error);
-  } finally {
-    // 脚本执行完毕,您可以在这里调用数据库断开连接
-    await disconnectFromDatabase(); // 在退出前断开数据库连接
+    // 如果在第一阶段发生错误,确保断开数据库连接
+    await disconnectFromDatabase();
+    throw error;
   }
 }
 

+ 8 - 2
omsapp/src/app/pages/message-record-detail.component.ts

@@ -27,8 +27,14 @@ import { NzModalRef } from 'ng-zorro-antd/modal';
       <nz-descriptions-item nzTitle="用户ID">{{
         record.uid
       }}</nz-descriptions-item>
-      <nz-descriptions-item nzTitle="活动ID">{{
-        record.activityId || ''
+      <nz-descriptions-item nzTitle="活动">{{
+        record.activityName || ''
+      }}</nz-descriptions-item>
+      <nz-descriptions-item nzTitle="策略">{{
+        record.strategyName || ''
+      }}</nz-descriptions-item>
+      <nz-descriptions-item nzTitle="模板">{{
+        record.templateName || ''
       }}</nz-descriptions-item>
       <nz-descriptions-item nzTitle="标题">{{
         record.title

Някои файлове не бяха показани, защото твърде много файлове са промени