Commit cb3c382b authored by 陈帅's avatar 陈帅

Features:Fetch increase cache

parent 50c8ce37
{
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
"rules": {
"selector-pseudo-class-no-unknown": null,
"shorthand-property-no-redundant-values": null,
"at-rule-empty-line-before": null,
"at-rule-name-space-after": null,
"comment-empty-line-before": null,
"declaration-bang-space-before": null,
"declaration-empty-line-before": null,
"function-comma-newline-after": null,
"function-name-case": null,
"function-parentheses-newline-inside": null,
"function-max-empty-lines": null,
"function-whitespace-after": null,
"number-leading-zero": null,
"number-no-trailing-zeros": null,
"rule-empty-line-before": null,
"selector-combinator-space-after": null,
"selector-descendant-combinator-no-non-space": null,
"selector-list-comma-newline-after": null,
"selector-pseudo-element-colon-notation": null,
"unit-no-unknown": null,
"no-descending-specificity": null,
"value-list-max-empty-lines": null
}
}
...@@ -236,10 +236,7 @@ class Analysis extends Component { ...@@ -236,10 +236,7 @@ class Analysis extends Component {
sorter: (a, b) => a.range - b.range, sorter: (a, b) => a.range - b.range,
render: (text, record) => ( render: (text, record) => (
<Trend flag={record.status === 1 ? 'down' : 'up'}> <Trend flag={record.status === 1 ? 'down' : 'up'}>
<span style={{ marginRight: 4 }}> <span style={{ marginRight: 4 }}>{text}%</span>
{text}
%
</span>
</Trend> </Trend>
), ),
align: 'right', align: 'right',
......
import fetch from 'dva/fetch'; import fetch from 'dva/fetch';
import { notification } from 'antd'; import { notification } from 'antd';
import router from 'umi/router'; import router from 'umi/router';
import hash from 'hash.js';
const codeMessage = { const codeMessage = {
200: '服务器成功返回请求的数据。', 200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。', 201: '新建或修改数据成功。',
...@@ -41,7 +41,18 @@ function checkStatus(response) { ...@@ -41,7 +41,18 @@ function checkStatus(response) {
* @param {object} [options] The options we want to pass to "fetch" * @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err" * @return {object} An object containing either "data" or "err"
*/ */
export default function request(url, options) { export default function request(url, options = {}) {
console.log(url);
/**
* Produce fingerprints based on url and parameters
* Maybe url has the same parameters
*/
const fingerprint = url + options.body ? JSON.stringify(options.body) : '';
const hashcode = hash
.sha256()
.update(fingerprint)
.digest('hex');
const defaultOptions = { const defaultOptions = {
credentials: 'include', credentials: 'include',
}; };
...@@ -66,10 +77,42 @@ export default function request(url, options) { ...@@ -66,10 +77,42 @@ export default function request(url, options) {
}; };
} }
} }
let cached = localStorage.getItem(hashcode);
let whenCached = localStorage.getItem(hashcode + ':timestamp');
const expirys = options.expirys || 60;
if (cached !== null && whenCached !== null && expirys !== false) {
let age = (Date.now() - whenCached) / 1000;
if (age < expirys) {
let response = new Response(new Blob([cached]));
return response.json();
} else {
localStorage.removeItem(hashcode);
localStorage.removeItem(hashcode + ':timestamp');
}
}
return fetch(url, newOptions) return fetch(url, newOptions)
.then(checkStatus) .then(checkStatus)
.then(response => { .then(response => {
/**
* Clone a response data and store it in localStorage
* Does not support data other than json, Cache only json
*/
let contentType = response.headers.get('Content-Type');
if (contentType && contentType.match(/application\/json/i)) {
// All data is saved as text
response
.clone()
.text()
.then(content => {
localStorage.setItem(hashcode, content);
localStorage.setItem(hashcode + ':timestamp', Date.now());
});
}
return response;
})
.then(response => {
// DELETE and 204 do not return data by default
// using .json will report an error.
if (newOptions.method === 'DELETE' || response.status === 204) { if (newOptions.method === 'DELETE' || response.status === 204) {
return response.text(); return response.text();
} }
...@@ -78,12 +121,14 @@ export default function request(url, options) { ...@@ -78,12 +121,14 @@ export default function request(url, options) {
.catch(e => { .catch(e => {
const status = e.name; const status = e.name;
if (status === 401) { if (status === 401) {
// @HACK
/* eslint-disable no-underscore-dangle */ /* eslint-disable no-underscore-dangle */
window.g_app._store.dispatch({ window.g_app._store.dispatch({
type: 'login/logout', type: 'login/logout',
}); });
return; return;
} }
// environment should not be used
if (status === 403) { if (status === 403) {
router.push('/exception/403'); router.push('/exception/403');
return; return;
......
export default {
extends: ['stylelint-config-standard', 'stylelint-config-prettier'],
rules: {
'selector-pseudo-class-no-unknown': null,
'shorthand-property-no-redundant-values': null,
'at-rule-empty-line-before': null,
'at-rule-name-space-after': null,
'comment-empty-line-before': null,
'declaration-bang-space-before': null,
'declaration-empty-line-before': null,
'function-comma-newline-after': null,
'function-name-case': null,
'function-parentheses-newline-inside': null,
'function-max-empty-lines': null,
'function-whitespace-after': null,
'number-leading-zero': null,
'number-no-trailing-zeros': null,
'rule-empty-line-before': null,
'selector-combinator-space-after': null,
'selector-descendant-combinator-no-non-space': null,
'selector-list-comma-newline-after': null,
'selector-pseudo-element-colon-notation': null,
'unit-no-unknown': null,
'no-descending-specificity': null,
'value-list-max-empty-lines': null,
'no-missing-end-of-source-newline': null,
},
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment