# Node.js 常用工具类 & 代码生成器

### 文档目录

* [代码目录说明](#代码目录说明)
* [安装配置](#安装配置)
* [代码生成器](#代码生成器)

### 代码目录结构

* constant/ # 全局常量
    * email_template.js # 邮件模板
    * errors.js # 自定义异常类
    * phone-msg-template.js # 手机验证码短信模板
    * redis_key.js # 全局redis key
    * regex.js # 正则表达式
    * response-wrapper.js # 响应体包装函数（统一返回格式）
* generator/ # 代码生成器
  ```
  npm run generate
  ```
* middlewares/ # 中间件
* test/
  ```
  npm run test
  ```
* utils/ # 工具类
    * aliyun_green/aliyun-green-util.js # 阿里云内容安全
    * oauth/ # 第三方登录oauth2.0
        * apple_oauth.js # 苹果登录（todo）
        * facebook_oauth.js # facebook登录（todo）
        * google_oauth.js # google登录（todo）
        * wechat_oauth.js # 微信登录
    * pay/ # 第三方支付
        * paypal_util.js # paypal支付
        * wxpay_util.js # 微信支付
          ```javascript
          const code = await AliyunMsgUtil.sendVcode(phone);
          ```
    * prototype/ # JavaScript扩展函数
        * date # 日期扩展函数
        * string # 字符串扩展函数
    * aes-util.js # AES加密
    * aliyun-msg-util.js # 阿里云SMS短信服务
      ```javascript
      const code = await AliyunMsgUtil.sendVcode(phone);
      ```
    * aliyun-oss-util.js # 阿里云OSS工具类
      ```javascript
      router.get('/sign', Auth(UserType.USER), async (ctx, next) => {
          // 阿里云签名直传
          const result = await AliyunOSSUtil.post(`user/${ctx.user_self.user_id}/`);
          ctx.body = SUCCESS(result);
      });
      ```
    * common-util.js # 常用函数
    * crypto-util.js # 加密工具类
    * db # sequelize初始化
      ```javascript
      global.db = db({
          ...global.config.db[getENV()],
          // 日志开关
          log_on_off: false,
      });
      ```
    * dingtalk-util.js # 钉钉群通知
      ```javascript
      await DingTalkUtil.sendText({config: "DEV_ROBOT", content: `AIGC手机验证码${phone}的：${code}`});
      ```
    * google-util.js # 谷歌登录
    * hello-world.js # 表情包ASCII图案字符串
    * logger.js # 日志
      ```javascript
      const prefix = getPrefix(__filename)
      const logger = new Logger(prefix, true)
      logger.info("hello world");
      ```
    * redis_util.js # redis
      ```javascript
      // set key value [EX seconds] [PX milliseconds] [NX|XX]
      await redisCommend("set", RedisKey.VCODE_EMAIL_USER_LOGIN(email), code, "EX", 5 * 60)
      await redisCommend("hexists", RedisKey.PAY_WXPAY_POLLING_QUERY(event, group), out_trade_no)
      ```
    * reg_util.js # 正则表达式
    * smtp_util.js # SMTP邮件发送
      ```javascript
      const code = generateCode(6);
      await SMTPUtil.send({
          to: email,
          ...EmailTemplate.VCODE(code)
      });
      ```
    * wechat_miniprogram_util.js # 微信小程序
    * wechat_offiaccount_util.js # 微信公众号
    * youdao_util.js # 有道翻译
      ```javascript
      if (isChinese(content)) {
          result = await youdaoapi({
              q: content,
              from: "zh-CHS",
              to: "en",
          });
      } else {
          if (isEnglish(content)) {
              result = await youdaoapi({
                  q: content,
                  from: "en",
                  to: "zh-CHS",
              });
          }
      }
      ```
* count.sql # api访问次数统计 数据表创建脚本
* init.js # 初始化配置

### 安装配置

#### 一、安装zckoauitls

##### 方法1（推荐）、在package.json中添加依赖

```json
{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "clean-cache": "npm cache clean --force",
    "dev-win": "set NODE_ENV=development && nodemon app.js",
    "dev-mac": "export NODE_ENV=development && nodemon app.js",
    "staging": "export NODE_ENV=test && nodemon app.js",
    "prd": "export NODE_ENV=production && pm2 start app.js",
    "migrate-dev": "cd ./db && npx sequelize-cli db:migrate",
    "migrate-prd": "cd ./db && npx sequelize-cli db:migrate --env production"
  },
  "dependencies": {
    ......
    // 避免阿里云镜像未同步，使用npmjsg官方源的绝对路径
    "zckoautils": "https://registry.npmjs.com/zckoautils/-/zckoautils-1.2.90.tgz"
  }
}
```

##### 方法2、npm install

```
npm i --registry https://registry.npmjs.org zckoautils
```

### 代码生成器

> 使用了[nunjucks](https://nunjucks.bootcss.com/templating.html)模板引擎

#### 生成逻辑

* 大小驼峰和下划线的转换
* 字符串替换
* 模板语法

#### 模板语法

```
{% if not loop.last %},{% endif %}
```

##### 循环

```

```

```
{% if not loop.last %},{% endif %}
```

#### 模板中可以拿到的数据

##### _copy 初始化直接复制的文件

##### table_level 数据表级迭代

|||
|----|----|
|||

##### database_level 数据库级迭代

* tables
    * config
* table
    * columns # 当前表的所有字段
        * COLUMN_KEY
        * COLUMN_KEY
        * COLUMN_KEY
    * columns2 # 基于columns，去掉了声明的字段如：created_at、updated_at、deleted_at
    * columns3 # 基于columns2，去掉了主键字段
* config
* primaryKey



