/**
 * 审批逻辑 success
 */

import moment = require("moment");
import { BANXUELEIXING, CERTIFICATETYPE, DOCUMENTTYPE, EDUCATION, INDIVIDUALMEMBERTYPE, LOGONSTATE, MAILTYPE, MEMBERLEVEL, MEMBERSTATE, MEMBERTYPE, MEMBERTYPEECCENUM, MSGTYPE, NATION, OPERATIONREHAVIOR, PAYMENTSTATUS, PROFCATEGORY, REGISTERFLOW, REGISTERFLOWCLIENT, SEX, STATE, UNITMEMBERTYPE, USERREGISTERSTATE } from "../../config/enum";
import { ERRORENUM } from "../../config/errorEnum";
import { addManyData, addOneData } from "../../data/add";
import { TABLEENUM } from "../../data/models/model";
import { find, findCount, findOnce, findToSortToPage } from "../../data/select";
import { updateOneData } from "../../data/update";
import { generateSystemId, getEdition, getMenberNum, getSessionByEdition, sessionToJoinTime, successResult } from "../../tools/system";
import { BizError } from "../../util/bizError";
import { extractData } from "../../util/piecemeal";
import { changeEnumValue } from "../../util/verificationEnum";
import { createOrder } from "./order";
import { getCityNameByCode } from "../../config/cityConfig";
import { sendMessage, sendPassNotice } from "../sms";
import { SessionTimeMsConfig } from "../../config/serverConfig";
import { deleteOneData } from "../../data/delete";
import { systemSendMail } from "../mail";

/**
 * 待审核列表 success 入会申请
 * @param name 名称关键字：个人会员匹配真实姓名，单位会员匹配单位名称
 * @param memberType 会员类别 unitMemberType、individualMemberType
 * 会员类别、职务、级别改成多选
 * 会员类别：个人【个人会员、专业会员】单位【院校、机构、其他】返回前端枚举：MEMBERTYPEECCENUM
 * @param documentId 身份证
 * @param phone 登录手机号
 * @param mail 单位/个人邮箱
 * @param sheng 省
 * @param shi 市
 * @param pageNumber 当前页 
 */
export async function pendingReviewList({name, memberType, documentId, phone, mail, examineState, pageNumber, pageSize}) {
    if (pageSize > 50 || pageSize < 10) throw new BizError(ERRORENUM.参数错误, "待审核页面大小错误", pageSize);
    /**查询条件 */
    let selectParam:any = {
        isAdmin:STATE.否
    }; //审批列表展示状态除通过外的数据
    if (name) {
        if (!selectParam["$and"]) selectParam["$and"] = [];
        selectParam["$and"] = [
            {"$or":[
                {unitName:{"$regex":`${name}`}},
                {name:{"$regex":`${name}`}}
            ]}
        ];
    }
    if (examineState) {
        if (examineState == 1) {
            if (!selectParam["$and"]) selectParam["$and"] = [];
            selectParam["$and"].push({"$or":[
                {userRegisterState:USERREGISTERSTATE.待审核}
            ]});
        } else {
            selectParam.userRegisterState = USERREGISTERSTATE.重新提交
        }
       
    }
    
    // 获取枚举中不能转换为数字的键 然后计算过滤后剩余键的数量
    let memberTypeLen = Object.keys(MEMBERTYPEECCENUM).filter(key => isNaN(Number(key))).length;
    /**通过获取的数量判断前端参数是否 全选 或者 全不选*/
    if (memberType.length == 0 || memberType.length == memberTypeLen) {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        selectParam["$or"].push(
            {"$or":[
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
                // { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
            ]},
            {"$or":[
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
                // { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
            ]}
        );
    } else {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        if (memberType.indexOf(MEMBERTYPE.个人会员) > -1) {
            // selectParam.memberType = MEMBERTYPE.个人会员;
            selectParam["$or"].push(
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
                // { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
            );
        }
        if (memberType.indexOf(UNITMEMBERTYPE.其他) > -1 || memberType.indexOf(UNITMEMBERTYPE.机构) > -1 || memberType.indexOf(UNITMEMBERTYPE.院校) > -1) {//单位
            // selectParam.unitMemberType = {"$in":memberType};
            selectParam["$or"].push(
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
                // { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
            );
        }
    }

    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;

    const SelectFiles = ["userId", "userRegisterState", "unitName", "name", "loginId", "phone", "askForTime", "memberLevel", "sheng", "shi", "qu", 
    "individualMemberType", "unitMemberType", "memberType", "mail", "documentId"];
    let dbList = await findToSortToPage(TABLEENUM.用户表, selectParam, SelectFiles, {askForTime:-1}, pageNumber, pageSize);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    dbList.forEach(info => {
        let item:any = extractData(info, SelectFiles);
        /**处理枚举值 */
        if (!item.userRegisterState) item.userRegisterState = USERREGISTERSTATE.待审核;
        else item.userRegisterState = changeEnumValue(USERREGISTERSTATE, item.userRegisterState);

        if (item.userRegisterState == "驳回修改") item.userRegisterState = "已驳回";
        if (item.userRegisterState == "重新提交") item.userRegisterState = "驳回提交";
        if (item.userRegisterState == "待审核") item.userRegisterState = "待审批"

        item.memberLevel = changeEnumValue(MEMBERLEVEL, item.memberLevel);
        item.sheng = getCityNameByCode(item.sheng);
        item.shi = getCityNameByCode(item.shi);
        item.qu = getCityNameByCode(item.qu);
        if(item.individualMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.individualMemberType);
        }
        if(item.unitMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.unitMemberType);
        }

        //这一行代码是兼容老用户没有 individualMemberType
        if (info.memberType == MEMBERTYPE.个人会员) {
            item.memberType = "个人会员";
        }
        item.day = moment().diff(item.askForTime, 'days') + "天";
        dataList.push(item);
    });

    return {dataList, dataCount};
}


