// 引入Node.js的path模块，用于处理文件路径相关操作，通过 `path.join` 方法将当前工作目录（`process.cwd()`）与相对路径拼接起来，
// 从而准确地引入自定义的 `dao/ManagerDAO` 模块所在的路径，该模块大概率封装了与管理员数据操作相关的数据库访问方法，比如查询、计数等操作。
var path = require("path");
// 引入自定义的 `ManagerDAO` 模块，用于执行与管理员数据相关的数据库操作，例如按照特定条件查询管理员信息、统计符合条件的管理员数量等，它是获取管理员数据的关键模块。
var managersDAO = require(path.join(process.cwd(), "dao/ManagerDAO"));
// 引入 `node-php-password` 库，可能用于密码相关的处理操作（虽然从当前代码来看暂未体现其具体使用场景，但可能在涉及管理员密码验证、加密等功能时会用到）。
var Password = require("node-php-password");
// 引入日志记录模块，通过调用 `../modules/logger` 模块中导出的 `logger` 函数来获取一个日志记录器对象，用于记录在获取管理员相关操作过程中的各种日志信息，方便调试和排查问题。
var logger = require('../modules/logger').logger();

/**
 * 获取所有管理员
 * 此函数用于根据传入的查询条件获取符合要求的管理员信息，并通过回调函数将查询结果（包含管理员列表以及相关统计信息）或错误信息返回给调用者，
 * 常用于管理员列表展示等业务场景中，根据不同的筛选条件展示相应的管理员数据。
 * 
 * @param  {[type]}   conditions 查询条件，它是一个对象，包含了用于筛选管理员信息的相关参数，遵循特定的规范格式，具体如下：
 * 查询条件统一规范
 * conditions
 * {
 *     "query" : 关键词查询，用于进行模糊搜索等操作，比如根据管理员姓名、手机号等关键信息来筛选管理员，该字段可以为空字符串，表示不进行关键词查询；
 *     "pagenum" : 页数，用于分页查询，指定要获取的是第几页的数据，必须是合法的正整数，否则会被判定为参数不合法；
 *     "pagesize" : 每页长度，用于分页查询，指定每页显示的管理员记录数量，同样必须是合法的正整数，否则会被判定为参数不合法；
 * }
 * @param  {Function} cb         回调函数，用于接收获取管理员操作的结果，若成功获取到管理员数据，则传递包含管理员列表以及相关统计信息（如总记录数、当前页码等）的对象作为参数；若出现错误情况（如参数不合法、数据库查询失败等），则传递相应的错误信息字符串作为参数。
 */
