lrf 1 ano atrás
commit
de3bc7ca1b
100 arquivos alterados com 3274 adições e 0 exclusões
  1. 29 0
      .autod.conf.js
  2. 1 0
      .eslintignore
  3. 3 0
      .eslintrc
  4. 46 0
      .github/workflows/nodejs.yml
  5. 14 0
      .gitignore
  6. 12 0
      .travis.yml
  7. 11 0
      README.md
  8. 35 0
      app.js
  9. 37 0
      app/controller/.admin.js
  10. 40 0
      app/controller/.building.js
  11. 23 0
      app/controller/.config.js
  12. 43 0
      app/controller/.department.js
  13. 42 0
      app/controller/.doctor.js
  14. 45 0
      app/controller/.fence.js
  15. 39 0
      app/controller/.grid.js
  16. 49 0
      app/controller/.guardian.js
  17. 45 0
      app/controller/.hospital.js
  18. 8 0
      app/controller/.import.js
  19. 40 0
      app/controller/.judge.js
  20. 42 0
      app/controller/.law.js
  21. 39 0
      app/controller/.level.js
  22. 39 0
      app/controller/.menu.js
  23. 43 0
      app/controller/.message.js
  24. 42 0
      app/controller/.police.js
  25. 45 0
      app/controller/.position.js
  26. 41 0
      app/controller/.range.js
  27. 39 0
      app/controller/.role.js
  28. 45 0
      app/controller/.sendcase.js
  29. 40 0
      app/controller/.sheriff.js
  30. 7 0
      app/controller/.statistics.js
  31. 40 0
      app/controller/.unit.js
  32. 37 0
      app/controller/.user.js
  33. 111 0
      app/controller/.ward.js
  34. 45 0
      app/controller/.warning.js
  35. 13 0
      app/controller/admin.js
  36. 13 0
      app/controller/building.js
  37. 13 0
      app/controller/config.js
  38. 13 0
      app/controller/department.js
  39. 42 0
      app/controller/doctor.js
  40. 13 0
      app/controller/fence.js
  41. 41 0
      app/controller/grid.js
  42. 44 0
      app/controller/guardian.js
  43. 113 0
      app/controller/home.js
  44. 49 0
      app/controller/hospital.js
  45. 13 0
      app/controller/import.js
  46. 13 0
      app/controller/judge.js
  47. 48 0
      app/controller/law.js
  48. 13 0
      app/controller/level.js
  49. 13 0
      app/controller/menu.js
  50. 13 0
      app/controller/message.js
  51. 50 0
      app/controller/police.js
  52. 26 0
      app/controller/position.js
  53. 13 0
      app/controller/range.js
  54. 13 0
      app/controller/role.js
  55. 13 0
      app/controller/sendcase.js
  56. 51 0
      app/controller/sheriff.js
  57. 42 0
      app/controller/statistics.js
  58. 13 0
      app/controller/unit.js
  59. 13 0
      app/controller/user.js
  60. 42 0
      app/controller/ward.js
  61. 13 0
      app/controller/warning.js
  62. 44 0
      app/middleware/belong-range.js
  63. 15 0
      app/middleware/equipment.js
  64. 42 0
      app/middleware/fence.js
  65. 9 0
      app/middleware/pip.js
  66. 53 0
      app/middleware/request-log.js
  67. 38 0
      app/middleware/warning.js
  68. 20 0
      app/model/admin.js
  69. 26 0
      app/model/building.js
  70. 18 0
      app/model/cardAdmin.js
  71. 22 0
      app/model/cardCache.js
  72. 18 0
      app/model/config.js
  73. 28 0
      app/model/department.js
  74. 26 0
      app/model/doctor.js
  75. 32 0
      app/model/fence.js
  76. 22 0
      app/model/grid.js
  77. 39 0
      app/model/guardian.js
  78. 38 0
      app/model/hospital.js
  79. 22 0
      app/model/judge.js
  80. 33 0
      app/model/law.js
  81. 22 0
      app/model/level.js
  82. 20 0
      app/model/menu.js
  83. 27 0
      app/model/message.js
  84. 31 0
      app/model/police.js
  85. 28 0
      app/model/position.js
  86. 26 0
      app/model/range.js
  87. 22 0
      app/model/role.js
  88. 32 0
      app/model/sendcase.js
  89. 24 0
      app/model/sheriff.js
  90. 24 0
      app/model/unit.js
  91. 63 0
      app/model/ward.js
  92. 24 0
      app/model/warning.js
  93. 50 0
      app/public/importSetting.js
  94. 55 0
      app/router.js
  95. 10 0
      app/schedule/cardPosition.js
  96. 15 0
      app/service/admin.js
  97. 15 0
      app/service/building.js
  98. 243 0
      app/service/card.js
  99. 25 0
      app/service/config.js
  100. 0 0
      app/service/department.js

+ 29 - 0
.autod.conf.js

@@ -0,0 +1,29 @@
+'use strict';
+
+module.exports = {
+  write: true,
+  prefix: '^',
+  plugin: 'autod-egg',
+  test: [
+    'test',
+    'benchmark',
+  ],
+  dep: [
+    'egg',
+    'egg-scripts',
+  ],
+  devdep: [
+    'egg-ci',
+    'egg-bin',
+    'egg-mock',
+    'autod',
+    'autod-egg',
+    'eslint',
+    'eslint-config-egg',
+  ],
+  exclude: [
+    './test/fixtures',
+    './dist',
+  ],
+};
+

+ 1 - 0
.eslintignore

@@ -0,0 +1 @@
+coverage

+ 3 - 0
.eslintrc

@@ -0,0 +1,3 @@
+{
+  "extends": "eslint-config-egg"
+}

+ 46 - 0
.github/workflows/nodejs.yml

@@ -0,0 +1,46 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Node.js CI
+
+on:
+  push:
+    branches:
+      - main
+      - master
+  pull_request:
+    branches:
+      - main
+      - master
+  schedule:
+    - cron: '0 2 * * *'
+
+jobs:
+  build:
+    runs-on: ${{ matrix.os }}
+
+    strategy:
+      fail-fast: false
+      matrix:
+        node-version: [10]
+        os: [ubuntu-latest, windows-latest, macos-latest]
+
+    steps:
+    - name: Checkout Git Source
+      uses: actions/checkout@v2
+
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+
+    - name: Install Dependencies
+      run: npm i -g npminstall && npminstall
+
+    - name: Continuous Integration
+      run: npm run ci
+
+    - name: Code Coverage
+      uses: codecov/codecov-action@v1
+      with:
+        token: ${{ secrets.CODECOV_TOKEN }}

+ 14 - 0
.gitignore

@@ -0,0 +1,14 @@
+logs/
+npm-debug.log
+yarn-error.log
+node_modules/
+package-lock.json
+yarn.lock
+coverage/
+.idea/
+run/
+.DS_Store
+*.sw*
+*.un~
+typings/
+.nyc_output/

+ 12 - 0
.travis.yml

@@ -0,0 +1,12 @@
+
+language: node_js
+node_js:
+  - '10'
+before_install:
+  - npm i npminstall -g
+install:
+  - npminstall
+script:
+  - npm run ci
+after_script:
+  - npminstall codecov && codecov

+ 11 - 0
README.md

@@ -0,0 +1,11 @@
+# 特殊接口说明:
+
+1.监护人注册接口:
+  因为需要将监护人和被监护人信息分开录入;并同时进行状态审核:即审核过监护人与被监护人信息,才允许这两个数据被使用
+2.多登录:,绑定微信小程序
+
+3.TODO 转移结束时: 
+  若是从一个地点转移到另一个地点,则需要修改其现住址
+  若是从一个地点转移到医院,则需要修改其 现住址 和 所属医院
+  若是从医院转移到一个地点,则需要修改其 现住址 和 所属医院
+  若是从医院转移到医院,则需要修改其 所属医院 

+ 35 - 0
app.js

@@ -0,0 +1,35 @@
+'use strict';
+class AppBootHook {
+  constructor(app) {
+    this.app = app;
+  }
+
+  async willReady() {
+    const data = await this.app.model.Admin.findOne();
+    if (!data) {
+      // 没有管理员,初始化一个
+      const data = {
+        account: 'admin',
+        password: { secret: '123456' },
+      };
+      await this.app.model.Admin.create(data);
+    }
+    // 初始化系统设置
+    const config = await this.app.model.Config.findOne();
+    if (!config) {
+      // 没有系统设置,初始化一个
+      const data = { config: {} };
+      await this.app.model.Config.create(data);
+    }
+  }
+
+  async serverDidReady() {
+    // 应用已经启动完毕
+    const ctx = await this.app.createAnonymousContext();
+    await ctx.service.card.login();
+    // // 检查种子
+    // // await ctx.service.install.index();
+    // await ctx.service.util.rabbitMq.mission();
+  }
+}
+module.exports = AppBootHook;

+ 37 - 0
app/controller/.admin.js