/**
 * 入会审批-提交资料列表
 */
export async function submitDocument({name, memberType, documentId, phone, mail, pageNumber, pageSize}) {
    if (pageSize > 50 || pageSize < 10) throw new BizError(ERRORENUM.参数错误, "待审核页面大小错误", pageSize);
    /**查询条件 */
    let selectParam:any = {
        isAdmin:STATE.否,
        // logonState:LOGONSTATE.完成第一步未提交,
        // registerFlow:REGISTERFLOW.完成第一步
    };
    if (name) {
        if (!selectParam["$and"]) selectParam["$and"] = [];
        selectParam["$and"] = [
            {"$or":[
                {unitName:{"$regex":`${name}`}},
                {name:{"$regex":`${name}`}}
            ]}
        ];
    }
    
    // 获取枚举中不能转换为数字的键 然后计算过滤后剩余键的数量
    let memberTypeLen = Object.keys(MEMBERTYPEECCENUM).filter(key => isNaN(Number(key))).length;
    /**通过获取的数量判断前端参数是否 全选 或者 全不选*/
    if (memberType.length == 0 || memberType.length == memberTypeLen) {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        selectParam["$or"].push(
            {"$or":[
                { memberType:MEMBERTYPE.个人会员, registerFlow:REGISTERFLOW.完成第一步 }
            ]},
            {"$or":[
                { memberType:MEMBERTYPE.单位会员, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.单位会员, registerFlow:REGISTERFLOW.完成第二步 },
            ]}
        );
    } else {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        if (memberType.indexOf(MEMBERTYPE.个人会员) > -1) {
            // selectParam.memberType = MEMBERTYPE.个人会员;
            selectParam["$or"].push(
                { memberType:MEMBERTYPE.个人会员, registerFlow:REGISTERFLOW.完成第一步 }
            );
        }
        if (memberType.indexOf(UNITMEMBERTYPE.其他) > -1 || memberType.indexOf(UNITMEMBERTYPE.机构) > -1 || memberType.indexOf(UNITMEMBERTYPE.院校) > -1) {//单位
            // selectParam.unitMemberType = {"$in":memberType};
            selectParam["$or"].push(
                { memberType:MEMBERTYPE.单位会员, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.单位会员, registerFlow:REGISTERFLOW.完成第二步 },
            );
        }
    }

    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;

    const SelectFiles = ["userId", "userRegisterState", "unitName", "name", "loginId", "phone", "askForTime", "memberLevel", 
    "individualMemberType", "unitMemberType", "memberType", "mail", "sheng", "shi", "qu", "documentId", "registerFlow"];
    let dbList = await findToSortToPage(TABLEENUM.用户表, selectParam, SelectFiles, {askForTime:-1}, pageNumber, pageSize);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    dbList.forEach(info => {
        let item:any = extractData(info, SelectFiles);
        /**处理枚举值 */
        if (!item.userRegisterState) item.userRegisterState = USERREGISTERSTATE.待审核;
        else item.userRegisterState = changeEnumValue(USERREGISTERSTATE, item.userRegisterState);
        


        item.registerFlow = changeEnumValue(REGISTERFLOWCLIENT, item.registerFlow);
        item.memberLevel = changeEnumValue(MEMBERLEVEL, item.memberLevel);
        item.sheng = getCityNameByCode(item.sheng);
        item.shi = getCityNameByCode(item.shi);
        item.qu = getCityNameByCode(item.qu);
        item.documentId = documentId || "-"
        if(item.individualMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.individualMemberType);
        } else {
            //这一行代码是兼容老用户没有 individualMemberType
            if (info.memberType == MEMBERTYPE.个人会员) {
                item.memberType = "个人会员";
            }
        }
        if(item.unitMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.unitMemberType);
        } else {
            //这一行代码是兼容老用户没有 unitMemberType
            if (info.memberType == MEMBERTYPE.单位会员) {
                item.memberType = "单位会员";
            }
        }

        item.askForTime = item.askForTime || item.firstStep;

        item.day = moment(item.askForTime).format("YYYY-MM-DD");

        dataList.push(item);
    });

    return {dataList, dataCount};
}


