|
@@ -1,6 +1,6 @@
|
|
|
'use strict';
|
|
|
|
|
|
-const { isString, isArray, get } = require('lodash');
|
|
|
+const { isString, isArray, cloneDeep, head: getHead, get } = require('lodash');
|
|
|
const { isNullOrUndefined, trimData } = require('naf-core').Util;
|
|
|
const assert = require('assert');
|
|
|
const { ObjectId } = require('mongoose').Types;
|
|
@@ -50,7 +50,7 @@ class CrudService extends NafService {
|
|
|
if (sort && isString(sort)) {
|
|
|
sort = { [sort]: desc ? -1 : 1 };
|
|
|
} else if (sort && isArray(sort)) {
|
|
|
- sort = sort.map((f) => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
|
+ sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
|
}
|
|
|
|
|
|
return await this.model.findOne(filter, projection).exec();
|
|
@@ -61,17 +61,35 @@ class CrudService extends NafService {
|
|
|
if (sort && isString(sort)) {
|
|
|
sort = { [sort]: desc ? -1 : 1 };
|
|
|
} else if (sort && isArray(sort)) {
|
|
|
- sort = sort.map((f) => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
|
+ sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
|
}
|
|
|
- filter = this.dealFilter(filter);
|
|
|
- const rs = await this.model.find(trimData(filter), projection, { skip, limit, sort }).exec();
|
|
|
+ let condition = cloneDeep(filter);
|
|
|
+ condition = this.dealFilter(condition);
|
|
|
+ const pipeline = [{ $match: condition }];
|
|
|
+ // 先排序
|
|
|
+ if (sort) pipeline.push({ $sort: sort });
|
|
|
+ // 再进行分页
|
|
|
+ if (skip && limit) {
|
|
|
+ pipeline.push({ $skip: parseInt(skip) });
|
|
|
+ pipeline.push({ $limit: parseInt(limit) });
|
|
|
+ }
|
|
|
+ // 再将数据过滤
|
|
|
+ if (projection) pipeline.push({ $project: projection });
|
|
|
+ const rs = await this.model.aggregate(pipeline);
|
|
|
+ // const rs = await this.model.find(trimData(condition), projection, { skip, limit, sort }).exec();
|
|
|
return rs;
|
|
|
}
|
|
|
|
|
|
async count(filter) {
|
|
|
- filter = this.dealFilter(filter);
|
|
|
- const res = await this.model.countDocuments(trimData(filter)).exec();
|
|
|
- return res;
|
|
|
+ let condition = cloneDeep(filter);
|
|
|
+ condition = this.dealFilter(condition);
|
|
|
+ let count = 0;
|
|
|
+ const res = await this.model.aggregate([{ $match: condition }, { $count: 'id' }]);
|
|
|
+ if (res && isArray(res)) {
|
|
|
+ const head = getHead(res);
|
|
|
+ count = get(head, 'id', 0);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
}
|
|
|
|
|
|
async queryAndCount(filter, options) {
|
|
@@ -87,12 +105,12 @@ class CrudService extends NafService {
|
|
|
}
|
|
|
|
|
|
turnFilter(filter) {
|
|
|
- let str = /^%\S*%$/;
|
|
|
- let keys = Object.keys(filter);
|
|
|
+ const str = /^%\S*%$/;
|
|
|
+ const keys = Object.keys(filter);
|
|
|
for (const key of keys) {
|
|
|
- let res = key.match(str);
|
|
|
+ const res = key.match(str);
|
|
|
if (res) {
|
|
|
- let newKey = key.slice(1, key.length - 1);
|
|
|
+ const newKey = key.slice(1, key.length - 1);
|
|
|
if (!ObjectId.isValid(filter[key])) filter[newKey] = new RegExp(filter[key]);
|
|
|
delete filter[key];
|
|
|
}
|
|
@@ -102,30 +120,36 @@ class CrudService extends NafService {
|
|
|
|
|
|
turnDateRangeQuery(filter) {
|
|
|
const keys = Object.keys(filter);
|
|
|
+ const times = [];
|
|
|
for (const k of keys) {
|
|
|
if (k.includes('@')) {
|
|
|
const karr = k.split('@');
|
|
|
if (karr.length === 2) {
|
|
|
+ const prefix = karr[0];
|
|
|
const type = karr[1];
|
|
|
if (type === 'start') {
|
|
|
if (filter[k] && filter[k] !== '') {
|
|
|
- filter[karr[0]] = {
|
|
|
- ...get(filter, karr[0], {}),
|
|
|
- $gte: filter[k],
|
|
|
- };
|
|
|
+ const obj = { key: prefix, opera: '$gte', value: new Date(filter[k]).toISOString() };
|
|
|
+ times.push(obj);
|
|
|
}
|
|
|
} else {
|
|
|
if (filter[k] && filter[k] !== '') {
|
|
|
- filter[karr[0]] = {
|
|
|
- ...get(filter, karr[0], {}),
|
|
|
- $lte: filter[k],
|
|
|
- };
|
|
|
+ const obj = { key: prefix, opera: '$lte', value: new Date(filter[k]).toISOString() };
|
|
|
+ times.push(obj);
|
|
|
}
|
|
|
}
|
|
|
delete filter[k];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ for (const i of times) {
|
|
|
+ const { key, opera, value } = i;
|
|
|
+ const obj = { [key]: { [opera]: value } };
|
|
|
+ if (!filter.$and) {
|
|
|
+ filter.$and = [];
|
|
|
+ }
|
|
|
+ filter.$and.push(obj);
|
|
|
+ }
|
|
|
return filter;
|
|
|
}
|
|
|
}
|