module.exports.getAllManagers = function (conditions, cb) {
    // 首先验证传入的查询条件（`conditions`）中的 `pagenum` 参数是否存在，如果不存在，说明页码参数不符合要求，直接通过回调函数 `cb` 返回错误信息，表示 `pagenum` 参数不合法，
    // 因为分页查询需要明确的页码信息，页码通常为正整数，若不传该参数则无法正确进行分页操作，告知调用者参数不符合要求。
    if (!conditions.pagenum) return cb("pagenum 参数不合法");
    // 同样验证 `conditions` 中的 `pagesize` 参数是否存在，如果不存在，说明每页显示记录数参数不符合要求，直接通过回调函数 `cb` 返回错误信息，表示 `pagesize` 参数不合法，
    // 因为分页查询需要明确每页显示多少条记录，该参数通常为正整数，若不传则无法正确进行分页操作，告知调用者参数不符合要求。
    if (!conditions.pagesize) return cb("pagesize 参数不合法");

    // 通过关键词获取管理员数量
    // 调用 `managersDAO` 模块的 `countByKey` 方法，传入 `conditions["query"]`（即关键词查询参数，可能用于在数据库中进行模糊查询等操作来统计符合该关键词的管理员数量），
    // 该方法是一个异步操作，通过回调函数来处理查询统计的结果情况，若成功则返回符合条件的管理员记录总数（`count`），用于后续的分页计算等操作。
    managersDAO.countByKey(conditions["query"], function (err, count) {
        // 获取查询条件中的关键词（`key`），赋值为 `conditions["query"]`，方便后续在查询管理员记录等操作中使用该关键词进行筛选，它可能是用于模糊匹配管理员的某些关键信息（如姓名、手机号等）的字符串。
        key = conditions["query"];
        // 将查询条件中的 `pagenum` 参数转换为整数类型，赋值给 `pagenum` 变量，确保页码参数是合法的数字格式，用于后续的分页相关计算和操作，例如计算偏移量等。
        pagenum = parseInt(conditions["pagenum"]);
        // 将查询条件中的 `pagesize` 参数转换为整数类型，赋值给 `pagesize` 变量，同样确保每页记录数参数是合法的数字格式，用于分页操作中的相关计算，如计算总页数、限制查询记录数量等。
        pagesize = parseInt(conditions["pagesize"]);

        // 计算总页数，通过将符合关键词条件的管理员记录总数（`count`）除以每页显示记录数（`pagesize`），然后使用 `Math.ceil` 函数向上取整，得到总共需要的页数，
        // 该总页数可用于判断传入的页码是否超出合理范围等情况，确保分页查询的完整性和正确性。
        pageCount = Math.ceil(count / pagesize);

        // 计算分页查询的偏移量（`offset`），通过公式 `(当前页码 - 1) * 每页显示记录数` 来确定从数据库中的哪条记录开始查询，
        // 例如当前页码为 `1` 时，偏移量为 `0`，表示从第一条记录开始查询；页码为 `2` 时，偏移量为 `pagesize`，表示从第 `pagesize + 1` 条记录开始查询，以此类推，
        // 这个偏移量用于数据库查询语句中指定查询的起始位置，实现分页功能。
        offset = (pagenum - 1) * pagesize;

        // 如果计算出的偏移量大于等于记录总数（`count`），说明传入的页码可能超出了合理范围（比如总共有 `100` 条记录，每页显示 `10` 条，传入页码 `11` 就会出现这种情况），
        // 此时将偏移量设置为记录总数，避免查询出现错误，相当于查询最后一页（可能不满一页的情况）的数据，保证分页查询的健壮性。
        if (offset >= count) {
            offset = count;
        }

        // 获取每页显示记录数（`pagesize`），赋值给 `limit` 变量，在后续的数据库查询操作中用于指定每次查询获取的管理员记录数量上限，确保分页查询按设定的每页数量返回数据。
        limit = pagesize;

        // 调用 `managersDAO` 模块的 `findByKey` 方法，按照关键词（`key`）以及分页相关的偏移量（`offset`）和限制数量（`limit`）来查询符合条件的管理员记录，
        // 该方法是一个异步操作，通过回调函数来处理查询结果，若成功则返回查询到的管理员记录数组（`managers`），每个元素是一个包含管理员详细信息的对象，后续会对这些信息进行整理和封装后返回给调用者。
        managersDAO.findByKey(key, offset, limit, function (err, managers) {
            // 创建一个空数组 `retManagers`，用于存储经过整理和格式化后的管理员信息，将原始查询到的管理员记录中的部分关键信息提取并按照统一格式进行封装，方便后续返回给调用者使用。
            var retManagers = [];

            // 遍历查询到的管理员记录数组 `managers`，通过索引 `idx` 来访问每个管理员信息对象，对每个管理员的信息进行整理和格式化操作，提取需要展示给调用者的关键信息，并添加到 `retManagers` 数组中。
            for (idx in managers) {
                var manager = managers[idx];
                var role_name = manager.role_name;
                // 如果管理员信息中的 `role_id` 不存在（可能表示未明确分配角色或者特殊情况），则将角色名称默认设置为 `超级管理员`，这是一种根据角色标识来处理角色名称显示的逻辑，确保有合理的角色名称展示给调用者。
                if (!manager.role_id) {
                    role_name = "超级管理员"
                }
                // 将整理好的管理员关键信息按照特定格式封装成一个新的对象，并添加到 `retManagers` 数组中，这些信息包括管理员ID（`id`）、角色名称（`role_name`）、用户名（`username`）、
                // 创建时间（`create_time`）、手机号（`mobile`）、邮箱（`email`）以及状态信息（`mg_state`，将数据库中的数字状态值转换为布尔类型，方便调用者理解和使用，例如 `1` 可能表示启用状态，转换后为 `true`）。
                retManagers.push({
                    "id": manager.mg_id,
                    "role_name": role_name,
                    "username": manager.mg_name,
                    "create_time": manager.mg_time,
                    "mobile": manager.mg_mobile,
                    "email": manager.mg_email,
                    "mg_state": manager.mg_state == 1
                });
            }

            // 创建一个空对象 `resultDta`，用于存储最终要返回给调用者的结果信息，包含符合条件的管理员记录总数（`total`）、当前页码（`pagenum`）以及整理好的管理员信息列表（`users`，即 `retManagers` 数组），
            // 这样将查询结果和相关统计信息统一封装后返回给调用者，方便调用者进行后续的业务处理，比如在前端页面展示管理员列表、进行分页导航等操作。
            var resultDta = {};
            resultDta["total"] = count;
            resultDta["pagenum"] = pagenum;
            resultDta["users"] = retManagers;

            // 将包含管理员相关信息和统计数据的 `resultDta` 对象通过回调函数 `cb` 返回给调用者，表示查询操作成功完成，调用者可以根据这些信息进行后续的业务操作，比如展示管理员列表、根据状态进行筛选等操作。
            cb(err, resultDta);
        });
    });
}
//这段代码实现了根据特定查询条件获取管理员信息并进行分页处理的功能，通过对数据库操作的封装以及
//数据的整理和格式化，能够方便地为调用者提供符合要求的管理员列表数据以及相关统计信息，常用于
//管理系统中管理员列表展示等业务场景。
/**
 * 创建管理员
 * 此函数用于创建新的管理员账号，接收包含管理员相关信息的参数对象以及一个回调函数，
 * 通过检查用户名是否已存在、对密码进行加密处理等操作后，将新管理员信息插入数据库，若操作成功则返回创建后的管理员关键信息，若失败则返回相应错误信息给回调函数。
 * 
 * @param  {[type]}   user 用户数据集，它是一个对象，应包含创建管理员所需的各种信息，例如用户名（`username`）、密码（`password`）、手机号（`mobile`）、邮箱（`email`）、角色ID（`rid`）等关键信息，具体格式和字段要求由业务逻辑决定。
 * @param  {Function} cb   回调函数，用于接收创建管理员操作的结果，若成功创建管理员，则传递包含创建后的管理员关键信息（如ID、用户名、手机号等）的对象作为参数；若出现错误情况（如用户名已存在、数据库插入失败等），则传递相应的错误信息字符串作为参数。
 */
module.exports.createManager = function (params, cb) {
    // 调用 `managersDAO` 模块的 `exists` 方法，传入要创建的管理员的用户名（`params.username`），用于检查该用户名在数据库中是否已经存在，
    // 该方法是一个异步操作，通过回调函数返回检查结果，若存在则 `isExists` 为 `true`，否则为 `false`，以此来判断是否能继续创建该管理员账号。
    managersDAO.exists(params.username, function (err, isExists) {
        // 如果在检查用户名是否存在的过程中出现错误（`err` 不为 `null`），比如数据库查询出现问题（连接故障、查询语句执行错误等），则直接通过回调函数 `cb` 返回错误信息，告知调用者操作出现问题及原因，终止创建操作。
        if (err) return cb(err);

        // 如果检查发现用户名已经存在（`isExists` 为 `true`），说明不能再使用该用户名创建新的管理员账号，直接通过回调函数 `cb` 返回相应的错误信息，表示用户名已存在，告知调用者需要更换用户名后再尝试创建操作。
        if (isExists) {
            return cb("用户名已存在");
        }

        // 调用 `managersDAO` 模块的 `create` 方法来执行创建管理员的数据库操作，传入一个包含管理员关键信息的对象，
        // 其中对密码进行了加密处理（使用 `Password.hash` 函数，可能是通过特定的加密算法将明文密码转换为加密后的密文，以提高安全性），
        // 同时包含用户名、手机号、邮箱、创建时间（获取当前时间并转换为合适的时间戳格式，方便数据库存储和后续查询对比等操作）以及角色ID等信息，
        // 该方法是一个异步操作，通过回调函数来处理数据库插入操作完成后的结果情况，若成功则返回创建后的管理员对象（`manager`），可从中提取关键信息返回给调用者，若失败则返回相应错误信息告知调用者创建失败。
        managersDAO.create({
            "mg_name": params.username,
            "mg_pwd": Password.hash(params.password),
            "mg_mobile": params.mobile,
            "mg_email": params.email,
            "mg_time": (Date.parse(new Date()) / 1000),
            "role_id": params.rid
        }, function (err, manager) {
            // 如果在创建管理员的数据库插入操作过程中出现错误（`err` 不为 `null`），比如违反数据库约束（可能某些字段长度限制、唯一性约束等问题）、数据库写入故障等原因，
            // 则直接通过回调函数 `cb` 返回错误信息，表示创建失败，告知调用者创建管理员操作未成功及原因。
            if (err) return cb("创建失败");

            // 如果管理员创建成功，将创建后的管理员对象（`manager`）中的关键信息提取出来，按照特定格式封装成一个新的对象（`result`），
            // 这些关键信息包括管理员ID（`id`）、用户名（`username`）、手机号（`mobile`）、邮箱（`email`）、角色ID（`role_id`）以及创建时间（`create_time`），方便统一返回给调用者展示或后续使用。
            result = {
                "id": manager.mg_id,
                "username": manager.mg_name,
                "mobile": manager.mg_mobile,
                "email": manager.mg_email,
                "role_id": manager.role_id,
                "create_time": manager.mg_time
            };

            // 将包含创建后管理员关键信息的 `result` 对象通过回调函数 `cb` 返回给调用者，表示管理员创建成功，调用者可以获取这些信息进行后续操作，比如记录新管理员信息、进行权限分配等业务操作。
            cb(null, result);
        });
    });
}

/**
 * 更新管理员信息
 * 此函数用于更新指定管理员的部分信息，接收包含要更新的管理员信息的参数对象以及一个回调函数，
 * 通过调用数据库更新操作来修改管理员的手机号、邮箱等信息（根据传入的参数确定具体更新的字段），若操作成功则返回更新后的管理员关键信息，若失败则返回相应错误信息给回调函数。
 * 
 * @param  {[type]}   params 管理员信息，它是一个对象，包含要更新的管理员相关信息，例如管理员ID（`id`）用于确定要更新的具体管理员记录，以及要更新的手机号（`mobile`）、邮箱（`email`）等字段信息，具体更新哪些字段由传入的参数决定。
 * @param  {Function} cb     回调函数，用于接收更新管理员操作的结果，若成功更新管理员信息，则传递包含更新后的管理员关键信息（如ID、用户名、手机号等）的对象作为参数；若出现错误情况（如数据库更新失败等），则传递相应的错误信息字符串作为参数。
 */
module.exports.updateManager = function (params, cb) {
    // 调用 `managersDAO` 模块的 `update` 方法来执行更新管理员信息的数据库操作，
    // 传入两个参数，第一个参数是一个对象，用于指定更新的条件以及要更新的部分字段信息，这里通过 `{"mg_id":params.id, "mg_mobile":params.mobile, "mg_email":params.email}` 指定了根据管理员ID（`params.id`）来确定要更新的记录，
    // 同时更新该记录对应的手机号（`mg_mobile`）和邮箱（`mg_email`）字段的值（使用传入的 `params.mobile` 和 `params.email` 的值进行更新），
    // 第二个参数是一个回调函数，用于处理数据库更新操作完成后的结果情况，若成功则返回更新后的管理员对象（`manager`），可从中提取关键信息返回给调用者，若失败则返回相应错误信息告知调用者更新失败。
    managersDAO.update(
        {
            "mg_id": params.id,
            "mg_mobile": params.mobile,
            "mg_email": params.email
        },
        function (err, manager) {
            // 如果在更新管理员信息的数据库操作过程中出现错误（`err` 不为 `null`），比如违反数据库约束（例如手机号格式不符合要求、邮箱唯一性冲突等问题）、数据库更新语句执行错误等原因，
            // 则直接通过回调函数 `cb` 返回错误信息，告知调用者操作出现问题及原因，终止更新操作。
            if (err) return cb(err);

            // 如果管理员信息更新成功，将更新后的管理员对象（`manager`）中的关键信息提取出来，按照特定格式封装成一个新的对象返回给调用者，
            // 这些关键信息包括管理员ID（`id`）、用户名（`username`）、角色ID（`role_id`）、手机号（`mobile`）以及邮箱（`email`），方便调用者获取更新后的管理员信息进行后续操作，比如展示更新后的管理员详情等业务操作。
            cb(null, {
                "id": manager.mg_id,
                "username": manager.mg_name,
                "role_id": manager.role_id,
                "mobile": manager.mg_mobile,
                "email": manager.mg_email
            });
        }
    )
}

