egg源码记录,

// /app/model/product.js
module.exports = app => {
    const { INTEGER, STRING, DATE, TEXT, DECIMAL, UUIT, UUIDV4 } = app.Sequelize;
    const ProductModel = app.model.define('product', {
        id: {//数据id
            type: UUID,
            defaultValue: UUIDV4,
            allowNull: false,
            primaryKey: true,
            // autoIncrement:true,
        },
        // 关联id 分类
        categoryId: {
            type: UUID,
            allowNull: false,
        },
        name: {
            type: STIRNG(50),
            allowNull: false,
        },
        subImages: {//json 格式扩展用
            type: TEXT,
            allowNull: true,
        },
        price: {    // 价格,保留两位小数
            type: DECIMAL(20, 2),
            allowNull: false,
        },
        status: {
            type: INTEGER(6),
            allowNull: true,
            defaultValue: 1,
        },
        createTime: {
            type: DATE,
            allowNull: false,
            defaultValue: new Date(),
        },
        updateTime: {
            type: DATE,
            allowNull: false,
            defaultValue: new Date(),
        }
    }, {
            // 配置
            timestamp: false,//不使用默认的 创建更新时间
            tableName: 'product',
        }, {
            indexes: [
                { field: ['categoryId'] }
            ]
        }, {
            classMethods: {
                associate() {
                    ProductModel.hasOne(app.model.CartModel, { foreignKey: 'id' })
                }
            }
        })
    // ProductModel.belongsTo(app.model.categoryModel)
    ProductModel.beforeBulkUpdate(product => {
        product.attributes.updateTime = new Date();
        return product;
    });
    return ProductModel;
}

// service.js
const productRow = await this.ProductModel.findOne({ where: { id } });
// undefined 没有返回
productRow.get('status') !== 1;//返回属性值
// asc 正序 
async productSearch({ productName, pageNum=1, pageSize=10, sortBy: 'asc' }){
    const { count, rows } = await this.ProductModel.findAndCount({
        where: { name: { $like: `%${productName}%` }, status: 1 },
        order: [['price', sortBy]],
        limit: Number(pageSize | 0),
        offset: Number(pageNum - 1 | 0) * Number(pageSize | 0),
    })
    if (rows.length < 1) //无产品数据;
        rows.forEach(row => row && row.toJSON())//数组数据
    ctx.body = rows
}
// /app/service/UserService
/**
 * 返回 undefined 
 * 或者 是数据行
 */
const question = await this.UserModel.findOne({
    attributes: ['question'],//筛选需要的字段
    where: { username },
})

/**
 * 设置redis 
 * 根据问题 回答 正确 返回有效期的token 比较用户 还有他的 缓存 判断缓存失效 相同
 * 校验这个token 来做密码修改 超时关闭
 */

await this.app.redis.set(TOKEN + username, forgetToken);
await this.app.redis.expire(TOKEN + username, 12 * 60 * 60);

// lodash 函数库  eq 判断相等 可以判断对象 全等的
_.eq(token, forgetToken)

// 密码的设置
const [rowCount] = await this.UserModel.update({
    password: md5(passwordNew + salt)
}, { where: { username }, individualHooks: true })
/**
 * 返回数组 rowCount 收影响的行数
 * 更新 返回 数组
 * 密码保密加盐
 */
if (rowCount > 0) { } //修改成功

// 判断密码
/**
 * 根据查找到结果,如果存在就是密码正确,不存在就是错误
 */
const result = await this.UserModel.findOne({
    attributes: ['username'],
    where: { id: currentUser.id, password: md5(passwordOld + salt) }
})

// 唯一字段  修改前判断是否存在 排除当前用户

const result = await this.UserModel.findOne({
    attributes: ['email'],
    where: {
        email: userInfo.email,
        id: { $not: currentUser.id }
    }
})
if (result) '邮箱已存在,不能改成这个邮箱了'

// 更新数据 会返回数据结果  这个结果包含全部字段  只有一条数据的情况
const [updateCount, [updateRow]] = await this.UserModel.update(userInfo, {
    where: { id: currentUser.id },
    individualHooks: true,
})
// pickBy 返回指定key字段的 组成的对象 
// 参数1:对象  参数2:回调函数 类似数组 
// 回调函数 参数1:对象value 参数2 :对象key
const user = _.pickBy(updateRow.toJSON(), (value, key) => {
    return ['id', 'useranme', 'email', 'phone'].find(item => key === item);
})

