|
|
@@ -147,48 +147,61 @@ class UserController {
|
|
|
public async getPaginatedUsers(req: Request, res: Response): Promise<void> {
|
|
|
try {
|
|
|
const page = parseInt(req.query.page as string) || 1;
|
|
|
- const limit = parseInt(req.query.limit as string) || 30; // 从 req.query 中筛选出只与 IUser 相关的属性,作为 MongoDB 的查询条件
|
|
|
+ const limit = parseInt(req.query.limit as string) || 30;
|
|
|
|
|
|
- const mongooseQuery: Partial<IUser> = {};
|
|
|
+ // 从 req.query 中筛选出只与 IUser 相关的属性,作为 MongoDB 的查询条件
|
|
|
+ const mongooseQuery: any = {};
|
|
|
for (const key in req.query) {
|
|
|
if (Object.prototype.hasOwnProperty.call(req.query, key)) {
|
|
|
// 检查 key 是否在 USER_MODEL_KEYS 中 (即是否是 IUser 的有效属性)
|
|
|
// 并且不是分页参数 'page' 或 'limit'
|
|
|
if (USER_MODEL_KEYS.includes(key as keyof IUser)) {
|
|
|
- const queryValue = req.query[key]; // 根据需要进行类型转换
|
|
|
+ const queryValue = req.query[key] as string;
|
|
|
+
|
|
|
+ // --- 新增:处理日期范围查询 ---
|
|
|
+ if (key === "firstLoginAt" || key === "lastActiveAt") {
|
|
|
+ // 检查是否为日期范围格式 (e.g., "2023-01-01,2023-01-31")
|
|
|
+ const dates = queryValue.split(",");
|
|
|
+ if (dates.length === 2) {
|
|
|
+ const startDate = new Date(dates[0]);
|
|
|
+ const endDate = new Date(dates[1]);
|
|
|
+
|
|
|
+ // 确保日期有效
|
|
|
+ if (!isNaN(startDate.getTime()) && !isNaN(endDate.getTime())) {
|
|
|
+ mongooseQuery[key] = {
|
|
|
+ $gte: startDate,
|
|
|
+ $lte: endDate,
|
|
|
+ };
|
|
|
+ continue; // 继续下一个查询参数
|
|
|
+ } else {
|
|
|
+ console.warn(`[API] Invalid date range format for ${key}: ${queryValue}. Skipping.`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ // --- 其他属性处理,保持不变 ---
|
|
|
if (key === "project" || key === "apiLevel" || key === "versionCode") {
|
|
|
- const numValue = parseInt(queryValue as string);
|
|
|
+ const numValue = parseInt(queryValue);
|
|
|
if (!isNaN(numValue)) {
|
|
|
- mongooseQuery[key as keyof IUser] = numValue as any;
|
|
|
+ mongooseQuery[key] = numValue;
|
|
|
}
|
|
|
} else if (key === "deviceMem") {
|
|
|
- const numValue = parseFloat(queryValue as string);
|
|
|
+ const numValue = parseFloat(queryValue);
|
|
|
if (!isNaN(numValue)) {
|
|
|
- mongooseQuery[key as keyof IUser] = numValue as any;
|
|
|
+ mongooseQuery[key] = numValue;
|
|
|
}
|
|
|
} else if (key === "tags") {
|
|
|
// 如果 tags 是以逗号分隔的字符串,可以将其转换为数组
|
|
|
- mongooseQuery[key as keyof IUser] = (queryValue as string).split(",").map((s) => s.trim()) as any;
|
|
|
- } else if (key === "firstLoginAt" || key === "lastActiveAt") {
|
|
|
- // 尝试将字符串转换为 Date 对象
|
|
|
- try {
|
|
|
- const dateValue = new Date(queryValue as string);
|
|
|
- if (!isNaN(dateValue.getTime())) {
|
|
|
- // 检查日期是否有效
|
|
|
- mongooseQuery[key as keyof IUser] = dateValue as any;
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.warn(`Invalid date format for ${key}: ${queryValue}. Skipping.`); // 可以选择在这里返回错误或忽略该查询参数
|
|
|
- }
|
|
|
- } // 对于其他字符串类型,直接赋值
|
|
|
- else {
|
|
|
- mongooseQuery[key as keyof IUser] = queryValue as any;
|
|
|
+ mongooseQuery[key] = queryValue.split(",").map((s) => s.trim());
|
|
|
+ } else {
|
|
|
+ // 对于其他字符串类型,直接赋值
|
|
|
+ mongooseQuery[key] = queryValue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 为了确保类型兼容性,我们暂时使用any来处理mongooseQuery
|
|
|
const { users, total } = await userService.getPaginatedUsers(
|
|
|
page,
|
|
|
limit,
|