Explorar o código

修复ingestor-service lastaActiveAt 为空的bug

guoziyun hai 9 meses
pai
achega
0861afe894

+ 5 - 3
oms/dist/services/ingestor-service.js

@@ -332,7 +332,11 @@ async function processMessage(msg) {
         // --- 3. Prepare User Data for MongoDB Batch Update ---
         // userSetData will contain fields to be updated using $set for both new and existing documents.
         // 'project' is now excluded here as it will be handled by $setOnInsert only.
-        const userSetData = { lastActiveAt: lastActiveAtDateObj };
+        // const userSetData: Partial<IUser> = { lastActiveAt: lastActiveAtDateObj };
+        const userSetData = {};
+        if (eventType !== "message_receive") {
+            userSetData.lastActiveAt = lastActiveAtDateObj;
+        }
         // SetOnInsert fields will only apply when a new document is created
         const setOnInsertFields = {
             uid: uid,
@@ -388,8 +392,6 @@ async function processMessage(msg) {
                 }
             }
         }
-        // 更正,message_receive 消息不应更新 lastActiveAt 时间
-        delete userSetData.lastActiveAt;
         // Initialize update object with $set and $setOnInsert
         const updateOperation = {
             $set: userSetData,

+ 1 - 3
oms/dist/src/controllers/messageRecordController.js

@@ -43,9 +43,7 @@ class MessageRecordController {
                 //           totalPages: Math.ceil(total / limitNum),
                 //         },
                 //       });
-                return res
-                    .status(200)
-                    .json({
+                return res.status(200).json({
                     success: true,
                     data: paginatedRecords.records,
                     pagination: { total: paginatedRecords.total, page: paginatedRecords.page, limit: paginatedRecords.limit, totalPages: paginatedRecords.totalPages },

+ 56 - 1
oms/dist/src/services/timezoneService.js

@@ -77,7 +77,62 @@ const defaultTimezoneMap = {
  * 这是一个处理时区转换的单例服务。
  */
 class TimezoneService {
-    constructor() { }
+    constructor() {
+        /**
+         * 将 YYYY-MM-DD 格式的日期转换为指定时区的时间范围(00:00:00 至 23:59:59.999)
+         * @param dateStr 日期字符串(YYYY-MM-DD)
+         * @param timeZone 时区(如 'Asia/Shanghai'、'America/New_York')
+         * @returns 包含 start(UTC 开始时间)和 end(UTC 结束时间)的对象,转换失败返回null
+         */
+        this.getTimeRangeInTimeZone = (dateStr, timeZone = "America/Los_Angeles") => {
+            if (!dateStr)
+                return null;
+            // 解析日期字符串
+            const [year, month, day] = dateStr.split("-").map(Number);
+            if (!year || !month || !day || month < 1 || month > 12 || day < 1 || day > 31) {
+                console.error("Invalid date format. Expected YYYY-MM-DD");
+                return null;
+            }
+            try {
+                // 1. 在指定时区创建当天00:00:00的日期
+                // 使用Intl.DateTimeFormat解析指定时区的日期
+                const formatter = new Intl.DateTimeFormat("en-US", {
+                    timeZone,
+                    year: "numeric",
+                    month: "2-digit",
+                    day: "2-digit",
+                    hour: "2-digit",
+                    minute: "2-digit",
+                    second: "2-digit",
+                    hour12: false,
+                });
+                // 构造指定时区的当天0点字符串
+                const dateStrInTimeZone = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")} 00:00:00`;
+                const parts = formatter.formatToParts(new Date(dateStrInTimeZone));
+                // 提取指定时区的年月日时分秒
+                const dateParts = {};
+                parts.forEach((part) => {
+                    if (["year", "month", "day", "hour", "minute", "second"].includes(part.type)) {
+                        dateParts[part.type] = parseInt(part.value, 10);
+                    }
+                });
+                // 2. 计算指定时区的00:00:00对应的UTC时间
+                const startInTimeZone = new Date(dateParts.year, dateParts.month - 1, // 月份从0开始
+                dateParts.day, dateParts.hour, dateParts.minute, dateParts.second);
+                // 3. 计算指定时区的23:59:59.999对应的UTC时间
+                const endInTimeZone = new Date(startInTimeZone);
+                endInTimeZone.setHours(23, 59, 59, 999);
+                return {
+                    start: new Date(startInTimeZone.toISOString()),
+                    end: new Date(endInTimeZone.toISOString()),
+                };
+            }
+            catch (error) {
+                console.error("Error converting date to time zone:", error);
+                return null;
+            }
+        };
+    }
     static getInstance() {
         if (!TimezoneService.instance) {
             TimezoneService.instance = new TimezoneService();

+ 5 - 4
oms/services/ingestor-service.ts

@@ -316,7 +316,11 @@ async function processMessage(msg: Message) {
     // --- 3. Prepare User Data for MongoDB Batch Update ---
     // userSetData will contain fields to be updated using $set for both new and existing documents.
     // 'project' is now excluded here as it will be handled by $setOnInsert only.
-    const userSetData: Partial<IUser> = { lastActiveAt: lastActiveAtDateObj };
+    // const userSetData: Partial<IUser> = { lastActiveAt: lastActiveAtDateObj };
+    const userSetData: Partial<IUser> = {};
+    if (eventType !== "message_receive") {
+      userSetData.lastActiveAt = lastActiveAtDateObj;
+    }
 
     // SetOnInsert fields will only apply when a new document is created
     const setOnInsertFields: any = {
@@ -364,9 +368,6 @@ async function processMessage(msg: Message) {
       }
     }
 
-    // 更正,message_receive 消息不应更新 lastActiveAt 时间
-    delete userSetData.lastActiveAt;
-
     // Initialize update object with $set and $setOnInsert
     const updateOperation: mongo.UpdateFilter<IUser> = {
       $set: userSetData,

+ 5 - 7
oms/src/controllers/messageRecordController.ts

@@ -57,13 +57,11 @@ class MessageRecordController {
       //         },
       //       });
 
-      return res
-        .status(200)
-        .json({
-          success: true,
-          data: paginatedRecords.records,
-          pagination: { total: paginatedRecords.total, page: paginatedRecords.page, limit: paginatedRecords.limit, totalPages: paginatedRecords.totalPages },
-        });
+      return res.status(200).json({
+        success: true,
+        data: paginatedRecords.records,
+        pagination: { total: paginatedRecords.total, page: paginatedRecords.page, limit: paginatedRecords.limit, totalPages: paginatedRecords.totalPages },
+      });
     } catch (error: any) {
       console.error("Error fetching paginated records:", error);
       return res.status(500).json({ success: false, message: "Server error", error: error.message });

+ 66 - 0
oms/src/services/timezoneService.ts

@@ -54,6 +54,72 @@ export class TimezoneService {
     return TimezoneService.instance;
   }
 
+  /**
+   * 将 YYYY-MM-DD 格式的日期转换为指定时区的时间范围(00:00:00 至 23:59:59.999)
+   * @param dateStr 日期字符串(YYYY-MM-DD)
+   * @param timeZone 时区(如 'Asia/Shanghai'、'America/New_York')
+   * @returns 包含 start(UTC 开始时间)和 end(UTC 结束时间)的对象,转换失败返回null
+   */
+  public getTimeRangeInTimeZone = (dateStr: string, timeZone: string = "America/Los_Angeles"): { start: Date; end: Date } | null => {
+    if (!dateStr) return null;
+
+    // 解析日期字符串
+    const [year, month, day] = dateStr.split("-").map(Number);
+    if (!year || !month || !day || month < 1 || month > 12 || day < 1 || day > 31) {
+      console.error("Invalid date format. Expected YYYY-MM-DD");
+      return null;
+    }
+
+    try {
+      // 1. 在指定时区创建当天00:00:00的日期
+      // 使用Intl.DateTimeFormat解析指定时区的日期
+      const formatter = new Intl.DateTimeFormat("en-US", {
+        timeZone,
+        year: "numeric",
+        month: "2-digit",
+        day: "2-digit",
+        hour: "2-digit",
+        minute: "2-digit",
+        second: "2-digit",
+        hour12: false,
+      });
+
+      // 构造指定时区的当天0点字符串
+      const dateStrInTimeZone = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")} 00:00:00`;
+      const parts = formatter.formatToParts(new Date(dateStrInTimeZone));
+
+      // 提取指定时区的年月日时分秒
+      const dateParts: Record<string, number> = {};
+      parts.forEach((part) => {
+        if (["year", "month", "day", "hour", "minute", "second"].includes(part.type)) {
+          dateParts[part.type] = parseInt(part.value, 10);
+        }
+      });
+
+      // 2. 计算指定时区的00:00:00对应的UTC时间
+      const startInTimeZone = new Date(
+        dateParts.year,
+        dateParts.month - 1, // 月份从0开始
+        dateParts.day,
+        dateParts.hour,
+        dateParts.minute,
+        dateParts.second
+      );
+
+      // 3. 计算指定时区的23:59:59.999对应的UTC时间
+      const endInTimeZone = new Date(startInTimeZone);
+      endInTimeZone.setHours(23, 59, 59, 999);
+
+      return {
+        start: new Date(startInTimeZone.toISOString()),
+        end: new Date(endInTimeZone.toISOString()),
+      };
+    } catch (error) {
+      console.error("Error converting date to time zone:", error);
+      return null;
+    }
+  };
+
   /**
    * 根据国家代码获取对应的时区。
    * 优先从自定义映射表中查找,如果找不到,则退回到 countries-and-timezones 库的第一个时区。