158 lines
5.7 KiB
JavaScript
158 lines
5.7 KiB
JavaScript
/*
|
||
* @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);
|
||
});
|
||
});
|
||
};
|