Selaa lähdekoodia

添加 用户、vip导入导出,模板下载、导出文件下载、进度查询

asd123a20 3 vuotta sitten
vanhempi
commit
a36379bb2d
32 muutettua tiedostoa jossa 698 lisäystä ja 11 poistoa
  1. 1 1
      service-files/config/config.default.js
  2. 29 0
      service-import-export/.autod.conf.js
  3. 1 0
      service-import-export/.eslintignore
  4. 3 0
      service-import-export/.eslintrc
  5. 14 0
      service-import-export/.gitignore
  6. 12 0
      service-import-export/.travis.yml
  7. 33 0
      service-import-export/README.md
  8. 25 0
      service-import-export/app/controller/handle.js
  9. 9 0
      service-import-export/app/exportFiled/user.js
  10. 13 0
      service-import-export/app/exportFiled/vip.js
  11. 6 0
      service-import-export/app/importFiled/user.js
  12. 6 0
      service-import-export/app/importFiled/vip.js
  13. 15 0
      service-import-export/app/model/progress.js
  14. 13 0
      service-import-export/app/model/user.js
  15. 13 0
      service-import-export/app/model/vip.js
  16. 13 0
      service-import-export/app/router.js
  17. 46 0
      service-import-export/app/service/excel.js
  18. 42 0
      service-import-export/app/service/exports.js
  19. 97 0
      service-import-export/app/service/handle.js
  20. 40 0
      service-import-export/app/service/imperts.js
  21. 25 0
      service-import-export/app/service/progress.js
  22. 21 0
      service-import-export/app/service/template.js
  23. 15 0
      service-import-export/app/service/total.js
  24. 14 0
      service-import-export/appveyor.yml
  25. 70 0
      service-import-export/config/config.default.js
  26. 9 0
      service-import-export/config/plugin.js
  27. 17 0
      service-import-export/ecosystem.config.js
  28. 5 0
      service-import-export/jsconfig.json
  29. 51 0
      service-import-export/package.json
  30. 9 0
      service-import-export/server.js
  31. 20 0
      service-import-export/test/app/controller/home.test.js
  32. 11 10
      service-user/app/service/user.js

+ 1 - 1
service-files/config/config.default.js

@@ -1,10 +1,10 @@
 /* eslint valid-jsdoc: "off" */
 
 'use strict';
-const path = require('path');
 /**
  * @param {Egg.EggAppInfo} appInfo app info
  */