/**
 * 通过管理员 ID 获取管理员信息
 * 此函数用于根据传入的管理员ID从数据库中获取对应的管理员详细信息，接收管理员ID以及一个回调函数，
 * 通过调用数据库查询操作查找指定ID的管理员记录，若找到则返回管理员关键信息，若未找到或者出现查询错误则返回相应错误信息给回调函数。
 * 
 * @param  {[type]}   id 管理员 ID，用于唯一确定要获取信息的管理员记录，是从数据库中查询对应管理员的关键标识。
 * @param  {Function} cb 回调函数，用于接收获取管理员信息操作的结果，若成功获取到管理员信息，则传递包含管理员关键信息（如ID、角色ID、用户名、手机号、邮箱等）的对象作为参数；若出现错误情况（如数据库查询失败、管理员不存在等），则传递相应的错误信息字符串作为参数。
 */
module.exports.getManager = function (id, cb) {
    // 调用 `managersDAO` 模块的 `show` 方法来执行查询指定ID管理员信息的数据库操作，传入管理员ID（`id`）作为查询条件，
    // 该方法是一个异步操作，通过回调函数来处理查询结果，若成功则返回对应的管理员对象（`manager`），若未找到对应的管理员记录或者出现查询错误（`err` 不为 `null`），则通过回调函数返回相应错误信息告知调用者。
    managersDAO.show(id, function (err, manager) {
        // 如果在查询管理员信息的数据库操作过程中出现错误（`err` 不为 `null`），比如数据库连接问题、查询语句执行错误等原因，
        // 则直接通过回调函数 `cb` 返回错误信息，告知调用者操作出现问题及原因，终止获取信息操作。
        if (err) return cb(err);

        // 如果查询结果没有获取到对应的管理员（`!manager`，即 `manager` 为 `null`），说明该管理员ID不存在，通过回调函数 `cb` 返回相应的错误信息，表示该管理员不存在，告知调用者无法获取对应的管理员信息。
        if (!manager) return cb("该管理员不存在");

        // 如果成功获取到管理员信息，将管理员对象（`manager`）中的关键信息提取出来，按照特定格式封装成一个新的对象返回给调用者，
        // 这些关键信息包括管理员ID（`id`）、角色ID（`rid`）、用户名（`mg_name`，这里重命名为 `username` 方便调用者理解和使用统一的命名规范）、手机号（`mg_mobile`）以及邮箱（`mg_email`），
        // 方便调用者获取管理员详细信息进行后续操作，比如展示管理员详情、进行权限判断等业务操作。
        cb(
            null,
            {
                "id": manager.mg_id,
                "rid": manager.role_id,
                "username": manager.mg_name,
                "mobile": manager.mg_mobile,
                "email": manager.mg_email
            }
        );
    });
}

/**
 * 通过管理员 ID 进行删除操作
 * 此函数用于根据传入的管理员ID从数据库中删除对应的管理员记录，接收管理员ID以及一个回调函数，
 * 通过调用数据库删除操作来移除指定ID的管理员记录，若操作成功则返回空值表示删除成功，若失败则返回相应错误信息给回调函数。
 * 
 * @param  {[type]}   id 管理员ID，用于唯一确定要删除的管理员记录，是从数据库中定位并删除对应管理员的关键标识。
 * @param  {Function} cb 回调函数，用于接收删除管理员操作的结果，若成功删除管理员记录，则传递 `null` 表示操作成功；若出现错误情况（如数据库删除失败等），则传递相应的错误信息字符串作为参数。
 */
module.exports.deleteManager = function (id, cb) {
    // 调用 `managersDAO` 模块的 `destroy` 方法来执行删除指定ID管理员记录的数据库操作，传入管理员ID（`id`）作为删除条件，
    // 该方法是一个异步操作，通过回调函数来处理操作结果，若成功删除则回调函数无额外返回数据（通常返回 `null` 表示操作成功），若出现错误（`err` 不为 `null`）则返回相应错误信息告知调用者删除失败。
    managersDAO.destroy(id, function (err) {
        // 如果在删除管理员记录的数据库操作过程中出现错误（`err` 不为 `null`），比如数据库权限不足、违反外键约束（若存在关联其他表的数据时可能出现此问题）、数据库删除语句执行错误等原因，
        // 则直接通过回调函数 `cb` 返回错误信息，表示删除失败，告知调用者删除管理员操作未成功及原因。
        if (err) return cb("删除失败");

        // 如果管理员记录删除成功，通过回调函数 `cb` 返回 `null`，表示删除操作顺利完成，告知调用者可以进行后续相关业务操作，比如刷新管理员列表等操作。
        cb(null);
    });
}

