const system=require("../system");
class Dao{
  constructor(modelName){
    this.modelName=modelName;
    var db=system.getObject("db.connection").getCon();
    this.db=db;
    console.log("........set dao model..........");
    this.model=db.models[this.modelName];
  }
  preCreate(u){
    return u;
  }
  async create(u,t){
      var u2=this.preCreate(u);
      if(t){
        return this.model.create(u2,{transaction: t}).then(u=>{
          return u;
        });
      }else{
        return this.model.create(u2,{transaction: t}).then(u=>{
          return u;
        });
      }
  }
   //批量插入
   async bulkCreate(objs) {
    if (!objs || objs.length == 0) {
      return;
    }
    return await this.model.bulkCreate(objs);
  }
  static getModelName(ClassObj){
    return ClassObj["name"].substring(0,ClassObj["name"].lastIndexOf("Dao")).toLowerCase()
  }
  async refQuery(qobj){
    var w =qobj.refwhere? qobj.refwhere:{};

    if(qobj.levelinfo){
      w[qobj.levelinfo.levelfield]=qobj.levelinfo.level;
    }
    if(qobj.parentinfo){
      w[qobj.parentinfo.parentfield]=qobj.parentinfo.parentcode;
    }
    if(qobj.likestr){
      w[qobj.fields[0]]={[this.db.Op.like]:"%"+qobj.likestr+"%"};
      return this.model.findAll({where:w,attributes:qobj.fields});
    }else{
      return this.model.findAll({where:w,attributes:qobj.fields});
    }
  }
  async bulkDelete(ids){
    var en= await this.model.destroy({where:{id:{[this.db.Op.in]:ids}}});
    return en;
  }
  async delete(qobj){
    var en= await this.model.findOne({where:qobj});
    if(en!=null){
      return en.destroy();
    }
    return null;
  }
  extraModelFilter(){
    //return {"key":"include","value":{model:this.db.models.app}};
    return null;
  }
  extraWhere(obj,where){
    return where;
  }
  orderBy(){
    //return {"key":"include","value":{model:this.db.models.app}};
    return [["created_at","DESC"]];
  }
  buildQuery(qobj){
    var linkAttrs=[];
    const pageNo=qobj.pageInfo.pageNo;
    const pageSize=qobj.pageInfo.pageSize;
    const search=qobj.search;
    const raw = qobj.raw;
    var qc={};
    //设置分页查询条件
    qc.limit=pageSize;
    qc.offset=(pageNo-1)*pageSize;
    if(qobj.distinct) {
      qc.distinct = true;
    }
    //默认的查询排序
    qc.order=this.orderBy();
    //构造where条件
    qc.where= qobj.customizedWhereObj || {};
    if(search){
      Object.keys(search).forEach(k=>{
        console.log(search[k],":search[k]search[k]search[k]");
        if(search[k] && search[k]!='undefined' && search[k]!=""){
          if((k.indexOf("Date")>=0 || k.indexOf("_at")>=0 )){
            if(search[k]!="" && search[k]){
              var stdate=new Date(search[k][0]);
              var enddate=new Date(search[k][1]);
              qc.where[k]={[this.db.Op.between]:[stdate,enddate]};
            }
          }
          else if (k.indexOf("id")>=0) {
            qc.where[k]=search[k];
          }
          else if (k.indexOf("channelCode")>=0) {
            qc.where[k]=search[k];
          }
          else if (k.indexOf("Type")>=0) {
            qc.where[k]=search[k];
          }
          else if (k.indexOf("Status")>=0) {
            qc.where[k]=search[k];
          }
          else if (k.indexOf("status")>=0) {
            qc.where[k]=search[k];
          }
          else if (k.indexOf("pcode")>=0 || k.indexOf("ccode")) {
            qc.where[k]=search[k];
          }
          else{
            if(k.indexOf("~")>=0){
              linkAttrs.push(k);
            }else{
              qc.where[k]={[this.db.Op.like]:"%"+search[k]+"%"};
            }
          }
        }
      });
    }
    this.extraWhere(qobj,qc.where,qc,linkAttrs);
    var extraFilter=this.extraModelFilter(qobj);
    if(extraFilter){
       qc[extraFilter.key]=extraFilter.value;
    }
    if(raw) {
      qc.raw = true;
    }
    console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm");
    console.log(qc);
    return qc;
  }
  async findAndCountAll(qobj,t){
    var qc=this.buildQuery(qobj);
    var apps=  await this.model.findAndCountAll(qc);
    return apps;
  }
  preUpdate(obj){
    return obj;
  }
  async update(obj,tm){
    var obj2=this.preUpdate(obj);
    if(tm!=null && tm!='undefined'){
      return this.model.update(obj2,{where:{id:obj2.id},transaction:tm});
    }else {
      return this.model.update(obj2,{where:{id:obj2.id}});
    }
  }
  async updateByWhere(setObj,whereObj,t){
    if(t&&t!='undefined'){
      if(whereObj&&whereObj!='undefined'){
        whereObj.transaction=t;
      } else {
        whereObj={transaction: t};
      }
    }
    return this.model.update(setObj,whereObj);
  }
  async customExecAddOrPutSql(sql,paras, t){
    paras = paras || {};
    if(t) {
      params.transaction = t; 
    }
    return this.db.query(sql,paras);
  }
  async customQuery(sql,paras,t){
    var tmpParas=null;//||paras=='undefined'?{type: this.db.QueryTypes.SELECT }:{ replacements: paras, type: this.db.QueryTypes.SELECT };
    if(t&&t!='undefined'){
      if(paras==null||paras=='undefined'){
        tmpParas={type: this.db.QueryTypes.SELECT };
        tmpParas.transaction=t;
      }else {
        tmpParas={replacements: paras, type: this.db.QueryTypes.SELECT };
        tmpParas.transaction=t;
      }
    }else {
      tmpParas=paras==null||paras=='undefined'?{type: this.db.QueryTypes.SELECT }:{ replacements: paras, type: this.db.QueryTypes.SELECT };
    }
    return this.db.query(sql,tmpParas);
  }
  async customUpdate(sql, paras, t) {
    var tmpParas = null;
    if (t && t != 'undefined') {
      if (paras == null || paras == 'undefined') {
        tmpParas = {
          type: this.db.QueryTypes.UPDATE
        };
        tmpParas.transaction = t;
      } else {
        tmpParas = {
          replacements: paras,
          type: this.db.QueryTypes.UPDATE
        };
        tmpParas.transaction = t;
      }
    } else {
      tmpParas = paras == null || paras == 'undefined' ? {
        type: this.db.QueryTypes.UPDATE
      } : {
        replacements: paras,
        type: this.db.QueryTypes.UPDATE
      };
    }
    return this.db.query(sql, tmpParas);
  }
  async findCount(whereObj=null){
    return this.model.count(whereObj, {logging : false}).then(c=>{
      return c;
    });
  }
  async findSum(fieldName,whereObj=null){
    return this.model.sum(fieldName,whereObj);
  }
  async getPageList(pageIndex,pageSize,whereObj=null,orderObj=null,attributesObj=null,includeObj=null){
    var tmpWhere={};
    tmpWhere.limit=pageSize;
    tmpWhere.offset= (pageIndex - 1) * pageSize;
    if(whereObj!=null){
      tmpWhere.where=whereObj;
    }
    if(orderObj!=null&&orderObj.length>0){
      tmpWhere.order=orderObj;
    }
    if(attributesObj!=null&&attributesObj.length>0){
      tmpWhere.attributes=attributesObj;
    }
    if(includeObj!=null&&includeObj.length>0){
      tmpWhere.include=includeObj;
      tmpWhere.distinct=true;
    }
    tmpWhere.raw=true;
    return await this.model.findAndCountAll(tmpWhere);
  }
  async findOne(obj){
    return this.model.findOne({"where":obj});
  }
  async findById(oid){
    return this.model.findById(oid);
  }
}
module.exports=Dao;