// /**
//  * 入会审批-提交资料-驳回
//  */
// export async function rejectJoin({id}) {
//     let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
//     if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);

//     /**驳回修改 */
//     let updateParam = {
//         logonState:LOGONSTATE.已驳回, 
//         registerFlow:REGISTERFLOW.完成第一步,
//         firstStep:new Date().valueOf(),
//         saveUnsubmitted:STATE.否
//     }
//     await updateOneData(TABLEENUM.用户表, {userId:id}, updateParam);
    
//     return successResult();
// }


/**
 * 入会审批-提交资料-删除
 * @param param0 
 */
export async function delRejectJoin({id}) {
    let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    
    await deleteOneData(TABLEENUM.用户表, {userId:id});
    
    return successResult();
}

/**
 * 入会审批-驳回列表
 */
export async function rejectList({name, memberType, documentId, phone, mail, pageNumber, pageSize}) {
    if (pageSize > 50 || pageSize < 10) throw new BizError(ERRORENUM.参数错误, "待审核页面大小错误", pageSize);
    /**查询条件 */
    let selectParam:any = {
        isAdmin:STATE.否,
        userRegisterState : USERREGISTERSTATE.驳回修改
    };
    if (name) {
        if (!selectParam["$and"]) selectParam["$and"] = [];
        selectParam["$and"] = [
            {"$or":[
                {unitName:{"$regex":`${name}`}},
                {name:{"$regex":`${name}`}}
            ]}
        ];
    }
    
    // 获取枚举中不能转换为数字的键 然后计算过滤后剩余键的数量
    let memberTypeLen = Object.keys(MEMBERTYPEECCENUM).filter(key => isNaN(Number(key))).length;
    /**通过获取的数量判断前端参数是否 全选 或者 全不选*/
    if (memberType.length == 0 || memberType.length == memberTypeLen) {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        selectParam["$or"].push(
            {"$or":[
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
            ]},
            {"$or":[
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
            ]}
        );
    } else {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        if (memberType.indexOf(MEMBERTYPE.个人会员) > -1) {
            // selectParam.memberType = MEMBERTYPE.个人会员;
            selectParam["$or"].push(
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
            );
        }
        if (memberType.indexOf(UNITMEMBERTYPE.其他) > -1 || memberType.indexOf(UNITMEMBERTYPE.机构) > -1 || memberType.indexOf(UNITMEMBERTYPE.院校) > -1) {//单位
            // selectParam.unitMemberType = {"$in":memberType};
            selectParam["$or"].push(
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
            );
        }
    }

    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;

    const SelectFiles = ["userId", "userRegisterState", "unitName", "name", "loginId", "phone", "askForTime", "memberLevel", 
    "individualMemberType", "unitMemberType", "memberType", "mail", "sheng", "shi", "qu", "documentId"];
    let dbList = await findToSortToPage(TABLEENUM.用户表, selectParam, SelectFiles, {askForTime:-1}, pageNumber, pageSize);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    for (let i = 0; i < dbList.length; i++) {
        let info = dbList[i];
        let item:any = extractData(info, SelectFiles);
        let historyInfo = await findOnce(TABLEENUM.审批历史表, {userId:info.userId, operationBehavipr:USERREGISTERSTATE.驳回修改});

        if (historyInfo && historyInfo.userId) {
            item.operationTime = moment(historyInfo.operationTime).format("YYYY-MM-DD");
        } else item.operationTime = "-"
        
        /**处理枚举值 */
        if (!item.userRegisterState) item.userRegisterState = USERREGISTERSTATE.待审核;
        else item.userRegisterState = changeEnumValue(USERREGISTERSTATE, item.userRegisterState);
        item.memberLevel = changeEnumValue(MEMBERLEVEL, item.memberLevel);
        if(item.individualMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.individualMemberType);
        }
        if(item.unitMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.unitMemberType);
        }
        item.sheng = getCityNameByCode(item.sheng);
        item.shi = getCityNameByCode(item.shi);
        item.qu = getCityNameByCode(item.qu);

        //这一行代码是兼容老用户没有 individualMemberType
        if (info.memberType == MEMBERTYPE.个人会员) {
            item.memberType = "个人会员";
        }

        dataList.push(item);
    }

    return {dataList, dataCount};
}


