初始化api

This commit is contained in:
whyour 2021-03-15 21:09:30 +08:00
parent f1f8ece8a2
commit 99a8dc78db
28 changed files with 664 additions and 49 deletions

8
.env.example Normal file
View File

@ -0,0 +1,8 @@
MONGODB_URI='mongodb://'
YIYAN_MONGODB_URI=''
PORT=8080
LOG_LEVEL='debug'
SECRET='test'

1
.gitignore vendored
View File

@ -19,3 +19,4 @@
/src/.umi-test /src/.umi-test
/.env.local /.env.local
/config /config
.env

42
back/api/auth.ts Normal file
View File

@ -0,0 +1,42 @@
import { Router, Request, Response, NextFunction } from 'express';
import { Container } from 'typedi';
import { Logger } from 'winston';
import * as fs from 'fs';
import config from '../config';
import jwt from 'jsonwebtoken';
const route = Router();
export default (app: Router) => {
app.use('/', route);
route.post(
'/auth',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
let username = req.body.username;
let password = req.body.password;
fs.readFile(config.authConfigFile, 'utf8', function (err, data) {
if (err) console.log(err);
var con = JSON.parse(data);
if (username && password) {
if (username == con.user && password == con.password) {
let token = jwt.sign(
{ username, password },
config.secret as any,
{ expiresIn: 60 * 60 * 24 * 7, algorithm: 'HS384' },
);
res.send({ err: 0, token });
} else {
res.send({ err: 1, msg: config.authError });
}
} else {
res.send({ err: 1, msg: '请输入用户名密码!' });
}
});
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
};

70
back/api/config.ts Normal file
View File

@ -0,0 +1,70 @@
import { Router, Request, Response, NextFunction } from 'express';
import { Container } from 'typedi';
import { Logger } from 'winston';
import * as fs from 'fs';
import config from '../config';
const route = Router();
export default (app: Router) => {
app.use('/', route);
route.get(
'/config/:key',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
let content = '未找到文件';
switch (req.params.key) {
case 'config':
content = getFileContentByName(config.confFile);
break;
case 'sample':
content = getFileContentByName(config.sampleFile);
break;
case 'crontab':
content = getFileContentByName(config.crontabFile);
break;
case 'shareCode':
let shareCodeFile = getLastModifyFilePath(config.shareCodeDir);
content = getFileContentByName(shareCodeFile);
break;
case 'diy':
content = getFileContentByName(config.diyFile);
break;
default:
break;
}
res.send({ code: 200, content });
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
};
function getFileContentByName(fileName) {
if (fs.existsSync(fileName)) {
return fs.readFileSync(fileName, 'utf8');
}
return '';
}
function getLastModifyFilePath(dir) {
var filePath = '';
if (fs.existsSync(dir)) {
var lastmtime = 0;
var arr = fs.readdirSync(dir);
arr.forEach(function (item) {
var fullpath = path.join(dir, item);
var stats = fs.statSync(fullpath);
if (stats.isFile()) {
if (stats.mtimeMs >= lastmtime) {
filePath = fullpath;
}
}
});
}
return filePath;
}

28
back/api/cookie.ts Normal file
View File

@ -0,0 +1,28 @@
import { Router, Request, Response, NextFunction } from 'express';
import { Container } from 'typedi';
import CookieService from '../services/cookie';
import { celebrate, Joi } from 'celebrate';
import { Logger } from 'winston';
const route = Router();
export default (app: Router) => {
app.use('/', route);
route.get(
'/qrcode',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
if (req) {
const cookieService = Container.get(CookieService);
const { shici } = await cookieService.getYiYan();
return res.status(200).json({ code: 200, data: shici });
} else {
return res.status(200).json({ err: 1, msg: 'loginFaild' });
}
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
};

12
back/api/index.ts Normal file
View File

@ -0,0 +1,12 @@
import { Router } from 'express';
import auth from './auth';
import cookie from './cookie';
import config from './config';
export default () => {
const app = Router();
auth(app);
cookie(app);
config(app);
return app;
};

28
back/app.ts Normal file
View File

@ -0,0 +1,28 @@
import 'reflect-metadata'; // We need this in order to use @Decorators
import config from './config';
import express from 'express';
import Logger from './loaders/logger';
async function startServer() {
const app = express();
await require('./loaders').default({ expressApp: app });
app
.listen(config.port, () => {
Logger.info(`
################################################
🛡 Server listening on port: ${config.port} 🛡
################################################
`);
})
.on('error', (err) => {
Logger.error(err);
process.exit(1);
});
}
startServer();

44
back/config/index.ts Normal file
View File

@ -0,0 +1,44 @@
import dotenv from 'dotenv';
import path from 'path';
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const envFound = dotenv.config();
const rootPath = path.resolve(__dirname, '../../');
const confFile = path.join(rootPath, 'config/config.sh');
const sampleFile = path.join(rootPath, 'sample/config.sh.sample');
const crontabFile = path.join(rootPath, 'config/crontab.list');
const confBakDir = path.join(rootPath, 'config/bak/');
const authConfigFile = path.join(rootPath, 'config/auth.json');
const shareCodeDir = path.join(rootPath, 'log/jd_get_share_code/');
const diyFile = path.join(rootPath, 'config/diy.sh');
const logPath = path.join(rootPath, 'log/');
const authError = '错误的用户名密码,请重试';
const loginFaild = '请先登录!';
const configString = 'config sample crontab shareCode diy';
if (envFound.error) {
throw new Error("⚠️ Couldn't find .env file ⚠️");
}
export default {
port: parseInt(process.env.PORT, 10),
secret: process.env.SECRET,
logs: {
level: process.env.LOG_LEVEL || 'silly',
},
api: {
prefix: '/api',
},
configString,
loginFaild,
authError,
logPath,
diyFile,
shareCodeDir,
authConfigFile,
confBakDir,
crontabFile,
sampleFile,
confFile,
};

View File

@ -0,0 +1,27 @@
export interface ICommon {
_id: string;
value: String;
name: String;
type: Number;
}
export interface ICommonInputDTO {
value: String;
name: String;
type: Number;
}
export enum ShareCodeType {
ddFactory = 1,
ddXw,
jxCfd,
jxFactory,
jxFactoryTuan,
jxNc,
jxStory,
jxCfdGroup,
jdZz,
jdZjdTuan,
didi,
jd818,
}

View File

@ -0,0 +1,7 @@
export interface IContent {
author: String;
paragraphs: [String];
title: String;
id: String;
created_at: Number;
}

View File

@ -0,0 +1,15 @@
import { Container } from 'typedi';
import LoggerInstance from './logger';
export default ({ models }: { models: { name: string; model: any }[] }) => {
try {
models.forEach((m) => {
Container.set(m.name, m.model);
});
Container.set('logger', LoggerInstance);
} catch (e) {
LoggerInstance.error('🔥 Error on dependency injector loader: %o', e);
throw e;
}
};

55
back/loaders/express.ts Normal file
View File

@ -0,0 +1,55 @@
import { Request, Response, NextFunction, Application } from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import routes from '../api';
import config from '../config';
import jwt from 'express-jwt';
export default ({ app }: { app: Application }) => {
app.enable('trust proxy');
app.use(cors());
app.use(bodyParser.json());
app.use(
jwt({ secret: config.secret as string, algorithms: ['HS384'] }).unless({
path: ['/api/auth'],
}),
);
app.use(config.api.prefix, routes());
app.use((req, res, next) => {
const err: any = new Error('Not Found');
err['status'] = 404;
next(err);
});
app.use(
(
err: Error & { status: number },
req: Request,
res: Response,
next: NextFunction,
) => {
if (err.name === 'UnauthorizedError') {
return res.status(err.status).send({ message: err.message }).end();
}
return next(err);
},
);
app.use(
(
err: Error & { status: number },
req: Request,
res: Response,
next: NextFunction,
) => {
res.status(err.status || 500);
res.json({
errors: {
message: err.message,
},
});
},
);
};

15
back/loaders/index.ts Normal file
View File

@ -0,0 +1,15 @@
import expressLoader from './express';
import dependencyInjectorLoader from './dependencyInjector';
import Logger from './logger';
export default async ({ expressApp }) => {
Logger.info('✌️ DB loaded and connected!');
await dependencyInjectorLoader({
models: [],
});
Logger.info('✌️ Dependency Injector loaded');
await expressLoader({ app: expressApp });
Logger.info('✌️ Express loaded');
};

32
back/loaders/logger.ts Normal file
View File

@ -0,0 +1,32 @@
import winston from 'winston';
import config from '../config';
const transports = [];
if (process.env.NODE_ENV !== 'development') {
transports.push(new winston.transports.Console());
} else {
transports.push(
new winston.transports.Console({
format: winston.format.combine(
winston.format.cli(),
winston.format.splat(),
),
}),
);
}
const LoggerInstance = winston.createLogger({
level: config.logs.level,
levels: winston.config.npm.levels,
format: winston.format.combine(
winston.format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
winston.format.errors({ stack: true }),
winston.format.splat(),
winston.format.json(),
),
transports,
});
export default LoggerInstance;

125
back/services/cookie.ts Normal file
View File

@ -0,0 +1,125 @@
import { Service, Inject } from 'typedi';
import winston from 'winston';
import fetch from 'node-fetch';
@Service()
export default class CookieService {
private cookies: string = '';
private s_token: string = '';
private guid: string = '';
private lsid: string = '';
private lstoken: string = '';
private okl_token: string = '';
private token: string = '';
constructor(@Inject('logger') private logger: winston.Logger) {}
public async getYiYan(): Promise<any> {
return { yiYan: 'test' };
}
private async step1() {
try {
let timeStamp = new Date().getTime();
let url =
'https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' +
timeStamp +
'&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport';
const text = await fetch(url, {
method: 'get',
headers: {
Connection: 'Keep-Alive',
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json, text/plain, */*',
'Accept-Language': 'zh-cn',
Referer:
'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' +
timeStamp +
'&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
Host: 'plogin.m.jd.com',
},
});
this.praseSetCookies(text);
} catch (error) {
this.logger.error(error.response.body);
}
}
private async step2() {
try {
if (this.cookies == '') {
return 0;
}
let timeStamp = new Date().getTime();
let url =
'https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=' +
this.s_token +
'&v=' +
timeStamp +
'&remember=true';
const response = await fetch(url, {
method: 'post',
body: JSON.stringify({
lang: 'chs',
appid: 300,
returnurl:
'https://wqlogin2.jd.com/passport/LoginRedirect?state=' +
timeStamp +
'&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action',
source: 'wq_passport',
}),
headers: {
Connection: 'Keep-Alive',
'Content-Type': 'application/x-www-form-urlencoded; Charset=UTF-8',
Accept: 'application/json, text/plain, */*',
Cookie: this.cookies,
Referer:
'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=' +
timeStamp +
'&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
Host: 'plogin.m.jd.com',
},
}).then((res) => res.json);
// this.token = response.body.token
// this.okl_token = response.headers['set-cookie'][0]
// this.okl_token = this.okl_token.substring(this.okl_token.indexOf("=") + 1, this.okl_token.indexOf(";"))
var qrUrl =
'https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token=' +
this.token;
return qrUrl;
} catch (error) {
console.log(error.response.body);
return 0;
}
}
private praseSetCookies(response: any) {
this.s_token = response.body.s_token;
this.guid = response.headers['set-cookie'][0];
this.guid = this.guid.substring(
this.guid.indexOf('=') + 1,
this.guid.indexOf(';'),
);
this.lsid = response.headers['set-cookie'][2];
this.lsid = this.lsid.substring(
this.lsid.indexOf('=') + 1,
this.lsid.indexOf(';'),
);
this.lstoken = response.headers['set-cookie'][3];
this.lstoken = this.lstoken.substring(
this.lstoken.indexOf('=') + 1,
this.lstoken.indexOf(';'),
);
this.cookies =
'guid=' +
this.guid +
'; lang=chs; lsid=' +
this.lsid +
'; lstoken=' +
this.lstoken +
'; ';
}
}

9
back/types/express/index.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import { Document, Model } from 'mongoose';
import { IContent } from '../../interfaces/IContent';
import { ICommon } from '../../interfaces/ICommon';
declare global {
namespace Models {
export type IContentModel = Model<IContent & Document>;
export type ICommonModel = Model<ICommon & Document>;
}
}

6
nodemon.json Normal file
View File

@ -0,0 +1,6 @@
{
"watch": ["back", ".env"],
"ext": "js,ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node --transpile-only ./back/app.ts"
}

View File

@ -3,6 +3,9 @@
"scripts": { "scripts": {
"start": "umi dev", "start": "umi dev",
"build": "umi build", "build": "umi build",
"build-back": "tsc",
"start-back": "nodemon",
"pm2": "npm run build && node build/app.js",
"postinstall": "umi generate tmp", "postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test", "test": "umi-test",
@ -22,22 +25,66 @@
"dependencies": { "dependencies": {
"@ant-design/pro-layout": "^6.5.0", "@ant-design/pro-layout": "^6.5.0",
"@umijs/preset-react": "1.x", "@umijs/preset-react": "1.x",
"agenda": "^3.1.0",
"agendash": "^1.0.0",
"argon2": "^0.27.0",
"body-parser": "^1.19.0",
"celebrate": "^13.0.3",
"codemirror": "^5.59.4", "codemirror": "^5.59.4",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"errorhandler": "^1.5.1",
"event-dispatch": "^0.4.1",
"eventemitter3": "^4.0.7",
"express": "^4.17.1",
"express-basic-auth": "^1.2.0",
"express-jwt": "^6.0.0",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.20",
"mailgun-js": "^0.22.0",
"method-override": "^3.0.0",
"moment": "^2.29.0",
"moment-timezone": "^0.5.31",
"mongoose": "^5.10.6",
"morgan": "^1.10.0",
"node-fetch": "^2.6.1",
"qrcode.react": "^1.0.1", "qrcode.react": "^1.0.1",
"react-codemirror2": "^7.2.1", "react-codemirror2": "^7.2.1",
"react-diff-viewer": "^3.1.1", "react-diff-viewer": "^3.1.1",
"reflect-metadata": "^0.1.13",
"socks-proxy-agent": "^4.0.2",
"telegraf": "^4.0.3",
"typedi": "^0.8.0",
"umi": "^3.3.9", "umi": "^3.3.9",
"umi-request": "^1.3.5" "umi-request": "^1.3.5",
"winston": "^3.3.3"
}, },
"devDependencies": { "devDependencies": {
"@types/agenda": "^2.0.9",
"@types/cors": "^2.8.10",
"@types/express": "^4.17.8",
"@types/express-jwt": "^6.0.1",
"@types/jsonwebtoken": "^8.5.0",
"@types/lodash": "^4.14.161",
"@types/mongoose": "^5.7.36",
"@types/node": "^14.11.2",
"@types/node-fetch": "^2.5.8",
"@types/qrcode.react": "^1.0.1", "@types/qrcode.react": "^1.0.1",
"@types/react": "^17.0.0", "@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0", "@types/react-dom": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^4.2.0",
"@typescript-eslint/parser": "^4.2.0",
"@umijs/test": "^3.3.9", "@umijs/test": "^3.3.9",
"eslint": "^7.9.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
"lint-staged": "^10.0.7", "lint-staged": "^10.0.7",
"nodemon": "^2.0.4",
"prettier": "^2.2.0", "prettier": "^2.2.0",
"react": "17.x", "react": "17.x",
"react-dom": "17.x", "react-dom": "17.x",
"ts-node": "^9.0.0",
"tslint": "^5.20.1",
"typescript": "^4.1.2", "typescript": "^4.1.2",
"yorkie": "^2.0.0" "yorkie": "^2.0.0"
} }

View File

@ -14,9 +14,12 @@ const Crontab = () => {
const getConfig = () => { const getConfig = () => {
setLoading(true); setLoading(true);
request.get(`${config.apiPrefix}config/shareCode`).then((data) => { request
setValue(data); .get(`${config.apiPrefix}config/shareCode`)
}).finally(() => setLoading(false)); .then((data) => {
setValue(data.content);
})
.finally(() => setLoading(false));
}; };
const updateConfig = () => { const updateConfig = () => {

View File

@ -15,9 +15,12 @@ const Config = () => {
const getConfig = () => { const getConfig = () => {
setLoading(true); setLoading(true);
request.get(`${config.apiPrefix}config/config`).then((data) => { request
setValue(data); .get(`${config.apiPrefix}config/config`)
}).finally(() => setLoading(false)); .then((data) => {
setValue(data.content);
})
.finally(() => setLoading(false));
}; };
const updateConfig = () => { const updateConfig = () => {

View File

@ -25,9 +25,7 @@ const columns = [
title: '状态', title: '状态',
key: 'status', key: 'status',
dataIndex: 'status', dataIndex: 'status',
render: (text: string, record: any) => ( render: (text: string, record: any) => <Tag color="success">success</Tag>,
<Tag color="success">success</Tag>
),
}, },
{ {
title: '操作', title: '操作',
@ -74,9 +72,12 @@ const Config = () => {
const getConfig = () => { const getConfig = () => {
setLoading(true); setLoading(true);
request.get(`${config.apiPrefix}config/config`).then((data) => { request
setValue(data); .get(`${config.apiPrefix}config/config`)
}).finally(() => setLoading(false)); .then((data) => {
setValue(data.content);
})
.finally(() => setLoading(false));
}; };
const updateConfig = () => { const updateConfig = () => {
@ -182,7 +183,11 @@ const Config = () => {
height: '100vh', height: '100vh',
}} }}
> >
<Table columns={columns} pagination={{hideOnSinglePage: true}} dataSource={data} /> <Table
columns={columns}
pagination={{ hideOnSinglePage: true }}
dataSource={data}
/>
</PageContainer> </PageContainer>
); );
}; };

View File

@ -14,9 +14,12 @@ const Crontab = () => {
const getConfig = () => { const getConfig = () => {
setLoading(true); setLoading(true);
request.get(`${config.apiPrefix}config/crontab`).then((data) => { request
setValue(data); .get(`${config.apiPrefix}config/crontab`)
}).finally(() => setLoading(false)); .then((data) => {
setValue(data.content);
})
.finally(() => setLoading(false));
}; };
const updateConfig = () => { const updateConfig = () => {

View File

@ -16,15 +16,18 @@ const Crontab = () => {
const getConfig = () => { const getConfig = () => {
request.get(`${config.apiPrefix}config/config`).then((data) => { request.get(`${config.apiPrefix}config/config`).then((data) => {
setValue(data); setValue(data.content);
}); });
}; };
const getSample = () => { const getSample = () => {
setLoading(true); setLoading(true);
request.get(`${config.apiPrefix}config/sample`).then((data) => { request
setSample(data); .get(`${config.apiPrefix}config/sample`)
}).finally(() => setLoading(false)); .then((data) => {
setSample(data.content);
})
.finally(() => setLoading(false));
}; };
useEffect(() => { useEffect(() => {
@ -63,16 +66,19 @@ const Crontab = () => {
}} }}
> >
<ReactDiffViewer <ReactDiffViewer
styles={{ diffRemoved: { styles={{
overflowX: 'auto', diffRemoved: {
maxWidth: 300, overflowX: 'auto',
}, maxWidth: 300,
diffAdded: { },
overflowX: 'auto', diffAdded: {
maxWidth: 300, overflowX: 'auto',
},line: { maxWidth: 300,
wordBreak: 'break-word', },
}, }} line: {
wordBreak: 'break-word',
},
}}
oldValue={value} oldValue={value}
newValue={sample} newValue={sample}
splitView={true} splitView={true}

View File

@ -14,9 +14,12 @@ const Crontab = () => {
const getConfig = () => { const getConfig = () => {
setLoading(true); setLoading(true);
request.get(`${config.apiPrefix}config/diy`).then((data) => { request
setValue(data); .get(`${config.apiPrefix}config/diy`)
}).finally(() => setLoading(false)); .then((data) => {
setValue(data.content);
})
.finally(() => setLoading(false));
}; };
const updateConfig = () => { const updateConfig = () => {

View File

@ -18,7 +18,7 @@ const Login = () => {
}) })
.then((data) => { .then((data) => {
if (data.err == 0) { if (data.err == 0) {
localStorage.setItem(config.authKey, 'true'); localStorage.setItem(config.authKey, data.token);
history.push('/cookie'); history.push('/cookie');
} else { } else {
notification.open({ notification.open({
@ -36,7 +36,7 @@ const Login = () => {
if (isAuth) { if (isAuth) {
history.push('/cookie'); history.push('/cookie');
} }
}, []) }, []);
return ( return (
<Fragment> <Fragment>
@ -50,7 +50,7 @@ const Login = () => {
rules={[{ required: true, message: '请输入用户名' }]} rules={[{ required: true, message: '请输入用户名' }]}
hasFeedback hasFeedback
> >
<Input placeholder="用户名" autoFocus/> <Input placeholder="用户名" autoFocus />
</FormItem> </FormItem>
<FormItem <FormItem
name="password" name="password"

View File

@ -1,7 +1,7 @@
export default { export default {
siteName: '京东羊毛脚本控制面板', siteName: '京东羊毛脚本控制面板',
apiPrefix: '/api/', apiPrefix: '/api/',
authKey: 'whyour', authKey: 'token',
/* Layout configuration, specify which layout to use for route. */ /* Layout configuration, specify which layout to use for route. */
layouts: [ layouts: [

View File

@ -1,29 +1,39 @@
import { extend } from 'umi-request'; import { extend } from 'umi-request';
import { history } from 'umi'; import { history } from 'umi';
import config from './config';
const time = Date.now(); const time = Date.now();
const errorHandler = function (error: any) { const errorHandler = function (error: any) {
if (error.response) { if (error.response) {
console.log(error.response) console.log(error.response);
} else { } else {
console.log(error.message); console.log(error.message);
} }
throw error; // 如果throw. 错误将继续抛出. throw error; // 如果throw. 错误将继续抛出.
// return {some: 'data'};
}; };
const _request = extend({ timeout: 5000, params: { t: time }, errorHandler }); const _request = extend({ timeout: 5000, params: { t: time }, errorHandler });
_request.interceptors.response.use(async response => { _request.interceptors.request.use((url, options) => {
const res = await response.clone().text() const token = localStorage.getItem(config.authKey);
if (res === '请先登录!') { if (token) {
const headers = {
Authorization: `Bearer ${token}`,
};
return { url, options: { ...options, headers } };
}
return { url, options };
});
_request.interceptors.response.use(async (response) => {
const res = await response.clone();
if (res.status === 401) {
setTimeout(() => { setTimeout(() => {
localStorage.removeItem('whyour');
history.push('/login'); history.push('/login');
}); });
} }
return response; return response;
}) });
export const request = _request; export const request = _request;

View File

@ -1,7 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "esnext", "target": "es2017",
"module": "esnext", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"importHelpers": true, "importHelpers": true,
"jsx": "react-jsx", "jsx": "react-jsx",
@ -13,11 +13,22 @@
"@/*": ["src/*"], "@/*": ["src/*"],
"@@/*": ["src/.umi/*"] "@@/*": ["src/.umi/*"]
}, },
"lib": ["dom", "es2017", "esnext.asynciterable"],
"typeRoots": [
"./node_modules/@types",
"./back/types",
"./node_modules/celebrate/lib/index.d.ts"
],
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"experimentalDecorators": true "experimentalDecorators": true,
"emitDecoratorMetadata": true,
"forceConsistentCasingInFileNames": true,
"pretty": true,
"allowJs": true,
"noEmit": false
}, },
"include": [ "include": [
"mock/**/*", "back/**/*",
"src/**/*", "src/**/*",
"config/**/*", "config/**/*",
".umirc.ts", ".umirc.ts",