@@ -0,0 +1,37 @@
+module.exports = {
+  create: {
+    requestBody: ['name', 'account', 'password'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['name', 'account', 'password'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 40 - 0
app/controller/.building.js

@@ -0,0 +1,40 @@
+module.exports = {
+    create: {
+      requestBody: ['name', 'account', 'password','phone', 'parent'],
+    },
+    destroy: {
+      params: ['!id'],
+      service: 'delete',
+    },
+    update: {
+      params: ['!id'],
+      requestBody: ['name', 'account', 'password','phone', 'parent'],
+    },
+    show: {
+      parameters: {
+        params: ['!id'],
+      },
+      service: 'fetch',
+    },
+    index: {
+      parameters: {
+        query: {
+          'name':'name',
+          'account':'account',
+          'password':'password',
+          'phone':'phone',
+          'parent':'parent',
+          'meta.createdAt@start': 'meta.createdAt@start',
+          'meta.createdAt@end': 'meta.createdAt@end',
+        },
+      },
+      service: 'query',
+      options: {
+        query: ['skip', 'limit'],
+        sort: ['meta.createdAt'],
+        desc: true,
+        count: true,
+      },
+    },
+  };
+  

+ 23 - 0
app/controller/.config.js

@@ -0,0 +1,23 @@
+module.exports = {
+  update: {
+    requestBody: ['config'],
+  },
+  index: {
+    parameters: {
+      query: {
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 43 - 0
app/controller/.department.js

@@ -0,0 +1,43 @@
+module.exports = {
+  create: {
+    requestBody: ['type', 'city_id', 'branch_id', 'num', 'name', 'brief'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['type', 'city_id', 'branch_id', 'num', 'name', 'brief'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        type: 'type',
+        city_id: 'city_id',
+        branch_id: 'branch_id',
+        num: 'num',
+        name: 'name',
+        brief: 'brief',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 42 - 0
app/controller/.doctor.js

@@ -0,0 +1,42 @@
+module.exports = {
+  create: {
+    requestBody: ['h_id', 'name', 'account', 'password', 'phone', 'belong'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['h_id', 'name', 'account', 'password', 'phone', 'belong'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        h_id: 'h_id',
+        name: 'name',
+        account: 'account',
+        phone: 'phone',
+        belong: 'belong',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 45 - 0
app/controller/.fence.js

@@ -0,0 +1,45 @@
+module.exports = {
+  create: {
+    requestBody: ['!belong', '!g_id', '!w_id', 'before_info', 'after_info', 'start_time', 'end_time', 'routes', 'process', 'rule'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['belong', 'g_id', 'w_id', 'before_info', 'after_info', 'start_time', 'end_time', 'routes', 'process', 'status', 'rule'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        belong: 'belong',
+        g_id: 'g_id',
+        w_id: 'w_id',
+        status: 'status',
+        rule: 'rule',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+  inputRoute: {
+    requestBody: ['!id', '!position'],
+  },
+};

+ 39 - 0
app/controller/.grid.js

@@ -0,0 +1,39 @@
+module.exports = {
+    create: {
+      requestBody: ['name', 'account', 'password','phone'],
+    },
+    destroy: {
+      params: ['!id'],
+      service: 'delete',
+    },
+    update: {
+      params: ['!id'],
+      requestBody: ['name', 'account', 'password','phone'],
+    },
+    show: {
+      parameters: {
+        params: ['!id'],
+      },
+      service: 'fetch',
+    },
+    index: {
+      parameters: {
+        query: {
+          'name':'name',
+          'account':'account',
+          'password':'password',
+          'phone':'phone',
+          'meta.createdAt@start': 'meta.createdAt@start',
+          'meta.createdAt@end': 'meta.createdAt@end',
+        },
+      },
+      service: 'query',
+      options: {
+        query: ['skip', 'limit'],
+        sort: ['meta.createdAt'],
+        desc: true,
+        count: true,
+      },
+    },
+  };
+  

+ 49 - 0
app/controller/.guardian.js

@@ -0,0 +1,49 @@
+module.exports = {
+  create: {
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'card', 'belong', 'app_openid', 'unionid', 'openid', 'status', 'card_id'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'card', 'belong', 'app_openid', 'unionid', 'openid', 'status', 'card_id'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        accnameount: 'account',
+        name: 'name',
+        phone: 'phone',
+        unit: 'unit',
+        belong: 'belong',
+        card: 'card',
+        status: 'status',
+        card_id: 'card_id',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+  check: {
+    params: ['!id'],
+    requestBody: ['!status'],
+  },
+};

+ 45 - 0
app/controller/.hospital.js

@@ -0,0 +1,45 @@
+module.exports = {
+  create: {
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'fence', 'role', 'belong', 'nature', 'place', 'bed_num'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'fence', 'role', 'belong', 'nature', 'place', 'bed_num'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        account: 'account',
+        name: 'name',
+        phone: 'phone',
+        unit: 'unit',
+        role: 'role',
+        belong: 'belong',
+        nature: 'nature',
+        place: 'place',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 8 - 0
app/controller/.import.js

@@ -0,0 +1,8 @@
+module.exports = {
+  importWard: {
+    requestBody: ['!uri'],
+  },
+  importFillWardInfo: {
+    requestBody: ['!uri'],
+  },
+};

+ 40 - 0
app/controller/.judge.js

@@ -0,0 +1,40 @@
+module.exports = {
+    create: {
+      requestBody: ['w_id', 'w_name', 'send_time', 'trajectory', 'content'],
+    },
+    destroy: {
+      params: ['!id'],
+      service: 'delete',
+    },
+    update: {
+      params: ['!id'],
+      requestBody:['w_id', 'w_name', 'send_time', 'trajectory', 'content'],
+    },
+    show: {
+      parameters: {
+        params: ['!id'],
+      },
+      service: 'fetch',
+    },
+    index: {
+      parameters: {
+        query: {
+           w_name: 'w_name',
+           send_time: 'send_time',
+          'meta.createdAt@start': 'meta.createdAt@start',
+          'meta.createdAt@end': 'meta.createdAt@end',
+        },
+        // options: {
+        //   "meta.state": 0 // 默认条件
+        // },
+      },
+      service: 'query',
+      options: {
+        query: ['skip', 'limit'],
+        sort: ['meta.createdAt'],
+        desc: true,
+        count: true,
+      },
+    },
+  };
+  

+ 42 - 0
app/controller/.law.js

@@ -0,0 +1,42 @@
+module.exports = {
+  create: {
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'role'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'role'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        account: 'account',
+        name: 'name',
+        phone: 'phone',
+        unit: 'unit',
+        role: 'role',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 39 - 0
app/controller/.level.js

@@ -0,0 +1,39 @@
+module.exports = {
+  create: {
+    requestBody: ['label', 'code', 'color'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['label', 'code', 'color'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        label: 'label',
+        code: 'code',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 39 - 0
app/controller/.menu.js

@@ -0,0 +1,39 @@
+module.exports = {
+  create: {
+    requestBody: ['title', 'index', 'icon'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['title', 'index', 'icon'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        title: 'title',
+        index: 'index',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 43 - 0
app/controller/.message.js

@@ -0,0 +1,43 @@
+module.exports = {
+  create: {
+    requestBody: ['title', 'content', 'user_id', 'status', 'time', 'receipt'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['title', 'content', 'user_id', 'status', 'time', 'receipt'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        title: 'title',
+        content: 'content',
+        user_id: 'user_id',
+        status: 'status',
+        time: 'time',
+        receipt: 'receipt',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 42 - 0
app/controller/.police.js

@@ -0,0 +1,42 @@
+module.exports = {
+  create: {
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'belong', 'role'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['account', 'password', 'name', 'phone', 'unit', 'address', 'email', 'belong', 'role'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        account: 'account',
+        name: 'name',
+        phone: 'phone',
+        unit: 'unit',
+        role: 'role',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 45 - 0
app/controller/.position.js

@@ -0,0 +1,45 @@
+module.exports = {
+  create: {
+    requestBody: ['user_id', 'longitude', 'latitude', 'name', 'card', 'type', 'info'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['user_id', 'longitude', 'latitude', 'name', 'card', 'type', 'info'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        user_id: 'user_id',
+        name: 'name',
+        card: 'card',
+        type: 'type',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+  wardInfo: {
+    params: ['!id'],
+    service: 'mapWardInfo',
+  },
+};

+ 41 - 0
app/controller/.range.js

@@ -0,0 +1,41 @@
+module.exports = {
+  create: {
+    requestBody: ['name', 'range', 'level', 'status', 'rule', 'category'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['name', 'range', 'level', 'status', 'rule', 'category'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        name: 'name',
+        level: 'level',
+        status: 'status',
+        rule: 'rule',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 39 - 0
app/controller/.role.js

@@ -0,0 +1,39 @@
+module.exports = {
+  create: {
+    requestBody: ['name', 'brief', 'menu', 'type'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['name', 'brief', 'menu', 'type'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        name: 'name',
+        type: 'type',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 45 - 0
app/controller/.sendcase.js

@@ -0,0 +1,45 @@
+module.exports = {
+  create: {
+    requestBody: ['w_id', 'w_name', 'level', 'place', 'send_time', 'status', 'handle_name', 'handle_phone', 'handle_time', 'content', 'reason'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['w_id', 'w_name', 'level', 'place', 'send_time', 'status', 'handle_name', 'handle_phone', 'handle_time', 'content', 'reason'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        w_name: 'w_name',
+        level: 'level',
+        phone: 'phone',
+        handle_name: 'handle_name',
+        send_time: 'send_time',
+        status: 'status',
+        w_name: 'w_name',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};
+  

+ 40 - 0
app/controller/.sheriff.js

@@ -0,0 +1,40 @@
+module.exports = {
+    create: {
+      requestBody: ['name', 'account', 'password','phone', 'belong'],
+    },
+    destroy: {
+      params: ['!id'],
+      service: 'delete',
+    },
+    update: {
+      params: ['!id'],
+      requestBody: ['name', 'account', 'password','phone', 'belong'],
+    },
+    show: {
+      parameters: {
+        params: ['!id'],
+      },
+      service: 'fetch',
+    },
+    index: {
+      parameters: {
+        query: {
+          'name':'name',
+          'account':'account',
+          'password':'password',
+          'phone':'phone',
+          'belong':'belong',
+          'meta.createdAt@start': 'meta.createdAt@start',
+          'meta.createdAt@end': 'meta.createdAt@end',
+        },
+      },
+      service: 'query',
+      options: {
+        query: ['skip', 'limit'],
+        sort: ['meta.createdAt'],
+        desc: true,
+        count: true,
+      },
+    },
+  };
+  

+ 7 - 0
app/controller/.statistics.js

@@ -0,0 +1,7 @@
+module.exports = {
+  index: {
+    parameters: {
+      query: {},
+    },
+  },
+};

+ 40 - 0
app/controller/.unit.js

@@ -0,0 +1,40 @@
+module.exports = {
+    create: {
+      requestBody: ['name', 'account', 'password','phone', 'parent'],
+    },
+    destroy: {
+      params: ['!id'],
+      service: 'delete',
+    },
+    update: {
+      params: ['!id'],
+      requestBody: ['name', 'account', 'password','phone', 'parent'],
+    },
+    show: {
+      parameters: {
+        params: ['!id'],
+      },
+      service: 'fetch',
+    },
+    index: {
+      parameters: {
+        query: {
+          'name':'name',
+          'account':'account',
+          'password':'password',
+          'phone':'phone',
+          'parent':'parent',
+          'meta.createdAt@start': 'meta.createdAt@start',
+          'meta.createdAt@end': 'meta.createdAt@end',
+        },
+      },
+      service: 'query',
+      options: {
+        query: ['skip', 'limit'],
+        sort: ['meta.createdAt'],
+        desc: true,
+        count: true,
+      },
+    },
+  };
+  

+ 37 - 0
app/controller/.user.js

@@ -0,0 +1,37 @@
+module.exports = {
+  create: {
+    requestBody: ['account', 'password', 'uid'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['account', 'password', 'uid'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 111 - 0
app/controller/.ward.js

@@ -0,0 +1,111 @@
+module.exports = {
+  create: {
+    requestBody: [
+      'place',
+      'name',
+      'gender',
+      'card',
+      'case',
+      'important_phone',
+      'important_wx',
+      'important_company',
+      'hj_address',
+      'address',
+      'g_id',
+      'g_name',
+      'g_phone',
+      'belong',
+      'police',
+      'police_phone',
+      'family_cars',
+      'family',
+      'sociology',
+      'level',
+      'h_id',
+      'fence',
+      'icon',
+      'year',
+      'card_id',
+      'use_medicine',
+      'healthy',
+      'status',
+      'password',
+    ],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: [
+      'place',
+      'name',
+      'gender',
+      'card',
+      'case',
+      'important_phone',
+      'important_wx',
+      'important_company',
+      'hj_address',
+      'address',
+      'g_id',
+      'g_name',
+      'g_phone',
+      'belong',
+      'police',
+      'police_phone',
+      'family_cars',
+      'family',
+      'sociology',
+      'level',
+      'h_id',
+      'fence',
+      'icon',
+      'year',
+      'card_id',
+      'use_medicine',
+      'healthy',
+      'status',
+      'password',
+    ],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        g_id: 'g_id',
+        name: '%name%',
+        card: '%card%',
+        phone: 'phone',
+        important_phone: 'important_phone',
+        g_name: 'g_name',
+        g_phone: 'g_phone',
+        police_phone: 'police_phone',
+        h_id: 'h_id',
+        status: 'status',
+        police: 'police',
+        belong: 'belong',
+        year: 'year',
+        card_id: 'card_id',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+};

+ 45 - 0
app/controller/.warning.js

@@ -0,0 +1,45 @@
+module.exports = {
+  create: {
+    requestBody: ['w_id', 'g_id', 'belong', 'status'],
+  },
+  destroy: {
+    params: ['!id'],
+    service: 'delete',
+  },
+  update: {
+    params: ['!id'],
+    requestBody: ['w_id', 'g_id', 'belong', 'status'],
+  },
+  show: {
+    parameters: {
+      params: ['!id'],
+    },
+    service: 'fetch',
+  },
+  index: {
+    parameters: {
+      query: {
+        w_id: 'w_id',
+        g_id: 'g_id',
+        belong: 'belong',
+        status: 'status',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+      },
+      // options: {
+      //   "meta.state": 0 // 默认条件
+      // },
+    },
+    service: 'query',
+    options: {
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
+      desc: true,
+      count: true,
+    },
+  },
+
+  pip:{
+    
+  }
+};

+ 13 - 0
app/controller/admin.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.admin.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 
+class AdminController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.admin;
+  }
+}
+module.exports = CrudController(AdminController, meta);

+ 13 - 0
app/controller/building.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.building.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 角色
+class BuildingController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.building;
+  }
+}
+module.exports = CrudController(BuildingController, meta);

+ 13 - 0
app/controller/config.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.config.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 设置表
+class ConfigController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.config;
+  }
+}
+module.exports = CrudController(ConfigController, meta);

+ 13 - 0
app/controller/department.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.department.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 部门表
+class DepartmentController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.department;
+  }
+}
+module.exports = CrudController(DepartmentController, meta);

+ 42 - 0
app/controller/doctor.js

@@ -0,0 +1,42 @@
+'use strict';
+const meta = require('./.doctor.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+// 随访医生
+class DoctorController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.doctor;
+  }
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let acc = await this.ctx.model.Doctor.findOne({ account }, '+password').exec();
+    if (!acc) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (acc.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    acc = JSON.parse(JSON.stringify(acc));
+    delete acc.password;
+    delete acc.meta;
+    delete acc.__v;
+    acc.type = 'doctor';
+    const token = this.ctx.service.util.jwt.encrypt(acc);
+    this.ctx.ok({ data: token });
+  }
+  async updatePassword() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const acc = await this.ctx.model.Doctor.findOne({ account }, '+password').exec();
+    if (oldPassword !== acc.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      acc.password = { secret: newPassword1 };
+      await acc.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+}
+module.exports = CrudController(DoctorController, meta);

+ 13 - 0
app/controller/fence.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.fence.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 围栏变更
+class FenceController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.fence;
+  }
+}
+module.exports = CrudController(FenceController, meta);

+ 41 - 0
app/controller/grid.js

@@ -0,0 +1,41 @@
+'use strict';
+const meta = require('./.grid.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+// 网格长
+class GridController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.grid;
+  }
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let acc = await this.ctx.model.Grid.findOne({ account }, '+password').exec();
+    if (!acc) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (acc.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    acc = JSON.parse(JSON.stringify(acc));
+    delete acc.password;
+    delete acc.meta;
+    delete acc.__v;
+    acc.type = 'grid';
+    const token = this.ctx.service.util.jwt.encrypt(acc);
+    this.ctx.ok({ data: token });
+  }
+  async updatePassword() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const acc = await this.ctx.model.Grid.findOne({ account }, '+password').exec();
+    if (oldPassword !== acc.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      acc.password = { secret: newPassword1 };
+      await acc.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+}
+module.exports = CrudController(GridController, meta);

+ 44 - 0
app/controller/guardian.js

@@ -0,0 +1,44 @@
+'use strict';
+const meta = require('./.guardian.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+// 监护人
+class GuardianController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.guardian;
+  }
+  /**
+   * 重写创建方法,因为该创建方法需要将监护人与被监护人的数据区分开
+   */
+  async createAll() {
+    const body = this.ctx.request.body;
+    const data = await this.service.createAll(body);
+    this.ctx.ok({ data });
+  }
+
+  /**
+ * 登陆
+ */
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let guardian = await this.ctx.model.Guardian.findOne({ account }, '+password').exec();
+    if (!guardian) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (guardian.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    guardian = JSON.parse(JSON.stringify(guardian));
+    delete guardian.password;
+    delete guardian.meta;
+    delete guardian.__v;
+
+    guardian.type = 'guardian';
+    const token = this.ctx.service.util.jwt.encrypt(guardian);
+    this.ctx.ok({ token, id: guardian.id });
+  }
+
+}
+module.exports = CrudController(GuardianController, meta);

+ 113 - 0
app/controller/home.js

@@ -0,0 +1,113 @@
+'use strict';
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const fs = require('fs');
+const { sep } = require('path');
+const _ = require('lodash');
+const { ObjectId } = require('mongoose').Types;
+// 项目测试及管理员登陆
+class HomeController extends Controller {
+  async index() {
+    const { ctx } = this;
+    ctx.body = 'hi, egg';
+  }
+  /**
+   * 系统管理员登陆
+   * 太简单了,就不写service了,直接在这处理完完事了
+   */
+  async login() {
+    let admin = await this.ctx.model.Admin.findOne({}, '+password').exec();
+    if (!admin) throw new BusinessError(ErrorCode.FILE_FAULT, '未初始化管理员,拒绝请求!');
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    if (admin.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (admin.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    admin = JSON.parse(JSON.stringify(admin));
+    delete admin.password;
+    delete admin.meta;
+    delete admin.__v;
+    admin.type = 'admin';
+    const token = this.ctx.service.util.jwt.encrypt(admin);
+    this.ctx.ok({ data: token });
+  }
+
+  /**
+   * 系统管理员修改密码
+   */
+  async adminUpdate() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const admin = await this.ctx.model.Admin.findOne({ account }, '+password').exec();
+    if (oldPassword !== admin.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      admin.password = { secret: newPassword1 };
+      await admin.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+
+  async util() {
+    const dirName = 'sps/icon';
+    // const dirPath = `d:${sep}temp${sep}${dirName}`;
+    const dirPath = `/usr/workspace/server/service-file/upload/${dirName}`;
+    const dirs = fs.readdirSync(dirPath);
+    const errorList = [];
+    for (const dir of dirs) {
+      const mpath = `${dirPath}${sep}${dir}`;
+      const r = fs.lstatSync(mpath);
+      if (r.isDirectory()) {
+        const errors = await this.dealPartsImage(mpath, dirName, dir);
+        errorList.push({ [dir]: errors });
+      }
+    }
+    this.ctx.ok({ data: errorList });
+  }
+
+  async dealPartsImage(dirPath, dirName, place) {
+    if (place !== '公主岭') return [];
+    // 短地址前缀,直接这个变量接上文件名即可组成完整的图片地址
+    const shortUri = `/files/${dirName}/${place}`;
+    // 该文件夹下的所有的图片
+    const dirs = fs.readdirSync(dirPath);
+    const errors = [];
+    for (const fileName of dirs) {
+      const mp = `${dirPath}${sep}${fileName}`;
+      const r = fs.lstatSync(mp);
+      // 不是文件就不处理
+      if (!r.isFile()) continue;
+      const fnarr = fileName.split('.');
+      const name = fnarr[0];
+      if (!name) continue;
+      const ward = await this.ctx.model.Ward.findOne({ name, place: new RegExp(place) });
+      if (ward) {
+        const icon = `${shortUri}/${fileName}`;
+        ward.icon = icon;
+        await ward.save();
+      } else {
+        errors.push(`文件:${fileName},未找到匹配患者`);
+      }
+    }
+    return errors;
+  }
+
+  // 清除患者数据的空格
+  async clearSpace() {
+    const list = await this.ctx.model.Ward.find();
+    const code = '\n';
+    for (const i of list) {
+      const { card } = i;
+      if (!card.includes(code)) continue;
+      i.card = i.card.replace(code, '');
+      await i.save();
+    }
+  }
+  async clearPositionData() {
+    // 清除定位数据,预警数据
+    const r1 = await this.ctx.model.Position.deleteMany({});
+    const r2 = await this.ctx.model.Sendcase.deleteMany({});
+  }
+}
+module.exports = CrudController(HomeController, {});

+ 49 - 0
app/controller/hospital.js

@@ -0,0 +1,49 @@
+'use strict';
+const meta = require('./.hospital.js');
+const Controller = require('egg').Controller;
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 医院账号
+class HospitalController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.hospital;
+  }
+  /**
+ * 医院账号登陆
+ */
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let hospital = await this.ctx.model.Hospital.findOne({ account }, '+password').exec();
+    if (!hospital) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (hospital.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    hospital = JSON.parse(JSON.stringify(hospital));
+    delete hospital.password;
+    delete hospital.meta;
+    delete hospital.__v;
+    hospital.type = 'hospital';
+    const token = this.ctx.service.util.jwt.encrypt(hospital);
+    this.ctx.ok({ data: token });
+  }
+  /**
+   * 医院账号系统管理员修改密码
+   */
+  async hospitalUpdate() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const hospital = await this.ctx.model.Hospital.findOne({ account }, '+password').exec();
+    if (oldPassword !== hospital.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      hospital.password = { secret: newPassword1 };
+      await hospital.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+
+}
+module.exports = CrudController(HospitalController, meta);

+ 13 - 0
app/controller/import.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.import.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 导入
+class ImportController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.import;
+  }
+}
+module.exports = CrudController(ImportController, meta);

+ 13 - 0
app/controller/judge.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.judge.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 角色
+class JudgeController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.judge;
+  }
+}
+module.exports = CrudController(JudgeController, meta);

+ 48 - 0
app/controller/law.js

@@ -0,0 +1,48 @@
+'use strict';
+const meta = require('./.law.js');
+const Controller = require('egg').Controller;
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 政法委账号
+class LawController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.law;
+  }
+  /**
+ * 政法委账号登陆
+ */
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let law = await this.ctx.model.Law.findOne({ account }, '+password').exec();
+    if (!law) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (law.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    law = JSON.parse(JSON.stringify(law));
+    delete law.password;
+    delete law.meta;
+    delete law.__v;
+    law.type = 'law';
+    const token = this.ctx.service.util.jwt.encrypt(law);
+    this.ctx.ok({ data: token });
+  }
+  /**
+   * 政法委账号系统管理员修改密码
+   */
+  async lawUpdate() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const law = await this.ctx.model.Law.findOne({ account }, '+password').exec();
+    if (oldPassword !== law.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      law.password = { secret: newPassword1 };
+      await law.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+}
+module.exports = CrudController(LawController, meta);

+ 13 - 0
app/controller/level.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.level.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 预警等级
+class LevelController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.level;
+  }
+}
+module.exports = CrudController(LevelController, meta);

+ 13 - 0
app/controller/menu.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.menu.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 菜单
+class MenuController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.menu;
+  }
+}
+module.exports = CrudController(MenuController, meta);

+ 13 - 0
app/controller/message.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.message.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 消息
+class MessageController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.message;
+  }
+}
+module.exports = CrudController(MessageController, meta);

+ 50 - 0
app/controller/police.js

@@ -0,0 +1,50 @@
+'use strict';
+const meta = require('./.police.js');
+const Controller = require('egg').Controller;
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 公安账号
+class PoliceController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.police;
+  }
+  /**
+ * 公安账号登陆
+ */
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let police = await this.ctx.model.Police.findOne({ account }, '+password').exec();
+    if (!police) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (police.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    police = JSON.parse(JSON.stringify(police));
+    delete police.password;
+    delete police.meta;
+    delete police.__v;
+    police.type = 'police';
+    const token = this.ctx.service.util.jwt.encrypt(police);
+    this.ctx.ok({ data: token });
+  }
+
+  /**
+   * 公安账号系统管理员修改密码
+   */
+  async policeUpdate() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const police = await this.ctx.model.Police.findOne({ account }, '+password').exec();
+    if (oldPassword !== police.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      police.password = { secret: newPassword1 };
+      await police.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+}
+
+module.exports = CrudController(PoliceController, meta);

+ 26 - 0
app/controller/position.js

@@ -0,0 +1,26 @@
+'use strict';
+const meta = require('./.position.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 定位
+class PositionController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.position;
+  }
+
+  async login() {
+    await this.ctx.service.card.login();
+    this.ctx.ok();
+  }
+  async loop() {
+    await this.ctx.service.card.loop();
+    this.ctx.ok();
+  }
+  async map() {
+    const data = await this.service.map(this.ctx.query);
+    this.ctx.ok({ data });
+  }
+}
+module.exports = CrudController(PositionController, meta);

+ 13 - 0
app/controller/range.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.range.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 围栏范围
+class RangeController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.range;
+  }
+}
+module.exports = CrudController(RangeController, meta);

+ 13 - 0
app/controller/role.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.role.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 角色
+class RoleController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.role;
+  }
+}
+module.exports = CrudController(RoleController, meta);

+ 13 - 0
app/controller/sendcase.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.sendcase.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 角色
+class SendcaseController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.sendcase;
+  }
+}
+module.exports = CrudController(SendcaseController, meta);

+ 51 - 0
app/controller/sheriff.js

@@ -0,0 +1,51 @@
+'use strict';
+const meta = require('./.sheriff.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+// 警长
+class SheriffController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.sheriff;
+  }
+
+  /**
+     * 警长账号登陆
+     */
+  async login() {
+    const { account, password } = this.ctx.request.body;
+    if (!account) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户账号');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let sheriff = await this.ctx.model.Sheriff.findOne({ account }, '+password').exec();
+    if (!sheriff) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    if (sheriff.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    sheriff = JSON.parse(JSON.stringify(sheriff));
+    delete sheriff.password;
+    delete sheriff.meta;
+    delete sheriff.__v;
+    sheriff.type = 'sheriff';
+    const token = this.ctx.service.util.jwt.encrypt(sheriff);
+    this.ctx.ok({ data: token });
+  }
+
+  /**
+     * 警长账号修改密码
+     */
+  async sheriffUpdate() {
+    const { account, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const sheriff = await this.ctx.model.Sheriff.findOne({ account }, '+password').exec();
+    if (oldPassword !== sheriff.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      sheriff.password = { secret: newPassword1 };
+      await sheriff.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+
+
+}
+module.exports = CrudController(SheriffController, meta);

+ 42 - 0
app/controller/statistics.js

@@ -0,0 +1,42 @@
+'use strict';
+const meta = require('./.statistics.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 统计
+class StatisticsController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.statistics;
+  }
+  async left1() {
+    const d1 = await this.service.getWardNumber();
+    const d2 = await this.service.getHospitalNumber();
+    const d3 = await this.service.getWardInHospital();
+    this.ctx.ok({ data: { d1, d2, d3 } });
+  }
+  async right1() {
+    const d1 = await this.service.getYearsWardNumber();
+    this.ctx.ok({ data: d1 });
+  }
+  async right2() {
+    const d1 = await this.service.getYearsWardIllNumber();
+    this.ctx.ok({ data: d1 });
+  }
+  async centerLeft1() {
+    const d1 = await this.service.getWardPlaceNumber();
+    this.ctx.ok({ data: d1 });
+  }
+  async centerRight1() {
+    const d1 = await this.service.getWardLevelNumber();
+    this.ctx.ok({ data: d1 });
+  }
+  async centerCount() {
+    const d1 = await this.service.centerCount();
+    this.ctx.ok({ data: d1 });
+  }
+  // 下面3个目前没法做
+  async downLeft1() {}
+  async downleft2() {}
+}
+module.exports = CrudController(StatisticsController, meta);

+ 13 - 0
app/controller/unit.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.unit.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 单元长
+class UnitController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.unit;
+  }
+}
+module.exports = CrudController(UnitController, meta);

+ 13 - 0
app/controller/user.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.user.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 用户管理
+class UserController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.user;
+  }
+}
+module.exports = CrudController(UserController, meta);

+ 42 - 0
app/controller/ward.js

@@ -0,0 +1,42 @@
+'use strict';
+const meta = require('./.ward.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+
+// 被监护人
+class WardController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.ward;
+  }
+  async login() {
+    const { card, password } = this.ctx.request.body;
+    if (!card) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆的患者');
+    if (!password) throw new BusinessError(ErrorCode.BADPARAM, '未找到要登陆用户密码');
+    let acc = await this.ctx.model.Ward.findOne({ card }, '+password').exec();
+    if (!acc) throw new BusinessError(ErrorCode.FILE_FAULT, '未找到该账号!');
+    // if (police.account !== account) throw new BusinessError(ErrorCode.USER_NOT_EXIST, '未找到要登录的用户');
+    if (acc.password.secret !== password) throw new BusinessError(ErrorCode.BAD_PASSWORD, '密码错误');
+    acc = JSON.parse(JSON.stringify(acc));
+    delete acc.password;
+    delete acc.meta;
+    delete acc.__v;
+    acc.type = 'ward';
+    const token = this.ctx.service.util.jwt.encrypt(acc);
+    this.ctx.ok({ data: token });
+  }
+  async updatePassword() {
+    const { card, oldPassword, newPassword1, newPassword2 } = this.ctx.request.body;
+    const acc = await this.ctx.model.Ward.findOne({ card }, '+password').exec();
+    if (oldPassword !== acc.password.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD, '旧密码错误!');
+    if (newPassword1 === newPassword2) {
+      acc.password = { secret: newPassword1 };
+      await acc.save();
+    } else {
+      throw new BusinessError(ErrorCode.BAD_PASSWORD, '两个新密码不一致!');
+    }
+    this.ctx.ok();
+  }
+}
+module.exports = CrudController(WardController, meta);

+ 13 - 0
app/controller/warning.js

@@ -0,0 +1,13 @@
+'use strict';
+const meta = require('./.warning.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose-free/lib/controller');
+
+// 报警信息
+class WarningController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.warning;
+  }
+}
+module.exports = CrudController(WarningController, meta);

+ 44 - 0
app/middleware/belong-range.js

@@ -0,0 +1,44 @@
+'use strict';
+const _ = require('lodash');
+
+// 查询子级
+
+const getChildren = async (ctx, id) => {
+  const dept = await ctx.model.Department.findById(id, 'type');
+  if (!dept) return [ id ];
+  const { type } = dept;
+  // const res = [];
+  // if (type === '1') {
+  //   // 需要一直查到3级
+
+  // } else if (type === '2') {
+  //   // 需要查到3级
+  //   const list = await ctx.model.Department.find({ branch_id: id }, 'type');
+  // } else res.push(id);
+  const arr = [];
+  let res = await ctx.model.Department.find({ $or: [{ city_id: { $in: [ id ] } }, { branch_id: { $in: [ id ] } }] }, { _id: 1 });
+  if (res.length > 0) {
+    res = JSON.parse(JSON.stringify(res));
+    for (const d of res) {
+      const r = await getChildren(ctx, d._id);
+      if (r.length > 0) arr.push(...r);
+    }
+  }
+  arr.push(id);
+  return _.uniq(_.flattenDeep(arr));
+};
+
+module.exports = options => {
+  return async function belongRange(ctx, next) {
+    // 需要看警局的所属问题
+    const query = ctx.request.query;
+    const belong = _.get(query, 'belong');
+    if (belong) {
+      // TODO 有所属关系字段,所以要转换,嵌套查询
+      // city_id/branch_id进行查询
+      const list = await getChildren(ctx, belong);
+      query.belong = list;
+    }
+    await next();
+  };
+};

+ 15 - 0
app/middleware/equipment.js

@@ -0,0 +1,15 @@
+'use strict';
+const _ = require('lodash');
+module.exports = options => {
+  return async function equipment(ctx, next) {
+    // 针对设备码,因为前端封装axios会自动过滤掉null和undefined类型,导致会无法解除设备
+    // 所以在修改后,专门查询下card_id是否为字符串内容为:'null' 或 'undefined',再次删除
+    await next();
+    const data = _.get(ctx.response, 'body.data');
+    const { _id, card_id } = data;
+    if (card_id === 'null' || card_id === 'undefined') {
+      await ctx.model.Ward.updateOne({ _id }, { card_id: undefined });
+      delete ctx.response.body.data.card_id;
+    }
+  };
+};

+ 42 - 0
app/middleware/fence.js

@@ -0,0 +1,42 @@
+'use strict';
+const _ = require('lodash');
+const { ObjectId } = require('mongoose').Types;
+
+
+const getInfo = async (ctx, data) => {
+  if (data) data = JSON.parse(JSON.stringify(data));
+  // 用3个id对应去3个表查数据,并返回
+  const belong_data = await ctx.model.Department.findOne({ _id: ObjectId(data.belong) });
+  if (belong_data) data.belong_data = belong_data;
+  const g_data = await ctx.model.Guardian.findOne({ _id: ObjectId(data.g_id) });
+  if (g_data) data.g_data = g_data;
+  const w_data = await ctx.model.Ward.findOne({ _id: ObjectId(data.w_id) });
+  if (w_data) data.w_data = w_data;
+  return data;
+};
+
+
+/**
+ * 处理fence接口的belong,g_id,w_id 获取其对应的数据
+ * @param {Object} options 中间件参数
+ */
+module.exports = options => {
+  return async function fence(ctx, next) {
+    await next();
+    let data = _.get(ctx.response, 'body.data');
+    if (data) data = JSON.parse(JSON.stringify(data));
+    if (_.isArray(data)) {
+      // 循环object处理
+      const arr = [];
+      for (const d of data) {
+        const newData = await getInfo(ctx, d);
+        arr.push(newData);
+      }
+      ctx.response.body.data = arr;
+    } else if (_.isObject(data)) {
+      // object处理
+      const newData = await getInfo(ctx, data);
+      ctx.response.body.data = newData;
+    }
+  };
+};

+ 9 - 0
app/middleware/pip.js

@@ -0,0 +1,9 @@
+'use strict';
+const _ = require('lodash');
+module.exports = options => {
+  return async function pip(ctx, next) {
+    await next();
+    const data = _.get(ctx.response, 'body.data');
+    ctx.service.warning.checkPoint(data);
+  };
+};

+ 53 - 0
app/middleware/request-log.js

@@ -0,0 +1,53 @@
+'use strict';
+module.exports = ({ toMongoDB = false, enable = false }) =>
+  async function requestLog(ctx, next) {
+    await next();
+    if(enable) {
+      try {
+        const request = ctx.request;
+        // 请求路由
+        const url = request.url;
+        // 请求方法
+        const method = request.method;
+        // get 请求不发日志
+        if (method === 'GET') return;
+        // 请求的分站标识
+        const tenant = ctx.tenant || 'master';
+        // 请求的用户
+        const user = ctx.user;
+        // 当前模块
+        const module = ctx.app.config.module;
+        // 所有的请求路由
+        const routers = ctx.router.stack;
+        // 匹配路由及http请求方法
+        const route = routers.find((route) => {
+          const reg = new RegExp(route.regexp);
+          // 正则验证
+          const regResult = reg.test(url);
+          // http方法验证
+          const methodResult = route.methods.includes(method);
+          if (regResult && methodResult) return true;
+          return false;
+        });
+        if (!route) return;
+        // 不往数据库里写,就回去
+        if (!toMongoDB) return;
+        // 组织数据,给MQ,让日志服务去写
+        const { id: user_id, account, name } = user;
+        const logData = { user_id, account, name, _tenant: tenant, opera: route.name, path: url, module };
+        // 先用mq发送,不行再用http发
+        if (ctx.mq) {
+          ctx.service.util.rabbitMq.sendToMqQueue(logData, 'logs');
+        } else {
+          // http请求
+          const httpPrefix = ctx.app.config.httpPrefix;
+          if (httpPrefix && httpPrefix.logs) {
+            const uri = `${httpPrefix.logs}/logs`;
+            ctx.service.util.httpUtil.cpost(uri, logData);
+          }
+        }
+      } catch (error) {
+        // 没啥可输出,别中断就行
+      }
+    }
+  };

+ 38 - 0
app/middleware/warning.js

@@ -0,0 +1,38 @@
+'use strict';
+const _ = require('lodash');
+const { ObjectId } = require('mongoose').Types;
+
+
+const getInfo = async (ctx, data) => {
+  console.log(data);
+  // 用3个id对应去3个表查数据,并返回
+  const belong_data = await ctx.model.Department.findOne({ _id: ObjectId(data.belong) });
+  if (belong_data) data.belong_data = belong_data;
+  const g_data = await ctx.model.Guardian.findOne({ _id: ObjectId(data.g_id) });
+  if (g_data) data.g_data = g_data;
+  const w_data = await ctx.model.Ward.findOne({ _id: ObjectId(data.w_id) });
+  if (w_data) data.w_data = w_data;
+  return data;
+};
+
+
+/**
+ * 处理fence接口的belong,g_id,w_id 获取其对应的数据
+ * @param {Object} options 中间件参数
+ */
+module.exports = options => {
+  return async function warning(ctx, next) {
+    await next();
+    let data = _.get(ctx.response, 'body.data');
+   
+    if (_.isArray(data)) {
+      // 循环object处理
+      for (let d of data) {
+        d = await getInfo(ctx, d);
+      }
+    } else if (_.isObject(data)) {
+      // object处理
+      data = await getInfo(ctx, data);
+    }
+  };
+};

+ 20 - 0
app/model/admin.js

@@ -0,0 +1,20 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 系统管理员表
+const admin = {
+  name: { type: String, default: '系统管理员' }, // 显示名称
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  role: { type: String, default: 'admin' },
+  remark: { type: String },
+};
+const schema = new Schema(admin, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Admin', schema, 'admin');
+};

+ 26 - 0
app/model/building.js

@@ -0,0 +1,26 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 楼栋长表
+const building = {
+    name: { type: String }, // 名称
+    account: { type: String }, // 账号
+    password: { type: Secret, select: false }, // 密码
+    phone: { type: String }, // 联系人
+    parent: { type: String }, // 上级
+};
+const schema = new Schema(building, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ name: 1 });
+schema.index({ account: 1 });
+schema.index({ phone: 1 });
+schema.index({ parent: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Building', schema, 'building');
+};

+ 18 - 0
app/model/cardAdmin.js

@@ -0,0 +1,18 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 工牌账号缓存
+const cardAdmin = {
+  uid: { type: String }, // 工牌账号id
+  uKey: { type: String }, // 工牌账号授权码
+  remark: { type: String },
+};
+const schema = new Schema(cardAdmin, { toJSON: { virtuals: true } });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('CardAdmin', schema, 'card_admin');
+};

+ 22 - 0
app/model/cardCache.js

@@ -0,0 +1,22 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 工牌缓存表
+const cardCache = {
+  vid: { type: String }, // 工牌id
+  vKey: { type: String }, // 工牌授权码
+  work_card: { type: String }, // 工牌id
+  remark: { type: String },
+};
+const schema = new Schema(cardCache, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ vid: 1 });
+schema.index({ work_card: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('CardCache', schema, 'card_cache');
+};

+ 18 - 0
app/model/config.js

@@ -0,0 +1,18 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 设置表
+const config = {
+  config: { type: Object }, // 动态编辑的Object,按约定处理
+  remark: { type: String },
+};
+const schema = new Schema(config, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Config', schema, 'config');
+};

+ 28 - 0
app/model/department.js

@@ -0,0 +1,28 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 部门表
+const department = {
+  type: { type: String },
+  city_id: { type: String },
+  branch_id: { type: String },
+  num: { type: String },
+  name: { type: String },
+  brief: { type: String },
+  remark: { type: String },
+};
+const schema = new Schema(department, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ type: 1 });
+schema.index({ city_id: 1 });
+schema.index({ branch_id: 1 });
+schema.index({ num: 1 });
+schema.index({ name: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Department', schema, 'department');
+};

+ 26 - 0
app/model/doctor.js

@@ -0,0 +1,26 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 随访医生
+const doctor = {
+  h_id: { type: String }, // 所属医院
+  name: { type: String }, // 名称
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  phone: { type: String }, // 联系人
+  belong: { type: String }, // 所属于
+};
+const schema = new Schema(doctor, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ h_id: 1 });
+schema.index({ name: 1 });
+schema.index({ account: 1 });
+schema.index({ phone: 1 });
+schema.index({ belong: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Doctor', schema, 'doctor');
+};

+ 32 - 0
app/model/fence.js

@@ -0,0 +1,32 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 围栏变更
+const fence = {
+  belong: { type: String }, // 所属警局id
+  g_id: { type: String }, // 监护人id
+  w_id: { type: String }, // 被监护人id
+  before_info: { type: Object }, // 变更前围栏的信息
+  after_info: { type: Object }, // 变更后围栏的信息
+  status: { type: String, default: '0' }, // 状态: 0:需要审核; 1审核通过,准备移动;-1,审核失败(可重新申请);2:开始移动;3:移动结束,本次申请结束
+  start_time: { type: String }, // 开始移动时间
+  end_time: { type: String }, // 结束移动时间
+  routes: { type: Array }, // 移动轨迹
+  process: { type: Array }, // 数据变更过程
+  rule: { type: String, default: '0' }, // 规则类型: 0:禁止出栏;1:禁止入栏
+};
+const schema = new Schema(fence, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ belong: 1 });
+schema.index({ g_id: 1 });
+schema.index({ w_id: 1 });
+schema.index({ status: 1 });
+schema.index({ rule: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Fence', schema, 'fence');
+};

+ 22 - 0
app/model/grid.js

@@ -0,0 +1,22 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 网格长表
+const grid = {
+  name: { type: String }, // 名称
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  phone: { type: String }, // 联系人
+};
+const schema = new Schema(grid, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ name: 1 });
+schema.index({ account: 1 });
+schema.index({ phone: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Grid', schema, 'grid');
+};

+ 39 - 0
app/model/guardian.js

@@ -0,0 +1,39 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 监护人
+const guardian = {
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  name: { type: String }, // 姓名
+  phone: { type: String }, // 电话
+  unit: { type: String }, // 单位
+  address: { type: String }, // 地址
+  email: { type: String }, // 邮件
+  card: { type: String }, // 身份证号
+  belong: { type: String }, // 所属分局
+  app_openid: { type: String }, // 微信小程序openid
+  unionid: { type: String }, // 微信开放平台id
+  openid: { type: String }, // 微信公众号id
+  status: { type: String, default: '1' }, // 状态:0-待审核;1-通过;-1:不通过
+  card_id: { type: String }, // 工牌id
+  remark: { type: String },
+};
+const schema = new Schema(guardian, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ account: 1 });
+schema.index({ name: 1 });
+schema.index({ phone: 1 });
+schema.index({ unit: 1 });
+schema.index({ belong: 1 });
+schema.index({ card: 1 });
+schema.index({ status: 1 });
+schema.index({ card_id: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Guardian', schema, 'guardian');
+};

+ 38 - 0
app/model/hospital.js

@@ -0,0 +1,38 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 医院账号
+const hospital = {
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  name: { type: String }, // 姓名
+  phone: { type: String }, // 电话
+  unit: { type: String }, // 单位
+  address: { type: String }, // 地址
+  email: { type: String }, // 邮件
+  fence: { type: Object }, // 电子围栏
+  role: { type: String }, // 角色
+  belong: { type: String }, // 所属区域
+  nature: { type: String }, // 机构性质
+  place: { type: String }, // 地区
+  bed_num: { type: Number }, // 床位数
+  remark: { type: String },
+};
+const schema = new Schema(hospital, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ account: 1 });
+schema.index({ name: 1 });
+schema.index({ phone: 1 });
+schema.index({ unit: 1 });
+schema.index({ role: 1 });
+schema.index({ belong: 1 });
+schema.index({ nature: 1 });
+schema.index({ place: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Hospital', schema, 'hospital');
+};

+ 22 - 0
app/model/judge.js

@@ -0,0 +1,22 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 研判表
+const judge = {
+  w_id: { type: String }, // 患者id
+  w_name: { type: String }, // 患者姓名
+  send_time: { type: String }, // 发生时间
+  trajectory: { type: String }, // 轨迹
+  content: { type: String }, // 内容
+};
+const schema = new Schema(judge, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ w_name: 1 });
+schema.index({ send_time: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Judge', schema, 'judge');
+};

+ 33 - 0
app/model/law.js

@@ -0,0 +1,33 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 政法委账号表
+const law = {
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  name: { type: String }, // 姓名
+  phone: { type: String }, // 电话
+  unit: { type: String }, // 单位
+  address: { type: String }, // 地址
+  email: { type: String }, // 邮件
+  role: { type: String }, // 角色
+  remark: { type: String },
+};
+const schema = new Schema(law, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ account: 1 });
+schema.index({ name: 1 });
+schema.index({ phone: 1 });
+schema.index({ unit: 1 });
+schema.index({ address: 1 });
+schema.index({ email: 1 });
+schema.index({ role: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Law', schema, 'law');
+};

+ 22 - 0
app/model/level.js

@@ -0,0 +1,22 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 预警等级
+const level = {
+  label: { type: String }, // 中文显示
+  code: { type: String }, // 等级编码
+  color: { type: String }, // 颜色
+};
+const schema = new Schema(level, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ label: 1 });
+schema.index({ type: 1 });
+schema.index({ code: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Level', schema, 'level');
+};

+ 20 - 0
app/model/menu.js

@@ -0,0 +1,20 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 菜单表
+const menu = {
+  title: { type: String }, // 菜单名称
+  index: { type: String }, // 路由
+  icon: { type: String }, // 图标
+  remark: { type: String },
+};
+const schema = new Schema(menu, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Menu', schema, 'menu');
+};

+ 27 - 0
app/model/message.js

@@ -0,0 +1,27 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 消息表
+const message = {
+  title: { type: String }, // 标题
+  content: { type: String }, // 内容
+  user_id: { type: String }, // 接收人id: 医生/警长/网格长
+  status: { type: String, default: '0' }, // 0:未读/1:已读
+  time: { type: String }, // 时间,精确到秒
+  receipt: { type: Object }, // 回执
+  remark: { type: String },
+};
+const schema = new Schema(message, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ title: 1 });
+schema.index({ user_id: 1 });
+schema.index({ time: 1 });
+schema.index({ status: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Message', schema, 'message');
+};

+ 31 - 0
app/model/police.js

@@ -0,0 +1,31 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 公安账号
+const police = {
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  name: { type: String }, // 姓名
+  phone: { type: String }, // 电话
+  unit: { type: String }, // 单位
+  address: { type: String }, // 地址
+  email: { type: String }, // 邮件
+  belong: { type: String }, // 所在分局(字典/自己写需要确认)
+  role: { type: String }, // 角色
+  remark: { type: String },
+};
+const schema = new Schema(police, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ account: 1 });
+schema.index({ name: 1 });
+schema.index({ phone: 1 });
+schema.index({ unit: 1 });
+schema.index({ role: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Police', schema, 'police');
+};

+ 28 - 0
app/model/position.js

@@ -0,0 +1,28 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 定位表
+const position = {
+  user_id: { type: String },
+  longitude: { type: String }, // 经度
+  latitude: { type: String }, // 纬度
+  name: { type: String }, // 姓名
+  card: { type: String }, // 身份证号
+  type: { type: String }, // 类型: ward:患者;guardian:监护人;....
+  info: { type: Object }, // 工牌定位额外信息
+  remark: { type: String },
+};
+const schema = new Schema(position, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ user_id: 1 });
+schema.index({ name: 1 });
+schema.index({ card: 1 });
+schema.index({ type: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Position', schema, 'position');
+};

+ 26 - 0
app/model/range.js

@@ -0,0 +1,26 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 围栏范围表
+const range = {
+  name: { type: String }, // 围栏名称
+  range: { type: Object }, // 地图上围栏属性:type,range
+  level: { type: Array }, // 等级
+  status: { type: String, default: '0' }, // 状态
+  rule: { type: String, default: '1' }, // 进出规则:0:禁止出栏;1:禁止入栏
+  category: { type: String }, // 分类
+  remark: { type: String },
+};
+const schema = new Schema(range, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ name: 1 });
+schema.index({ level: 1 });
+schema.index({ status: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Range', schema, 'range');
+};

+ 22 - 0
app/model/role.js

@@ -0,0 +1,22 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const moment = require('moment');
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+// 角色表
+const role = {
+  name: { type: String }, // 名称
+  brief: { type: String }, // 简介
+  menu: { type: Array }, // 菜单
+  type: { type: String }, // 类型
+  remark: { type: String },
+};
+const schema = new Schema(role, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ type: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Role', schema, 'role');
+};

+ 32 - 0
app/model/sendcase.js

@@ -0,0 +1,32 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 发案表
+const sendcase = {
+  w_id: { type: String }, // 患者id
+  w_name: { type: String }, // 患者姓名
+  level: { type: String }, // 患者等级
+  place: { type: Array }, // 发案经纬度
+  send_time: { type: String }, // 发案时间
+  reason: { type: String }, // 报警原因
+  status: { type: String, default: '0' }, // 状态
+  handle_name: { type: String }, // 处理人
+  handle_phone: { type: String }, // 处理人联系方式
+  handle_time: { type: String }, // 处理时间
+  content: { type: String }, // 详细信息
+};
+const schema = new Schema(sendcase, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ w_name: 1 });
+schema.index({ level: 1 });
+schema.index({ phone: 1 });
+schema.index({ handle_name: 1 });
+schema.index({ send_time: 1 });
+schema.index({ create_time: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Sendcase', schema, 'sendcase');
+};

+ 24 - 0
app/model/sheriff.js

@@ -0,0 +1,24 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 警长
+const sheriff = {
+  name: { type: String }, // 名称
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false }, // 密码
+  phone: { type: String }, // 联系人
+  belong: { type: String }, // 所属于
+};
+const schema = new Schema(sheriff, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ name: 1 });
+schema.index({ account: 1 });
+schema.index({ phone: 1 });
+schema.index({ belong: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Sheriff', schema, 'sheriff');
+};

+ 24 - 0
app/model/unit.js

@@ -0,0 +1,24 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 单元长表
+const unit = {
+  name: { type: String }, // 名称
+  account: { type: String }, // 账号
+  password: { type: Secret, select: false}, // 密码
+  phone: { type: String }, // 联系人
+  parent: { type: String }, // 上级
+};
+const schema = new Schema(unit, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ name: 1 });
+schema.index({ account: 1 });
+schema.index({ phone: 1 });
+schema.index({ parent: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Unit', schema, 'unit');
+};

+ 63 - 0
app/model/ward.js

@@ -0,0 +1,63 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 被监护人账号
+const ward = {
+  password: { type: Secret, select: false }, // 密码
+  place: { type: String }, // 地区
+  name: { type: String }, // 姓名
+  gender: { type: String }, // 性别
+  card: { type: String }, // 身份证号
+  case: { type: String }, // 病例
+  important_phone: { type: String }, // 重点人联系方式
+  important_wx: { type: String }, // 重点人微信号
+  important_company: { type: String }, // 重点人工作单位
+  hj_address: { type: String }, // 户籍地址
+  address: { type: String }, // 实际住址
+  g_id: { type: String }, // 监护人id
+  g_name: { type: String }, // 监护人姓名
+  g_phone: { type: String }, // 监护人电话
+  belong: { type: String }, // 管辖派出所(此处是选择派出所)
+  police: { type: String }, // 具体管辖的民警
+  police_phone: { type: String }, // 民警的联系电话
+  family_cars: { type: String }, // 特殊人员所属车辆信息
+  icon: { type: String }, // 头像
+  family: { type: Array }, // 家庭情况
+  sociology: { type: Array }, // 社会信息
+  level: { type: String }, // 预警等级
+  h_id: { type: String }, // 被监护人所在医院id
+  fence: { type: Object }, // 病人围栏信息
+  status: { type: String, default: '1' }, // 病人状态:0待审核;1:通过;-1:不通过
+
+  year: { type: String }, // 登记年份
+
+  card_id: { type: String }, // 工牌id
+
+  use_medicine: { type: Array }, // 用药情况
+  healthy: { type: Array }, // 健康情况
+  remark: { type: String },
+};
+const schema = new Schema(ward, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ g_id: 1 });
+schema.index({ name: 1 });
+schema.index({ card: 1 });
+schema.index({ phone: 1 });
+schema.index({ important_phone: 1 });
+schema.index({ g_name: 1 });
+schema.index({ g_phone: 1 });
+schema.index({ police_phone: 1 });
+schema.index({ h_id: 1 });
+schema.index({ status: 1 });
+schema.index({ police: 1 });
+schema.index({ belong: 1 });
+schema.index({ year: 1 });
+schema.index({ card_id: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Ward', schema, 'ward');
+};

+ 24 - 0
app/model/warning.js

@@ -0,0 +1,24 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose-free/lib/model/meta-plugin');
+const { ObjectId } = require('mongoose').Types;
+const { Secret } = require('naf-framework-mongoose-free/lib/model/schema');
+// 报警信息(废弃)
+const warning = {
+  w_id: { type: String }, // 被监护人id
+  g_id: { type: String }, // 监护人id
+  belong: { type: String }, // 所属分局
+  status: { type: String, default: '0' }, // 状态  0未处理  1已处理
+};
+const schema = new Schema(warning, { toJSON: { virtuals: true } });
+schema.index({ id: 1 });
+schema.index({ w_id: 1 });
+schema.index({ g_id: 1 });
+schema.index({ belong: 1 });
+schema.index({ status: 1 });
+schema.index({ 'meta.createdAt': 1 });
+schema.plugin(metaPlugin);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('Warning', schema, 'warning');
+};

+ 50 - 0
app/public/importSetting.js

@@ -0,0 +1,50 @@
+'use strict';
+/**
+ * 导入的设置
+ * key:表名
+ * value:[
+ *  {
+ *    key:excel中的字段名,值一定要与表头对上,位置不限制.不管excel的顺序,之和写配置的顺序有关,不过也没啥影响
+ *    column: 字段名
+ *    turn:非强制需要,函数名,所有转换函数写到service/import.js中 如果有这个字段,就把值用this[turn](value)转换掉,不过有的特殊字段,在create接口中会转
+ *    index: (此字段不能写,只是在这里说明),该字段为 映射的字段在 excel 中的第几列,是用来取每行的数据.所以不能写,没有index会被过滤掉.乱写可能出现空值,严重会影响导入功能(没有字段也传进来了,还扔去添加了)
+ *  },
+ *  ...
+ * ]
+ */
+module.exports = {
+  test: [
+    { key: 'c1', column: 'name', turn: 'valueToString' },
+    { key: 'c2', column: 'age' },
+    { key: 'c3', column: 'date' },
+    { key: 'c4', column: 'column4' },
+    { key: 'c5', column: 'column5' },
+  ],
+  ward: [
+    { key: '序号', column: 'index' },
+    { key: '地区', column: 'place' },
+    { key: '姓名', column: 'name' },
+    { key: '性别', column: 'gender' },
+    { key: '身份证号', column: 'card' },
+    { key: '病例病情信息', column: 'case' },
+    { key: '重点人联系方式', column: 'important_phone' },
+    { key: '重点人微信号', column: 'important_wx' },
+    { key: '重点人工作单位', column: 'important_company' },
+    { key: '户籍地址', column: 'hj_address' },
+    { key: '实际住址', column: 'address' },
+
+    // 监护人信息需要创建
+    { key: '监护人姓名', column: 'g_name' },
+    { key: '监护人电话', column: 'g_phone' },
+
+    { key: '管辖派出所', column: 'belong' }, // 需要对应department表,没有则空
+
+    { key: '管辖民警', column: 'police' },
+    { key: '管辖民警联系方式', column: 'police_phone' },
+    { key: '精神障碍患者所属车辆信息', column: 'family_cars' },
+
+    // 不一定能有的数据
+    { key: '头像', column: 'icon' },
+    { key: '预警等级', column: 'level' },
+  ],
+};

+ 55 - 0
app/router.js

@@ -0,0 +1,55 @@
+'use strict';
+
+/**
+ * @param {Egg.Application} app - egg application
+ */
+module.exports = app => {
+  const { router, controller } = app;
+  router.get('/', controller.home.index);
+  router.post('/psychosis/api/login', controller.home.login);
+  router.post('/psychosis/api/adminUpdate', controller.home.adminUpdate);
+
+  router.post('/psychosis/api/util', controller.home.util);
+
+  router.post('/psychosis/api/policeLogin', controller.police.login);
+  router.post('/psychosis/api/policeUpdate', controller.police.policeUpdate);
+
+  router.post('/psychosis/api/hospitalLogin', controller.hospital.login);
+  router.post('/psychosis/api/hospitalUpdate', controller.hospital.hospitalUpdate);
+
+  router.post('/psychosis/api/lawLogin', controller.law.login);
+  router.post('/psychosis/api/lawUpdate', controller.law.lawUpdate);
+
+  router.post('/psychosis/api/sheriffLogin', controller.sheriff.login);
+  router.post('/psychosis/api/sheriffUpdate', controller.sheriff.sheriffUpdate);
+
+  // 监护人
+  router.post('/psychosis/api/guardianLogin', controller.guardian.login);
+
+  router.get('/psychosis/api/admin', controller.admin.index);
+  // require('./z_router/user')(app); // 管理员
+  require('./z_router/menu')(app); // 菜单
+  require('./z_router/fence')(app); // 围栏
+  require('./z_router/guardian')(app); // 监护人
+  require('./z_router/hospital')(app); // 医院账号
+  require('./z_router/level')(app); // 预警等级
+  require('./z_router/police')(app); // 公安信息
+  require('./z_router/ward')(app); // 被监护人
+  require('./z_router/warning')(app); // 报警信息
+  require('./z_router/department')(app); // 部门
+  require('./z_router/role')(app); // 角色
+  require('./z_router/import')(app); // 导入
+  require('./z_router/sendcase')(app); // 发案
+  require('./z_router/judge')(app); // 研判
+  require('./z_router/statistics')(app); // 统计
+  require('./z_router/range')(app); // 围栏范围
+  require('./z_router/grid')(app); // 网格长
+  require('./z_router/building')(app); // 楼栋长
+  require('./z_router/unit')(app); // 单元长
+  require('./z_router/position')(app); // 定位
+  require('./z_router/law')(app); // 政法委账号
+  require('./z_router/sheriff')(app); // 警长
+  require('./z_router/config')(app); // 设置
+  require('./z_router/doctor')(app); // 随访医生
+  require('./z_router/message')(app); // 消息通知
+};

+ 10 - 0
app/schedule/cardPosition.js

@@ -0,0 +1,10 @@
+'use strict';
+module.exports = {
+  schedule: {
+    interval: '5s', // 1 分钟间隔
+    type: 'worker', // 指定所有的 worker 都需要执行
+  },
+  async task(ctx) {
+    await ctx.service.card.loop();
+  },
+};

+ 15 - 0
app/service/admin.js

@@ -0,0 +1,15 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose-free/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const _ = require('lodash');
+const assert = require('assert');
+
+// 管理员
+class AdminService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'admin');
+    this.model = this.ctx.model.Admin;
+  }
+}
+
+module.exports = AdminService;

+ 15 - 0
app/service/building.js

@@ -0,0 +1,15 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose-free/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const _ = require('lodash');
+const assert = require('assert');
+
+// 发案表
+class BuildingService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'building');
+    this.model = this.ctx.model.Building;
+  }
+}
+
+module.exports = BuildingService;

+ 243 - 0
app/service/card.js

@@ -0,0 +1,243 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose-free/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const _ = require('lodash');
+const assert = require('assert');
+const axios = require('axios');
+const crypto = require('crypto');
+// 定位卡
+class CardService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'card');
+    this.model = this.ctx.model.Position;
+    this.ward = this.ctx.model.Ward;
+    this.guardian = this.ctx.model.Guardian;
+    this.cardCacheModel = this.ctx.model.CardCache;
+    this.cardAdminModel = this.ctx.model.CardAdmin;
+    this.tp = this.ctx.service.transformPosition;
+    this.dbConfig = this.app.config.dbServer;
+  }
+
+  /**
+   * 定时任务执行函数,login是在应用加载完成时开始的.
+   * 登陆过期时间是12h,请求更新token时间,所以应该不用担心会有token过期问题
+   */
+  async loop() {
+    // 查询 患者有工牌的
+    const wardList = await this.ward.find({ card_id: { $exists: true } });
+    // 查询 监护人有工牌的
+    const guardianList = await this.ward.find({ card_id: { $exists: true } });
+    const data = [ ...wardList, ...guardianList ];
+    // 分散开处理,不需要await进行等待,各玩各的
+    for (const worker of data) {
+      this.dealPosition(worker);
+    }
+    // 入职,个人信息,服务对象
+  }
+
+  /**
+   * 组织每个保安员的定位信息 及 信息保存
+   * @param {Object} worker 符合条件的保安员基础信息(security_guard_base)
+   */
+  async dealPosition(worker) {
+    if (!worker) return;
+    let positionData = {};
+    const { id, _id, card_id } = worker;
+    positionData = _.pick(worker, [ 'name', 'card' ]);
+    positionData.user_id = id || _id;
+    positionData.type = 'ward';
+    // 获取定位信息
+    const position = await this.getPosition(card_id);
+    if (position) {
+      const { latitude, longitude, ...info } = position;
+      positionData = { ...positionData, latitude, longitude, info };
+      this.model.create(positionData);
+    }
+  }
+
+  /**
+   * 获取该工牌实时定位信息
+   * @param {String} vid 工牌id
+   */
+  async getPosition(vid) {
+    if (!vid) return;
+    let vObj = await this.getAuthorizeCode(vid);
+    // 有vKey的话,就试试好不好使
+    // 第一次可能是缓存,也可能是请求,不确定;所以第一次如果没有返回
+    // 则接下来需要禁用缓存再来一遍,如果还是不行,那就没辙了
+    if (vObj) {
+      const position = await this.toGetPosition(vObj.vKey, vObj.vid);
+      if (position) return position;
+    }
+    vObj = null;
+    // 第二次了,不使用缓存了,第一次要是有就结束了,不会来这了
+    vObj = await this.getAuthorizeCode(vid, false);
+    if (vObj) {
+      const position = await this.toGetPosition(vObj.vKey, vObj.vid);
+      if (position) return position;
+    }
+  }
+
+  /**
+   * 请求车辆最新信息并处理
+   * @param {String} vKey 工牌授权码
+   * @param {String} vid 工牌id
+   */
+  async toGetPosition(vKey, vid) {
+    // 查询定位点
+    const method = 'loadLocation';
+    const data = await this.toRequest(method, { vid, vKey });
+    const position = this.getPositionFromData(data);
+    if (position) {
+      const obj = { info: {} };
+      if (_.get(position, 'lat')) obj.latitude = _.get(position, 'lat');
+      if (_.get(position, 'lng')) obj.longitude = _.get(position, 'lng');
+      if (obj.latitude && obj.longitude) {
+        const [ latitude, longitude ] = this.tp.transform(obj.latitude, obj.longitude);
+        if (latitude && longitude) {
+          obj.latitude = latitude;
+          obj.longitude = longitude;
+        }
+      }
+      // 额外内容
+      if (_.get(position, 'info')) obj.info = _.get(position, 'info'); // 文字位置信息
+      if (_.get(position, 'state')) obj.state = _.get(position, 'state'); // 工牌状态
+      if (_.get(position, 'speed')) obj.speed = _.get(position, 'speed'); // 速度
+      if (_.get(position, 'direct')) obj.direct = _.get(position, 'direct'); // 方向
+      if (_.get(position, 'vhcofflinemin')) obj.vhcofflinemin = _.get(position, 'vhcofflinemin'); // 不在线时长(分钟)
+      if (Object.keys(obj).length > 0) return obj;
+    }
+  }
+
+  /**
+   * 处理最新定位信息接口返回结果
+   * @param {Object} data 请求最新定位信息接口返回结果
+   */
+  getPositionFromData(data) {
+    if (data) {
+      const { locs } = data;
+      if (locs && _.isArray(locs)) {
+        const l = _.head(locs);
+        if (l) return l;
+      }
+    }
+  }
+
+  /**
+   * 获取工牌授权码
+   * @param {String} work_card 工牌id
+   * @param {Boolean} useCache 是否使用缓存
+   */
+  async getAuthorizeCode(work_card, useCache = true) {
+    if (!work_card) return;
+    let data;
+    // 先在缓存中找下
+    if (useCache) {
+      data = await this.cardCacheModel.findOne({ work_card });
+      if (data) return data;
+    }
+    // 如果缓存里没有,从接口走一遍再找
+    const list = await this.toCacheCardGroup();
+    const r = list.find(f => `${f.work_card}` === `${work_card}`);
+    // 再没有就GG
+    if (r) return r;
+  }
+
+  /**
+   * 缓存并返回获取的车辆数据
+   */
+  async toCacheCardGroup() {
+    const users = await this.cardAdminModel.find({}).limit(1);
+    if (users.length <= 0) return;
+    const user = _.head(users);
+    const data = await this.toRequest('loadVehicles', { uid: user.uid, uKey: user.uKey });
+    let list = _.get(data, 'groups', []);
+    list = _.flattenDeep(list.map(i => i.vehicles));
+    list = list.map(i => ({ vid: i.id, vKey: i.vKey, work_card: i.name }));
+    // 缓存
+    await this.cardCacheModel.deleteMany();
+    await this.cardCacheModel.insertMany(list);
+    // 返回
+    return list;
+  }
+
+
+  /**
+   * 登陆;用户放在session中
+   */
+  async login() {
+    console.log('初始化----------工牌接口登陆');
+    const name = 'fwedz';
+    const pwd = '000000';
+    const method = 'loginSystem';
+    const res = await this.toRequest(method, { name, pwd });
+    if (res.success) {
+      await this.cardAdminModel.deleteMany();
+      await this.cardAdminModel.create(_.pick(res, [ 'uid', 'uKey' ]));
+      // 不能存在session中,不共享,存在库里吧
+      // await this.cardAdminModel.findOne() = _.pick(res, [ 'uid', 'uKey' ]);
+    }
+  }
+
+  /**
+   * 请求接口
+   * @param {String} method 函数
+   * @param {Object} params 参数
+   */
+  async toRequest(method, params = {}) {
+    if (!method) return;
+    let url = `http://47.104.0.190:89/gpsonline/GPSAPI?version=1&method=${method}`;
+    for (const key in params) {
+      url += `&${key}=${params[key]}`;
+    }
+    const req = await axios.get(url);
+    const data = this.requestReturnDeal(req);
+    return data;
+  }
+
+  /**
+   * 错误码文案
+   * @param {Number} code 错误码
+   */
+  errorType(code) {
+    const object = {
+      0: '系统出错',
+      1: '方法名不存在',
+      2: '版本号不存在',
+      3: '参数不能为空',
+      4: '参数值格式有误',
+      5: '用户名或密码错误',
+      6: '授权码无效',
+      7: '超过一小时最大访问次数',
+    };
+
+    return object[code];
+  }
+  /**
+   * 请求结果处理
+   * @param {Object} req 统一处理请求
+   */
+  requestReturnDeal(req) {
+    if (req.status !== 200) {
+      console.error('接口请求失败----http失败');
+      return;
+    }
+    if (req.data) return req.data;
+  }
+
+  /**
+   * 保安系统接口处理
+   * @param {Object} req 统一处理请求
+   */
+  selfRequestDeal(req) {
+    if (req.status !== 200) {
+      console.error('接口请求失败----http失败');
+      return;
+    }
+    const { data } = req.data;
+    if (data) return data;
+  }
+
+}
+
+module.exports = CardService;

+ 25 - 0
app/service/config.js

@@ -0,0 +1,25 @@
+'use strict';
+const { CrudService } = require('naf-framework-mongoose-free/lib/service');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const _ = require('lodash');
+const assert = require('assert');
+
+// 设置表
+class ConfigService extends CrudService {
+  constructor(ctx) {
+    super(ctx, 'config');
+    this.model = this.ctx.model.Config;
+  }
+  async query() {
+    const res = await this.model.findOne();
+    return res;
+  }
+
+  async update(data) {
+    let res = await this.model.findOne();
+    if (!res) res = await this.model.create({ config: {} });
+    await this.model.updateOne({ _id: res._id }, data);
+  }
+}
+
+module.exports = ConfigService;

+ 0 - 0
app/service/department.js


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff