amos-processor
v2.2.4
Published
amos processor
Downloads
25
Readme
amos-processor
useage
npm i --save amos-processor
amos basi processor
contains redux、store and other redux middleware
apis
config
import SysConsts from 'amos-processor/lib/config/consts';
import SysConsts from 'amos-processor/lib/config';
import QueryEnum, {
enumList,
enumItemByValue,
enumItemByName,
SingleQueryEnum
} from 'amos-processor/lib/config/queryEnum'; // @since v1.2.22
// consts/default:
{
permissions: 'permissions',
api_key: 'X-Api-Key',
userId: 'userId',
userName: 'userName',
password: 'password',
remembered: 'remembered',// 记住密码
nickName: 'name',// 昵称
company: 'company',// 公司
role: 'role',// 角色
token: 'X-Access-Token',
hasPermissions: 'hasPermissions'
}
// endconf:
import * as endConf from 'amos-processor/lib/config/endconf';
// `包含如下模块`
completePrefix(left, right);// 补全url
/**
* @param {any} actionConf *必填项
* @param {any} baseUrl 选填,如果不传入参数,则默认为系统统一的baseURI
* @return object
* @doc
* import {completeUrl, baseURI, AsyncMethod} from 'amos-processor/lib/config/endconf';
* const PUT = AsyncMethod.PUT;
* let b = 'http://XXXX/',
* actionConf = {
* url: 'user/login',
* method: PUT
* }
* completeUrl(actionConf, b);
*/
completeUrl(actionConf, baseUrl);
staticPrefix: '/src/assets/'
baseURI
mockPrefix
prefix
securityBaseURI
nmpsBaseURI
nmpsWsBaseURI
operate_process_design
operationBaseURI
fireiotBaseURI
fireiotWsBaseURI
fireiotStatisticsURI
// permission:
gatherpermissionMenu();// 收集所有菜单项(有权限)
mergeMenu();// 合并公共菜单项,即有效的菜单项
sysConf; // 常量 Amos.config.sysConf
filterPermission(menusConf = []);// 权限过滤
checkLevel1Permissions(fn);// 过滤一级菜单
checkHomePermissions();// 检查是否有二级主页权限
// query enum
// -- 以防引起 sql 注入,此处,禁止使用 QueryEnum 中的 name,统一使用 value,否则将会被后端关键字过滤掉, 如:
QueryEnum.LESS_VALUE.value
QueryEnum.BIGGER_VALUE.value
QueryEnum.EQUAL_VALUE.value
// 或者直接使用 SingleQueryEnum
SingleQueryEnum.LESS
SingleQueryEnum.BIGGER
SingleQueryEnum.EQUAL
// enumList,将 QueryEnum 转化为 数组, 或者直接使用 `Object.values(QueryEnum)`
[
{ value: 1, name: 'LESS' },
{ value: 2, name: 'BIGGER' },
{ value: 3, name: 'EQUAL' },
...
]
// enumItem, 通过 value 获取具体的 enum 值 => enumItem(2)
enumItem(2) // => { value: 2, name: 'BIGGER' }
endconf
默认情况下,从 amos-processor/lib/config/endconf
获取到的模块 AmosConfig
数据,内容是禁止修改的
import * as endConf from 'amos-processor/lib/config/endconf';
const AmosConfig = endConf.AmosConfig;
// AmosConfig.xxx = ''; // 赋值操作是禁止的
enum
import AmosEnum from 'amos-processor/lib/enum/AmosEnum';
enum - AmosEnum
// use it as module
import AmosEnum from 'amos-processor/lib/enum/AmosEnum';
// or extend node.js with this new type
require('amos-processor/lib/enum/AmosEnum').register();
// 定义一个简单的枚举 (该枚举将会自动转化为flaggable枚举 -> A: 0x01, B: 0x02, C: 0x04)
// 采用位运算中的 ‘|’ 运算出的值定义枚举常量. EXP: if 'Read':1, 'Write':2, then ReadWrite = Read | Write = 1 | 2 = 3;
let demoEnum = new AmosEnum(['A', 'B', 'C']);
//定义一个标识多种颜色选择的flagged枚举; 只传递数组
let demoEnum = new AmosEnum(['Black', 'Red', 'Green', 'Blue']);
demoEnum; //=> AmosEnum {_options: Object, enums: Array[4], Black: EnumItem, Red: EnumItem, Green: EnumItem….....}
demoEnum.isFlaggable; //=> true
for(let i = 1; i < 8; i++){
console.log(demoEnum.get(i).value + '=> '+ demoEnum.get(i).key)
}
// 结果:
1=> Black
2=> Red
3=> Black | Red
4=> Green
5=> Black | Green
6=> Red | Green
7=> Black | Red | Green
// 定义一个自带数值的枚举
let demoEnum = new AmosEnum({'A': 1, 'B': 2, 'C': 4});
// 如果定义一个flaggable枚举,你可以定义自己的分离器(默认为|”)
let demoEnum = new AmosEnum(['A', 'B', 'C'], { separator: ' | ' });
// 定义一个自带名字的枚举
// 方式一:
let demoEnum = new AmosEnum(['A', 'B', 'C'], { name: 'demoEnum' });
// 方式二:
let demoEnum = new AmosEnum(['A', 'B', 'C'], 'demoEnum');
// 定义一个具有明确 "endianness"的枚举 (默认是 `os.endianness()`)
let demoEnum = new AmosEnum(['A', 'B', 'C'], { endianness: 'BE' });
// 设置枚举是否区分大小写 (默认不区分 false)
let demoEnum = new AmosEnum(['One', 'tWo', 'ThrEE'], { ignoreCase: true });
demoEnum.get('one'); // => demoEnum.One
demoEnum.get('TWO'); // => demoEnum.tWo
demoEnum.ThrEE.is('three'); // => true
// 设置枚举是否可扩展(默认不可扩展,false)
let demoEnum = new AmosEnum(['ONE', 'TWO', 'THREE'], { freez: true });
// 定义一个非 Flaggable 枚举
let demoEnum = new AmosEnum({'None': 0, 'Black':1, 'Red': 2, 'Red2': 3, 'Green': 4, 'Blue': 5});
demoEnum; //=> AmosEnum {_options: Object, enums: Array[6], None: EnumItem, Black: EnumItem, Red: EnumItem…........}
demoEnum.isFlaggable; //=> false
demoEnum.toJSON(); // returns {'None': 0, 'Black':1, 'Red': 2, 'Red2': 3, 'Green': 4, 'Blue': 5}
JSON.stringify(demoEnum); // returns '{"None":0,"Black":1,"Red":2,"Red2":3,"Green":4,"Blue":5}'
for(let i=0; i<=5; i++){
console.log(demoEnum.get(i).value + '=> '+ demoEnum.get(i).key)
}
// 结果:
0=> None
1=> Black
2=> Red
3=> Red2
4=> Green
5=> Blue
// 循环遍历一个枚举
demoEnum.enums.forEach(function(enumItem) {
console.log(enumItem.key);
});
// 结果:
// => None
// => Black
// => Red
// => Red2
// => Green
// => Blue
// 获取指定的枚举
// 方法一:
demoEnum.A
// 方法二:
demoEnum.get('A')
// 方法三:
demoEnum.get(1)
// 方法四:
demoEnum.get('A | B')
// 方法五:
demoEnum.get(3)
// 获取枚举值
// 直接获取:
demoEnum.A.value
// 通过key获取
demoEnum.A.key
// 获取所有的枚举
demoEnum.enums // 以数组的方式返回所有枚举
// 两个枚举的比较
// 方式一:
demoEnum.A.is(demoEnum.A)
// 方式二:
demoEnum.A.is('A')
// 方式三
demoEnum.A.is(1)
// 方式四:
demoEnum.A == demoEnum.A
// 方式五:
demoEnum.A === demoEnum.A
// 检测枚举是否存在某一个item
let myItem = demoEnum.get(3); // 或者 [demoEnum.get('A | B')]
myItem.has(demoEnum.A)
// 通过名称
myItem.has('A')
// 通过值
myItem.has(1)
// 其它的一些方法
myItem.toString() // returns 'A | C'
myItem.toJSON() // returns '"A | C"'
myItem.valueOf() // returns 3
JSON.stringify(myItem) // returns '"A | C"'
// 类型安全:
// 确保新创建的枚举对象Type-Safe,主要采用不可配置和不可扩展来实现.
// 每一个EnumItem 最终都有一个隐式构造器.
Object.getOwnPropertyDescriptor(demoEnum, 'Red'); //=> Object {value: EnumItem, writable: false, enumerable: true, configurable: false}
Object.isExtensible(demoEnum); //=> false
demoEnum instanceof AmosEnum; //=> true
// 采用同样的对象创建的实例枚举对象是不相等的,要比较相等只能比较key或value
demoEnum1=new AmosEnum({'A':1, 'B':2, 'C':4});
demoEnum2=new AmosEnum({'A':1, 'B':2, 'C':4});
demoEnum1 == demoEnum2 //=> false
demoEnum1.A == demoEnum2.A //=> false
demoEnum1.A.value == demoEnum2.A.value //=> true
//枚举被创建以后,将不能再为其添加属性、修改值等. 已存在的数据都是持久的,同时保留原来的版本
demoEnum.B.value; //=> 2
// 修改枚举值会抛出异常
demoEnum.B = 5; //=> Throws TypeError
// 不可删除
delete demoEnum.B; //=> false
// 不可添加
demoEnum.D = 6; //=> 不可添加枚举对象,会直接忽略
demoEnum.D; // undefined
//定义新的 property 将会跑出异常:throws TypeError
Object.defineProperty(demoEnum, D, {value:6, writable:false, enumerable:true});
//=>TypeError: Cannot define property:D, object is not extensible.
enum - lang
enum 国际化
import AmosEnum from 'amos-processor/lib/enum/AmosEnum';
import { stringUtil, enums2array } from 'amos-processor/lib/enum/enumLang';
const defaultOpts = {
ignoreCase: true
};
const btnEnum = new AmosEnum({
'SUBMIT': 1, // 提交
'FICTION': 0, // 拟制
}, defaultOpts);
const langs = {
SUBMIT: '提交',
FICTION: '拟制',
};
const valueOrKey = 'SUBMIT'; // 或者 1
/**
* 将string/number 转化为相应的locale数据
* @param {any} enums 具体的枚举实例 来自于 new AmosEnum()
* @param {any} valueOrKey 枚举的value或者key 默认是从后端获取到的数据
* @param {any} module 具体需要进行国际化的模块, exp: bizs
* @returns
*/
tringUtil(btnEnum, valueOrKey, langs); // 提交
/**
* 将枚举转换成对象数组
*
* @export
* @param {any} enums 具体的枚举实例 来自于 new AmosEnum()
* @param {any} module 具体需要进行国际化的模块, default bizs
* @returns [{key:'SUBMIT',value:1,label:'提交'},{key:'FICTION',value:0,label:'拟制'}]
*/
enums2array(btnEnum, langs); // [{key:'SUBMIT',value:1,label:'提交'},{key:'FICTION', value:0, label:'拟制'}]
fetch
模块包含如下:
import {
AmosFetch, XssAmosFetch, fetchJson, postJson, postJsonCall, putJson, getByParams,
saveExportExcel, api, amosRequest
} from 'amos-processor/lib/fetch';
fetch - AmosFetch
AmosFetch[get|post|head|options|put|del](url, {params:{}, data:{}})
/**
* 参数加密,同时需要校验 sign 值,用于解决相关伪造数据请求
**/
XssAmosFetch[get|post|head|options|put|del](url, {params:{}, data:{}})
/**
* 请求后端json数据
*
* @export
* @param {any} url 请求地址
* @param {any} callback 请求成功回调
**/
fetchJson(url, callback)
/**
* 将json数据发送给服务器
*
* @export
* @param {any} url 后端url
* @param {any} data object数据,如:{name:'ilex',pwd:'xxxxxx'}
*/
postJson(url,data)
/**
* 将json数据发送给服务器
*
* @export
* @param {any} url 后端url
*/
getJson(url)
/**
* 将json数据发送给服务器,采用回调方式
*
* @export
* @param {any} url 后端url
* @param {any} data object数据,如:{name:'ilex',pwd:'xxxxxx'}
* @param {any} callback 请求成功回调
*/
postJsonCall(url, data, callback)
/**
* 将json数据发送给服务器
*
* @export
* @param {any} url 后端url
*/
putJson(url,data)
/**
* get请求,默认分页方式
*
* @export
* @param {any} url 后端url
* @param {any} data object数据,如:{name:'ilex',pwd:'xxxxxx'} 或者 {page:1, size:10, code:'other'}
* @param {any} callback 请求成功回调
*/
getByParams(url, data, callback)
/**
* 导出excel
* method: post
* @export
* @param {any} url 后端url
* @param {any} data object数据
* @param {any} callback 请求成功回调
*/
saveExportExcel(url, data, callback)
fetch - amosRequest
import amosRequest, {
commonGet,
commonPost,
commonPut,
commonDelete,
singleFetch
} from 'amos-processor/lib/fetch/amosRequest';
// 以下api, 数据结果已经处理,原始数据是 { result: 'SUCCESS', dataList: any } => dataList: any
commonGet(url, params): Promise
commonPost(url, data, params): Promise
commonPut(url, data, params): Promise
commonDelete(url, data, params): Promise
singleFetch(...args) // 同 fetch,添加 timeout
// 处理失败, 如果不设置 reject,则需要采用 promise 处理,否则异常无法 reject出去,会显示在 succes 中
singleFetch(url, { ...args, reject(err){
// 失败
console.log('err', err)
}}).then(d => console.log('success', d))
fetch - xssRequest
注意 仅 commonGet、commonPost、commonPut、commonDelete
默认添加了 校验,其它请求,可采用 amos-processor/lib/utils/xssTools
中先关方法,进行 body 或者 url 进行加密
import amosRequest, {
commonGet,
commonPost,
commonPut,
commonDelete,
singleFetch
} from 'amos-processor/lib/fetch/xssRequest';
// 以下api, 数据结果已经处理,原始数据是 { result: 'SUCCESS', dataList: any } => dataList: any
commonGet(url, params): Promise
commonPost(url, data, params): Promise
commonPut(url, data, params): Promise
commonDelete(url, data, params): Promise
singleFetch(...args) // 同 fetch,添加 timeout
注意,amosRequest (xssRequest 相同) 默认开启的 timeout = 15000;如果需要设置,则给
params
中设置 timeout即可。params的可填参数如下
params: { reject = noop, hasCookie, isFormData, timeout = 15000, headers = {}, 其它fetch options }
注意,基础平台中,数据格式为
{ status, result, message }
, 此时需要自定义 payload,如下:
import amosRequest, {
commonGet as get,
commonPost as post,
commonPut as put,
commonDelete as del,
singleFetch
} from 'amos-processor/lib/fetch/amosRequest';
import * as xar from 'amos-processor/lib/fetch/xssRequest';
const successStatus = 200;
// 统一平台处理数据结果
function payload(data){
return new Promise((resolve, reject) => {
if (data.state) {
resolve(data);
} else {
if (data && data.status === successStatus) {
if (data.result || data.result === null){
resolve(data.result);
} else {
resolve(data);
}
} else {
if (data) {
reject(data.message);
} else {
reject(data);
}
}
}
});
}
export const commonGet = (url) => {
return get(url, {
payload,
hasCookie: true
});
};
export const commonPost = (url, data) => {
return post(url, data, {
payload,
hasCookie: true
});
};
export const commonPut = (url, data) => {
return put(url, data, {
payload,
hasCookie: true
});
};
export const commonDelete = (url, data) => {
return del(url, data, {
payload,
hasCookie: true
});
};
export const xssAmosRequest = {
commonGet(url){
return xar.commonGet(url, {
payload,
hasCookie: true
});
},
commonPost(url, data){
return xar.commonPost(url, data, {
payload,
hasCookie: true
});
},
commonPut(url, data){
return xar.commonPut(url, data, {
payload,
hasCookie: true
});
},
commonDelete(url, data){
return xar.commonDelete(url, data, {
payload,
hasCookie: true
});
}
};
特殊:
FormData
使用案例
import { commonPost } from 'amos-processor/lib/fetch/amosRequest';
import { toFormData } from 'amos-processor/lib/utils';
const fd = toFormData({
userName: 'ilex',
password: 'xxxxxx'
});
commonPost(url, fd, {
isFormData: true,
headers: {
// 'Content-Type': 'multipart/form-data;charset=UTF-8'
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
});
future
`async/await`
import { asyncAwait, AmosFetch } from 'amos-processor';
// import { AmosFetch } from 'amos-processor/lib/fetch';
// import asyncAwait from 'amos-processor/lib/future/asyncAwait';
asyncAwait(AmosFetch.get('url', { params: {}, data: {} })).then(d=>d);
middleware
redux 中间件
redux
redux 核心创造器
- actionCreator
actionCreator 和 xssActionCreator
import actionCreator, { xssActionCreator } from 'amos-processor/lib/redux/actionCreator';
// xssActionCreator
actionCreator({
type: '',
method: 'get',
url: '',
params: {},
data: {},
});
- storeCreator
simpleStore 、 smartStore 和 asyncStore
import asyncStore, { simpleStore, smartStore } from 'amos-processor/lib/redux/storeCreator';
asyncStore(reducers);
simpleStore(reducers); // 自行处理异步,没有加入 `thunkMiddleware`
// 根据环境不同,添加不同的中间件
smartStore(reducers, initialState = {}, middleware = [], hotFunc);
// 示例, hotFunc 可选
smartStore(reducers, {}, [
promiseMiddleware({ promiseTypeSuffixes: ['PENDING', 'SUCCESS', 'ERROR'] }),
amosFetchMiddleware(),
], (store) => {
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../model/reducers', () => {
const nextRootReducer = require('../model/reducers');
store.replaceReducer(nextRootReducer);
});
}
});
注意,如果未使用
amos-dll
则需要自行安装redux 相关依赖
,执行如下:npm i --save [email protected] [email protected] [email protected]
。
utils
AmosValidate: `details @see ray-validate`
// 过滤reducer中的数据
filterPayload(payload);
FetchColor(index);
collectionListIds(list=[], id='id');
//合并数组,以第一个数组基准
merageArray(arrayA=[] ,arrayB=[], detailId='id');
// 格式化时间
renderSimpleTime(text, record);// YYYY-MM-DD
renderLongTime(text, record); // YYYY-MM-DD HH:mm:ss
/**
* 格式化url
* @param {string} targetStr
* @param {object} dataObj
* @param {string|RegExp} regexps 可选, default: /\{(.*)\}/g);
* @doc formatUrl('a/{b}/{c}/d',{a: 1, b:2}) 返回: 'a/1/2/d'
* @doc formatUrl('a/{{b}}/{{c}}/d',{a: 1, b:2}, /\{\{(.*)\}\}/g) 返回: 'a/1/2/d'
*
* 自动补全token, 以 `.../user` api 为例, 只需要在 url中添加: `.../user?token={token}` 或 `.../user/{token}`
* formatUrl('a/user?token={token}', {}) 返回: 'a/user?token=WEB00022ss-0dss0dsdsf00sd'
* formatUrl('a/user?token={token}') 返回: 'a/user?token=WEB00022ss-0dss0dsdsf00sd'
* formatUrl('a/user/{token}') 返回: 'a/user/WEB00022ss-0dss0dsdsf00sd'
*/
formatUrl(targetStr, dataObj, regexps);
/**
* 格式化url
* @param {string} targetStr
* @param {object} dataObj
* @param {string|RegExp} regexps 可选 default: /\{\s*([^\|\}]+?)\s*(?:\|([^\}]*))?\s*\}/g,
* @doc RestfulUrl.format('a/{b}/{c}/d',{a: 1, b:2}) 返回: 'a/1/2/d'
* @doc RestfulUrl.format('a/{{b}}/{{c}}/d',{a: 1, b:2}, /\{\{(.*)\}\}/g) 返回: 'a/1/2/d'
*/
RestfulUrl.format(_url, options, regexps)
/**
*
* 函数节流,控制相关事件提交间隔
* @param {Function} fn
* @param {any} data 执行的数据
* @param {any} context 执行函数的上下文 可以为null [默认为null]
* @param {Number} delay 两次事件触发间隔 [默认间隔500ms]
* @param {any} mustApplyTime l两次执行时间差 [可选, 不传递参数时,默认间隔0ms]
*
* @description 简单使用方式:
* 1.const fn = (data) =>console.log(data);
* 2.点击事件: handleClick = (e) => funcThrottle(fn, e.target.value);
*
* @author ilex
*/
funcThrottle(fn, data, context, delay, mustApplyTime)
utils - xssTools
import {
encodeFormBody, encodeKeyValue, encodeOnlyKey, encodeFullUrl, validateKeyValueSign,
decodeOnlyKey, validateKeySign, validateUrlSign
} from 'amos-processor/lib/utils/xssTools';
encodeFormBody(body): {};
encodeKeyValue(body): {};
encodeOnlyKey(body): {};
encodeFullUrl(url, secretKey = 'qaz'): string;
validateKeyValueSign(dec = {}): boolean;
decodeOnlyKey(dec, secretKey = 'qaz'): boolean;
validateKeySign(dec, secretKey = 'qaz'): boolean;
validateUrlSign(decUrl, secretKey = 'qaz'): boolean;
注意,如果需要将请求加密方式提供给外部使用,则需要执行
npm run dist
将dist
目录生成的js
文件拷贝即可。
utils - events
import AmostEvent, { stopEvent, AmosMsgSpread } from 'amos-processor/lib/utils/events';
AmostEvent.EventUtil.addHandler(element , type , handler);
AmostEvent.EventUtil.removeHandler(element , type , handler);
AmostEvent.PubSub.trigger(event, data);
AmostEvent.PubSub.subscribe(event, callback);
AmostEvent.Observer.deliver(topic);
AmostEvent.Observer.subscribe(publish);
AmostEvent.Observer.unsubscribe(publish);
stopEvent(e);
const ams = AmosMsgSpread();
ams.subscribe(topic, action);
ams.unsubscribe(topic);
ams.publish(topic, data, concurrency);
utils - toFormData
import toFormData from 'amos-processor/lib/utils/toFormData';
toFormData({
userName: '111',
userName1: '111',
userName2: '111'
});
AmosValidate 提供的方法
使用方式
import AmosValidate from 'amos-processor/lib/utils/validate';
AmosValidate.validate(r, value, cb, error = ERROR_TIP);
AmosValidate.encodeUrl(url);
...
const REGEXS = AmosValidate.REGEXS;
REGEXS.PHONE
- methods
|name|params|description|
|------|------|------|
|validate|(r, value, cb, error = ERROR_TIP)
|校验|
|encodeUrl|(url)
|将url中特殊的字符进行转换|
|isIp|(ip)
|判断string是否是ip|
|isPhone|(phoneNumber)
|带区号的电话号码|
|isMobile|(m)
|移动电话,匹配 13/15/18|
|isNotEmpty|(value)
|不为空|
|isNum|(value)
|数字|
|isInt|isInt(value)
|整数|
|isDecimal|(value)
|大数|
|isArray|(value)
|数组|
|isRegExp|(value)
|正则|
|isObject|(value)
|对象|
|isFunc|(value)
|function|
|isEmail|(value)
|邮箱|
|isUrl|(value)
|url|
|isFullUrl|(value)
|full url|
|isOnlyIpUrl|(value)
|only ip url|
|isHex|(value)
|16进制|
|isIdCard|(value)
|身份证|
|isCNMobile|(value)
|中国电话号码|
|isPassword|(value, options:{pwdMaxLen, pwdMinLen})
|密码判断|
|isUsername|(value)
|用户名判断|
|formatMoney|(str, delimiter = ' ', fixedNum)
|格式化 钱|
|formatMobile|(str, delimiter = ' ')
|格式化 电话号码|
|formatCard|(str, delimiter = ' ')
|格式化 card(身份证)|
|formatDate|(str, pattern)
|格式化date|
- REGEXS
使用方式: REGEXS.PHONE
/**
* 带区号的电话号码
*/
PHONE
/**
* 移动电话,匹配 13/15/18
*/
MOBILE
/**
* email
*/
EMAIL
/**
* url
*/
URL
/**
* ip url
*/
ONLY_IP_URL
/**
* full url
*/
FULL_URL
/**
* IP
*/
IP
/**
* hex 16进制
*/
HEX
/**
* 数字
*/
NUM
/**
* 身份证
*/
ID_CARD
/**
* 电话
*/
CN_MOBILE
/**
* 用户名 1-16位 字母、数字、下划线、横杠
*/
USER_NAME
/**
* 字母、字符、非字母字符至少包含1种
*/
PWD_L
/**
* 字母、字符、非字母字符至少包含2种
*/
PWD_M
/**
* 字母、字符、非字母字符至少包含3种
*/
PWD_H
changelogs
v2.1.3
*+*
modifyend conf
v2.1.0
+
adddependencies
v2.0.4
+
addstoreCreator
v2.0.0
+
modify amosRequest use 基础平台v1.2.22
+
queryEnumv1.2.21
+
xssTools+
xssRequest+
XssAmosFetch