// 鉴权
async checkAdminRole(user){
    if (user && user.role === 1) return '成功'
    return '失败'
}

async checkAdminAndLogin(){
    const user = this.session.currentUser;
    if (!user) return '用户未登录'
    const response = await this.checkAdminRole(user);
    // 返回是否有权限
}

// /app/service/shippingservice.js
/**
 * 新建内容
 * create
 * 返回 新建的row
 */
async add(shipping){
    if (!Object.keys(shipping).every(k ==> !!shipping)) return '存在参数为空'
    const { id: userId } = this.session.currentUser
    shipping = { ...shipping, userId }
    const shippingRow = await this.ShippingModel.create(shipping)
    if (!shippingRow) return '创建失败'
    ctx.body = shippingRow.toJSON()
}

/**
 * 根据分类信息搜索产品
 * 数组 分页 findAndCount
 * 
 */

async getProductListByCategoryId({ categoryName, categoryId, pageNum=1, pageSize=10, sortBy='asc' }){
    const { data: categoryIdArr } = await this.ctx.service.categoryManageService.getCategoryAndDeepChildCategory(categoryId);
    const { count, rows } = await this.ProductModel.findAndCount({
        where: { categoryId: { $in: categoryIdArr }, status: ON_SALE.CODE },
        order: [['price', sortBy]],
        limit: Number(pageSize | 0),
        offset: Number(pageNum - 1 | 0) * Number(pageSize | 0),
    });
    if (rows.length < 1) this.ServerResponse.createBySuccessMsg('无产品数据');
    rows.forEach(row => row && row.toJSON());
}


//  多张图片处理

const subImgArr = product.subImages.split(',');
if (subImgArr.length > 0) product.mainImage = subImgArr[0];

// 如果有id就更新 没有就添加  
// 先findOne 再 create 或者 update
// resultRow undefinde 表示没有 如果有返回数据内容
const resultRow = await this.ProductModel.findOne({
    where: { id: product.id }
})

if (!resultRow) {
    // todo 添加
    productRow = await this.ProductModel.create(product);
    addOrUpdate = '添加'
    if (!productRow) return '添加失败'
} else {
    // 更新
    const [updateCount, [updateRow]] = await this.ProductModel.update(product, {
        where: { id: product.id },
        individualHooks: true
    })
    addOrUpdate = '更新'
    if (updateCount < 1) '更新'
}

// 属性排除 
async getProductList({ pageNum=1, pageSize=10 }){
    const { count, rows } = await this.ProductModel.findAndCount({
        // attributes:{exclude:['createTime','updateTime']}
        order: [['id', 'ASC']],
        limit: Number(pageSize | 0),
        offset: Number(pageNum - 1 | 0) * Number(pageSize | 0),
    })
    rows.forEach(row => row && row.toJSON());
}

