query.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. 'use strict';
  2. const _ = require('lodash');
  3. const Service = require('egg').Service;
  4. const columns = require('../public/query');
  5. const { BusinessError, ErrorCode } = require('naf-core').Error;
  6. // 通用列表/多查/全查 查询实现
  7. class QueryService extends Service {
  8. constructor(ctx) {
  9. super(ctx, 'query');
  10. this.http = this.ctx.service.util.httpUtil;
  11. this.spMark = this.ctx.service.special;
  12. this.prefix = '/db';
  13. // 默认查询条件
  14. this.defaultType = 'like';
  15. // 强制全等 key 列表
  16. this.eqList = [ 'status' ];
  17. }
  18. /**
  19. * 常规查询
  20. * @param {Object} param0 表名
  21. * @param {Object} param1 正常query的参数,保函skip(指的是page),limit
  22. */
  23. async index({ table }, { skip = 1, limit, ...query } = {}) {
  24. query = this.dealQuery(table, query);
  25. const data = await this.http.$post(`${this.prefix}/query`, query, { table, page: skip, size: limit });
  26. if (data && data.code) {
  27. throw new BusinessError(ErrorCode.SERVICE_FAULT, data.message);
  28. }
  29. const { list, total } = data;
  30. // 在dbToData中找是否有该表需要特殊处理的字段
  31. const resetList = this.spMark.resetDataToFront(list, table);
  32. return { data: resetList || [], total };
  33. }
  34. /**
  35. * 处理参数,给java部分
  36. * 最后形成数组,数组每个元素都是条件,包括查询与排序
  37. * [
  38. * {key:xxx,value:xxx,type:xxx}
  39. * ]
  40. * @param {String} table 表名
  41. * @param {Object} query 参数
  42. */
  43. dealQuery(table, query) {
  44. const arr = _.get(columns, table, []);
  45. let order = [];
  46. let aboutQuery = [];
  47. if (arr.length > 0) {
  48. // orderBy分离开,因为与查询条件没关系,与最后数据的过滤有关
  49. order = arr.filter(f => f.type === 'orderBy');
  50. // 取arr,order,between的差集就是正常处理的内容
  51. aboutQuery = _.differenceWith(arr, [ ...order ]);
  52. }
  53. const nq = [];
  54. for (const key in query) {
  55. let obj = { key, value: query[key], type: this.defaultType };
  56. const r = aboutQuery.find(f => f.key === key);
  57. if (r) obj.type = _.get(r, 'type', this.defaultType);
  58. // 特殊处理:如果该key在eqList中,无论什么匹配类型,都改成eq
  59. if (this.eqList.includes(key)) obj.type = 'eq';
  60. // 处理key中是否带有@:范围查询的标志,需要把@后面的start/end砍掉
  61. obj = this.spMark.dealMarkQuery(_.cloneDeep(obj));
  62. if (!obj.key) continue;
  63. if (obj.value === 'null') {
  64. // 特殊处理,如果value为null字符串,需要数据库端进行特殊处理,在这里把类型转换成null类型
  65. obj.type = 'null';
  66. } else if (_.isArray(obj.value)) {
  67. // 检查值,如果为数组,则需要将type变成in
  68. obj.value = obj.value.join(',');
  69. obj.type = 'in';
  70. }
  71. nq.push(obj);
  72. }
  73. // 处理orderBy
  74. for (const i of order) {
  75. const { key, value } = i;
  76. nq.push({ key, value, type: 'orderBy' });
  77. }
  78. return nq;
  79. }
  80. }
  81. module.exports = QueryService;