+const path = require('path');
 const { sep } = require('path');
 module.exports = appInfo => {
   /**

+ 29 - 0
service-import-export/.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
service-import-export/.eslintignore

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

+ 3 - 0
service-import-export/.eslintrc

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

+ 14 - 0
service-import-export/.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
service-import-export/.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

+ 33 - 0
service-import-export/README.md

@@ -0,0 +1,33 @@
+# service-code
+
+# 点赞/收藏/评论/留言
+
+## QuickStart
+
+<!-- add docs here for user -->
+
+see [egg docs][egg] for more detail.
+
+### Development
+
+```bash
+$ npm i
+$ npm run dev
+$ open http://localhost:7001/
+```
+
+### Deploy
+
+```bash
+$ npm start
+$ npm stop
+```
+
+### npm scripts
+
+- Use `npm run lint` to check code style.
+- Use `npm test` to run unit test.
+- Use `npm run autod` to auto detect dependencies upgrade, see [autod](https://www.npmjs.com/package/autod) for more detail.
+
+
+[egg]: https://eggjs.org

+ 25 - 0
service-import-export/app/controller/handle.js

@@ -0,0 +1,25 @@
+'use strict';
+const Controller = require('egg').Controller;
+const { v4: uuidv4 } = require('uuid');
+class HandleController extends Controller {
+  async import() {
+    const taskId = uuidv4();
+    this.ctx.service.handle.import({ ...this.ctx.params, taskId });
+    this.ctx.body = { errcode: 0, errmsg: '', data: [], taskId };
+  }
+  async export() {
+    const taskId = uuidv4();
+    this.ctx.service.handle.export({ ...this.ctx.request.body, taskId });
+    this.ctx.body = { errcode: 0, errmsg: '', data: [], taskId };
+  }
+  async progressed() {
+    const res = await this.ctx.service.progress.progressed(this.ctx.params);
+    this.ctx.body = res;
+  }
+  async template() {
+    const res = await this.ctx.service.handle.template(this.ctx.query);
+    this.ctx.body = res;
+  }
+}
+
+module.exports = HandleController;

+ 9 - 0
service-import-export/app/exportFiled/user.js

@@ -0,0 +1,9 @@
+'use strict';
+
+module.exports = [
+  { name: 'name', title: '姓名' },
+  { name: 'phone', title: '电话' },
+  { name: 'company', title: '单位' },
+  { name: 'tab', title: '标识' },
+  { name: 'openid', title: 'openid' },
+];

+ 13 - 0
service-import-export/app/exportFiled/vip.js

@@ -0,0 +1,13 @@
+'use strict';
+
+module.exports = [
+  { name: 'name', title: '姓名' },
+  { name: 'phone', title: '电话' },
+  { name: 'company', title: '单位' },
+  { name: 'tab', title: '标识' },
+  { name: 'openid', title: 'openid' },
+  { name: 'vipTab', title: 'Vip标识' },
+  { name: 'status', title: '状态' },
+  { name: 'startTime', title: '会员开始时间' },
+  { name: 'endTime', title: '会员过期时间' },
+];

+ 6 - 0
service-import-export/app/importFiled/user.js

@@ -0,0 +1,6 @@
+'use strict';
+
+module.exports = [
+  { '姓名': 'name' },
+  { '电话': 'phone' },
+];

+ 6 - 0
service-import-export/app/importFiled/vip.js

@@ -0,0 +1,6 @@
+'use strict';
+
+module.exports = [
+  { '姓名': 'name' },
+  { '电话': 'phone' },
+];

+ 15 - 0
service-import-export/app/model/progress.js

@@ -0,0 +1,15 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const SchemaDefine = {
+  // 任务ID
+  taskId: { type: String, required: true },
+  // 进度
+  progress: { type: Number, required: true },
+  // 类型
+  type: { type: String, required: true },
+};
+const schema = new Schema(SchemaDefine);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('progress', schema, 'progress');
+};

+ 13 - 0
service-import-export/app/model/user.js

@@ -0,0 +1,13 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const SchemaDefine = {
+  // 姓名
+  name: { type: String, required: true },
+  // 电话
+  phone: { type: String, required: true },
+};
+const schema = new Schema(SchemaDefine);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('user', schema, 'user');
+};

+ 13 - 0
service-import-export/app/model/vip.js

@@ -0,0 +1,13 @@
+'use strict';
+const Schema = require('mongoose').Schema;
+const SchemaDefine = {
+  // 姓名
+  name: { type: String, required: true },
+  // 电话
+  phone: { type: String, required: true },
+};
+const schema = new Schema(SchemaDefine);
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('vip', schema, 'vip');
+};

+ 13 - 0
service-import-export/app/router.js

@@ -0,0 +1,13 @@
+'use strict';
+
+/**
+ * @param {Egg.Application} app - egg application
+ */
+module.exports = app => {
+  const { router, controller } = app;
+  // 点赞
+  router.post('/api/importandexport/handle/import/:type', controller.handle.import);
+  router.post('/api/importandexport/handle/exports', controller.handle.export);
+  router.get('/api/importandexport/handle/template', controller.handle.template);
+  router.get('/api/importandexport/handle/progressed/:taskId', controller.handle.progressed);
+};

+ 46 - 0
service-import-export/app/service/excel.js

@@ -0,0 +1,46 @@
+'use strict';
+
+const Service = require('egg').Service;
+const ExcelJS = require('exceljs');
+class ExcelService extends Service {
+  // 创建
+  async establish({ fileName, type, _this }) {
+    const workbook = new ExcelJS.Workbook();
+    const sheet = workbook.addWorksheet('Sheet');
+    const exportFiled = _this.app.config.exportFiled[`export${type}`];
+    sheet.columns = exportFiled.map(e => ({ header: e.title, key: e.name, width: 30 }));
+    return await workbook.xlsx.writeFile(`${_this.app.config.exportsPath}/${fileName}.xlsx`).then(function() {
+      return 'success';
+    }, function(err) {
+      return err;
+    });
+  }
+  // 写入
+  async insertFile({ type, data, fileName, _this }) {
+    const filename = `${_this.app.config.exportsPath}/${fileName}.xlsx`;
+    const workbook = new ExcelJS.Workbook();
+    const exportFiled = _this.app.config.exportFiled[`export${type}`];
+    // 读取文件
+    await workbook.xlsx.readFile(filename)
+      .then(async function() {
+        // 获取sheet
+        const worksheet = workbook.getWorksheet(1);
+        // 遍历数据
+        data.forEach(e => {
+          // 获取左后可编辑行
+          const lastRow = worksheet.lastRow;
+          // 获取最后一行加一
+          const getRowInsert = worksheet.getRow(lastRow.number + 1);
+          // 遍历头文件 为制造单元格下表
+          for (let i = 0; i < exportFiled.length; i++) {
+            // 向最后一行加一的行 对应的单元格内添加数据
+            getRowInsert.getCell(i + 1).value = e[exportFiled[i].name] || '';
+          }
+          getRowInsert.commit();
+        });
+        await workbook.xlsx.writeFile(filename);
+      });
+  }
+}
+
+module.exports = ExcelService;

+ 42 - 0
service-import-export/app/service/exports.js

@@ -0,0 +1,42 @@
+'use strict';
+
+const Service = require('egg').Service;
+class ExportsService extends Service {
+  // 用户导出
+  async exportsuser({ filter, skip, ids, _this }) {
+    const key = Object.keys(filter);
+    if (key.length > 0) return await _this.ctx.model.User.find({ ...filter }).skip(skip * 10).limit(10);
+    let list = await Promise.all(
+      ids.map(async e => {
+        const res = await _this.ctx.model.User.findOne({ _id: e });
+        if (res) return res;
+      })
+    );
+    list = list.filter(e => e !== undefined);
+    return list;
+  }
+  // vip导出
+  async exportsvip({ filter, skip, ids, _this }) {
+    const key = Object.keys(filter);
+    if (key.length > 0) return await _this.ctx.model.Vip.find({ ...filter }).skip(skip * 10).limit(10);
+    let list = await Promise.all(
+      ids.map(async e => {
+        const res = await _this.ctx.model.Vip.findOne({ _id: e });
+        if (res) {
+          const data = await this.convert({ data: res });
+          return data;
+        }
+      })
+    );
+    list = list.filter(e => e !== undefined);
+    return list;
+  }
+  // 数据转换函数
+  async convert({ data }) {
+    console.log(data);
+    // startTime endTime status
+    return data;
+  }
+}
+
+module.exports = ExportsService;

+ 97 - 0
service-import-export/app/service/handle.js

@@ -0,0 +1,97 @@
+'use strict';
+
+const Service = require('egg').Service;
+const xlsx = require('xlsx');
+const fs = require('fs');
+class HandleService extends Service {
+  constructor(ctx) {
+    super(ctx);
+    this.progressModel = this.ctx.model.Progress;
+    this.config = this.app.config;
+  }
+  // 导入处理
+  async import({ type, taskId }) {
+    const files = this.ctx.request.files[0];
+    const workbook = xlsx.readFile(files.filepath);
+    const name = workbook.SheetNames[0];
+    const sheet = workbook.Sheets[name];
+    const data = xlsx.utils.sheet_to_json(sheet);
+    const total = data.length;
+    let progress = 0;
+    for (let i = 0; i < data.length; i++) {
+      // 此处根据类型调用不同的数据存储服务
+      const item = data[i];
+      const fun = this.ctx.service.imperts[`import${type}`];
+      await fun({ item, _this: this });
+      // 此处调用进度存储
+      progress = (i + 1) / total * 100;
+      await this.ctx.service.progress.updateProgress({ taskId, progress, type });
+    }
+  }
+  // 导出处理
+  async export({ type, taskId, filters, ids, fileType }) {
+    // 创建过滤条件
+    const filter = {};
+    let res;
+    // 默认总数
+    let total = (ids && ids.length) || 0;
+    // 如果条件存在
+    if (filters) {
+      filter.$or = [];
+      for (const i in filters) {
+        const data = `{ "${i}": { "$regex": "${filters[i]}" } }`;
+        filter.$or.push(JSON.parse(data));
+      }
+      // 获取查询总数函数
+      const totalfun = this.ctx.service.total[`total${type}`];
+      // 赋值总数
+      total = await totalfun({ ...filter, _this: this });
+    }
+    // 获取查询函数
+    const fun = this.ctx.service.exports[`exports${type}`];
+    // 计算页数
+    const pages = Math.ceil(total / 10);
+    // 此处调用创建文件
+    const file = await this.establishFile({ taskId, type, fileType });
+    if (file === 'success') {
+      for (let i = 0; i < pages; i++) {
+        // 进度
+        const progress = (i + 1) / pages * 100;
+        // 更新进度
+        await this.ctx.service.progress.updateProgress({ taskId, progress, type });
+        // 调用查询数据函数
+        res = await fun({ skip: i, filter, ids, _this: this });
+        // 此处调用写入文件
+        if (res.length <= 0) return;
+        await this.insertFile({ type, data: res, taskId, fileType });
+      }
+    }
+  }
+  // 创建文件
+  async establishFile({ taskId, type, fileType }) {
+    const fun = this.ctx.service[fileType].establish;
+    return await fun({ fileName: taskId, type, _this: this });
+  }
+  // 持续写入文件
+  async insertFile({ type, data, taskId, fileType }) {
+    const fun = this.ctx.service[fileType].insertFile;
+    await fun({ type, fileName: taskId, data, _this: this });
+  }
+  // 模板下载
+  async template({ type, fileType, fileName }) {
+    const fun = this.ctx.service.template[fileType];
+    const url = await fun({ fileName, type, _this: this });
+    const postfix = url.split('.')[1];
+    this.ctx.attachment(`${fileName}.${postfix}`);
+    return fs.createReadStream(url);
+  }
+  // 文件下载
+  async exportsDownload({ taskId, fileName }) {
+    const url = `${this.app.config.exportsPath}/${taskId}.xlsx`;
+    const postfix = url.split('.')[1];
+    this.ctx.attachment(`${fileName}.${postfix}`);
+    return fs.createReadStream(url);
+  }
+}
+
+module.exports = HandleService;

+ 40 - 0
service-import-export/app/service/imperts.js

@@ -0,0 +1,40 @@
+'use strict';
+
+const Service = require('egg').Service;
+const moment = require('moment');
+class ImpertsService extends Service {
+  constructor(ctx) {
+    super(ctx);
+    this.config = this.app.config;
+    this.userModel = this.ctx.model.User;
+    this.vipModel = this.ctx.model.Vip;
+  }
+  // 用户导入
+  async importuser({ item, _this }) {
+    const filed = _this.config.filed.user;
+    const data = {};
+    for (const i in item) {
+      const val = filed.find(e => e[i]);
+      data[val[i]] = item[i];
+    }
+    const res = await _this.ctx.model.User.findOne({ phone: data.phone });
+    if (res) return;
+    await _this.ctx.model.User.create({ ...data });
+  }
+  // vip导入
+  async importvip({ item, _this }) {
+    const filed = _this.config.filed.vip;
+    const data = {};
+    for (const i in item) {
+      const val = filed.find(e => e[i]);
+      data[val[i]] = item[i];
+    }
+    const startTime = moment().valueOf();
+    const endTime = moment().add(1, 'Y').valueOf();
+    const res = await _this.ctx.model.Vip.findOne({ phone: data.phone });
+    if (res) return;
+    await _this.ctx.model.Vip.create({ ...data, vipTab: 'svip', status: '0', startTime, endTime });
+  }
+}
+
+module.exports = ImpertsService;

+ 25 - 0
service-import-export/app/service/progress.js

@@ -0,0 +1,25 @@
+'use strict';
+
+const Service = require('egg').Service;
+class HandleService extends Service {
+  constructor(ctx) {
+    super(ctx);
+    this.progressModel = this.ctx.model.Progress;
+  }
+  // 修改进度
+  async updateProgress({ taskId, progress, type }) {
+    const res = await this.progressModel.findOne({ taskId });
+    if (!res) {
+      await this.progressModel.create({ type, taskId, progress });
+      return;
+    }
+    await this.progressModel.updateOne({ _id: res._id }, { type, taskId, progress });
+  }
+  // 查询进度
+  async progressed({ taskId }) {
+    const res = await this.progressModel.findOne({ taskId });
+    return { errcode: 0, errmsg: '', data: res };
+  }
+}
+
+module.exports = HandleService;

+ 21 - 0
service-import-export/app/service/template.js

@@ -0,0 +1,21 @@
+'use strict';
+
+const Service = require('egg').Service;
+const ExcelJS = require('exceljs');
+class TemplateService extends Service {
+  // 创建excel模板
+  async excel({ type, _this }) {
+    const workbook = new ExcelJS.Workbook();
+    const sheet = workbook.addWorksheet('Sheet');
+    const exportFiled = _this.app.config.exportFiled[`export${type}`];
+    sheet.columns = exportFiled.map(e => ({ header: e.title, key: e.name, width: 30 }));
+    return await workbook.xlsx.writeFile(`${_this.app.config.templatePath}/template${type}.xlsx`).then(function() {
+      _this.ctx.set('Content-Type', 'application/vnd.ms-excel;charset=UTF-8');
+      return `${_this.app.config.templatePath}/template${type}.xlsx`;
+    }, function(err) {
+      return err;
+    });
+  }
+}
+
+module.exports = TemplateService;

+ 15 - 0
service-import-export/app/service/total.js

@@ -0,0 +1,15 @@
+'use strict';
+
+const Service = require('egg').Service;
+class TotalService extends Service {
+  // 用户 总数
+  async totaluser({ filter, _this }) {
+    return await _this.ctx.model.User.estimatedDocumentCount({ ...filter });
+  }
+  // vip 总数
+  async totalvip({ filter, _this }) {
+    return await _this.ctx.model.Vip.estimatedDocumentCount({ ...filter });
+  }
+}
+
+module.exports = TotalService;

+ 14 - 0
service-import-export/appveyor.yml

@@ -0,0 +1,14 @@
+environment:
+  matrix:
+    - nodejs_version: '10'
+
+install:
+  - ps: Install-Product node $env:nodejs_version
+  - npm i npminstall && node_modules\.bin\npminstall
+
+test_script:
+  - node --version
+  - npm --version
+  - npm run test
+
+build: off

+ 70 - 0
service-import-export/config/config.default.js

@@ -0,0 +1,70 @@
+/* eslint valid-jsdoc: "off" */
+
+'use strict';
+
+/**
+ * @param {Egg.EggAppInfo} appInfo app info
+ */
+const { sep } = require('path');
+const user = require('../app/importFiled/user');
+const vip = require('../app/importFiled/vip');
+const exportuser = require('../app/exportFiled/user');
+const exportvip = require('../app/exportFiled/vip');
+module.exports = appInfo => {
+  /**
+   * built-in config
+   * @type {Egg.EggAppConfig}
+   **/
+  const config = exports = {};
+
+  // use for cookie sign key, should change to your own and keep security
+  config.keys = appInfo.name + '_1635902541751_9477';
+
+  // add your middleware config here
+  config.middleware = [];
+  // add your user config here
+  const userConfig = {
+    // myAppName: 'egg',
+  };
+  // 安全配置
+  config.security = {
+    csrf: {
+      // ignoreJSON: true, // 默认为 false,当设置为 true 时,将会放过所有 content-type 为 `application/json` 的请求
+      enable: false,
+    },
+  };
+  config.cluster = {
+    listen: {
+      port: 9021,
+    },
+  };
+  // 数据库配置
+  config.mongoose = {
+    url: 'mongodb://127.0.0.1/Microservices',
+    options: {
+      // user: 'root',
+      // pass: 'cms@cc-lotus',
+      // authSource: 'admin',
+      // useNewUrlParser: true,
+      // useCreateIndex: true,
+    },
+  };
+  // 限制文件大小
+  config.multipart = {
+    mode: 'file',
+    fileSize: '50mb',
+    fileExtensions: [ '.zip', '.xlsx', '.xls' ], // 新增允许接收的文件后缀
+    // whitelist: [], // 覆盖允许接收的文件后缀
+  };
+  config.filed = { user, vip };
+  config.exportFiled = { exportuser, exportvip };
+  config.exportsPath = `${appInfo.baseDir}${sep}exports`;
+  config.templatePath = `${appInfo.baseDir}${sep}templates`;
+  config.logger = {
+    level: 'DEBUG',
+  };
+  return {
+    ...config,
+    ...userConfig,
+  };
+};

+ 9 - 0
service-import-export/config/plugin.js

@@ -0,0 +1,9 @@
+'use strict';
+
+/** @type Egg.EggPlugin */
+module.exports = {
+  mongoose: {
+    enable: true,
+    package: 'egg-mongoose',
+  },
+};

+ 17 - 0
service-import-export/ecosystem.config.js

@@ -0,0 +1,17 @@
+'use strict';
+
+const app = 'service-code';
+module.exports = {
+  apps: [{
+    name: app, // 应用名称
+    script: './server.js', // 实际启动脚本
+    out: `./logs/${app}.log`,
+    error: `./logs/${app}.err`,
+    watch: [ // 监控变化的目录,一旦变化,自动重启
+      'app', 'config',
+    ],
+    env: {
+      NODE_ENV: process.env.NODE_ENV || 'production', // 环境参数,当前指定为生产环境
+    },
+  }],
+};

+ 5 - 0
service-import-export/jsconfig.json

@@ -0,0 +1,5 @@
+{
+  "include": [
+    "**/*"
+  ]
+}

+ 51 - 0
service-import-export/package.json

@@ -0,0 +1,51 @@
+{
+  "name": "service-media",
+  "version": "1.0.0",
+  "description": "",
+  "private": true,
+  "egg": {
+    "declarations": true
+  },
+  "dependencies": {
+    "egg": "^2.15.1",
+    "egg-mongoose": "^3.3.1",
+    "egg-scripts": "^2.11.0",
+    "exceljs": "^4.3.0",
+    "moment": "^2.29.1",
+    "uuid": "^8.3.2",
+    "xlsx": "^0.18.3"
+  },
+  "devDependencies": {
+    "autod": "^3.0.1",
+    "autod-egg": "^1.1.0",
+    "egg-bin": "^4.11.0",
+    "egg-ci": "^1.11.0",
+    "egg-mock": "^3.21.0",
+    "eslint": "^5.13.0",
+    "eslint-config-egg": "^7.1.0"
+  },
+  "engines": {
+    "node": ">=10.0.0"
+  },
+  "scripts": {
+    "start": "egg-scripts start --daemon --title=egg-server-service-media",
+    "stop": "egg-scripts stop --title=egg-server-service-media",
+    "dev": "egg-bin dev",
+    "debug": "egg-bin debug",
+    "test": "npm run lint -- --fix && npm run test-local",
+    "test-local": "egg-bin test",
+    "cov": "egg-bin cov",
+    "lint": "eslint .",
+    "ci": "npm run lint && npm run cov",
+    "autod": "autod"
+  },
+  "ci": {
+    "version": "10"
+  },
+  "repository": {
+    "type": "git",
+    "url": ""
+  },
+  "author": "",
+  "license": "MIT"
+}

+ 9 - 0
service-import-export/server.js

@@ -0,0 +1,9 @@
+
+// eslint-disable-next-line strict
+const egg = require('egg');
+
+const workers = Number(process.argv[2] || require('os').cpus().length);
+egg.startCluster({
+  workers,
+  baseDir: __dirname,
+});

+ 20 - 0
service-import-export/test/app/controller/home.test.js

@@ -0,0 +1,20 @@
+'use strict';
+
+const { app, assert } = require('egg-mock/bootstrap');
+
+describe('test/app/controller/home.test.js', () => {
+  it('should assert', () => {
+    const pkg = require('../../../package.json');
+    assert(app.config.keys.startsWith(pkg.name));
+
+    // const ctx = app.mockContext({});
+    // yield ctx.service.xx();
+  });
+
+  it('should GET /', () => {
+    return app.httpRequest()
+      .get('/')
+      .expect('hi, egg')
+      .expect(200);
+  });
+});

+ 11 - 10
service-user/app/service/user.js

@@ -11,17 +11,18 @@ class UserService extends Service {
     assert(name, '昵称不存在');
     assert(phone, '电话不存在');
     assert(openid, 'openid不存在');
-    let user;
-    // 如果手机号与openid同时存在
-    user = await this.model.findOne({ phone, openid });
-    if (user) {
-      return { errcode: -1001, errmsg: '手机号与微信已存在' };
+    const filter = {};
+    const arr = { phone, openid };
+    for (const e in arr) {
+      const data = `{ "${e}": "${arr[e]}" }`;
+      if (arr[e]) {
+        filter.$or = [];
+        filter.$or.push(JSON.parse(data));
+      }
     }
-    // 如果查询用户只存在手机号
-    user = await this.model.findOne({ phone });
-    if (user && !user.openid) {
-      await this.update({ id: user._id, phone });
-      return;
+    const total = await this.model.find({ ...filter });
+    if (total.length > 0) {
+      return { errcode: -1001, errmsg: '手机号或微信已存在' };
     }
     try {
       const res = await this.model.create({ name, thumbnail, phone, stcompanyatus, tab, openid });