// 订单服务
// 支付宝 common/alipayConfig.js
module.exports = {
    /* 更多参数请翻源码 */
    /* 应用AppID */
    appid: 2016091200492877,

    /* 通知URL */
    notifyUrl: 'http://9bqaiq.natappfree.cc/order/alipaycallback',

    /* 应用RSA私钥 请勿忘记 -----BEGIN RSA PRIVATE KEY----- 与 -----END RSA PRIVATE KEY-----  */
    merchantPrivateKey: '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEApsBXKCC0pZmKAAosGCgPfrWKpmyCG32LzZO3XJhuROpgfLYBCPF2t1k3i3o7E6ViCT7nlhZu8/vDszdCyIJhD2fLZEKy0knPTykzpGtp4S7H4wiDuPsQRsJ2qktd8knNzEthN/CXQu+AUj3ggrnkiqDxQ5EbdXQ4sK1VlgJ6t+gWLfepXC4KwtkVwJVIt3s67xghRiOpl2Y+AZL1HIfZvLQJUWzP92Ts/pNnvgotaywKM535kK8CcFrehmXObvYQ7zSauZTcWNcWI1qaKkjG1LGvCU2J4VQU43B2NY9blTpyuL9qxJ9hexP/fAAXToslf2aPAmdeSvvB5xoDZf2X6QIDAQABAoIBAEPoNlY4I3kA8wsbGWPpBI5kXgdyTvXlBcb9bgG+bcGQ9SQ0dm1u8BqwsYcSivZwNmFvhZ5AmoSvtb3JNmAzgFVmvpSg+PPcbRlevRIrUB4NEAfsEsCFNdarIOou8R5XYgDdfcTrLJ5srIRRgJmcHG88JaSPdnA5mVCR9jW14sX7jKrF+mE9zuVlxzEQFBEIKu9pGsqdutsvhfPwZH2kp1ji6Ltd1OxPgymFu3MQW+I7agZB8lqvOQql3/EbOaw6vy1uaqR4qSD6la2ckVlLxdyeDjBZZOKsR0R8SOkzJi9BBDnmx12aDatW4DwZI4uwOBJL4lhJN5ys/+D34wCI5oUCgYEA0InpKu3eoo6h+ghMeGRJ5buKbWjfmI8yUl39eOQ/ip3rO75N/TAFDKSCo3TtaA3ftfhn13MU6EEjDhoyix3NhLGndLHfrrtMM7umYq5P8AafEDjHiHqqo12Wvtg2pw943AFGg8V1EV+luB1m/qbWnA4tRQk1INbQ+A+ulyudrqsCgYEAzLPFi6WCmRoSGMlHX60E7B2nmVXrEVb80qg2qh34ZgLXLOqLt9pQgWkCw0LersKWIwIrFkhd9CTZk7ccpbAYfKlPuIxo4L+zxzqq1g9Z90A3yoVxCQG+RKdl2eGoUwuIj1TnubCy8DPxTyOm3TwJo50i4D/HNEtixXyujqZJA7sCgYBxoeRjFxDMpUoP03vP0l4OB74rVg0YtVanWT3oJP+WyexHNrCKeSMXO4FQDkPbAkxXfM8gsD3BPNUcNxw5f/jgCGoGBXKsZLTmL6c/eFpooUMFdNsNPEJFGJcu0OQe7iheQXeqD+t1lxfXFnZr5n9ks7jpOFYx2bwun2T0TLj0VwKBgC2tb8dZh2rihmdBgsu2sAKAG4X7xhh4cLIRFyGezm70807yh3rfHFfENvmbUlVs1lO5iCPQwiZYkrSDh8DxKoWmwkNMEZsVK+ipDrX1dv3VNp3aaP65hNuM/w0/bXAagr55E7w70bIH5TDjo7h6TSxVRBMGKE1jBQdMaycps+FBAoGAKe7TNAohYjde+Hc6DMad7FPX1vZnMad8khWmw2vE+KAJe2I5VflBMPk6OekUa3l8GLbecIl9+dICbyqpVo9u3c4JI9MkwJGzx6qdEmqT6cumgBay6CE7eX/wIkZQ+/VZVEt2zgrReMNx1NtbHxp8ushGpblQcUKdwqn063gmnOg=\n-----END RSA PRIVATE KEY-----',

    /* 支付宝公钥 如果为空会使用默认值 请勿忘记 -----BEGIN PUBLIC KEY----- 与 -----END PUBLIC KEY----- */
    alipayPublicKey: '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs1qN9Jc9Sf+wnRxVHcHruXQq/YjWIe47Ay1e0ujNb8Ga+GS5Vlvg9UoISI1J8GUbNQR7gK2j81h6icbBVbMc4s5ZvPJTIOD0xODxdRH3daY04mkfYnshbu+ri5GhwrlGS9wAFKa57Ksb8P+EUZumNQL7rIJwFlW1UEiF/x252xG+1zplTnLnKkf1ERcPb4fo/kdtBD53bW5TFsY7IJ4NPqj9AnnfDdpFTZsXZ3ixPVz8uY8J5qganVXEieKpH1OSR9us9Egsh2OfR8AvLl1u2Py/qBecvXbggqPEzbNWLbNyJY0iK/KPXiDYiOV+MN/HHgCRXAEqR3g7Whh6ARswZwIDAQAB\n-----END PUBLIC KEY-----',

    /* 支付宝支付网关 如果为空会使用沙盒网关 */
    gatewayUrl: 'https://openapi.alipaydev.com/gateway.do',
};

const alipayftof = require('alipay-ftof');
const alipayf2f = new alipayftof(alipayf2fConfig);
const Alipay = require('alipay-mobile');
const alipayService = new Alipay(options);

this.ProductModel.hasOne(this.CartModel, { foreignKey: 'id' })
this.ProductModel.belongsTo(this.ProductModel, { foreignKey: 'productId' })

