// 引入Express框架的核心模块，用于创建Web应用、定义路由以及处理HTTP请求等相关操作。
// Express是Node.js中常用的Web应用开发框架，提供了便捷的方式来搭建服务器、配置不同路径对应的路由以及处理各类HTTP请求与响应，是整个后端服务构建的基础框架。
var express = require('express');

// 创建一个Express路由器实例，方便以模块化的方式来定义一组相关的路由，便于在整个应用中进行有条理的路由管理。
// 使用路由器实例可以将不同功能模块（比如用户模块、文件管理模块等）相关的路由进行分组管理，使代码结构更加清晰，易于维护和扩展，避免所有路由逻辑混杂在一起。
var router = express.Router();

// 引入Node.js的path模块，主要用于处理文件路径相关的操作，例如拼接、解析文件路径等。
// 在Node.js项目中，经常需要根据项目的目录结构准确地处理文件路径，path模块提供了诸如path.join（拼接路径）、path.resolve（解析绝对路径）等方法来辅助完成这些操作，确保文件操作能准确找到对应的文件位置。
var path = require("path");

// 引入Node.js的文件系统模块（fs），用于对文件进行读写、重命名等操作。
// fs模块提供了丰富的文件操作接口，比如读取文件内容（fs.readFile）、写入文件内容（fs.writeFile）、判断文件是否存在（fs.existsSync）以及这里用到的重命名文件（fs.rename）等功能，方便在Node.js应用中进行各种文件层面的处理。
var fs = require('fs');

// 引入Node.js的操作系统模块（os），通常可以获取操作系统相关的信息等，不过在这段代码里暂未体现其具体使用。
// os模块可以获取诸如系统内存信息、CPU核心数、操作系统平台（如Windows、Linux等）相关的信息，虽然在此处当前没看到具体使用场景，但在一些需要根据不同操作系统特性进行适配的功能中会发挥作用。
var os = require('os');

// 引入multer模块，它是一个用于处理文件上传的中间件，能够方便地解析上传的文件数据。
// 在Web应用中，当需要接收客户端上传的文件时，multer可以帮助解析HTTP请求中的文件部分，将其转换为Node.js中便于处理的格式，并且可以进行一些配置，比如指定文件存储位置等。
var multer  = require('multer');

// 创建一个multer实例，配置文件上传的临时存储目录为'tmp_uploads/'，意味着上传的文件会先临时存放在这个目录下。
// 通过这种配置，multer会将客户端上传的文件先暂存到指定的临时目录中，后续再根据业务需求对这些临时文件进行进一步处理，比如重命名、移动到正式存储位置等操作。
var upload = multer({ dest: 'tmp_uploads/' });

// 引入自定义的配置文件（config），并获取其中名为"upload_config"的配置项，这里的配置项可能包含了与文件上传相关的一些配置信息，比如文件访问的基础URL等。
// 自定义的配置文件通常用于集中管理应用中的各种配置参数，方便根据不同环境（开发环境、生产环境等）进行灵活调整，在这里获取的'upload_config'可能包含了如文件在服务器上对外可访问的基础URL等重要信息，用于后续构建文件的完整访问路径。
var upload_config = require('config').get("upload_config");

// 定义一个处理POST请求的路由，路径为根路径 "/"，该路由用于处理文件上传的业务逻辑。
// 当客户端向服务器的根路径发送POST请求时，服务器会依据此路由定义来处理请求，在这里就是专门处理文件上传相关的操作，比如接收客户端传来的文件数据，并进行后续的保存、重命名等处理。
// 这里使用了upload.single('file')中间件，意味着它期望接收一个名为'file'的文件上传字段。这表示客户端在上传文件时，HTTP请求中的表单数据里，文件对应的字段名应该是'file'，这样multer才能正确解析并获取到上传的文件信息。
router.post("/", upload.single('file'), function (req, res, next) {
    // 从上传的文件信息（req.file）中获取原始文件名，通过split方法以'.'为分隔符将文件名拆分成数组。
    // 例如，对于原始文件名'test.txt'，经过split操作后会得到一个数组['test', 'txt']，方便后续提取文件扩展名等操作。
    var fileExtArray = req.file.originalname.split(".");
    // 获取文件扩展名，即数组中的最后一个元素，例如对于文件名'test.txt'，获取到的ext就是'txt'。
    // 通过获取文件扩展名，后续可以将其添加到临时存储的文件上，确保文件重命名后具有正确的完整文件名，符合实际的文件格式要求。
    var ext = fileExtArray[fileExtArray.length - 1];
    // 构建目标文件路径，先获取上传文件的临时存储路径（req.file.path），然后拼接上文件扩展名，形成最终带有正确扩展名的完整路径。
    // 因为最初文件上传到临时目录时可能没有完整的扩展名（由multer的默认存储机制决定），所以这里需要重新拼接扩展名来得到最终正确的文件路径，以便后续能准确访问和使用该文件。
    var targetPath = req.file.path + "." + ext;

    // 使用fs模块的rename方法对文件进行重命名操作，将临时存储的文件重命名为带有正确扩展名的目标文件路径。
    // path.join方法用于拼接当前工作目录（process.cwd()）、文件路径相关部分，确保路径的准确性。通过这种方式准确指定文件的源路径和目标路径，避免因路径错误导致文件重命名失败。
    fs.rename(path.join(process.cwd(), "/" + req.file.path), path.join(process.cwd(), targetPath), function (err) {
        // 如果重命名文件的操作出现错误（err不为null），则返回包含错误信息的响应给客户端，状态码为400，表示请求出现错误，同时附带提示信息"上传文件失败"。
        // 比如可能出现文件权限不足无法重命名、目标路径已存在同名文件等情况导致重命名操作失败，此时需要告知客户端上传文件的操作没有成功，并传递具体的错误原因（通过err对象）。
        if (err) {
            return res.sendResult(null, 400, "上传文件失败");
        }
        // 如果文件重命名成功，即文件上传操作顺利完成，则返回包含相关信息的成功响应给客户端。
        // 返回的数据包含了文件的临时路径（tmp_path）以及完整的访问URL（通过配置项中的基础URL和目标文件路径拼接而成），状态码为200，表示请求成功，同时附带提示信息"上传成功"。
        // 客户端可以根据返回的URL来访问已上传的文件，而tmp_path可以用于服务器端后续可能的其他文件管理操作或者记录等用途。
        res.sendResult({"tmp_path": targetPath, "url": upload_config.get("baseURL") + "/" + targetPath}, 200, "上传成功");
    });
});

// 将配置好的路由器对象导出，以便在主应用中可以引入并挂载到对应的路径上，使得这个文件上传的路由能够正确响应客户端发送的相应HTTP请求。
// 在主应用中，通过引入这个路由器模块，并将其挂载到对应的根路径（"/"）上，服务器就能正确识别客户端发送的文件上传请求，按照路由中定义的逻辑进行文件接收、重命名以及返回相应结果等操作，从而实现文件上传功能。
module.exports = router;
//这段代码实现了一个简单的文件上传功能的后端路由处理逻辑，借助 multer 中间件接收文件上传，然后
//通过 fs 模块对临时存储的文件进行重命名等操作，最后根据操作结果向客户端返回相应的响应信息，告知
//上传是否成功以及提供文件的相关访问信息。