/* * @Description: mock数据方法 * @Author: smileswlin * @LastEditor: smileswlin * @Date: 020-05-24 21:16:49 * @LastEditTime: 2022-02-22 17:33:24 */ const path = require('path'); const fs = require('fs'); // 引入文件系统模块 const Mock = require('mockjs'); // mockjs 导入依赖模块 // const { file } = require('@gtff/tdesign-gt-vue/icon/icon-map'); /** * 读取json文件 * @param filePath * @returns {any} */ function getMockFile(filePath) { // 读取指定json文件 const json = fs.readFileSync(filePath, 'utf-8'); // 解析并返回 return JSON.parse(json); } /** * 读取文件夹下所有文件名并替换为路由模式字符串 eg: user_bulk__delete.json => /user/bulk_delete * @param jsonPath * @returns {{}} */ function getMockRouter(jsonPath) { const jsonFiles = []; try { // 检查传入目录是否存在 fs.accessSync(jsonPath); const files = fs.readdirSync(jsonPath); files.forEach((item) => { let fileName = item; fileName = `/${item.replace(/_/g, '/').replace('.json', '')}`; fileName = fileName.replace(/\/\//g, '_'); // 若出现‘//’ , 则改为_ jsonFiles.push(fileName); }); } catch (e) { console.log('error', e); } return jsonFiles; } /** * @description: 设置mock数据路由, 对应目录下,创建get或者post目录,该目录下的文件则为url请求地址 eg: user_bulk__delete.json => /user/bulk_delete * @param app {Object} app对象 * @param method {String} 请求方式,get或者post * @param urlPrefix {String} url的前缀 * @param dirPath {String} 对应的目录 * @return: undefined */ exports.setMock = function (app, method, urlPrefix, dirPath) { const newDirPath = dirPath || path.join(process.cwd(), 'mock', method); getMockRouter(newDirPath).forEach((item) => { app[method](`${urlPrefix}${item}`, (req, res) => { // 每次响应请求时读取mock data的json文件 // util.getMockFile方法定义了如何读取json文件并解析成数据对象 const jsonPath = path.resolve(newDirPath, `${item.substr(1).replace(/_/g, '__').replace(/\//g, '_')}.json`); const json = getMockFile(jsonPath); res[method === 'get' ? 'json' : 'send'](Mock.mock(json)); // 将json传入 Mock.mock 方法中,生成的数据返回给浏览器 }); }); }; /** * @description: 已知当前目录,输出目录下所有文件信息(文件地址,文件名) * @param rootDir {String} 当前目录 * @param files {Array} 目录下的文件 * 1. 输入根目录,默认目录下文件为空 * 2. 向下读取文件 * 3. 判断是否是文件 * 如果是合法文件,添加 * 如果是目录,回到到第2步 * 如果读取为空 */ const formattedFiles = (rootDir, files = []) => { const childFiles = fs.readdirSync(rootDir); if (childFiles && childFiles.length && childFiles.length > 0) { // eslint-disable-next-line consistent-return childFiles.forEach((f) => { const url = path.join(rootDir, f); const isFile = fs.statSync(url).isFile(); if (isFile) { // 判断文件是否 .DS_Store const isValid = f !== '.DS_Store'; const ele = { jsonPath: url, pathName: url.replace('.json', ''), fileName: f, }; isValid && files.push(ele); } else { return formattedFiles(url, files); } }); } return files; }; /** * @description: 设置mock数据路由, 对应目录下,创建get或者post目录,再请求目录下创建业务目录demo(没有层级层级的限制),该目录下的文件则为url请求地址 eg: fail.json => /demo/fail * @param app {Object} app对象 * @param method {String} 请求方式,get或者post * @param urlPrefix {String} url的前缀 * @param dirPath {String} 对应的目录 * @return: undefined */ exports.setMockByBasePath = (app, method, urlPrefix, dirPath) => { // 读取到根目录 const rootDir = dirPath || path.join(process.cwd(), 'mock', method); const files = formattedFiles(rootDir).map((f) => { // eslint-disable-next-line no-param-reassign f.pathName = f.pathName.replace(rootDir, '').replace(/\\/g, '/'); return f; }); files.forEach(({ pathName, jsonPath }) => { app[method](`${urlPrefix}${pathName}`, (req, res) => { // 每次响应请求时读取mock data的json文件 // util.getMockFile方法定义了如何读取json文件并解析成数据对象 const json = getMockFile(jsonPath); res[method === 'get' ? 'json' : 'send'](Mock.mock(json)); // 将json传入 Mock.mock 方法中,生成的数据返回给浏览器 }); }); }; /** * @description: 设置mock数据路由, 增加子目录,mock/xxx/post 目录下的文件为url请求地址 eg: user_bulk__delete.json => /xxx/abc/user/bulk_delete * @param app {Object} app对象 * @param methods {Array} 请求方式,,eg: ['get', 'post'] * @param urlPrefix {String} url的前缀 * @return: undefined */ exports.mockSubDirs = function (app, methods, urlPrefix) { const rootDirPath = path.join(process.cwd(), 'mock'); const files = fs.readdirSync(rootDirPath); const dirs = files.filter((item) => fs.lstatSync(path.resolve(rootDirPath, item)).isDirectory()); dirs.forEach((dir) => { const subUrlPrefix = dir.replace(/(?:[^_])_(?:[^_])/g, '/').replace(/__/g, '_'); const dirPath = path.join(process.cwd(), 'mock', dir); methods.forEach((method) => { const rootUrlPrefix = urlPrefix[urlPrefix.length] === '/' ? urlPrefix.slice(0, -1) : urlPrefix; const urlPrefixResult = `${rootUrlPrefix}${subUrlPrefix}`; const dirPathResult = `${dirPath}/${method}`; console.log('mock with method:', method, ' urlPrefix:', urlPrefixResult, ' dir:', dirPathResult); exports.setMock(app, method, urlPrefixResult, dirPathResult); }); }); };