this.OrderItemModel.hasMany(this.OrderModel, { foreignKey: 'orderNum', targetKey: 'orderNum' })
this.OrderModel.belongsTo(this.OrderItemModel, { foreignKey: 'orderNum', targetKey: 'orderNum' })

this.ShippingModel.hasOne(this.OrderModel, { foreginKey: 'id' })
this.OrderModel.belongsTo(this.ShippingModel, { foreginKey: 'shippingId' })

module.exports = {
    CANCELED: { CODE: 0, VALUE: '已取消' },
    NO_PAY: { CODE: 10, VALUE: '未支付' },
    PAID: { CODE: 20, VALUE: '已支付' },
    SHIPPED: { CODE: 40, VALUE: '已发货' },
    ORDER_SUCCESS: { CODE: 50, VALUE: '订单已完成' },
    ORDER_CLOSE: { CODE: 60, VALUE: '订单关闭' },
};

// 生产支付二维码
async pay(orderNum){
    const { id: userId } = this.session.currentUser;
    const order = await this.OrderModel.findOne({ where: { userId, orderNum } })
        .then(row => row && row.toJSON())
    if (order.status >= OrderStus.PAID.CODE) '该订单不可支付'

    const result = await alipayf2f.createQRPay(this.alipayData(order))
    const { filename, url } = this.saveQrcode(result)
}
/**
 * 返回对象 第一个匹配的 key
 * 可以回调函数判断 类似数组
 */
_getEnumValueByCode(mapper, code){
    return mapper[_.findKey(mapper, item => item.CODE === code)].VALUE
}

// 连表查询  例子:https://www.jb51.net/article/106782.htm
/* 'use strict'  https://blog.csdn.net/huwei2003/article/details/77646054

const Sequelize = require('sequelize');

// 创建 sequelize 实例
const sequelize = new Sequelize('db1', 'root', '111111', { logging: console.log });

// 定义User模型
var User = sequelize.define('user', {
    id: { type: Sequelize.BIGINT(11), autoIncrement: true, primaryKey: true, unique: true },
    name: { type: Sequelize.STRING, comment: '姓名' },
    sex: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 0, comment: '性别' },
    companyId: { type: Sequelize.BIGINT(11), field: 'company_id', allowNull: false, comment: '所属公司' },
    isManager: { type: Sequelize.BOOLEAN, field: 'is_manager', allowNull: false, defaultValue: false, comment: '是否管理员' }
},
    {
        charset: 'utf8',
        collate: 'utf8_general_ci'
    });

// 定义Company模型
var Company = sequelize.define('company', {
    id: { type: Sequelize.BIGINT(11), autoIncrement: true, primaryKey: true, unique: true },
    name: { type: Sequelize.STRING, comment: '公司名称' }
},
    {
        charset: 'utf8',
        collate: 'utf8_general_ci'
    });

// 定义User-Company关联关系
User.belongsTo(Company, { foreignKey: 'companyId' });

// sequelize.sync({force:true}).then(() => {
// process.exit();
// });


Company.create({ name: '某公司' }).then((result) => {
    return Promise.all([
        User.create({ name: '何民三', sex: 1, companyId: result.id, isManager: true }),
        User.create({ name: '张老二', sex: 1, companyId: result.id })
    ])
}).then((result) => {
    console.log('done');
}).catch((err) => {
    console.error(err);
});


var include = [{
    model: Company,
    as: 'company'
}];
User.findOne({ include: include }).then((result) => {
    console.log(result.name + ' 是 ' + result.company.name + ' 的员工');
}).catch((err) => {
    console.error(err);
});
何民三 是 某公司 的员工

var include = [{
    association: Company.hasOne(User, { foreignKey: 'companyId', as: 'manager' }),
    where: { isManager: true }
}]

Company.findOne({ include: include }).then((result) => {
    console.log(result.name + ' 的管理员是 ' + result.manager.name);
}).catch((err) => {
    console.error(err);
});

某公司 的管理员是 何民三 */


async _getCartListWithProduct(userId){
    const arr = await this.CartModel.findAll({
        where: { userId, checked: CHECKED },
        include: [{ model: this.ProductModel, where: { id: app.Sequelize.col('productId'), status: ON_SALE.CODE } }]
    // 返回处理好的数组?
    }).then(rows => rows && rows.map(r => r.toJSON()))
    
    /* 
    估计返回
        商品,
        数量,
        用户,
        选择,
        product:商品表具体内容
    */
    if(arr.length === 0) '购无车为空'
    // 检测是否有货
    if(!this._ckeckStock(arr).hasStock) '库存不足'
}
 // 检查库存
 /* 
 存在无库存的情况就push到数组里面

 
 */
 _checkStock(list) {
    let arr = []
    list.forEach(item => {
        // 商品库存 小于 购物车下单量
      if (item.product.stock < item.quantity) {
        arr.push(item.product.name)
      }
    })
    return { hasStock : arr.length === 0, noStockList: arr }
  }

  const orderNum = Date.now() + _.random(100)
