@@ -8,7 +8,7 @@ import { createHash, validateHash } from 'src/lib/crypt';
88import { countTailZero , inferNumber } from 'src/lib/lang/number' ;
99import { buildMongooseQuery , genAggGroupId , genSort , unWindGroupId } from 'src/mongo' ;
1010
11- import { AggregateUserDto } from './dto/aggregate.dto' ;
11+ import { AggregateUserDto , DateUnit , GroupField } from './dto/aggregate.dto' ;
1212import { CreateUserDto } from './dto/create-user.dto' ;
1313import { ListUsersQuery } from './dto/list-users.dto' ;
1414import { UpdateUserDto } from './dto/update-user.dto' ;
@@ -180,8 +180,23 @@ export class UserService {
180180 */
181181 aggregate ( query : ListUsersQuery , dto : AggregateUserDto ) : Promise < UserAggregateResult [ ] > {
182182 const { filter, offset, limit, sort } = buildMongooseQuery ( wrapFilter ( query ) ) ;
183- const { group = [ ] } = dto ;
184- const groupId = genAggGroupId ( group ) ;
183+ const { group = [ ] , dateUnit = DateUnit . day } = dto ;
184+
185+ // 处理时间字段分组
186+ let groupId : any = { } ;
187+ const hasCreatedAt = group . includes ( GroupField . createdAt ) ;
188+
189+ if ( hasCreatedAt ) {
190+ // 分离出非时间字段
191+ const nonTimeFields = group . filter ( ( field ) => field !== GroupField . createdAt ) ;
192+ // 为时间字段生成特殊的分组ID
193+ groupId = {
194+ ...genAggGroupId ( nonTimeFields ) ,
195+ createdAt : this . getDateGroupExpression ( dateUnit ) ,
196+ } ;
197+ } else {
198+ groupId = genAggGroupId ( group ) ;
199+ }
185200
186201 // 特殊字段需要先进行 $unwind
187202 const unwindFields = [ 'labels' , 'groups' , 'roles' ] ;
@@ -218,4 +233,44 @@ export class UserService {
218233
219234 return this . userModel . aggregate ( pipeline ) ;
220235 }
236+
237+ private getDateGroupExpression ( dateUnit : DateUnit ) {
238+ const dateExpression = '$createdAt' ;
239+
240+ switch ( dateUnit ) {
241+ case DateUnit . hour :
242+ return {
243+ year : { $year : dateExpression } ,
244+ month : { $month : dateExpression } ,
245+ day : { $dayOfMonth : dateExpression } ,
246+ hour : { $hour : dateExpression } ,
247+ } ;
248+ case DateUnit . day :
249+ return {
250+ year : { $year : dateExpression } ,
251+ month : { $month : dateExpression } ,
252+ day : { $dayOfMonth : dateExpression } ,
253+ } ;
254+ case DateUnit . week :
255+ return {
256+ year : { $year : dateExpression } ,
257+ week : { $week : dateExpression } ,
258+ } ;
259+ case DateUnit . month :
260+ return {
261+ year : { $year : dateExpression } ,
262+ month : { $month : dateExpression } ,
263+ } ;
264+ case DateUnit . year :
265+ return {
266+ year : { $year : dateExpression } ,
267+ } ;
268+ default :
269+ return {
270+ year : { $year : dateExpression } ,
271+ month : { $month : dateExpression } ,
272+ day : { $dayOfMonth : dateExpression } ,
273+ } ;
274+ }
275+ }
221276}
0 commit comments