/**
 * 为管理员设置角色
 * 此函数用于为指定的管理员设置新的角色，接收管理员ID和角色ID以及一个回调函数，
 * 通过先查询管理员是否存在，再执行数据库更新操作来修改管理员对应的角色ID字段值，若操作成功则返回更新后的管理员关键信息，若失败则返回相应错误信息给回调函数。
 * 
 * @param {[type]}   id  管理员ID，用于唯一确定要设置角色的管理员记录，是从数据库中定位对应管理员的关键标识。
 * @param {[type]}   rid 角色ID，用于指定要为管理员设置的新角色的唯一标识，通过更新操作将该角色ID关联到对应的管理员记录上。
 * @param {Function} cb  回调函数，用于接收为管理员设置角色操作的结果，若成功为管理员设置了新角色，则传递包含更新后的管理员关键信息（如ID、角色ID、用户名、手机号、邮箱等）的对象作为参数；若出现错误情况（如管理员ID不存在、数据库更新失败等），则传递相应的错误信息字符串作为参数。
 */
module.exports.setRole = function (id, rid, cb) {
    // 调用 `managersDAO` 模块的 `show` 方法来执行查询指定ID管理员信息的数据库操作，传入管理员ID（`id`）作为查询条件，
    // 该方法是一个异步操作，通过回调函数来处理查询结果，若成功则返回对应的管理员对象（`manager`），若未找到对应的管理员记录或者出现查询错误（`err` 不为 `null`），则通过回调函数返回相应错误信息告知调用者管理员ID不存在，终止设置角色操作。
    managersDAO.show(id, function (err, manager) {
        // 如果在查询管理员信息的过程中出现错误（`err` 不为 `null`），或者查询结果没有获取到对应的管理员（`!manager`），说明管理员ID不存在或者出现其他查询问题，
        // 通过回调函数 `cb` 返回相应的错误信息，表示管理员ID不存在，告知调用者无法为不存在的管理员设置角色，终止操作。
        if (err ||!manager) cb("管理员ID不存在");

        // 调用 `managersDAO` 模块的 `update` 方法来执行更新管理员角色ID的数据库操作，传入两个参数，
        // 第一个参数是一个对象，用于指定更新的条件以及要更新的角色ID字段信息，这里通过 `{"mg_id":manager.mg_id,"role_id":rid}` 指定了根据管理员的实际ID（`manager.mg_id`）来确定要更新的记录，
        // 并将角色ID字段（`role_id`）更新为传入的新角色ID（`rid`）的值，第二个参数是一个回调函数，用于处理数据库更新操作完成后的结果情况，若成功则返回更新后的管理员对象（`manager`），可从中提取关键信息返回给调用者，若失败则返回相应错误信息告知调用者设置失败。
        managersDAO.update({"mg_id": manager.mg_id, "role_id": rid}, function (err, manager) {
            // 如果在更新管理员角色ID的数据库操作过程中出现错误（`err` 不为 `null`），比如违反数据库约束（例如角色ID不存在、不满足关联关系等问题）、数据库更新语句执行错误等原因，
            // 则直接通过回调函数 `cb` 返回错误信息，表示设置失败，告知调用者设置管理员角色操作未成功及原因。
            if (err) return cb("设置失败");

            // 如果管理员角色ID更新成功，将更新后的管理员对象（`manager`）中的关键信息提取出来，按照特定格式封装成一个新的对象返回给调用者，
            // 这些关键信息包括管理员ID（`id`）、角色ID（`rid`）、用户名（`mg_name`，重命名为 `username`）、手机号（`mg_mobile`）以及邮箱（`mg_email`），
            // 方便调用者获取更新后的管理员信息进行后续操作，比如查看管理员角色变更后的权限情况等业务操作。
            cb(null, {
                "id": manager.mg_id,
                "rid": manager.role_id,
                "username": manager.mg_name,
                "mobile": manager.mg_mobile,
                "email": manager.mg_email,
            });
        });

    })
}