//   整数 获取整数100 内随机  创建订单号

//   创建订单
// 1.拿到收货地址
const shipping= await this.ShippingModel.findOne({where:{id:shippingId,userId}}).then(r=>r&&r.toJSON())
if(!shipping) reutn '用户无收货地址'
// 2.购物车获取数据 判断有没有货
_getCartListWithProduct
// 3. 创建支付订单 用户,收货地址 支付总价
// 4. 更新库存
await this.ProductModel.update({ stock: app.Sequelize.literal(`stock - ${item.quantity}`) }, { where: { id: item.productId }})
await this.ProductModel.update({stock:app.Sequelize.literal(`stock-${item.quantity}`)},{where:{id:item.productId}})
// 清空购物车 这个逻辑不好 不能做在下一单
   // 清空购物车
   async _cleanCart(cartList) {
    cartList.forEach(async item => {
      await this.CartModel.destroy({ where: { id: item.id } })
    })
  }


  /model/CategoryModel.js
      // 父类别id 为0时为根节点,一级类别
      parentId: {
        type: UUID,
        allowNull: true,
      },

          // 类别状态1-正常,2-废弃
    status: {
        type: INTEGER(1),
        allowNull: true,
        defaultValue: 1,
      },
      // 排序编号,同类展示顺序,相等则自然排序
      sortOrder: {
        type: INTEGER(4),
        allowNull: true,
      },

// 返回去重后的数组
      const categoryUniqList = _.uniqWith(categoryList, _.isEqual);

    //   /router.js
      module.exports=app=>{
          const {router,controller}=app;
          router.get('/',controller.home.index)
          require('./router/portal/cartRouter')(app)//路由分文件夹
      }

    // /router/portal/cartRouter.js
    module.exports=app=>{
        const checkLogin=app.middleware.checkLogin();//登录中间件
    }
// 购物车更新 需要权限 使用中间件
    app.router.post('/cart/update',checkLogin,app.controller.portal.cartController.addOrUpdate)

    // /server.js
    cosnt egg=require('egg');
    const workers =Number(process.argv[2]||require('os').cpus().length)
    egg.startCluster({
        workers,
        baseDir:__dirname,
    })


    // app.js
    module.exports = app => {
        app.beforeStart(async function() {
          // 应用会等待这个函数执行完成才启动
          // await app.model.sync({ force: true }); // 开发环境使用
      
          /* egg-sequelize
          We strongly recommend you to use migrations to create or migrate database.
      
          This code should only be used in development.
      
          if (app.config.env === 'local') {
            app.beforeStart(function* () {
              yield app.model.sync({force: true});
            });
          }
          同步数据  迁移
          */
          await app.model.sync({});
        });
      };

      exports.relativeTime = time => moment(new Date(time * 1000)).fromNow();//a minute ago
    //   返回日期距离当前的一个 描述

// 封装响应
    const ServerResponse = require('../common/serverResponse');
    const ResponseCode = require('../common/responseCode');
// 定义返回错误标志
    module.exports = {
        SUCCESS: 0,
        ERROR: 1,
        NEED_LOGIN: 10,
        NO_AUTH: 20,
        ILLEGAL_ARGUMENT: 2,
      };
      
// server 返回一个对象 调用serverResponse类 返回 对象
module.exports = class ServerResponse {
    constructor(status, msg, data) {
      this.status = status;
      this.msg = msg;
      this.data = data;
    }

    // 这个返回结果类可以拿到 数据 提示 和code 统一定义返回
}  
      if (!productId || !count) 
      return this.ServerResponse
      .createByErrorMsg(this.ResponseCode.ILLEGAL_ARGUMENT, 'ILLEGAL_ARGUMENT');


      static createByErrorCodeMsg(errorCode, errorMsg) {
        return new ServerResponse(errorCode, errorMsg, null);
      }

      

猜你喜欢

转载自blog.csdn.net/qq_33269443/article/details/81005650
egg
今日推荐