Node+TS+Koa+vue 商城全栈(七)创建模板文件

1.模板入口文件

app/models/index.ts

'use strict';

// const fs = require('fs');
import * as fs from 'fs';
// const path = require('path');
import * as path from 'path';
// const Sequelize = require('sequelize');
import * as Sequelize from 'sequelize';

// ts默认不能把json文件作为模块去处理(加载),写一个声明文件
import configs = require('../config/config.json');

const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';

let config: IConf = configs;
config = config[env];
let db: IDB = {};

// 根据配置文件 configs 创建数据库实例
let sequelize: Sequelize.Sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

// 通过fs模块自动过去加载模型文件所在的目录下的所有的模型文件,比如user.ts,user-profile.ts
fs
  .readdirSync(__dirname)
  .filter((file) => {
    // basename => index.js
    // 对加载的文件进行过滤,过滤出来除了index.ts,已 .js 结尾的(编译后要加载的)
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach((file) => {
    // 通过上面的过滤,找出来了所有的模型文件,调用sequelize['import']加载并实例化
    const model = sequelize['import'](path.join(__dirname, file));
    // 把实例化每一个模型对象保存到一个db对象下,这个对象的结构如下
    /**
      db = {
        user: new User(),
        'user-profile': new UserProfile()
        ....
      }
     */
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

// db.sequelize = sequelize;
// db.Sequelize = Sequelize;

// module.exports = db;


export default db;

2.用户模板(示例)

app/models/user.ts

import { Sequelize, DataTypes, Models, Model } from "sequelize";
import * as md5 from "md5";

'use strict';
module.exports = (sequelize: Sequelize, DataTypes: DataTypes) => {
  const User = sequelize.define('user', {
    id: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER
    },
    username: {
      type: DataTypes.STRING(50),
      unique: true,
      allowNull: false,
      defaultValue: ''
    },
    password: {
      type: DataTypes.CHAR(32),
      allowNull: false,
      defaultValue: '',
      set(val: string) {
        return md5(val)
      }
    },
    disabled: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
      defaultValue: false
    },
    mobile: {
      type: DataTypes.CHAR(12),
      unique: true,
      allowNull: false,
      defaultValue: ''
    },
    email: {
      type: DataTypes.STRING(50),
      unique: true,
      allowNull: false,
      defaultValue: ''
    },
    createdIpAt: {
      type: DataTypes.CHAR(15),
      allowNull: false,
      field: 'created_ip_at',
      defaultValue: ''
    },
    updatedIpAt: {
      type: DataTypes.CHAR(15),
      allowNull: false,
      field: 'updated_ip_at',
      defaultValue: ''
    },
    createdAt: {
      allowNull: false,
      type: DataTypes.DATE,
      field: 'created_at'
    },
    updatedAt: {
      allowNull: false,
      type: DataTypes.DATE,
      field: 'updated_at'
    }
  }, {
    tableName: 'user',
    charset: 'utf8mb4',
    collate: 'utf8mb4_bin',
    indexes: [
      {
        
      }
    ],
    defaultScope: {
      attributes: {
        exclude: ['password']
      }
    },
    scopes: {
      zmouse: {
        limit: 1
      }
    }
  });
  User.associate = function(this: Model<any, any>, models: Models) {
    // associations can be defined here
    // 基本资料
    this.hasOne( models['user-profile'] );

    // // 登录日志
    this.hasMany( models['login-log'] );

    // // 我的收藏
    this.hasMany( models['favorite'] );

    // // 食谱
    this.hasMany( models['cookbook'] );

    // // 评论
    this.hasMany( models['comment'] );
  };
  return User;
};

3.项目入口文件

app/index.ts

通过中间件,把db对象等其他一些数据挂在到当前的state下面

// import Koa from 'koa'; // 错误的写法
// import Koa = require('koa');
import * as Koa from 'koa';
import { useControllers } from 'koa-controllers';
import db from './models';

let app = new Koa();

// 中间件
app.use(async (ctx: Koa.Context, next) => {
  // 把db对象等其他一些数据挂在到当前的state下面
  ctx.state.db = db;

  await next();
});

useControllers(app, __dirname + '/controllers/**/*.controller.js', {
  multipart: {
    dest: './uploads'
  }
})

app.listen(8000);

4.控制器文件

app/controllers/main.controller.ts

调用模板文件

/**
 * 控制器是通过 class 来实现的
 * 但是并不是随便一个 class 他就能成为控制器
 * 类似继承的概念,koa-controllers 为我们提供了一个装饰器:Controller
 * 通过这个装饰器我们就可以把一个普通的类变成 具有 控制器特征的控制器类
 */
import { Controller, Get, Ctx, Post } from 'koa-controllers';
import { Context } from 'koa';
import { Model } from 'sequelize';

@Controller
class MainController {
  @Get('/')
  public async index(@Ctx ctx: Context) {
    /**
     * 我们希望用户在通过get方式访问 / 的时候执行该方法,我们就可以使用
     * Get,Post 装饰器来装饰该方法 
     */
    // console.log(ctx);
    ctx.body = 'hello';
  }

  @Post('/')
  public async indexPost(@Ctx ctx: Context) {
    ctx.body = 'hello post - zMouse';
  }

  // 查询用户信息
  @Get('/user')
  public async user(@Ctx ctx: Context) {
    // let userList = await (<Model<any, any>>ctx.state.db['user']).findAll();

    // 通过自定义作用域查找
    let userList = await (<Model<any, any>>ctx.state.db['user']).scope('zmouse').findAll();
    ctx.body = userList;
  }
}

.

原文地址:https://www.cnblogs.com/crazycode2/p/12247052.html