import React from 'mui/reactjs/react';
import Callbacks from './callbacks';
import Request from './request';
const PAGE_PREFIX = 'ostium';
const API_PREFIX = 'api';
const cache = {};
const convertPermission = (keys, type = API_PREFIX)=> {
const apis = keys.split(',');
return apis.map(api => {
api = api.trim();
if (api) {
return [type].concat(api.split('/')).join('-');
}
}).filter(api=>!!api);
};
const getPermissions = apis => Promise.all(apis.map(api => new Promise((resolve) => {
if (!cache[api]) {
cache[api] = Callbacks();
Request(api).then(cache[api].fire).catch(() => {
// 请求失败后,先标记为无权限,再清空缓存,下次可以重试
cache[api].fire(false);
delete cache[api];
});
}
cache[api].add(result => {
const obj = {};
obj[api] = result;
resolve(obj);
});
}))).then(results => results.reduce((prev, current)=> Object.assign(prev, current), {}));
class Component extends React.Component {
constructor(props) {
super(props);
this.init = this.init.bind(this);
this.state = {
authorized: false
};
}
componentDidMount() {
this.init(this.props);
}
componentWillReceiveProps(next) {
if (!next.apiKeys || !next.pageKeys) {
return;
}
if (next.apiKeys !== this.apiKeys || next.pageKeys !== this.pageKeys) {
this.init(next);
}
}
init(props) {
const {apiKeys, pageKeys} = props;
let permissions;
if (apiKeys) {
permissions = convertPermission(apiKeys);
} else if (pageKeys) {
permissions = convertPermission(pageKeys, PAGE_PREFIX);
}
if (permissions) {
getPermissions(permissions).then(this.judge.bind(this)).catch(()=> {
});
}
}
judge(data) {
this.setState({
authorized: Object.values(data).every(v => v)
});
}
static canUseApi = (apiKeys) => {
return getPermissions(convertPermission(apiKeys)).then(data => {
return {
result: Object.values(data).every(v => v),
data: data
}
});
};
static canUsePage = (pageKeys) => {
return getPermissions(convertPermission(pageKeys, PAGE_PREFIX)).then(data=> {
return {
result: Object.values(data).every(v => v),
data: data
}
});
};
render() {
const { type='hide' } = this.props;
let { authorized } = this.state;
let { children } = this.props;
if (!(children instanceof Array)) {
children = [children];
}
return (
<span style={this.props.style} className={this.props.className}>
{
authorized ? children :
type == 'hide' ? '' :
type == 'disabled' ?
children.map(o => {
return React.cloneElement(o, {disabled: true})
}) :
type == 'deny' ?
children.map(o => {
return React.cloneElement(o, {
onClick: ()=> {
o.props.onDeny && o.props.onDeny()
}
})
}) : ''
}
</span>
);
}
}
// 每使用一次都要初始化。
export default Component;
Requese.js:
'use strict';
const fetch = require('ascm-comp/lib-fetch/index');
module.exports = (()=> {
const cache = {};
const host = (window._env_ === 'pre' || window._env_ == 'prod') ? 'xx' : 'yy';
const url = `//${host}/webapi/permission/queryPermissions`;
const request = (keys)=> {
return new Promise((resolve, reject)=> {
fetch({
url,
method: 'get',
timeout: 1000 * 10,
data: {
_0: keys
}
}).then(res => {
if (res.success && res.data) {
resolve(res.data);
} else {
reject();
}
}).catch(()=> {
reject();
});
})
};
const waitThenSend = (()=> {
const map = {};
const queue = [];
let timer;
const send = (list)=> {
request(list).then((data)=> {
Object.keys(data).forEach((key)=> {
if (map[key] && map[key].resolve) {
map[key].resolve(data[key]);
}
});
}).catch(()=> {
list.forEach((key)=> {
if (map[key] && map[key].reject) {
map[key].reject();
}
delete map[key];
delete cache[key];
});
});
};
return (key, resolve, reject)=> {
queue.push(key);
map[key] = {
resolve,
reject
};
clearTimeout(timer);
if (queue.length < 8) {
timer = setTimeout(()=> {
send(queue.splice(0, 8));
}, 200);
}
else {
send(queue.splice(0, 8));
}
};
})();
return key=> {
if (!cache[key]) {
cache[key] = new Promise((resolve, reject)=> {
waitThenSend(key, resolve, reject);
});
}
return cache[key];
}
})();
Callbacks:
'use strict';
module.exports = ()=> {
const queue = [];
let fired = false;
let result;
return {
add: callback=> {
if (fired) {
setTimeout(()=> {
callback(result);
}, 1);
}
else {
queue.push(callback);
}
},
fire: value => {
fired = true;
result = value;
let t = queue.shift();
while (t) {
t(result);
t = queue.shift();
}
}
}
};