From c2a74385b067984294264a2112d737cc441f4ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=A6=8F=E8=B4=A2?= <1471584931@qq.com> Date: Mon, 19 Jan 2026 16:43:02 +0800 Subject: [PATCH] =?UTF-8?q?----=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- src/api/mdm/CountryRegion/index.ts | 34 ++++++--- src/utils/storage.ts | 117 +++++++++++++++++++++++++++++ src/utils/type-tools.ts | 78 +++++++++++++++++++ 4 files changed, 219 insertions(+), 12 deletions(-) create mode 100644 src/utils/storage.ts create mode 100644 src/utils/type-tools.ts diff --git a/.env.development b/.env.development index a06aa67..c8f7be9 100644 --- a/.env.development +++ b/.env.development @@ -10,7 +10,7 @@ VITE_PUBLIC_PATH = / # 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题 # 可以有多个,注意多个不能换行,否则代理将会失效 #VITE_PROXY = [["/api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]] -VITE_PROXY=[["/api","http://10.10.2.102:9500"]] +VITE_PROXY=[["/api","http://127.0.0.1:8090"]] #VITE_PROXY=[["/api/system/generator/","http://127.0.0.1:8091/system/generator/"],["/api/system/file/","http://127.0.0.1:8091/system/file/"],["/api/system/oss/","http://127.0.0.1:8091/system/oss/"],["/api/sales/","http://127.0.0.1:8096","/sales/"],["/api/mdm/","http://127.0.0.1:8096","/mdm/"],["/api","http://10.10.2.102:9500"]] #VITE_PROXY=[["/api/sales/","http://127.0.0.1:8096","/sales/"],["/api/mdm/","http://127.0.0.1:8096","/mdm/"],["/api","http://10.10.2.102:9500"]] #VITE_PROXY=[["/api/mdm/","http://127.0.0.1:8096","/mdm/"],["/api/sales/","http://127.0.0.1:8096","/sales/"],["/api","http://10.10.2.102:9500"]] diff --git a/src/api/mdm/CountryRegion/index.ts b/src/api/mdm/CountryRegion/index.ts index 559d020..96c5bb9 100644 --- a/src/api/mdm/CountryRegion/index.ts +++ b/src/api/mdm/CountryRegion/index.ts @@ -1,6 +1,7 @@ import { LngBRegionPageModel, LngBRegionPageParams, LngBRegionPageResult } from './model/CountryRegionModel'; import { defHttp } from '/@/utils/http/axios'; import { ErrorMessageMode } from '/#/axios'; +import TStorage,{cache} from '/@/utils/storage'; enum Api { Page = '/mdm/countryRegion/page', @@ -37,7 +38,9 @@ export async function getTreeData(params: LngBRegionPageParams, mode: ErrorMessa * @description: 分节点查询LngBRegion树 */ export async function getAreaList(params: LngBRegionPageParams, mode: ErrorMessageMode = 'modal') { - return defHttp.get( + let pkey = params.pid?params.pid:"#"; + return cache(CacheKey.TREE_CHILD_DATA+":"+pkey, TStorage.timeOf(TStorage.TIME.MINUTE, 10), + defHttp.get( { url: Api.TreeChild, params, @@ -45,21 +48,30 @@ export async function getAreaList(params: LngBRegionPageParams, mode: ErrorMessa { errorMessageMode: mode, }, - ); + )); } + +const CacheKey = { + TREE_DATA: 'LngBRegion:TreeChildInfo', + TREE_CHILD_DATA: 'LngBRegion:TreeChild', +}; + + + /** * @description: 分节点查询LngBRegion树回显 */ export async function getAreaInfo(params: LngBRegionPageParams, mode: ErrorMessageMode = 'modal') { - return defHttp.get( - { - url: Api.TreeChildInfo, - params, - }, - { - errorMessageMode: mode, - }, - ); + return cache(CacheKey.TREE_DATA+":"+params.code, TStorage.timeOf(TStorage.TIME.MINUTE, 10), + defHttp.get( + { + url: Api.TreeChildInfo, + params, + }, + { + errorMessageMode: mode, + }, + )); } /** * @description: 查询LngBRegion分页列表 diff --git a/src/utils/storage.ts b/src/utils/storage.ts new file mode 100644 index 0000000..4278aff --- /dev/null +++ b/src/utils/storage.ts @@ -0,0 +1,117 @@ +import TypeTools, { TYPES } from './type-tools'; + +class StorageData { + + data: any; + + type: string; + + timeout: number; + + constructor(data: any, type: string, timeout: number) { + this.data = data; + this.type = type; + this.timeout = timeout; + } + + + + + + /** + * 判断缓存是否过期 + */ + isExpired(): boolean { + if (!this.timeout) return false; + return new Date().getTime() > this.timeout; + } + + getData(): any { + if(this.type === TYPES.DATE){ + return new Date(parseInt(this.data)); + }else if(this.type== TYPES.OBJ || this.type== TYPES.ARRAY){ + return JSON.parse(this.data); + }else if(this.type== TYPES.REGEXP){ + return new RegExp(this.data.pattern, this.data.flags); + }else if(this.type== TYPES.BOOLEAN){ + return this.data === 'true'; + }else if(this.type== TYPES.NUMBER){ + return new Number(this.data); + }else if(this.type== TYPES.STRING){ + return this.data; + } + return this.data; + } + + static fromData(data: any,timeout?: number): StorageData { + if(timeout==undefined) timeout = new Date().getTime() + 600000; // Default timeout to 10 minutes from now + let type = TypeTools.parseType(data); + if(type === TYPES.UNKNOWN ||type== TYPES.FUNCTION || type== TYPES.JSON){ + throw new Error('错误的数据类型,不能保存'); + } + let sdata = data; + if(type === TYPES.DATE){ + sdata = data.getTime(); + }else if(type== TYPES.OBJ || type== TYPES.ARRAY){ + sdata = JSON.stringify(data); + }else if(type== TYPES.REGEXP){ + sdata = JSON.stringify({ + pattern: data.pattern, + flags: data.flags + }); + } + return new StorageData(sdata,type,timeout); + } + + static fromJSON(json: string): StorageData { + const data = JSON.parse(json); + return new StorageData(data.data,data.type,parseInt(data.timeout)); + } +} + +const TStorage = { + TIME:{SECOND:1000,MINUTE:60000,HOUR:3600000,DAY:86400000}, + timeOf(type: number,total:number): number { + return type*total; + }, + set(key: string, data: any, timeout: number = 0) { + const storageData = StorageData.fromData(data,timeout); + localStorage.setItem(key, JSON.stringify(storageData)); + }, + get(key: string,timeout?:number) { + const sData = localStorage.getItem(key); + if (sData) { + const data = StorageData.fromJSON(sData); + if (data.isExpired()) { + if(timeout && timeout > 0){ + data.timeout = new Date().getTime() + timeout; + localStorage.setItem(key,JSON.stringify(data)); + }else{ + localStorage.removeItem(key); + return null; + } + } + return data.getData(); + } + return null; + } +} + +export async function cache(key:string, timeout: number = 0, promise: Promise):Promise{ + return new Promise((resolve, reject) => { + const cachedData = TStorage.get(key,timeout); + if (cachedData!=undefined) { + resolve(cachedData); + } else { + promise.then((data) => { + TStorage.set(key, data, timeout); + resolve(data); + }).catch((err) => { + reject(err); + }); + } + }); +} + +export default TStorage; + diff --git a/src/utils/type-tools.ts b/src/utils/type-tools.ts new file mode 100644 index 0000000..0c6debd --- /dev/null +++ b/src/utils/type-tools.ts @@ -0,0 +1,78 @@ +const OBJ_TYPE = { + OBJ: "[object Object]", + NUMBER: "[object Number]", + STRING: "[object String]", + UNDEFINED: "[object Undefined]", + NULL: "[object Null]", + BOOLEAN: "[object Boolean]", + ARRAY: "[object Array]", + FUNCTION: "[object Function]", + DATE: "[object Date]", + REGEXP: "[object RegExp]", + JSON: "[object JSON]", +} + +const TYPES = { + BOOLEAN: "BOOLEAN", + NUMBER: "NUMBER", + STRING: "STRING", + DATE: "DATE", + REGEXP: "REGEXP", + NULL: "NULL", + OBJ: "OBJ", + ARRAY: "ARRAY", + JSON: "JSON", + FUNCTION: "FUNCTION", + UNKNOWN: "UNKNOWN", +} + +const TypeTools = { + parseType: function (obj: any) { + if (obj === null) return TYPES.NULL; + if(this.isNull(obj)) return TYPES.NULL; + if(this.isString(obj)) return TYPES.STRING; + if(this.isNumber(obj)) return TYPES.NUMBER; + if(this.isBoolean(obj)) return TYPES.BOOLEAN; + if(this.isDate(obj)) return TYPES.DATE; + if(this.isRegExp(obj)) return TYPES.REGEXP; + if(this.isArray(obj)) return TYPES.ARRAY; + if(this.isFunction(obj)) return TYPES.FUNCTION; + if(this.isObject(obj)) return TYPES.OBJ; + if(this.isJSON(obj)) return TYPES.JSON; + return TYPES.UNKNOWN; + }, + isString: function (obj: any) { + return OBJ_TYPE.STRING === Object.prototype.toString.call(obj); + }, + isBoolean: function (obj: any) { + return OBJ_TYPE.BOOLEAN === Object.prototype.toString.call(obj); + }, + isNumber: function (obj: any) { + return OBJ_TYPE.NUMBER === Object.prototype.toString.call(obj); + }, + isDate: function (obj: any) { + return OBJ_TYPE.DATE === Object.prototype.toString.call(obj); + }, + isRegExp: function (obj: any) { + return OBJ_TYPE.REGEXP === Object.prototype.toString.call(obj); + }, + isNull: function (obj: any) { + const type = Object.prototype.toString.call(obj); + return OBJ_TYPE.NULL === type || OBJ_TYPE.UNDEFINED === type; + }, + isJSON: function (obj: any) { + return OBJ_TYPE.JSON === Object.prototype.toString.call(obj); + }, + isArray: function (obj: any) { + return OBJ_TYPE.ARRAY === Object.prototype.toString.call(obj); + }, + isFunction: function (obj: any) { + return OBJ_TYPE.FUNCTION === Object.prototype.toString.call(obj); + }, + isObject: function (obj: any) { + return OBJ_TYPE.OBJ === Object.prototype.toString.call(obj); + } +}; + +export default TypeTools; +export { TYPES };