module.exports.updateMgrState = function (id, state, cb) {
    // 调用 `managersDAO` 模块的 `show` 方法来执行查询指定ID管理员信息的数据库操作，传入管理员ID（`id`）作为查询条件，
    // 该方法是一个异步操作，通过回调函数来处理查询结果，若成功则返回对应的
	// 先调用 `managersDAO` 模块的 `show` 方法，根据传入的管理员 `id` 去数据库中查询对应的管理员信息。
// 这是一个异步操作，会传入一个回调函数来处理查询结果，在回调函数中接收可能出现的错误信息 `err` 以及查询到的管理员对象 `manager`。
managersDAO.show(id, function (err, manager) {
    // 如果在查询管理员信息的过程中出现错误（`err` 不为 `null`），或者没有查询到对应的管理员（`!manager`，即 `manager` 为 `null`），
    // 说明管理员ID不存在或者出现了数据库查询相关的问题，此时通过回调函数 `cb` 返回错误信息“管理员ID不存在”，告知调用者无法进行后续操作，因为要操作的管理员对象不存在。
    if (err ||!manager) cb("管理员ID不存在");

    // 如果查询到了对应的管理员信息，接下来调用 `managersDAO` 模块的 `update` 方法，尝试更新该管理员的状态信息。
    // 传入一个对象作为更新条件和要更新的数据，对象中 `{"mg_id":manager.mg_id,"mg_state":state}` 表示根据当前查询到的管理员的实际 `mg_id` 来确定要更新的记录，
    // 并将 `mg_state` 字段更新为传入的 `state` 参数值，同样这是一个异步操作，通过传入的回调函数来处理更新操作的结果。
    managersDAO.update({"mg_id": manager.mg_id, "mg_state": state}, function (err, manager) {
        // 如果在更新管理员状态的数据库操作过程中出现错误（`err` 不为 `null`），比如数据库更新语句执行失败、违反数据约束等原因，
        // 则通过回调函数 `cb` 返回错误信息“设置失败”，告知调用者更新管理员状态的操作没有成功，方便调用者进行相应的错误处理或提示给用户等操作。
        if (err) return cb("设置失败");

        // 如果管理员状态更新成功，通过回调函数 `cb` 返回一个包含更新后管理员关键信息的对象。
        // 其中包括管理员 `id`（`manager.mg_id`）、角色 `id`（`manager.role_id`）、用户名（`manager.mg_name`）、手机号（`manager.mg_mobile`）、邮箱（`manager.mg_email`）以及更新后的状态信息（`mg_state`），
        // 这里对 `mg_state` 进行了一个简单的处理，将其转换为 `1`（如果 `mg_state` 为真）或 `0`（如果 `mg_state` 为假）的格式，方便后续业务逻辑中对状态的判断和使用，然后将整个对象返回给调用者，告知调用者更新操作已完成且返回了最新的管理员信息。
        cb(null, {
            "id": manager.mg_id,
            "rid": manager.role_id,
            "username": manager.mg_name,
            "mobile": manager.mg_mobile,
            "email": manager.mg_email,
            "mg_state": manager.mg_state? 1 : 0
        });
    });

})
}

/**
 * 管理员登录
 * 此函数用于处理管理员登录的逻辑，接收用户名和密码作为参数，以及一个回调函数用于返回登录操作的结果。
 * 通过查询数据库验证用户名是否存在、检查用户权限及状态等多步操作，判断登录是否成功，若成功则返回管理员相关信息，若失败则返回相应的错误信息给回调函数。
 * 
 * @param  {[type]}   username 用户名，是管理员登录时输入的标识信息，用于在数据库中查找对应的管理员记录。
 * @param  {[type]}   password 密码，是管理员登录时输入的密码信息，用于和数据库中存储的加密密码进行比对验证。
 * @param  {Function} cb       回调函数，用于接收管理员登录操作的结果，若登录成功，则传递包含管理员关键信息（如ID、角色ID、用户名、手机号、邮箱等）的对象作为参数；若出现错误情况（如用户名不存在、用户无权限、密码错误等），则传递相应的错误信息字符串作为参数。
 */
