lrf пре 2 година
комит
486d9259fc
13 измењених фајлова са 321 додато и 0 уклоњено
  1. 1 0
      .eslintignore
  2. 4 0
      .eslintrc
  3. 46 0
      .github/workflows/nodejs.yml
  4. 15 0
      .gitignore
  5. 33 0
      README.md
  6. 55 0
      app/controller/home.js
  7. 12 0
      app/router.js
  8. 51 0
      config/config.default.js
  9. 9 0
      config/plugin.js
  10. 17 0
      ecosystem.config.js
  11. 49 0
      package.json
  12. 9 0
      server.js
  13. 20 0
      test/app/controller/home.test.js

+ 1 - 0
.eslintignore

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

+ 4 - 0
.eslintrc

@@ -0,0 +1,4 @@
+{
+  "extends": "eslint-config-egg",
+  "root": true
+}

+ 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: [16, 18]
+        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
+
+    - name: Continuous Integration
+      run: npm run ci
+
+    - name: Code Coverage
+      uses: codecov/codecov-action@v1
+      with:
+        token: ${{ secrets.CODECOV_TOKEN }}

+ 15 - 0
.gitignore

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

+ 33 - 0
README.md

@@ -0,0 +1,33 @@
+# service-sms
+
+短信服务
+
+## 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

+ 55 - 0
app/controller/home.js

@@ -0,0 +1,55 @@
+'use strict';
+
+const { Controller } = require('egg');
+const sms = require('@alicloud/dysmsapi20170525');
+const OpenApi = require('@alicloud/openapi-client');
+const Util = require('@alicloud/tea-util');
+const _ = require('lodash');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const assert = require('assert');
+
+class HomeController extends Controller {
+  async index() {
+    const { ctx } = this;
+    ctx.body = 'hi, egg';
+  }
+
+  async sendMessage() {
+    const { config, template, params = {}, phone } = this.ctx.request.body;
+    console.log(config, template, params, phone);
+    assert(config, '缺少服务设置');
+    assert(template, '缺少消息模');
+    assert(phone, '缺少发送对象');
+    const appConfig = _.get(this.app.config.appConfig, config);
+    const tt = _.get(appConfig, `template.${template}`);
+    const cc = _.pick(appConfig, [ 'accessKeyId', 'accessKeySecret' ]);
+    const client = await this.createClient(cc);
+    // 设置参数
+    tt.phoneNumbers = phone;
+    tt.templateParam = JSON.stringify(params);
+    const sendSmsRequest = new sms.SendSmsRequest(tt);
+    const runtime = new Util.RuntimeOptions({});
+    try {
+      // 复制代码运行请自行打印 API 的返回值
+      const res = await client.sendSmsWithOptions(sendSmsRequest, runtime);
+      if (res.body.code !== 'OK') {
+        throw new BusinessError(ErrorCode.SERVICE_FAULT, `${_.get(res.body.message)}`);
+      }
+      this.ctx.ok();
+    } catch (error) {
+      // 如有需要,请打印 error
+      Util.assertAsString(error.message);
+      throw new BusinessError(ErrorCode.SERVICE_FAULT, `${error.message}`);
+    }
+  }
+
+  // api生成客户端
+  async createClient({ accessKeyId, accessKeySecret }) {
+    const config = new OpenApi.Config({ accessKeyId, accessKeySecret });
+    config.endpoint = 'dysmsapi.aliyuncs.com';
+    const client = new sms.default(config);
+    return client;
+  }
+}
+
+module.exports = HomeController;

+ 12 - 0
app/router.js

@@ -0,0 +1,12 @@
+'use strict';
+
+/**
+ * @param {Egg.Application} app - egg application
+ */
+module.exports = app => {
+  const { router, controller } = app;
+  const { routePrefix, cluster } = app.config;
+  router.get('/', controller.home.index);
+  console.log(`http://127.0.0.1:14003${routePrefix}/sendMessage`);
+  router.post(`${routePrefix}/sendMessage`, controller.home.sendMessage);
+};

+ 51 - 0
config/config.default.js

@@ -0,0 +1,51 @@
+/* eslint valid-jsdoc: "off" */
+
+'use strict';
+
+/**
+ * @param {Egg.EggAppInfo} appInfo app info
+ */
+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 + '_1665737297528_5907';
+
+  // add your middleware config here
+  config.middleware = [];
+
+  // add your user config here
+  const userConfig = {
+    // myAppName: 'egg',
+  };
+  // 进程设置
+  config.cluster = {
+    listen: {
+      port: 14003,
+    },
+  };
+  // 项目配置
+  config.appConfig = {
+    free: {
+      accessKeyId: 'LTAI5tRTS3rXJTgf2Fqp8tGg',
+      accessKeySecret: 'g6DkQvBA4R7e9BEkPlQLhz683pq1SP',
+      template: {
+        bind: {
+          signName: '长春市福瑞科技有限公司',
+          templateCode: 'SMS_254730020',
+        },
+      },
+    },
+  };
+  // 路由设置
+  config.routePrefix = '/sms/api';
+
+  return {
+    ...config,
+    ...userConfig,
+  };
+};

+ 9 - 0
config/plugin.js

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

+ 17 - 0
ecosystem.config.js

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

+ 49 - 0
package.json

@@ -0,0 +1,49 @@
+{
+  "name": "service-sms",
+  "version": "1.0.0",
+  "description": "短信服务",
+  "private": true,
+  "egg": {
+    "framework": "naf-framework-mongoose-free"
+  },
+  "dependencies": {
+    "@alicloud/dysmsapi20170525": "^2.0.22",
+    "egg": "^3",
+    "egg-scripts": "^2",
+    "lodash": "^4.17.21",
+    "moment": "^2.29.1",
+    "naf-framework-mongoose-free": "^0.0.37"
+  },
+  "devDependencies": {
+    "egg-bin": "^5",
+    "egg-ci": "^2",
+    "egg-mock": "^5",
+    "eslint": "^8",
+    "eslint-config-egg": "^12",
+    "jsonwebtoken": "^8.5.1"
+  },
+  "engines": {
+    "node": ">=16.0.0"
+  },
+  "scripts": {
+    "start": "egg-scripts start --daemon --title=egg-server-service-sms",
+    "stop": "egg-scripts stop --title=egg-server-service-sms",
+    "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"
+  },
+  "ci": {
+    "version": "16, 18",
+    "type": "github"
+  },
+  "repository": {
+    "type": "git",
+    "url": ""
+  },
+  "author": "",
+  "license": "MIT"
+}

+ 9 - 0
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
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', async () => {
+    const pkg = require('../../../package.json');
+    assert(app.config.keys.startsWith(pkg.name));
+
+    // const ctx = app.mockContext({});
+    // yield ctx.service.xx();
+  });
+
+  it('should GET /', async () => {
+    return app.httpRequest()
+      .get('/')
+      .expect('hi, egg')
+      .expect(200);
+  });
+});