/**
 * 入会审批-驳回列表-删除
 * @param param0 
 */
export async function delReject({id}) {
    let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    
    await deleteOneData(TABLEENUM.用户表, {userId:id});
    
    return successResult();
}


/**
 * 通过审核 success
 * @param id 待审核列表返回的用户id 
 * @returns 
 */
export async function adopt({id, session}) {
    let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    if (userInfo.memberType == MEMBERTYPE.个人会员 && userInfo.registerFlow != REGISTERFLOW.完成第二步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为个人会员，并没有完成第二步`);
    }
    if (userInfo.memberType == MEMBERTYPE.单位会员 && userInfo.registerFlow != REGISTERFLOW.完成第三步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为单位会员，并没有完成第三步`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.驳回修改) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}当前状态为驳回修改`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.通过) {
        throw new BizError(ERRORENUM.重复提交, `${userInfo.userId}当前状态为已通过`);
    }

    let thisDate = new Date();
    const NowMs = thisDate.valueOf();
    
    let userCount = await findCount(TABLEENUM.用户表, {isAdmin:0, memberType:userInfo.memberType,  userRegisterState:USERREGISTERSTATE.通过});

    let joinTime = await sessionToJoinTime(session, id);
    let memberNum = getMenberNum(joinTime, userInfo.sheng, userCount, userInfo.memberType);
    // getSessionByEdition(Math.floor(session/100),Math.floor(session%100));
    let updateInfo:any = {
        auditTime:NowMs,
        joinTime,
        userRegisterState:USERREGISTERSTATE.通过,
        session:session,
        paymentStatus:PAYMENTSTATUS.未支付,
        lifespanStartTime:joinTime,
        lifespanEndTime:joinTime + 1000,
        memberLevel:MEMBERLEVEL.普通会员,
        memberState:MEMBERSTATE.提醒,
        memberNum
    };
    let unitName = userInfo.unitName;
    let subType = userInfo.unitMemberType;
    if (userInfo.memberType == MEMBERTYPE.个人会员) {
        updateInfo.individualMemberType = INDIVIDUALMEMBERTYPE.普通会员;
        subType = userInfo.individualMemberType;
    }

    //创建初始订单
    //创建初始订单应该使用
    //创建今年的订单
    let thisYear = new Date().getFullYear();
    let orderStartMonthStr = moment(joinTime).format("MM-DD HH:mm:SS");
    let orderStartMs = new Date(`${thisYear}-${orderStartMonthStr}`).valueOf();
    await createOrder(id, userInfo.loginId, userInfo.phone, unitName, orderStartMs, MEMBERLEVEL.普通会员, userInfo.memberType, subType, true);

    await updateOneData(TABLEENUM.用户表, {userId:id}, updateInfo);

    /**提交审批历史信息 */
    let addApprovalHistory = {
        id:generateSystemId(TABLEENUM.审批历史表, id),
        userId:id,
        operationTime:NowMs,
        operationBehavior:OPERATIONREHAVIOR.通过,
        remarks:"通过"
    };
    await addManyData(TABLEENUM.审批历史表, addApprovalHistory);

   
    //发送邮件
    await systemSendMail(userInfo.userId, MAILTYPE.审核通过以及缴费通知 );

     //发送短信
    let smsName = userInfo.memberType == MEMBERTYPE.个人会员 ? userInfo.name : userInfo.unitName;
    sendMessage(userInfo.phone, {name:smsName}, MSGTYPE.审核通过以及缴费通知);
    

    return successResult();
}


/**
 * 批量通过
 * @param param0 
 */
export async function batchAdopt({idList, session}) {
    //限制长度
    if (idList.length > 50) throw new BizError(ERRORENUM.批量操作超过个数限制);

    let thisDate = new Date();
    const NowMs = thisDate.valueOf();

    for (let i = 0; i < idList.length; i++) {
        let id = idList[i];
        if (!id) continue;//空id跳过

        let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
        if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在, id);
        if (userInfo.memberType == MEMBERTYPE.个人会员 && userInfo.registerFlow != REGISTERFLOW.完成第二步) {
            throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为个人会员，并没有完成第二步`);
        }
        if (userInfo.memberType == MEMBERTYPE.单位会员 && userInfo.registerFlow != REGISTERFLOW.完成第三步) {
            throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为单位会员，并没有完成第三步`);
        }
        if (userInfo.userRegisterState == USERREGISTERSTATE.驳回修改) {
            throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}当前状态为驳回修改`);
        }
        if (userInfo.userRegisterState == USERREGISTERSTATE.通过) {
            throw new BizError(ERRORENUM.重复提交, `${userInfo.userId}当前状态为已通过`);
        }

        let userCount = await findCount(TABLEENUM.用户表, {isAdmin:0, memberType:userInfo.memberType,  userRegisterState:USERREGISTERSTATE.通过});
        let joinTime = await sessionToJoinTime(session, id);
        let memberNum = getMenberNum(joinTime, userInfo.sheng, userCount, userInfo.memberType);

        let updateInfo:any = {
            auditTime:NowMs,
            joinTime,
            userRegisterState:USERREGISTERSTATE.通过,
            session:session,
            paymentStatus:PAYMENTSTATUS.未支付,
            lifespanStartTime:joinTime,
            lifespanEndTime:joinTime + 1000,
            memberLevel:MEMBERLEVEL.普通会员,
            memberState:MEMBERSTATE.提醒,
            memberNum
        };
        let unitName = userInfo.unitName;
        let subType = userInfo.unitMemberType;
        if (userInfo.memberType == MEMBERTYPE.个人会员) {
            updateInfo.individualMemberType = INDIVIDUALMEMBERTYPE.普通会员;
            subType = userInfo.individualMemberType;
        }
        
        //创建初始订单
        await createOrder(id, userInfo.loginId, userInfo.phone, unitName, NowMs + 1000, MEMBERLEVEL.普通会员, userInfo.memberType, subType, true);
    
        await updateOneData(TABLEENUM.用户表, {userId:id}, updateInfo);
    
        /**提交审批历史信息 */
        let addApprovalHistory = {
            id:generateSystemId(TABLEENUM.审批历史表, id),
            userId:id,
            operationTime:NowMs,
            operationBehavior:OPERATIONREHAVIOR.通过,
            remarks:"通过"
        };
        await addManyData(TABLEENUM.审批历史表, addApprovalHistory);

    }

    return successResult();
}


