Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)
生活随笔
收集整理的這篇文章主要介紹了
Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
項目結構
?
index.js
//必須要安裝否則就別想運行了????????????????????????????????????????????????????????????????
//npm i body-parser -D & cnpm i express & cnpm i node-xlsx & cnpm i moment & node index
//全局引入對象????????????????????????????????????????????????????????????????
global.SG = {config: require("./js/common/config.js"),//全局配置文件(不同項目可能需要換下里面的配置)$g: require("./js/common/sg.js"),//強哥全局大對象方法express: require("express"),//cnpm i expressbodyParser: require("body-parser"),//npm i body-parser -Dfs: require("fs"),path: require("path"),xlsx: require("node-xlsx"),//cnpm i node-xlsxwebsocket: require("nodejs-websocket"),//cnpm i nodejs-websocketmoment: require("moment"),//cnpm i momentmulter: require("multer"),//cnpm i multerrequest: require("request"),xmlreader: require("xmlreader"),crypto: require("crypto")
};
global.SG.router = global.SG.express.Router();//全局路由//----------------------------------------------------------------
const app = global.SG.express(),bodyParser = global.SG.bodyParser,API_PATH = global.SG.config.API_PATH || "/api",port = global.SG.config.port || 9999;
app.listen(port, () => console.log(`測試讀取數據地址:http://127.0.0.1:${port}/api/demo/select`));//打印一下接口用例地址
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
//設置跨域訪問
app.all("*", (req, res, next) => {res.header("Access-Control-Allow-Origin", "*");res.header("Access-Control-Allow-Headers", "*");res.header("Access-Control-Allow-Methods", "*");res.header("X-Powered-By", "http://www.shuzhiqiang.com");res.header("Content-Type", "application/json;charset=utf-8");res.header("Access-Control-Allow-Credentials", true);//攜帶cookie跨域請求req.method.toUpperCase() === "OPTIONS" ? res.sendStatus(200) : next();//防止在預請求階段就響應接口
});//加入前端需要訪問的接口API名稱????????????????????????????????????????????????????????????????
//增刪改查----------------------------------------------------------------
app.use(API_PATH, require(`.${API_PATH}/demo/insert`));//增加數據
app.use(API_PATH, require(`.${API_PATH}/demo/delete`));//刪除數據
app.use(API_PATH, require(`.${API_PATH}/demo/update`));//修改數據
app.use(API_PATH, require(`.${API_PATH}/demo/select`));//查詢數據
app.use(API_PATH, require(`.${API_PATH}/demo/CURD`));//增刪改查數據//WebSocket----------------------------------------------------------------
app.use(API_PATH, require(`.${API_PATH}/demo/websocket`));//websocket//支付----------------------------------------------------------------
app.use(API_PATH, require(`.${API_PATH}/demo/wxpay`));//微信支付//文件處理----------------------------------------------------------------
app.use(API_PATH, require(`.${API_PATH}/demo/copyFileOrFolder`));//復制文件or文件夾
app.use(API_PATH, require(`.${API_PATH}/demo/deleteFileOrFolder`));//刪除文件or文件夾
app.use(API_PATH, require(`.${API_PATH}/demo/exportAndDownloadExcel`));//導出并下載Excel
app.use(API_PATH, require(`.${API_PATH}/demo/uploadExcel`));//上傳并解析Excel
js/common/config.js
module.exports = {API_PATH: "/api",//接口統一前綴以及接口文件目錄文件夾名port: 9999//設置端口號,如果端口號被占用需要自己修改,否則無法跑起來(建議不要用80和8080,一般情況都會被占用)
};
?js/common/sg.js
module.exports = {//CURD________________________CURD: {hasAndNoHasFields(req, hasFields = [], noHasFields = []) {const a = hasFields.length === 0 ? this.hasExceptFields(req, noHasFields) : this.hasFields(req, hasFields, true);const b = noHasFields.length === 0 ? !this.hasExceptFields(req, hasFields) : this.hasFields(req, noHasFields, false);return a && b;},hasExceptFields(body, exceptFields) {for (let key in body) {if (!exceptFields.includes(key)) return true;//判斷是否包含指定字段以外的未知字段}return false;//不包含指定字段以外的字段},hasFields(body, fields, isHasOrNoHas) {let fieldLen = 0;for (let i = 0, len = fields.length; i < len; i++) {let field = fields[i];if (isHasOrNoHas) {body.hasOwnProperty(field) && fieldLen++;//判斷是否都包含} else {body.hasOwnProperty(field) || fieldLen++; //判斷是否都不包含}}return fields.length === fieldLen;}},//對文件路徑的處理________________________dir: {delayDestroyFile(filePath, delayDestroyFileSecond = 60) {setTimeout(() => {global.SG.fs.exists(filePath, exists => {if (exists) {global.SG.fs.statSync(filePath).isFile() ? global.SG.fs.unlink(filePath, err => console.log(`${module.exports.date.nowtime()}刪除${filePath}${err ? "失敗" : "成功"}`)) : console.log(`${module.exports.date.nowtime()}刪除失敗(該路徑不是一個有效的文件路徑,注意需要文件而不是文件夾的路徑!)`);} else {console.log(`${module.exports.date.nowtime()}刪除失敗(該路徑${filePath}所對應的文件或者文件夾不存在!)`);}});}, 1000 * delayDestroyFileSecond);},//延時銷毀服務器文件mkdirsByFolderPath: (folderPath, callback) => global.SG.fs.exists(folderPath, exists => (exists ? callback() : (module.exports.dir.mkdirsByFolderPath(global.SG.path.dirname(folderPath), () => global.SG.fs.mkdir(folderPath, callback))))),//遞歸創建文件夾目錄(基于文件夾路徑)mkdirsByFilePath: (filePath, callback) => (filePath = global.SG.path.dirname(filePath), global.SG.fs.exists(filePath, exists => exists ? callback() : module.exports.dir.mkdirsByFilePath(filePath, () => global.SG.fs.mkdir(filePath, callback))))//遞歸創建文件夾目錄(基于文件路徑)},json: {//返回體報文結構公共方法________________________res(req, res, msg, data, success = true) {res.json({nowtime: module.exports.date.nowtime(), token: req.headers.token, code: success ? 0 : -1, success, msg, data});}},array: {/* 判斷一個數組(支持一個字符串)里面的是否有任何一個元素被包含在了某個字符串里面 */isStringContain(str, arr) {Array.isArray(arr) || (arr = [arr]);for (let i = 0, len = arr.length; i < len; i++) {if (str.includes(arr[i])) return true; //只要有一個元素被包含了就終止循環}return false;},/**獲取數組最大值*/getMax(arr) {// 利用apply 將數組元素拆成一個個參數讓Math.max去計算// return Math.max.apply(null, arr); // ES5寫法;return Math.max(...arr); // ES6寫法;},/**獲取數組最小值*/getMin(arr) {// 利用apply 將數組元素拆成一個個參數讓Math.min去計算// return Math.min.apply(null, arr);// ES5寫法return Math.min(...arr); // ES6寫法;},/**判斷是否為數組類型*/isArray(o) {return Object.prototype.toString.call(o) == "[object Array]";},/**刪除數組中指定元素*/removeFirstByValue(val) {for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];if (a == val) {arr.splice(i, 1);break;}}return arr;/*測試用例*//*let arr = ["mon", "tue", "wed", "thur"];alert(removeFirstByValue(arr, "wed"));*/},/**刪除數組中指定匹配的所有元素*/removeAllByValue(val) {let newArr = [];for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];a != val && newArr.push(a);}return newArr;/*測試用例*//*let arr = ["mon", "tue", "wed","wed","wed", "thur"];alert(removeAllByValue(arr, "wed"));*/},/**刪除對應鍵值的→第一個元素*/removeFirstByMatchKey(arr, macthKey, matchKeyValue) {for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];if (a[macthKey] == matchKeyValue) {arr.splice(i, 1);break;}}return arr;},/**刪除對應鍵值的→所有元素*/removeAllByMatchKey(arr, macthKey, matchKeyValue) {let newArr = [];for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];a[macthKey] != matchKeyValue && newArr.push(a);}return newArr;},/**移動數組里面的對應元素step個位置,注意!!!會直接修改原數組*/moveArray(arr, index, step) {/*如step為負數,則往前面移動對應步數。如:-2往前移動兩步,3往后移動三步*/let moveToIndex = index + step;moveToIndex < 0 && (moveToIndex = arr.length - 1);moveToIndex > arr.length - 1 && (moveToIndex = 0);arr.splice(moveToIndex, 0, arr.splice(index, 1)[0]);return arr;/*測試用例*//*let arr = ['第一個', '第二個', '第三個', '第四個']; array.moveArray(arr, 1, -2); /!*第二個元素往前移動2步,將會移動到數組最后一個位置*!/ console.log(arr);*/},/**把數組里面的對應元素插入到某個位置,注意!!!會直接修改原數組*/jumpQueue(arr, currentIndex, targetIndex) {/*把數組arr里面的currentIndex索引插到targetIndex索引位置*/if (!arr || arr.length === 0) return console.log("%c報錯信息:", "background:red;color:white;padding:5px;border-radius:5px;", "arr不能為空");if (currentIndex < 0 || targetIndex < 0 || currentIndex > arr.length - 1 || targetIndex > arr.length - 1) return console.log("%c報錯信息:", "background:red;color:white;padding:5px;border-radius:5px;", "currentIndex或者targetIndex超出了arr的索引范圍");arr.splice(targetIndex, 0, arr.splice(currentIndex, 1)[0]);return arr;/*測試用例*//*let arr = ['第一個', '第二個', '第三個', '第四個']; array.jumpQueue(arr, 3, 0); /!*第四個元素插隊到第一個位置*!/ console.log(arr);*/},/**對比兩個數組不同元素,從第一個數組里面排除第二個數組里面相同元素,isAddBdiffPart為true時加入第二個數組不同部分返回結果*/getdiffarr(A, B, isAddBdiffPart) {let C = [];let D = [];let Astr = "," + A.toString() + ",";let Bstr = "," + B.toString() + ",";for (let i in A) {if (!Bstr.includes("," + A[i] + ",")) {C.push(A[i]);}}for (let p in B) {if (!Astr.includes("," + B[p] + ",")) {D.push(B[p]);}}return isAddBdiffPart ? C.concat(D) : C;/*測試用例*//*let F = array.getdiffarr([9, 7, 1, 2, 3, 4], [3, 4, 1, 8], true); console.log(F);*/},/**數組排序:isAsc=true升序;isAsc=false降序*/getSort(arr, isAsc) {var arr = arr.concat();arr.sort((a, b) => {return isAsc ? a - b : b - a;});return arr;},/**關聯數組排序:isAsc=true升序;isAsc=false降序*/getSortByKey(arr, key, isAsc) {let o = arr.concat();o.sort((a, b) => {return isAsc ? a[key] - b[key] : b[key] - a[key];});return o;},/**數組對象根據某個值相同合并分組(collectKeyName是用于比對合并的鍵值,addOtherKeys是附加的鍵值)*/collect(arr, collectKeyName, addOtherKeys) {let map = {},arr2 = [];for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];if (!map[a[collectKeyName]]) {let obj = {collectName: a[collectKeyName], collectValue: [a]};/*追加可選鍵值*/let arr3 = addOtherKeys || [];for (let k = 0, len3 = arr3.length; k < len3; k++) {let c = arr3[k];obj[c] = a[c];}arr2.push(obj);map[a[collectKeyName]] = a;} else {for (let j = 0, len2 = arr2.length; j < len2; j++) {let b = arr2[j];if (b.collectName == a[collectKeyName]) {b.collectValue.push(a);break;}}}}return arr2;},/**獲取ID→對應的記錄*/getById(arr, id) {return this.getByMatchKey(arr, "id", id);},/**獲取ID→對應的值*/getValueById(arr, id) {let re = this.getById(arr, id);return re ? re.value : null;},/**獲取對應值的→ID*/getIdByValue(arr, value) {let re = this.getByMatchKey(arr, "value", value);return re ? re.id : null;},/**獲取對應值的→記錄*/getByMatchKey(arr, matchKey, matchKeyValue) {for (let k in arr) {let a = arr[k];if (a && a[matchKey] == matchKeyValue) {return a;}}},/**獲取對應值的→鍵的值*/getValueByMatchKey(arr, matchKey, matchKeyValue, keyName) {let re = this.getByMatchKey(arr, matchKey, matchKeyValue);return re ? re[keyName] : null;},/**設置數組對應ID→對應的key值*/setKeyValueById(arr, id, keyName, keyValue) {this.setValueByMatchKey(arr, "id", id, keyName, keyValue);},/**設置數組對應自定義匹配key→對應的值keyValue*/setValueByMatchKey(arr, matchKey, matchKeyValue, keyName, keyValue) {for (let k in arr) {let a = arr[k];if (a && a[matchKey] == matchKeyValue) {a[keyName] = keyValue;}}},/**根據對應自定義匹配key→對應的值index*/getIndexByMatchKey(arr, matchKey, matchKeyValue) {for (let k in arr) {let a = arr[k];if (a && a[matchKey] == matchKeyValue) {return k; //返回值記得用parseInt()轉換為int類型,如果搜索的arr是一個object對象則不用轉換值類型,返回的就是key的字符串}}},/**根據value的值獲取元素索引值index*/getIndexByValue(arr, value) {return this.getIndexByMatchKey(arr, "value", value);},/**根據id的值獲取元素索引值index*/getIndexById(arr, id) {return this.getIndexByMatchKey(arr, "id", id);},/**獲取數組對應key→對應的valueKey值(key的格式{key: "id", value: 2, valueKey: "b"}),指定對應id等于2的b字段返回值;valueKey為空時返回整個元素記錄*/getkeyValueByKeyValue(arr, key) {for (let k in arr) {let a = arr[k];if (a[key.key] == key.value) {return key.valueKey ? a[key.valueKey] : a;}}/*測試用例*//* console.log(getkeyValueByKeyValue([{id: 1, a: 11, b: 111}, {id: 2, a: 22, b: 222}], {key: "id", value: 2, valueKey: "b"}));*/},/**設置數組對應key→對應的valueKey值(key的格式{key: "id", value: 2, setKey: "b", setValue: "999"}),設置對應id等于2的b字段的值為999*/setkeyValueByKeyValue(arr, key) {for (let k in arr) {let a = arr[k];if (a[key.key] == key.value) {a[key.setKey] = key.setValue;}}return arr;/*測試用例*//* console.log(setkeyValueByKeyValue([{id: 1, a: 11, b: 111}, {id: 2, a: 22, b: 222}], {key: "id", value: 2, setKey: "b", setValue: 999}));*/},/**根據by數組的key對應的值→去from的arr數組里面查詢key對應的值相同的項并返回數組,o的結構: { from: { arr: arr1, key: "value", }, by: { arr: arr2, key: "id", } } */getArrayByTwoKey(o) {let reArr = [];let arr1 = o.from.arr,k1 = o.from.key,arr2 = o.by.arr,k2 = o.by.key;for (let i = 0, len = arr2.length; i < len; i++) {let b = arr2[i];arr1.forEach(a => {a[k1] == (k2 ? b[k2] : b) && reArr.push(a);});}return reArr;},__convertToKeyValueObject(obj) {for (let i in obj) {let a = obj[i];return {"key": i, "value": a};}},/**模糊搜索key→對應的value值(obj的格式{keyName:keyValue})*/searchArrayByKey(arr, obj) {let reArr = [];obj = this.__convertToKeyValueObject(obj);for (let k in arr) {let a = arr[k];if (a[obj.key].toString().includes(obj.value)) {reArr.push(a);}}return reArr;},/**模糊搜索→全字段值匹配*/searchArrayByValue(arr, value) {let reArr = [];for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];for (let k in a) {let b = a[k];if (b.toString().toLowerCase().includes(value.toLowerCase())) {reArr.push(a);break;}}}return reArr;},/**獲取longString字符串中被startStr和end重復夾住的字符串*/getBetween(longString, startStr, endStr) {let arr = longString.split(startStr),reArr = [];arr.shift();for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];reArr.push(a.split(endStr)[0]);}return reArr;},/**用指定字符串分割將相同元素歸類,并返回新的數組*/getSortOutArrayBySplit(arr, splitStr) {let retArr = [],ind = -1,oldValue;for (let i = 0, len = arr.length; i < len; i++) {let newValue = arr[i];oldValue == newValue ? (retArr[ind] = retArr[ind] + (splitStr || "/") + newValue) : (oldValue = newValue, ind++, retArr[ind] = newValue);}return retArr;/* 測試用例let subList = [1, 1, 1, 2, 2, 3, 3];console.log(array.getSortOutArrayBySplit(subList,'/'));//output: ["1/1/1", "2/2", "3/3"];*/},/**去重(效率最高的方法)*/distinct(arr) {let re = [],obj = {};for (let i of arr) {obj[i] || (re.push(i), obj[i] = true);}return re;// return [...new Set(arr)];//去重最精簡方法},/** es6語法:過濾JS數組中的空值,假值等(es6語法) */filterNullUndefined: arr => arr.filter(item => item)//測試用例//console.log(array.filterNullUndefined([undefined, undefined, 1, "", "false", false, true, null, "null"]));},/**驗證一切*/checkEverything(type, s) {switch (type.toString().toLocaleLowerCase()) {case "postcode":/**驗證郵政編碼*/return /^(0[1234567]|1[012356]|2[01234567]|3[0123456]|4[01234567]|5[1234567]|6[1234567]|7[012345]|8[013456])\d{4}$/.test(s);case "uppercase":/**驗證是否包含大寫字母*/return /[A-Z]/.test(s);case "car":s = s.toString();if (s.length == 8) {return /^[京津滬渝冀豫云遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陜吉閩貴粵青藏川寧瓊使領A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/.test(s);} else if (s.length == 7) {return /^[京津滬渝冀豫云遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陜吉閩貴粵青藏川寧瓊使領A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9掛學警港澳]{1}$/.test(s);} else {return false;}case "integer":return /^[0-9]+$/.test(s);case "special":return /[\<\>]/.test(s);case "name":/*中文名*/return /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/.test(s);case "cn":/*包含中文*/return /[\u4E00-\u9FA5]/i.test(s);case "id":/*身份證*/return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(s);case "user":/*賬號*/return /^[a-zA-z]\w{3,15}$/.test(s);case "httpurl":return /(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(s);case "url":return /^(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/.test(s);case "mobile":/*手機號*/return /^1\d{10}$/.test(s);case "tel":/*座機號*/return /^0\d{2,3}-?\d{7,8}$/.test(s);case "email":return /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(s);case "number":return /^\d+$/g.test(s);case "password":if (s == "") {return false;} else if (s.split(" ").length != 1) {return false;} else {if ((s.search(/^[a-zA-Z]+$/g) != -1) || (s.search(/^[0-9]+$/g) != -1)) {return false;} else if (s.search(/^[a-zA-Z0-9]+$/g) != -1) {return false;} else {return false;}}return true;}},date: {nowtime: () => global.SG.moment().format("YYYY-MM-DD HH:mm:ss:ms"),//獲取當前時間(含毫秒)timestamp: () => (global.SG.moment().format("YYYYMMDDHHmmssms") + new Date().getTime() + Math.random()).replace(/\./g, ""),//獲取時間戳()//新方法(時:分:秒)HH_mm_ss(date = null) {return new Date(date).toLocaleString("zh-Hans-CN", {hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false});},//新方法(年-月-日)yyyy_MM_dd(date = null) {return new Date(date).toLocaleString("zh-Hans-CN", {year: "numeric", month: "2-digit", day: "2-digit"}).replace(/\//g, "-");},//新方法(年-月-日 時:分:秒)yyyy_MM_dd_HH_mm_ss(date = null) {return new Date(date).toLocaleString("zh-Hans-CN", {year: "numeric", month: "2-digit", day: "2-digit", hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit"}).replace(/\//g, "-");},yearMonthDay() {return new Date().getFullYear() + ("0" + (new Date().getMonth() + 1)).slice(-2) + ("0" + new Date().getDate()).slice(-2);},year_Month_Day() {return new Date().getFullYear() + "-" + ("0" + (new Date().getMonth() + 1)).slice(-2) + "-" + ("0" + new Date().getDate()).slice(-2);},yMd(dt, split) {dt || (dt = new Date());split || (split = "-");return dt.getFullYear() + split + ("0" + (dt.getMonth() + 1)).slice(-2) + split + ("0" + dt.getDate()).slice(-2);},/**判斷是否逾期*/over(endDate, isEqual) {let d1 = new Date().getTime(),d2 = new Date(endDate).getTime();return isEqual ? d1 >= d2 : d1 > d2;},/**比較日期大小,前一個日期大于(isEqual=true時 比較大于等于)后一個日期時返回true*/compare(d1, d2, isEqual) {d1 = new Date(d1).getTime(), d2 = new Date(d2).getTime();return isEqual ? d1 >= d2 : d1 > d2;},/**獲取指定日期之前/之后的某天*/pointDate(dt, n) {if (!n) return dt;let s = "/";if (dt.indexOf("-") > -1) {s = "-", dt = dt.replace(/-/g, "/");} else if (dt.indexOf(".") > -1) {s = ".", dt = dt.replace(/\./g, "/");}let d = new Date(dt),lw = new Date(Number(d) + 1000 * 60 * 60 * 24 * Math.floor(n)),/*n天數*/ly = lw.getFullYear(),lm = lw.getMonth() + 1,ld = lw.getDate(),sd = ly + s + (lm < 10 ? "0" + lm : lm) + s + (ld < 10 ? "0" + ld : ld);return sd;},/**獲得當前日期之前之后任意天的日期*/anyDate(n) {let dt = new Date();dt.setDate(dt.getDate() + n);return date.yMd(dt);},/**獲得當前日期之前之后任意天的日期+時間*/anyDateTime(n) {let dt = new Date();dt.setDate(dt.getDate() + n);return formatDateTime(dt);},/**獲得任意天的日期時間戳:n為負數就是過去的天數,正數則為未來的天數*/anyDateTimeStamp(n) {return new Date(date.anyDate(n) + " 00:00:00").getTime();},/**獲得本月的開始日期、結束日期*/monthStartOrEndDate(isStart) {let now = new Date(),m = now.getMonth(),y = now.getFullYear(),msd = new Date(y, m, Boolean(isStart) ? 1 : new Date(y, m + 1, 0).getDate());return date.yMd(msd);},/**獲得本周的開始日期、結束日期*/weekStartOrEndDate(isStart) {let now = new Date(),d = now.getDay(),nd = now.getDate(),m = now.getMonth(),y = now.getFullYear(),wsd = new Date(y, m, nd + (Boolean(isStart) ? -d : 6 - d));return date.yMd(wsd);},/**計算指定日期加上多少天、加多少月、加多少年的日期*/add(type, number, date) {let d = date ? (date instanceof Date ? date : new Date(date)) : new Date();switch (type) {case "y":d.setFullYear(d.getFullYear() + number);return d;case "q":d.setMonth(d.getMonth() + number * 3);return d;case "m":d.setMonth(d.getMonth() + number);return d;case "w":d.setDate(d.getDate() + number * 7);return d;case "d":d.setDate(d.getDate() + number);return d;case "h":d.setHours(d.getHours() + number);return d;case "m":d.setMinutes(d.getMinutes() + number);return d;case "s":d.setSeconds(d.getSeconds() + number);return d;default:d.setDate(d.getDate() + number);return d;}/*/!* 加2天.*!/ alert(date.add("d ", 2).toLocaleString()) /!* 加2月.*!/ alert(date.add("m ", 2).toLocaleString()) /!* 加2年*!/ alert(date.add("y ", 2).toLocaleString());*/},format(date, fmt) {date = date instanceof Date ? date : new Date(date);let o = {"M+": date.getMonth() + 1,"d+": date.getDate(),"h+": date.getHours() % 12 == 0 ? 12 : date.getHours() % 12,"H+": date.getHours(),"m+": date.getMinutes(),"s+": date.getSeconds(),"q+": Math.floor((date.getMonth() + 3) / 3),"S": date.getMilliseconds()};if (/(y+)/.test(fmt)) {fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));}if (/(E+)/.test(fmt)) {fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "星期" : "周") : "") + "日一二三四五六".charAt(date.getDay()));}for (let k in o) {if (new RegExp("(" + k + ")").test(fmt)) {fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));}}return fmt;},/**格式化日期:yyyy-MM-dd HH:mm:ss */formatDate(timeStamp) {return date.format(timeStamp ? (timeStamp instanceof Date ? timeStamp : new Date(timeStamp)) : new Date(), "yyyy-MM-dd");},/**格式化日期:yyyy-MM-dd HH:mm:ss */formatDateTime(timeStamp) {return date.format(timeStamp ? (timeStamp instanceof Date ? timeStamp : new Date(timeStamp)) : new Date(), "yyyy-MM-dd HH:mm:ss");},/**格式化日期:yyyy年MM月dd日 HH:mm:ss */formatToyyyyMMddHHmmssEE(timeStamp) {return date.format(timeStamp ? (timeStamp instanceof Date ? timeStamp : new Date(timeStamp)) : new Date(), "yyyy年MM月dd日 HH:mm:ss EE");},getDay() {return "星期" + "日一二三四五六".charAt(new Date().getDay());},/**轉換Date為24小時計時時間格式*/to24hours(date) {let now = date ? (date instanceof Date ? date : new Date(date)) : new Date();now = now.toLocaleTimeString("zh-Hans-CN", {hour12: false}),now = now.substr(0, now.lastIndexOf(":"));return now;},/**將秒數量轉換為時分秒字符串*/toHourMinuteSecond(second, data) {let t = "",s = Math.round(second),d = data.isDoubleDigits, //顯示雙位數hz = data.hideZero, //隱藏為0的時間單位hh = data.hideHour, //隱藏小時hm = data.hideMinute, //隱藏分鐘hs = data.hideSecond; //隱藏秒鐘if (s > 0) {let hour = Math.floor(s / 3600),min = Math.floor(s / 60) % 60,sec = s % 60;hh || (hz && !hour) || (d && hour < 10 && (t += "0"), t += hour + "時");hm || (hz && !min) || (d && min < 10 && (t += "0"), t += min + "分");hs || (hz && !sec) || (d && sec < 10 && (t += "0"), t += sec + "秒");}return t;//測試用例/*alert(toHourMinuteSecond(3661,{// isDoubleDigits:true,hideZero:true,// hideHour:true,// hideMinute:true,// hideSecond:true,}));*/},/**獲取最近幾個月的年月份*/getRecentSeveralMonth(n) {let date = new Date();let nearMonth = [];for (let i = 1; i <= n; i++) {date.setMonth(date.getMonth() - 1);nearMonth.unshift(date.getFullYear() + "/" + (date.getMonth() + 1));}return nearMonth;},/**把時間轉換為分鐘數*/hourMinuteToMinute(timeString) {timeString = timeString.replace(/:/g, ":").replace(/\ |\ /g, "").replace(/::/g, ":").split(":");return parseInt(timeString[0] * 60) + parseInt(timeString[1]);},/**顯示幾分鐘前剛剛發布文章*/timeAgo(timeStamp) {let minute = 1000 * 60,hour = minute * 60,day = hour * 24,week = day * 7,month = day * 30,now = new Date().getTime(),diffValue = now - timeStamp;let minC = diffValue / minute,hourC = diffValue / hour,dayC = diffValue / day,weekC = diffValue / week,monthC = diffValue / month,res;if (monthC > 3 && monthC < 12) {res = "半年前";} else if (monthC >= 1 && monthC <= 3) {res = parseInt(monthC) + "月前";} else if (weekC >= 1 && weekC < 4) {res = parseInt(weekC) + "周前";} else if (dayC >= 1 && dayC < 7) {res = parseInt(dayC) + "天前";} else if (hourC >= 1 && hourC < 24) {res = parseInt(hourC) + "小時前";} else if (minC >= 1 && minC < 60) {res = parseInt(minC) + "分鐘前";} else if (diffValue >= 0 && diffValue <= minute) {res = "剛剛";} else {res = this.formatDateTime(timeStamp);}return res;},between(startDate, endDate) {startDate = startDate instanceof Date ? startDate : new Date(startDate);endDate = endDate instanceof Date ? endDate : new Date(endDate);var today = new Date().getTime(),startDate = new Date(startDate).getTime(),endDate = new Date(endDate).getTime();return startDate < today && today < endDate;},/**計算兩個日期相差天數*/getDayBetween(startDate, endDate) {startDate = startDate instanceof Date ? startDate : new Date(startDate);endDate = endDate instanceof Date ? endDate : new Date(endDate);return Math.floor(this.getMillisecondBetween(startDate, endDate));},/**計算兩個日期相差毫秒數*/getMillisecondBetween(startDate, endDate) {startDate = startDate instanceof Date ? startDate : new Date(startDate);endDate = endDate instanceof Date ? endDate : new Date(endDate);return Math.abs((Date.parse(endDate) - Date.parse(startDate)) / 86400000);}}
};
api/demo/insert.js
const $g = global.SG.$g, fs = global.SG.fs, router = global.SG.router;
module.exports = global.SG.router;const writeJSON = (url, params, success, fail) => {fs.readFile(url, (err, data) => {if (err) {fail && fail({code: -1, msg: "讀取數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----添加失敗----");}data = JSON.parse(data.toString());data.push(params);fs.writeFile(url, JSON.stringify(data), err => {if (err) {fail && fail({code: -1, msg: "寫入數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----添加失敗----");}success && success({change: params, data});//回顯發生改變的內容用于關聯表處理的前端業務邏輯console.log($g.date.nowtime() + "\n", data, "\n----添加成功----");});});
};//添加數據(all方法支持POST、GET、PUT、PATCH、DELETE傳參方式)
router.all("/demo/insert", (req, res) => {const name = req.body.name || req.query.name;const tel = req.body.tel || req.query.tel;let params = {id: $g.date.timestamp(), name: name, tel: tel};if (!params.name) return $g.json.res(req, res, "缺少姓名字段", params, false);if (!params.tel) return $g.json.res(req, res, "缺少手機號字段", data, false);if (!$g.checkEverything("mobile", params.tel)) return $g.json.res(req, res, "手機號格式不正確", params, false);writeJSON("json/demo/demo.json", params, data => $g.json.res(req, res, "添加成功", data, true), err => $g.json.res(req, res, err.msg || "添加失敗", err.data, false));
});
?api/demo/delete.js
const $g = global.SG.$g, fs = global.SG.fs, router = global.SG.router;
module.exports = global.SG.router;const writeJSON = (url, id, success, fail) => {const ids = Array.isArray(id) ? id : [id.toString()]; //批量刪除功能fs.readFile(url, (err, data) => {if (err) {fail && fail({code: -1, msg: "讀取數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----刪除失敗----");}data = JSON.parse(data.toString());let arr = data, re = [], successIds = [], changes = [];for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];ids.includes((a.id || "null").toString()) ? (successIds.push(a.id), changes.push(a)) : re.push(a);}if (!successIds.length) {fail && fail({code: -1, msg: `沒有找到對應id:${ids}的記錄,刪除失敗`, data});return console.error($g.date.nowtime(), "\n----刪除失敗----");}fs.writeFile(url, JSON.stringify(re), err => {if (err) {fail && fail({code: -1, msg: "寫入數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----刪除失敗----");}success && success({change: changes, data: re});//回顯發生改變的內容用于關聯表處理的前端業務邏輯console.log($g.date.nowtime() + "\n", re, `\n----id:${successIds}刪除成功----`);});});
};//刪除數據(all方法支持POST、GET、PUT、PATCH、DELETE傳參方式)
router.all("/demo/delete", (req, res) => {const id = req.body.id || req.query.id;if (!id) return $g.json.res(req, res, "缺少id字段", id, false);writeJSON("json/demo/demo.json", id, data => $g.json.res(req, res, "刪除成功", data, true), err => $g.json.res(req, res, err.msg || "刪除失敗", err.data, false));
});
?api/demo/update.js
const $g = global.SG.$g, fs = global.SG.fs, router = global.SG.router;
module.exports = global.SG.router;const writeJSON = (url, params, success, fail) => {let id = params.id;delete params.id;fs.readFile(url, (err, data) => {if (err) {fail && fail({code: -1, msg: "讀取數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----修改失敗----");}data = JSON.parse(data.toString());let change = null, arr = data;for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];if (a.id === id) {for (let key in params) a[key] = params[key];change = a;break;}}if (!change) {fail && fail({code: -1, msg: `沒有找到對應${id}的記錄,修改失敗`, data});return console.error($g.date.nowtime(), "\n----修改失敗----");}fs.writeFile(url, JSON.stringify(data), err => {if (err) {fail && fail({code: -1, msg: "寫入數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----修改失敗----");}success && success({change, data});//回顯發生改變的內容用于關聯表處理的前端業務邏輯console.log($g.date.nowtime() + "\n", data, `\n----id:${id}修改成功----`);});});
};//修改數據(all方法支持POST、GET、PUT、PATCH、DELETE傳參方式)
router.all("/demo/update", (req, res) => {const id = req.body.id || req.query.id;const name = req.body.name || req.query.name;const tel = req.body.tel || req.query.tel;let params = {};id && (params.id = id);name && (params.name = name);tel && (params.tel = tel);if (!params.id) return $g.json.res(req, res, "缺少id字段", params, false);if (params.tel && !$g.checkEverything("mobile", params.tel)) return $g.json.res(req, res, "請輸入正確的手機號", params, false);writeJSON("json/demo/demo.json", params, data => $g.json.res(req, res, "修改成功", data, true), err => $g.json.res(req, res, err.msg || "修改失敗", err.data, false));
});
api/demo/select.js
const $g = global.SG.$g, fs = global.SG.fs, router = global.SG.router;
module.exports = global.SG.router;const isMatch = (record, obj) => {let countDefault = 0;let countMatch = 0;for (let key in obj) {countDefault++;let value = obj[key];record[key] == value && (countMatch++);}return countDefault === countMatch;
};const readJSON = (url, params, success, fail) => {let pageNum = parseInt(params.pageNum || 0);//默認從第1頁開始pageNum < 0 && (pageNum = 0);let pageSize = parseInt(params.pageSize || 0);//不傳參就顯示所有數據pageSize < 0 && (pageSize = 10);delete params.pageNum;delete params.pageSize;fs.readFile(url, (err, data) => {if (err) {fail && fail({code: -1, msg: "讀取數據失敗", data: err});return console.error($g.date.nowtime() + "\n", err, "\n----查詢失敗----");}data = JSON.parse(data.toString());let re = [];let arr = data;for (let i = 0, len = arr.length; i < len; i++) {let a = arr[i];isMatch(a, params) && re.push(a);}re = re.slice(pageNum * pageSize, pageSize ? (pageNum + 1) * pageSize : re.length);success && success({data: re, total: re.length, pageNum: pageNum, pageSize: pageSize});console.log($g.date.nowtime() + "\n", re, "\n----查詢成功----");});
};//查詢數據(all方法支持POST、GET、PUT、PATCH、DELETE傳參方式)
router.all("/demo/select", (req, res) => {const id = req.body.id || req.query.id;const name = req.body.name || req.query.name;const tel = req.body.tel || req.query.tel;const pageNum = req.body.pageNum || req.query.pageNum;const pageSize = req.body.pageSize || req.query.pageSize;let params = {};id && (params.id = id);name && (params.name = name);tel && (params.tel = tel);pageNum && (params.pageNum = pageNum);pageSize && (params.pageSize = pageSize);readJSON("json/demo/demo.json", params, data => $g.json.res(req, res, "查詢成功", data, true), err => $g.json.res(req, res, err.msg || "查詢失敗", err.data, false));
});
?json/demo/demo.json
[{"id": 1,"name": "張三","tel": "13888888888"},{"id": 2,"name": "李四","tel": "13888888888"},{"id": 3,"name": "王五","tel": "13888888888"}
]
按照上面的方式創建好項目后,記得在根目錄運行:
npm i body-parser -D & cnpm i express & cnpm i node-xlsx & node index
啟動后訪問:
http://127.0.0.1:9999/api/demo/select
總結
以上是生活随笔為你收集整理的Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何关闭vue项目中eslint的校验
- 下一篇: 进一步封装axios并调用其读取数据(吐