|
@@ -1,6 +1,6 @@
|
|
|
'use strict';
|
|
|
|
|
|
-const { isString, isArray, cloneDeep, head: getHead, get, omit, last } = require('lodash');
|
|
|
+const _ = require('lodash');
|
|
|
const { isNullOrUndefined, trimData } = require('naf-core').Util;
|
|
|
const assert = require('assert');
|
|
|
const { ObjectId } = require('mongoose').Types;
|
|
@@ -125,9 +125,9 @@ class CrudService extends NafService {
|
|
|
if (_id || id) filter = { _id: ObjectId(_id || id) };
|
|
|
|
|
|
// 处理排序
|
|
|
- if (sort && isString(sort)) {
|
|
|
+ if (sort && _.isString(sort)) {
|
|
|
sort = { [sort]: desc ? -1 : 1 };
|
|
|
- } else if (sort && isArray(sort)) {
|
|
|
+ } else if (sort && _.isArray(sort)) {
|
|
|
sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
|
}
|
|
|
let res = await this.model.findOne(filter, projection).exec();
|
|
@@ -144,16 +144,16 @@ class CrudService extends NafService {
|
|
|
|
|
|
async query(filter, { skip = 0, limit, sort, desc, projection } = {}) {
|
|
|
// 处理排序
|
|
|
- if (sort && isString(sort)) {
|
|
|
+ if (sort && _.isString(sort)) {
|
|
|
sort = { [sort]: desc ? -1 : 1 };
|
|
|
- } else if (sort && isArray(sort)) {
|
|
|
+ } else if (sort && _.isArray(sort)) {
|
|
|
sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
|
}
|
|
|
- let condition = cloneDeep(filter);
|
|
|
+ let condition = _.cloneDeep(filter);
|
|
|
condition = await this.beforeQuery(condition);
|
|
|
condition = this.dealFilter(condition);
|
|
|
// 过滤出ref字段
|
|
|
- const { refMods, populate } = await this.getRefMods();
|
|
|
+ const { refMods, populate } = this.getRefMods();
|
|
|
// 带ref查询
|
|
|
let rs = await this.model.find(trimData(condition), projection, { skip, limit, sort }).populate(populate).exec();
|
|
|
rs = JSON.parse(JSON.stringify(rs));
|
|
@@ -162,21 +162,21 @@ class CrudService extends NafService {
|
|
|
for (const obj of refMods) {
|
|
|
const { col, prop, type } = obj;
|
|
|
if (!prop) continue;
|
|
|
- if (isArray(prop)) {
|
|
|
+ if (_.isArray(prop)) {
|
|
|
for (const p of prop) {
|
|
|
- if (type === 'String') i[`${col}_${p}`] = get(i, `${col}.${p}`);
|
|
|
+ if (type === 'String') i[`${col}_${p}`] = _.get(i, `${col}.${p}`);
|
|
|
if (type === 'Array') {
|
|
|
const list = [];
|
|
|
- const oList = get(i, `${col}`);
|
|
|
+ const oList = _.get(i, `${col}`);
|
|
|
for (const d of oList) {
|
|
|
const obj = { _id: d._id };
|
|
|
- obj[p] = get(d, p);
|
|
|
+ obj[p] = _.get(d, p);
|
|
|
list.push(obj);
|
|
|
}
|
|
|
i[`${col}_${p}`] = list;
|
|
|
}
|
|
|
}
|
|
|
- i[col] = get(i, `${col}._id`);
|
|
|
+ i[col] = _.get(i, `${col}._id`);
|
|
|
}
|
|
|
}
|
|
|
return i;
|
|
@@ -185,39 +185,8 @@ class CrudService extends NafService {
|
|
|
return rs;
|
|
|
}
|
|
|
|
|
|
- async getRefMods() {
|
|
|
- const mod = await this.getModel();
|
|
|
- const refMods = [];
|
|
|
- const populate = [];
|
|
|
- for (const key in mod) {
|
|
|
- if (!mod[key].ref && !mod[key].refPath) continue;
|
|
|
- const obj = { col: key, prop: mod[key].getProp, type: mod[key].type.name };
|
|
|
- if (mod[key].ref) {
|
|
|
- const ref = mod[key].ref;
|
|
|
- if (ref.includes('.')) {
|
|
|
- // 说明是跨数据源
|
|
|
- const arr = ref.split('.');
|
|
|
- const conn = this.app.mongooseDB.get(getHead(arr));
|
|
|
- const refModel = last(arr);
|
|
|
- const schema = get(this.ctx.model, `${refModel}.schema`);
|
|
|
- const model = conn.model(refModel, schema);
|
|
|
- const p = { path: key, model };
|
|
|
- populate.push(p);
|
|
|
- } else {
|
|
|
- const p = { path: key };
|
|
|
- populate.push(p);
|
|
|
- }
|
|
|
- } else if (mod[key].refPath) {
|
|
|
- const p = { path: key };
|
|
|
- populate.push(p);
|
|
|
- }
|
|
|
- refMods.push(obj);
|
|
|
- }
|
|
|
- return { refMods, populate };
|
|
|
- }
|
|
|
-
|
|
|
async count(filter) {
|
|
|
- let condition = cloneDeep(filter);
|
|
|
+ let condition = _.cloneDeep(filter);
|
|
|
condition = await this.beforeQuery(condition);
|
|
|
condition = this.dealFilter(condition);
|
|
|
const count = await this.model.count(condition);
|
|
@@ -238,7 +207,8 @@ class CrudService extends NafService {
|
|
|
|
|
|
turnFilter(filter) {
|
|
|
const str = /^%\S*%$/;
|
|
|
- let keys = Object.keys(filter);
|
|
|
+ // $是mongodb固定条件,不用处理;大多为手写特殊处理过的条件
|
|
|
+ let keys = Object.keys(filter).filter(f => !f.includes('$'));
|
|
|
for (const key of keys) {
|
|
|
const res = key.match(str);
|
|
|
if (res) {
|
|
@@ -248,9 +218,9 @@ class CrudService extends NafService {
|
|
|
}
|
|
|
}
|
|
|
// 再次过滤数据,将数组的数据都变成{$in:value},因为查询变成了聚合查询
|
|
|
- keys = Object.keys(filter);
|
|
|
+ keys = Object.keys(filter).filter(f => !f.includes('$'));
|
|
|
for (const key of keys) {
|
|
|
- if (isArray(filter[key])) {
|
|
|
+ if (_.isArray(filter[key])) {
|
|
|
filter[key] = { $in: filter[key] };
|
|
|
} else if (filter[key] === 'true' || filter[key] === 'false') {
|
|
|
// 布尔类型的值检查,如果是布尔类型,则将字符串转为布尔
|
|
@@ -294,13 +264,6 @@ class CrudService extends NafService {
|
|
|
return filter;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 获取model的配置
|
|
|
- */
|
|
|
- async getModel() {
|
|
|
- const obj = this.model.prototype.schema.obj;
|
|
|
- return obj;
|
|
|
- }
|
|
|
/**
|
|
|
* 读取model中不显示的字段
|
|
|
*/
|
|
@@ -313,6 +276,62 @@ class CrudService extends NafService {
|
|
|
}
|
|
|
if (Object.keys(project).length > 0) return project;
|
|
|
}
|
|
|
+
|
|
|
+ getRefMods() {
|
|
|
+ // 找到该表的schema(表结构)
|
|
|
+ const mod = this.getSchema();
|
|
|
+ const populate = this.resetPopulate(mod);
|
|
|
+ const refMods = [];
|
|
|
+ for (const key in mod) {
|
|
|
+ if (!mod[key].ref && !mod[key].refPath) continue;
|
|
|
+ const obj = { col: key, prop: mod[key].getProp, type: mod[key].type.name };
|
|
|
+ refMods.push(obj);
|
|
|
+ }
|
|
|
+ return { refMods, populate };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 格式化model路径
|
|
|
+ formatModelPath(str) {
|
|
|
+ let arr = str.split('.');
|
|
|
+ arr = arr.map(i => _.upperFirst(i));
|
|
|
+ const modelPath = arr.join('.');
|
|
|
+ return modelPath;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取model的模式
|
|
|
+ getSchema(path) {
|
|
|
+ const model = this.getModel(path);
|
|
|
+ return _.get(model, 'prototype.schema.obj');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取model实例
|
|
|
+ getModel(path) {
|
|
|
+ if (!path) return this.model;
|
|
|
+ let model = _.get(this.ctx.model, path);
|
|
|
+ const clients = this.app.mongooseDB.clients;
|
|
|
+ if (clients && !model) {
|
|
|
+ model = _.get(this.ctx.model, `${this.app.config.defaultModule}.${path}`);
|
|
|
+ }
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+ // 针对每个表进行检查
|
|
|
+ resetPopulate(schema) {
|
|
|
+ const arr = [];
|
|
|
+ for (const key in schema) {
|
|
|
+ const e = schema[key];
|
|
|
+ const { ref } = e;
|
|
|
+ if (!ref) continue;
|
|
|
+ const obj = { path: key };
|
|
|
+ const modelPath = this.formatModelPath(ref);
|
|
|
+ const model = this.getModel(modelPath);
|
|
|
+ obj.model = model;
|
|
|
+ const msch = this.getSchema(modelPath);
|
|
|
+ const popu = this.resetPopulate(msch);
|
|
|
+ if (popu.length > 0) obj.populate = popu;
|
|
|
+ arr.push(obj);
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 聚合式查询
|
|
@@ -332,5 +351,4 @@ class CrudService extends NafService {
|
|
|
// }
|
|
|
// let rs = await this.model.aggregate(pipeline);
|
|
|
|
|
|
-
|
|
|
module.exports.CrudService = CrudService;
|