/**
 * 驳回 success
 * @param userId 
 * @param remarks 驳回理由
 * @returns 
 */
export async function reject({id, remarks, rejectType}) {
    let userId = id;
    let userInfo = await findOnce(TABLEENUM.用户表, {userId, isAdmin:STATE.否});
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    if (userInfo.memberType == MEMBERTYPE.个人会员 && userInfo.registerFlow != REGISTERFLOW.完成第二步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为个人会员，并没有完成第二步`);
    }
    if (userInfo.memberType == MEMBERTYPE.单位会员 && userInfo.registerFlow != REGISTERFLOW.完成第三步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为单位会员，并没有完成第三步`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.驳回修改) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}当前状态为驳回修改`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.通过) {
        throw new BizError(ERRORENUM.重复提交, `${userInfo.userId}当前状态为已通过`);
    }

    /**驳回修改，修改该会员注册流程回到第二步 */
    let updateParam = {
        userRegisterState:USERREGISTERSTATE.驳回修改, 
        registerFlow:REGISTERFLOW.完成第一步,
        firstStep:new Date().valueOf(),
        saveUnsubmitted:STATE.否
    }
    await updateOneData(TABLEENUM.用户表, {userId}, updateParam);
    
    /**提交审批历史信息 */
    const NowMs = new Date().valueOf(); 
    let addApprovalHistory = {
        id:generateSystemId(TABLEENUM.审批历史表, userId),
        userId,
        operationTime:NowMs,
        operationBehavior:OPERATIONREHAVIOR.驳回修改,
        remarks
    };
    await addManyData(TABLEENUM.审批历史表, addApprovalHistory);

    //发送邮件
    systemSendMail(userInfo.userId, MAILTYPE.审核期间驳回通知 );

    //发短信
    let smsName = userInfo.memberType == MEMBERTYPE.个人会员 ? userInfo.name : userInfo.unitName;
    sendMessage(userInfo.phone, {name:smsName}, MSGTYPE.审核期间驳回通知, rejectType);

    return successResult();
}


/**
 * 审核历史 success
 * @param userId
 * @returns 
 */
export async function approvalHistoryList({userId}) {
    let dbList = await find(TABLEENUM.审批历史表, {userId});

    let dataList = [];
    dbList.forEach(info => {
        let item:any = extractData(info, ["operationTime", "operationBehavior", "remarks"]);
        item.operationBehavior = changeEnumValue(OPERATIONREHAVIOR, item.operationBehavior);
        dataList.push(item);
    });

    return {dataList};
}


/**
 * 导出
 * @param param0 
 * @returns 
 */
export async function outPutPendingReviewList({memberType, exportColumns}) {
    let selectParam:any = {
        isAdmin:STATE.否
    }; //审批列表展示状态除通过外的数据
    if (memberType == MEMBERTYPE.个人会员) {
        // selectParam.memberType = MEMBERTYPE.个人会员;
        selectParam["$or"] = [
            { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
            { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
            { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
        ];
    }
    else {//单位
        selectParam["$or"] = [
            { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
            { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
            { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
        ];
    }

    let selectTitle = ["序号"];
    let selectConf = [];
    exportColumns.forEach( info=> {
        if (info.key == "省市区") {
            selectTitle.push("省", "市", "区");
            selectConf.push("sheng", "shi", "qu");
        } else {
            selectTitle.push(info.key);
            selectConf.push(info.value);
        }
    })
   
    let dbList = await find(TABLEENUM.用户表, selectParam, selectConf);
    let timeChnageList = ["joinTime", "birth"];
    let addList = ["sheng", "shi", "qu"];
    
    let dataList = [selectTitle];
    dbList.forEach((info, index) => {
        let subList = [ (index+1).toString() ];
        for (let i = 0; i < selectConf.length; i++) {
            let key = selectConf[i];
            let value = info[key] || "";
            if (value) {
                if (timeChnageList.indexOf(key) != -1) value = moment(value).format("YYYY-MM-DD");
                else if (key == "isInput" || key == "isGracePeriod") value = value == true ? "是" : "否";
                else if (key == "memberState") value = changeEnumValue(MEMBERSTATE, value);
                else if (key == "certificateType") value = changeEnumValue(CERTIFICATETYPE, value);
                else if (key == "individualMemberType") value = changeEnumValue(INDIVIDUALMEMBERTYPE, value);
                else if (key == "unitMemberType") value = changeEnumValue(UNITMEMBERTYPE, value);
                else if (key == "yuanXiaoBanXueLeiXing") value = changeEnumValue(BANXUELEIXING, value);
                else if (key == "memberLevel") value = changeEnumValue(MEMBERLEVEL, value);
                else if (key == "sex") value = changeEnumValue(SEX, value);
                else if (key == "documentType") value = changeEnumValue(DOCUMENTTYPE, value);
                else if (key == "nation") value = changeEnumValue(NATION, value);
                else if (key == "education") value = changeEnumValue(EDUCATION, value);
                else if (key == "profCategory") value = changeEnumValue(PROFCATEGORY, value);
                else if (key == "session") value = getEdition(Math.floor(value/100), value%100 );
                else if (addList.indexOf(key) != -1) value = getCityNameByCode(value);
            }
            subList.push(value);
        }
        dataList.push(subList);
    });

    return {dataList};
}
