feat: Implement date formatting across controllers for improved readability
- Added a new utility function `formatDateTime` to standardize date formatting across various controllers. - Updated multiple controllers (admin, article, ladder, match, points, store, user) to utilize the new formatting function for timestamps, enhancing the clarity of date and time displays in API responses. - Ensured consistent date representation in user and match details, improving overall user experience.
This commit is contained in:
parent
b2ed278505
commit
3923217e0e
@ -1,7 +1,7 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const { User, Store, SystemUser, LadderUser, Match, PointOrder, StoreStaff } = require('../models');
|
||||
const { success, error, getPagination, pageResult } = require('../utils/helper');
|
||||
const { success, error, getPagination, pageResult, formatDateTime } = require('../utils/helper');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
class AdminController {
|
||||
@ -145,7 +145,7 @@ class AdminController {
|
||||
memberCode: user.member_code,
|
||||
totalPoints: user.total_points,
|
||||
status: user.status,
|
||||
createdAt: user.created_at,
|
||||
createdAt: formatDateTime(user.created_at),
|
||||
// 前端根据该字段隐藏“添加为天梯用户”按钮
|
||||
hasLadderUser: ladderUserIdSet.has(user.id)
|
||||
})), count, page, pageSize));
|
||||
@ -232,7 +232,7 @@ class AdminController {
|
||||
memberCode: user.member_code,
|
||||
totalPoints: user.total_points,
|
||||
status: user.status,
|
||||
createdAt: user.created_at,
|
||||
createdAt: formatDateTime(user.created_at),
|
||||
ladderUsers: user.ladderUsers.map(lu => ({
|
||||
id: lu.id,
|
||||
storeId: lu.store_id,
|
||||
@ -382,8 +382,8 @@ class AdminController {
|
||||
storeId: user.store_id,
|
||||
storeName: user.store?.name,
|
||||
status: user.status,
|
||||
lastLoginAt: user.last_login_at,
|
||||
createdAt: user.created_at
|
||||
lastLoginAt: formatDateTime(user.last_login_at),
|
||||
createdAt: formatDateTime(user.created_at)
|
||||
})), count, page, pageSize));
|
||||
} catch (err) {
|
||||
console.error('获取系统用户列表失败:', err);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const { Article } = require('../models');
|
||||
const { success, error } = require('../utils/helper');
|
||||
const { success, error, formatDateTime } = require('../utils/helper');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
class ArticleController {
|
||||
@ -31,7 +31,7 @@ class ArticleController {
|
||||
category: a.category,
|
||||
coverImage: a.cover_image,
|
||||
summary: a.summary,
|
||||
createdAt: a.created_at,
|
||||
createdAt: formatDateTime(a.created_at),
|
||||
isTop: a.is_top === 1,
|
||||
}));
|
||||
|
||||
@ -66,7 +66,7 @@ class ArticleController {
|
||||
coverImage: article.cover_image,
|
||||
summary: article.summary,
|
||||
contentHtml: article.content_html,
|
||||
createdAt: article.created_at,
|
||||
createdAt: formatDateTime(article.created_at),
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const { User, LadderUser, Store } = require('../models');
|
||||
const { LADDER_LEVEL_NAMES } = require('../config/constants');
|
||||
const { success, error, getPagination, pageResult, generateMemberCode } = require('../utils/helper');
|
||||
const { success, error, getPagination, pageResult, formatDateTime, generateMemberCode } = require('../utils/helper');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
class LadderAdminController {
|
||||
@ -63,8 +63,8 @@ class LadderAdminController {
|
||||
matchCount: lu.match_count,
|
||||
winCount: lu.win_count,
|
||||
monthlyMatchCount: lu.monthly_match_count,
|
||||
lastMatchTime: lu.last_match_time,
|
||||
createdAt: lu.created_at
|
||||
lastMatchTime: formatDateTime(lu.last_match_time),
|
||||
createdAt: formatDateTime(lu.created_at)
|
||||
})), count, page, pageSize));
|
||||
} catch (err) {
|
||||
console.error('获取天梯用户列表失败:', err);
|
||||
|
||||
@ -9,6 +9,7 @@ const {
|
||||
error,
|
||||
getPagination,
|
||||
pageResult,
|
||||
formatDateTime,
|
||||
} = require("../utils/helper");
|
||||
const { Op } = require("sequelize");
|
||||
const sequelize = require("../config/database");
|
||||
@ -247,7 +248,7 @@ class LadderController {
|
||||
rank: higherCount + 1,
|
||||
storeId: ladderUser.store_id,
|
||||
storeName: ladderUser.store?.name,
|
||||
lastMatchTime: ladderUser.last_match_time,
|
||||
lastMatchTime: formatDateTime(ladderUser.last_match_time),
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
@ -319,7 +320,7 @@ class LadderController {
|
||||
rank: higherCount + 1,
|
||||
storeId: ladderUser.store_id,
|
||||
storeName: ladderUser.store && ladderUser.store.name,
|
||||
lastMatchTime: ladderUser.last_match_time,
|
||||
lastMatchTime: formatDateTime(ladderUser.last_match_time),
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const { Match, MatchGame, MatchPlayer, MatchRound, LadderUser, User, Store, sequelize } = require('../models');
|
||||
const { MATCH_TYPES, MATCH_STATUS, RANKING_STAGE, CONFIRM_STATUS } = require('../config/constants');
|
||||
const { generateMatchCode, success, error, getPagination, pageResult } = require('../utils/helper');
|
||||
const { generateMatchCode, success, error, getPagination, pageResult, formatDateTime } = require('../utils/helper');
|
||||
const PowerCalculator = require('../services/powerCalculator');
|
||||
const { broadcastToUsers, sendMatchNotification } = require('../websocket');
|
||||
const { Op } = require('sequelize');
|
||||
@ -53,9 +53,9 @@ class MatchAdminController {
|
||||
refereeName: match.referee?.nickname,
|
||||
status: match.status,
|
||||
stage: match.stage,
|
||||
startTime: match.start_time,
|
||||
endTime: match.end_time,
|
||||
createdAt: match.created_at
|
||||
startTime: formatDateTime(match.start_time),
|
||||
endTime: formatDateTime(match.end_time),
|
||||
createdAt: formatDateTime(match.created_at)
|
||||
})), count, page, pageSize));
|
||||
} catch (err) {
|
||||
console.error('获取比赛列表失败:', err);
|
||||
@ -244,8 +244,8 @@ class MatchAdminController {
|
||||
storeName: match.store?.name,
|
||||
refereeId: match.referee_id,
|
||||
refereeName: match.referee?.nickname,
|
||||
startTime: match.start_time,
|
||||
endTime: match.end_time,
|
||||
startTime: formatDateTime(match.start_time),
|
||||
endTime: formatDateTime(match.end_time),
|
||||
players: sortedPlayers.map(p => ({
|
||||
id: p.id,
|
||||
ladderUserId: p.ladder_user_id,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const { Match, MatchGame, MatchPlayer, MatchRound, LadderUser, User, Store, sequelize } = require('../models');
|
||||
const { MATCH_TYPES, MATCH_STATUS, CONFIRM_STATUS, RANKING_STAGE, MATCH_WEIGHTS, POWER_CALC } = require('../config/constants');
|
||||
const { generateMatchCode, success, error, getPagination, pageResult, normalizeAvatarForClient } = require('../utils/helper');
|
||||
const { generateMatchCode, success, error, getPagination, pageResult, formatDateTime, normalizeAvatarForClient } = require('../utils/helper');
|
||||
const PowerCalculator = require('../services/powerCalculator');
|
||||
const { sendChallengeNotification, sendScoreConfirmNotification, sendMatchNotification, broadcastToUsers, sendToUser } = require('../websocket');
|
||||
const matchAdminController = require('./matchAdminController');
|
||||
@ -1036,7 +1036,7 @@ class MatchController {
|
||||
stageName: stageNames[match.stage] || '未知',
|
||||
weight: match.weight,
|
||||
storeName: match.store?.name,
|
||||
startTime: match.start_time,
|
||||
startTime: formatDateTime(match.start_time),
|
||||
refereeId: match.referee_id,
|
||||
isReferee: isReferee,
|
||||
players: (match.players || []).map(p => ({
|
||||
@ -1392,7 +1392,7 @@ class MatchController {
|
||||
powerChange: game.winner_id === myLadderId
|
||||
? game.winner_power_change
|
||||
: game.loser_power_change,
|
||||
confirmedAt: game.confirmed_at
|
||||
confirmedAt: formatDateTime(game.confirmed_at)
|
||||
};
|
||||
}));
|
||||
|
||||
@ -1446,17 +1446,6 @@ class MatchController {
|
||||
});
|
||||
const opponentMap = new Map(opponents.map((o) => [String(o.id), o]));
|
||||
|
||||
const formatMatchTime = (date) => {
|
||||
if (!date) return '';
|
||||
const d = new Date(date);
|
||||
const Y = d.getFullYear();
|
||||
const M = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const D = String(d.getDate()).padStart(2, '0');
|
||||
const h = String(d.getHours()).padStart(2, '0');
|
||||
const m = String(d.getMinutes()).padStart(2, '0');
|
||||
return `${Y}-${M}-${D} ${h}:${m}`;
|
||||
};
|
||||
|
||||
const list = rows.map((game) => {
|
||||
const isPlayer1 = game.player1_id === player.id;
|
||||
const opponentId = isPlayer1 ? game.player2_id : game.player1_id;
|
||||
@ -1466,7 +1455,7 @@ class MatchController {
|
||||
const opponentScore = isPlayer1 ? game.player2_score : game.player1_score;
|
||||
const isWin = game.winner_id === player.id;
|
||||
const typeName = game.match && game.match.type === MATCH_TYPES.CHALLENGE ? '挑战赛' : '排位赛';
|
||||
const timeText = formatMatchTime(game.confirmed_at);
|
||||
const timeText = formatDateTime(game.confirmed_at);
|
||||
|
||||
return {
|
||||
id: game.id,
|
||||
@ -1682,8 +1671,8 @@ class MatchController {
|
||||
opponent,
|
||||
currentGame,
|
||||
playerCount,
|
||||
startTime: match.start_time,
|
||||
createdAt: match.created_at,
|
||||
startTime: formatDateTime(match.start_time),
|
||||
createdAt: formatDateTime(match.created_at),
|
||||
isReferee: match.referee_id === user.id
|
||||
};
|
||||
}));
|
||||
@ -1745,9 +1734,9 @@ class MatchController {
|
||||
match.type === MATCH_TYPES.RANKING
|
||||
? ["报名中", "循环赛", "淘汰赛", "已结束"][match.stage]
|
||||
: null,
|
||||
startTime: match.start_time,
|
||||
endTime: match.end_time,
|
||||
createdAt: match.created_at,
|
||||
startTime: formatDateTime(match.start_time),
|
||||
endTime: formatDateTime(match.end_time),
|
||||
createdAt: formatDateTime(match.created_at),
|
||||
storeId: match.store?.id,
|
||||
storeName: match.store?.name,
|
||||
}));
|
||||
@ -1801,7 +1790,7 @@ class MatchController {
|
||||
opponentName: opponent?.real_name,
|
||||
myScore: game.player1_id === ladderUser.id ? game.player1_score : game.player2_score,
|
||||
opponentScore: game.player1_id === ladderUser.id ? game.player2_score : game.player1_score,
|
||||
createdAt: game.created_at
|
||||
createdAt: formatDateTime(game.created_at)
|
||||
};
|
||||
}));
|
||||
|
||||
@ -1983,8 +1972,8 @@ class MatchController {
|
||||
status: match.status,
|
||||
stage: match.stage,
|
||||
storeName: match.store?.name,
|
||||
startTime: match.start_time,
|
||||
endTime: match.end_time,
|
||||
startTime: formatDateTime(match.start_time),
|
||||
endTime: formatDateTime(match.end_time),
|
||||
challenger: challengerInfo,
|
||||
defender: defenderInfo,
|
||||
myRole: myRole || null,
|
||||
|
||||
@ -12,6 +12,7 @@ const {
|
||||
error,
|
||||
getPagination,
|
||||
pageResult,
|
||||
formatDateTime,
|
||||
} = require("../utils/helper");
|
||||
const PowerCalculator = require("../services/powerCalculator");
|
||||
const { Op } = require("sequelize");
|
||||
@ -311,7 +312,7 @@ class PointsAdminController {
|
||||
status: product.status,
|
||||
storeId: product.store_id,
|
||||
storeName: product.store?.name,
|
||||
createdAt: product.created_at,
|
||||
createdAt: formatDateTime(product.created_at),
|
||||
})),
|
||||
count,
|
||||
page,
|
||||
@ -458,8 +459,8 @@ class PointsAdminController {
|
||||
status: order.status,
|
||||
storeId: order.store_id,
|
||||
storeName: order.store?.name,
|
||||
createdAt: order.created_at,
|
||||
verifiedAt: order.verified_at,
|
||||
createdAt: formatDateTime(order.created_at),
|
||||
verifiedAt: formatDateTime(order.verified_at),
|
||||
})),
|
||||
count,
|
||||
page,
|
||||
@ -501,7 +502,7 @@ class PointsAdminController {
|
||||
orderId: order.id,
|
||||
orderNo: order.order_no,
|
||||
status: order.status,
|
||||
verifiedAt: order.verified_at,
|
||||
verifiedAt: formatDateTime(order.verified_at),
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -556,7 +557,7 @@ class PointsAdminController {
|
||||
orderId: order.id,
|
||||
orderNo: order.order_no,
|
||||
status: order.status,
|
||||
verifiedAt: order.verified_at,
|
||||
verifiedAt: formatDateTime(order.verified_at),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const { User, PointRecord, PointProduct, PointOrder, Store } = require('../models');
|
||||
const { ORDER_STATUS } = require('../config/constants');
|
||||
const { generateOrderNo, generateExchangeCode, success, error, getPagination, pageResult } = require('../utils/helper');
|
||||
const { generateOrderNo, generateExchangeCode, success, error, getPagination, pageResult, formatDateTime } = require('../utils/helper');
|
||||
const { Op } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
const QRCode = require('qrcode');
|
||||
@ -42,7 +42,7 @@ class PointsController {
|
||||
consumeAmount: record.consume_amount,
|
||||
storeName: record.store?.name,
|
||||
remark: record.remark,
|
||||
createdAt: record.created_at
|
||||
createdAt: formatDateTime(record.created_at)
|
||||
})), count, page, pageSize));
|
||||
} catch (err) {
|
||||
console.error('获取积分记录失败:', err);
|
||||
@ -225,8 +225,8 @@ class PointsController {
|
||||
status: order.status,
|
||||
storeName: order.store?.name,
|
||||
storeAddress: order.store?.address,
|
||||
createdAt: order.created_at,
|
||||
verifiedAt: order.verified_at
|
||||
createdAt: formatDateTime(order.created_at),
|
||||
verifiedAt: formatDateTime(order.verified_at)
|
||||
})), count, page, pageSize));
|
||||
} catch (err) {
|
||||
console.error('获取订单列表失败:', err);
|
||||
@ -267,8 +267,8 @@ class PointsController {
|
||||
storeContact: order.store?.contact,
|
||||
storeLatitude: order.store?.latitude,
|
||||
storeLongitude: order.store?.longitude,
|
||||
createdAt: order.created_at,
|
||||
verifiedAt: order.verified_at
|
||||
createdAt: formatDateTime(order.created_at),
|
||||
verifiedAt: formatDateTime(order.verified_at)
|
||||
}));
|
||||
} catch (err) {
|
||||
console.error('获取订单详情失败:', err);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const { Store, LadderUser } = require('../models');
|
||||
const { success, error, getPagination, pageResult, calculateDistance } = require('../utils/helper');
|
||||
const { success, error, getPagination, pageResult, formatDateTime, calculateDistance } = require('../utils/helper');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
class StoreController {
|
||||
@ -194,7 +194,7 @@ class StoreController {
|
||||
realName: lu.real_name,
|
||||
level: lu.level,
|
||||
powerScore: lu.power_score,
|
||||
lastMatchTime: lu.last_match_time
|
||||
lastMatchTime: formatDateTime(lu.last_match_time)
|
||||
}))));
|
||||
} catch (err) {
|
||||
console.error('获取天梯门店失败:', err);
|
||||
|
||||
@ -8,6 +8,7 @@ const {
|
||||
success,
|
||||
error,
|
||||
calculateDistance,
|
||||
formatDateTime,
|
||||
getFullUrl,
|
||||
normalizeAvatarUrl,
|
||||
normalizeAvatarForClient,
|
||||
@ -548,7 +549,7 @@ class UserController {
|
||||
matchCount: lu.match_count,
|
||||
winCount: lu.win_count,
|
||||
monthlyMatchCount: lu.monthly_match_count,
|
||||
lastMatchTime: lu.last_match_time,
|
||||
lastMatchTime: formatDateTime(lu.last_match_time),
|
||||
})),
|
||||
),
|
||||
);
|
||||
|
||||
@ -204,6 +204,23 @@ function getFullUrl(path, req) {
|
||||
return `${protocol}://${host}${path}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一接口返回的时间格式:YYYY-MM-DD HH:mm(服务器本地时区)
|
||||
* @param {Date|string|null|undefined} date - 日期对象或 ISO 字符串
|
||||
* @returns {string} 格式化后的时间字符串,无效时返回空字符串
|
||||
*/
|
||||
function formatDateTime(date) {
|
||||
if (date == null) return '';
|
||||
const d = new Date(date);
|
||||
if (Number.isNaN(d.getTime())) return '';
|
||||
const Y = d.getFullYear();
|
||||
const M = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const D = String(d.getDate()).padStart(2, '0');
|
||||
const h = String(d.getHours()).padStart(2, '0');
|
||||
const m = String(d.getMinutes()).padStart(2, '0');
|
||||
return `${Y}-${M}-${D} ${h}:${m}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 规范化返回给客户端的头像URL
|
||||
* 如果头像是服务端的默认头像URL,返回null让前端使用本地默认头像
|
||||
@ -233,6 +250,7 @@ module.exports = {
|
||||
success,
|
||||
error,
|
||||
pageResult,
|
||||
formatDateTime,
|
||||
getFullUrl,
|
||||
normalizeAvatarUrl,
|
||||
normalizeAvatarForClient
|
||||
|
||||
Loading…
Reference in New Issue
Block a user