module.exports.login = function (username, password, cb) {
    // 使用 `logger` 对象的 `debug` 方法记录调试信息，输出登录操作时传入的用户名和密码信息，方便在开发调试阶段查看登录时的参数情况，有助于排查问题，例如查看是否传入了正确的用户名和密码值。
    logger.debug('login => username:%s,password:%s', username, password);
    // 再次使用 `logger` 对象的 `debug` 方法记录调试信息，单独输出用户名信息，进一步方便在调试时查看用户名相关情况，比如确认用户名是否符合预期格式等。
    logger.debug(username);

    // 调用 `managersDAO` 模块的 `findOne` 方法，根据传入的用户名（`{"mg_name":username}`）去数据库中查找对应的管理员记录，
    // 这是一个异步操作，通过传入的回调函数来处理查询结果，在回调函数中接收可能出现的错误信息 `err` 以及查询到的管理员对象 `manager`。
    managersDAO.findOne({"mg_name": username}, function (err, manager) {
        // 使用 `logger` 对象的 `debug` 方法记录调试信息，输出查询管理员过程中出现的错误信息 `err`，方便在调试时查看是否出现了数据库查询相关的错误以及具体错误内容，有助于定位问题所在。
        logger.debug(err);

        // 如果在查询管理员的过程中出现错误（`err` 不为 `null`），或者没有查询到对应的管理员（`!manager`，即 `manager` 为 `null`），
        // 说明用户名不存在或者出现了数据库查询相关的问题，此时通过回调函数 `cb` 返回错误信息“用户名不存在”，告知调用者登录操作失败，因为找不到对应的管理员账号，方便调用者进行相应的提示给用户等操作。
        if (err ||!manager) return cb("用户名不存在");

        // 如果查询到的管理员的角色 `id`（`manager.role_id`）小于 `0`，说明该用户可能不符合正常的权限设定规则（具体含义由业务逻辑定义，可能是特殊标记表示无登录权限等情况），
        // 此时通过回调函数 `cb` 返回错误信息“该用户没有权限登录”，告知调用者该管理员账号不能用于登录，可能需要联系相关人员处理权限问题等操作。
        if (manager.role_id < 0) {
            return cb("该用户没有权限登录");
        }

        // 如果管理员的角色 `id` 不等于 `0`（可能表示不是超级管理员之类具有特殊权限的角色）且管理员的状态（`manager.mg_state`）不等于 `1`（通常 `1` 表示启用状态，`0` 表示禁用等其他状态，具体由业务逻辑定义），
        // 说明该用户虽然存在且有相应角色，但当前处于被禁用状态，此时通过回调函数 `cb` 返回错误信息“该用户已经被禁用”，告知调用者该管理员账号不能登录，可能需要联系管理员进行账号启用等操作。
        if (manager.role_id!= 0 && manager.mg_state!= 1) {
            return cb("该用户已经被禁用");
        }

        // 使用 `Password` 模块的 `verify` 方法来验证输入的密码（`password`）与数据库中存储的该管理员的加密密码（`manager.mg_pwd`）是否匹配，
        // 如果匹配成功（即密码验证通过），说明登录信息正确，通过回调函数 `cb` 返回一个包含管理员关键信息的对象，
        // 这些信息包括管理员 `id`（`manager.mg_id`）、角色 `id`（`manager.role_id`）、用户名（`manager.mg_name`）、手机号（`manager.mg_mobile`）、邮箱（`manager.mg_email`），方便后续业务逻辑根据登录后的管理员信息进行相应操作，比如进入管理系统主界面、记录登录日志等操作。
        if (Password.verify(password, manager.mg_pwd)) {
            cb(
                null,
                {
                    "id": manager.mg_id,
                    "rid": manager.role_id,
                    "username": manager.mg_name,
                    "mobile": manager.mg_mobile,
                    "email": manager.mg_email,
                }
            );
        } else {
            // 如果密码验证不通过，说明输入的密码错误，通过回调函数 `cb` 返回错误信息“密码错误”，告知调用者登录失败，方便调用者进行相应的提示给用户等操作，比如提示用户重新输入密码。
            return cb("密码错误");
        }
    });
}
//这段代码实现了管理员相关的重要操作逻辑，包括更新管理员状态以及管理员登录验证等功能。通过与数
//据库的交互以及各种条件判断，保证了这些操作的准确性和安全性，同时借助日志记录方便了调试与问
//题排查。