npm package: @jv2/egg-jv-common-server
Description: > 服务于jv项目各个子系统的一个egg的公共服务插件
Latest version: 1.0.0

## jv 账号系统公共服务插件

> 服务于jv项目各个子系统的一个egg的公共服务插件

### 目前实现功能点:

* 登录验证
* 消息推送

### 插件配置项说明：

> config.xx.js

```js

exports.jvCommon = {
    //登录验证中间件
    useMiddleAuth: true,
    port: {
        "loginUrl": "https://jv.oa.com/admin/login", //用户中心设置登录
        "logoutUrl": "https://jv.oa.com/admin/logout", //用户中心设置登出
        "mainSystemUrl": "https://jv.oa.com", //请求地址
    },
    appId: "A_v6gtjmQ4RH5i1ICRBt", //子系统的appid
    ignorePath: ['/', '/test/:id'] //中间件需要忽略的请求路由配置
}

```

### 1.  登录验证(中间件) 
useMiddleAuth 控制整个中间件是否使用
```js
//该中间件在每一次请求时验证是否登录，且登录态是否有效
详情见 /middleware/passportJvAuth.js

//可配置需要登录验证的接口规则，决定每个请求是否需要登录验证

//根据配置获取路由规则信息
let ignorePath = ctx.app.config.jvCommon.ignorePath;

let pathRegs = ignorePath.reduce((item, next) => {
    item.push(pathToRegexp(next));
    return item;
}, []);

//匹配到，则直接跳过中间件
for (let i = 0; i < pathRegs.length; i++) {
    if (pathRegs[i].exec(ctx.request.url)) {
        next();
        return;
    }
}

```

### 2. 企业微信消息推送

目前支持：1.文本消息  2.文字卡片消息  3.图片信息  4.图文消息

入参参考 [企业微信API](https://work.weixin.qq.com/api/doc#90000/90135/90236)

使用：
```js
this.ctx.sendMsg({
    "touser": "UserID1|UserID2|UserID3",
    "toparty": "PartyID1|PartyID2",
    "totag": "TagID1 | TagID2",
    "msgtype": "text",
    "agentid": 1,
    "text": {
        "content": "你的快递已到，请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>，聪明避开排队。"
    },
    "safe": 0,
    "enable_id_trans": 0,
    "enable_duplicate_check": 0,
});
```

```js
//对curl做一层封装，便于以后扩展

const httpCallSymbol = Symbol.for('context#httpCall');

module.exports = {
    initDataType(headers) {
        let contentType = headers['content-type'] || '';
        let dataType;

        if (contentType.toLowerCase().startsWith('application/json')) {
            dataType = 'json';
        } else {
            dataType = this.app.config.curl.defDataType;
        }

        return dataType;
    },

    async curlGet(url, data = {}, headers = {}) {
        if (!url) {
            return null;
        }
        let dataType = this.initDataType(headers);
        return await this[httpCallSymbol](url, 'GET', data, dataType, headers);
    },
    async curlPost(url, data = {}, headers = {}) {
        if (!url) {
            return null;
        }
        let dataType = this.initDataType(headers);
        return await this[httpCallSymbol](url, 'POST', data, dataType, headers);
    },
    async [httpCallSymbol](url, method, data, dataType, headers) {

        let host = this.app.config.jvCommon.port.main_system_url || this.app.config.jvCommon.defaultHost;

        url = `${host}${url}`;

        const result = await this.ctx.curl(url, {
            beforeRequest: options => {
                for (const header in headers) {
                    options.headers[header] = headers[header];
                }
            },
            method: method,
            data: data,
            dataType: dataType,
            timeout: this.app.config.curl.timeout //连接和返回的超时时间
        });

        if (result.status !== 200) {
            this.logger.error(`[context httpCall] error: ${JSON.stringify(result)}`);
            return null;
        }
        return result.data;
    }
};
```

### 测试方法：

#### 进入test/fixtures/apps/jv-common-server-test目录下

`执行 npm i` 和 `npm link ../../../..` ,完成后，`npm run debug` 或者 `npm run start`，项目启动后，修改项目代码，做插件测试。

关于`httpclient`请求的代理问题

在 config.xxxx.js 中配置如下：

```
exports.httpclient = {
      request: {
        enableProxy: true,
        rejectUnauthorized: false,
        proxy: process.env.http_proxy,
      },
    };
```
启动时， `http_proxy=http://127.0.0.1:8888 npm run dev ` 在前面加上需要代理到的ip即可