|
@@ -1,416 +1,417 @@
|
|
-// @flow
|
|
|
|
-/**
|
|
|
|
- * @name utils/request.js
|
|
|
|
- * @fileOverview 封装异步请求调用
|
|
|
|
- * @author liyi
|
|
|
|
- */
|
|
|
|
-import axios from 'axios';
|
|
|
|
-import _ from 'lodash';
|
|
|
|
-import qs from 'qs';
|
|
|
|
-import {
|
|
|
|
- getApiUrl,
|
|
|
|
- getNewApiUrl,
|
|
|
|
- getApiUrlByServiceType,
|
|
|
|
- getNewApiUrlByServiceType,
|
|
|
|
- ServicePath,
|
|
|
|
- getAjaxUrl,
|
|
|
|
- getUrlPath,
|
|
|
|
-} from 'utils/constants';
|
|
|
|
-import NProgress from 'nprogress';
|
|
|
|
-import 'nprogress/nprogress.css';
|
|
|
|
-import { removeLoginData, getRefreshToken, getToken, getCurrentContext } from 'utils/authPermit';
|
|
|
|
-import { notification, Modal } from 'antd';
|
|
|
|
-import cryptoJS from 'crypto-js';
|
|
|
|
-import { hasFeatureAuths } from 'components/auth/switchAuth';
|
|
|
|
-
|
|
|
|
-let isRefreshing = true;
|
|
|
|
-let subscribers = [];
|
|
|
|
-axios.defaults.retry = 4;
|
|
|
|
-axios.defaults.retryDelay = 10000;
|
|
|
|
-//let globalModal = null;
|
|
|
|
-const tplApiUrl = _.template(getApiUrl());
|
|
|
|
-const tplNewApiUrl = _.template(getNewApiUrl());
|
|
|
|
-const newServiceNames = [
|
|
|
|
- 'codemodel',
|
|
|
|
- 'project',
|
|
|
|
- 'dsem',
|
|
|
|
- 'ocr',
|
|
|
|
- 'appscene',
|
|
|
|
- 'ammc',
|
|
|
|
- 'soc',
|
|
|
|
- 'sic',
|
|
|
|
- 'biz',
|
|
|
|
- 'rcc',
|
|
|
|
- 'scc',
|
|
|
|
- 'labels',
|
|
|
|
- 'mc',
|
|
|
|
- 'route',
|
|
|
|
- 'upload',
|
|
|
|
- 'uc',
|
|
|
|
- 'learning',
|
|
|
|
- 'job-manage',
|
|
|
|
- 'job-serve',
|
|
|
|
- 'guide-train',
|
|
|
|
- 'gitlab',
|
|
|
|
- 'data-pre',
|
|
|
|
- 'streaming-reasoning',
|
|
|
|
- 'tp',
|
|
|
|
-];
|
|
|
|
-NProgress.configure({
|
|
|
|
- showSpinner: true,
|
|
|
|
- easing: 'ease',
|
|
|
|
- speed: 500,
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * 检测请求响应状态码,检测请求结果状态,错误时抛出异常
|
|
|
|
- * @param {*} response
|
|
|
|
- */
|
|
|
|
-/* eslint-disable prefer-promise-reject-errors */
|
|
|
|
-function handleResponse(response) {
|
|
|
|
- NProgress.done();
|
|
|
|
- if (response && response.status >= 200 && response.status < 300) {
|
|
|
|
- const { data: result } = response;
|
|
|
|
- if (
|
|
|
|
- (result.code && result.code > 0) ||
|
|
|
|
- result.success === true ||
|
|
|
|
- result.code === '1' ||
|
|
|
|
- typeof result.code === 'string'
|
|
|
|
- ) {
|
|
|
|
- const authorization = response.headers.authorization || response.headers.Authorization;
|
|
|
|
- if (authorization) {
|
|
|
|
- localStorage.setItem('AI.token', authorization);
|
|
|
|
- }
|
|
|
|
- return Promise.resolve({
|
|
|
|
- success: true,
|
|
|
|
- code: result.code,
|
|
|
|
- message: result.message,
|
|
|
|
- data: _.get(result, 'data', result.value || ''),
|
|
|
|
- pagination: result.pagination,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- if ((result.code && result.code < 0) || result.success === false) {
|
|
|
|
- return Promise.reject({
|
|
|
|
- success: result.success,
|
|
|
|
- code: result.code,
|
|
|
|
- message: result.message,
|
|
|
|
- error: result.error || result.errors || '',
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- return Promise.resolve({
|
|
|
|
- data: _.get(result, 'data', result.value) || response.data,
|
|
|
|
- datalearn: response.data, //学件中心接口返回使用
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- return Promise.reject({
|
|
|
|
- success: false,
|
|
|
|
- code: _.get(response || {}, 'status', -1),
|
|
|
|
- message: _.get(response || {}, 'statusText', '请求异常'),
|
|
|
|
- error: _.get(response || {}, 'statusText', '请求异常'),
|
|
|
|
- data: _.get(response, 'result.data', {}),
|
|
|
|
- });
|
|
|
|
-}
|
|
|
|
-/* eslint-disable prefer-promise-reject-errors */
|
|
|
|
-
|
|
|
|
-function handleError(error) {
|
|
|
|
- NProgress.done();
|
|
|
|
- const { statusText, status } = error.response || {};
|
|
|
|
- let errInfo = _.get(error.response || {}, ['data', 'message']) || error.message || '请求服务出错';
|
|
|
|
- const errCode = _.get(error.response || {}, ['data', 'code']) || error.code || -1;
|
|
|
|
- // 请求资源不存在
|
|
|
|
- if (status === 404) errInfo = `请求的资源[${_.get(error.response, ['config', 'url'])}]不存在!`;
|
|
|
|
- if (errCode === '4016' || errCode === '4019') {
|
|
|
|
- if (isRefreshing) {
|
|
|
|
- let { role, id } = getCurrentContext();
|
|
|
|
- refreshToken(role, id);
|
|
|
|
- }
|
|
|
|
- isRefreshing = false;
|
|
|
|
- let config = error.config;
|
|
|
|
- const retryOriginalRequest = new Promise(resolve => {
|
|
|
|
- addSubscriber(() => {
|
|
|
|
- resolve(nextAjax(config));
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- return retryOriginalRequest;
|
|
|
|
- }
|
|
|
|
- //更新服务端客户端时间差
|
|
|
|
- if (errCode === '1310002') {
|
|
|
|
- const nowDate = new Date().getTime();
|
|
|
|
- const serverTime = getServerTime();
|
|
|
|
- const timeDeviation = serverTime - nowDate;
|
|
|
|
- localStorage.setItem('AI.timeDeviation', timeDeviation);
|
|
|
|
- }
|
|
|
|
- // 请求超时打断
|
|
|
|
- if (errCode === 'ECONNABORTED') {
|
|
|
|
- errInfo = '服务连接失败或请求超时!';
|
|
|
|
- }
|
|
|
|
- /* eslint-disable */
|
|
|
|
- if (status === 401 && !_.includes(window.location.pathname, '/login')) {
|
|
|
|
- handleLoginTimeout('授权失败');
|
|
|
|
- } else if (errCode === '4035' || errCode === '4018') {
|
|
|
|
- handleLoginTimeout('登录超时');
|
|
|
|
- } else {
|
|
|
|
- notification.error({
|
|
|
|
- key: 'SYSTEM_ERROR',
|
|
|
|
- message: '系统错误',
|
|
|
|
- description: errInfo,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- return Promise.reject({
|
|
|
|
- success: false,
|
|
|
|
- code: errCode,
|
|
|
|
- message: errInfo || statusText,
|
|
|
|
- error: errInfo || statusText,
|
|
|
|
- data: _.get(error.response, 'data.data', {}),
|
|
|
|
- });
|
|
|
|
-}
|
|
|
|
-/* eslint-disable prefer-promise-reject-errors */
|
|
|
|
-function onAccessTokenFetched() {
|
|
|
|
- subscribers.forEach(callback => {
|
|
|
|
- callback();
|
|
|
|
- });
|
|
|
|
- subscribers = [];
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-function addSubscriber(callback) {
|
|
|
|
- console.dir('callback:加入' + callback);
|
|
|
|
- subscribers.push(callback);
|
|
|
|
-}
|
|
|
|
-const nextAjax = config => {
|
|
|
|
- const token = getToken();
|
|
|
|
- console.dir('2次请求' + token);
|
|
|
|
- config.headers.Authorization = token; //将token设置成请求头
|
|
|
|
- return axiosInstance(config);
|
|
|
|
-};
|
|
|
|
-/**
|
|
|
|
- * 处理登录超时/授权失败
|
|
|
|
- */
|
|
|
|
-const handleLoginTimeout = (errorMsg = '登录超时') => {
|
|
|
|
- logOut();
|
|
|
|
- let secondsToGo = 5;
|
|
|
|
- const modal = Modal.warn({
|
|
|
|
- title: errorMsg,
|
|
|
|
- content: `系统${errorMsg},${secondsToGo} 秒后自动跳转至登录页面!`,
|
|
|
|
- okText: '立即跳转至登录页面',
|
|
|
|
- onOk: () => {
|
|
|
|
- clearInterval(timer);
|
|
|
|
- modal.destroy();
|
|
|
|
- window.location.reload();
|
|
|
|
- },
|
|
|
|
- });
|
|
|
|
- const timer = setInterval(() => {
|
|
|
|
- secondsToGo -= 1;
|
|
|
|
- if (modal.update) {
|
|
|
|
- modal.update({
|
|
|
|
- content: `${errorMsg},${secondsToGo} 秒后自动跳转至登录页面!`,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }, 1000);
|
|
|
|
- setTimeout(() => {
|
|
|
|
- clearInterval(timer);
|
|
|
|
- modal.destroy();
|
|
|
|
- const token = getToken();
|
|
|
|
- window.location.reload();
|
|
|
|
- }, secondsToGo * 1000);
|
|
|
|
- return modal;
|
|
|
|
-};
|
|
|
|
-/**
|
|
|
|
- * 创建axios实例,设置默认api请求跟路径、超时时间,请求头content-type
|
|
|
|
- */
|
|
|
|
-const axiosInstance = axios.create({
|
|
|
|
- timeout: 1200000,
|
|
|
|
- headers: {
|
|
|
|
- 'Content-Type': 'application/json;charset=UTF-8',
|
|
|
|
- Accept: 'application/json',
|
|
|
|
- },
|
|
|
|
-});
|
|
|
|
-/**
|
|
|
|
- * axios 拦截
|
|
|
|
- * TODO 通过config为每次api请求调用添加token
|
|
|
|
- */
|
|
|
|
-axiosInstance.interceptors.request.use(
|
|
|
|
- function(config) {
|
|
|
|
- const token = getToken();
|
|
|
|
- const ssoType = config.url.indexOf('/authc/sso') !== -1 || config.url.indexOf('/oauth/token') !== -1 ? true : false;
|
|
|
|
- if (token && !ssoType) {
|
|
|
|
- //判断token是否存在
|
|
|
|
- config.headers.Authorization = token; //将token设置成请求头
|
|
|
|
- }
|
|
|
|
- //拦截所有AI图像、文字识别的参数,赋值store供界面显示
|
|
|
|
- if (config.dispatch) {
|
|
|
|
- //SET_REQUEST_CONFIG
|
|
|
|
- config.dispatch(platFormActions.setRequestConfig(config));
|
|
|
|
- }
|
|
|
|
- const isOld = _.indexOf(newServiceNames, config.basePath) === -1 && config.url !== '/oauth/token';
|
|
|
|
- const basePath = config.basePath || ServicePath.MODELING_SERVICE;
|
|
|
|
- const urlPath = config.url;
|
|
|
|
- //专门为切换网关访问场景IP
|
|
|
|
- if (config.serviceType) {
|
|
|
|
- let upServiceType = _.toUpper(config.serviceType);
|
|
|
|
- config.baseURL = isOld
|
|
|
|
- ? getApiUrlByServiceType(upServiceType, basePath)
|
|
|
|
- : getNewApiUrlByServiceType(upServiceType, basePath);
|
|
|
|
- // mc 服务网关地址切换
|
|
|
|
- } else if (config.serviceType2Mc) {
|
|
|
|
- let upServiceType2Mc = _.toUpper(config.serviceType2Mc);
|
|
|
|
- config.baseURL = isOld
|
|
|
|
- ? getApiUrlByServiceType(upServiceType2Mc, basePath, true)
|
|
|
|
- : getNewApiUrlByServiceType(upServiceType2Mc, basePath, true);
|
|
|
|
- } else {
|
|
|
|
- if (config.basePath === 'relative') {
|
|
|
|
- config.baseURL = '/';
|
|
|
|
- } else {
|
|
|
|
- config.baseURL = isOld ? tplApiUrl({ BASE_PATH: basePath }) : tplNewApiUrl({ BASE_PATH: basePath });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //updateExpiredTime();
|
|
|
|
- if (!config.sync && _.isEmpty({})) {
|
|
|
|
- NProgress.start();
|
|
|
|
- }
|
|
|
|
- let params = config.params || {};
|
|
|
|
- if (hasFeatureAuths('root.app.enableSignature')) {
|
|
|
|
- params = getSignatureParams({ params, isOld, basePath, urlPath });
|
|
|
|
- }
|
|
|
|
- config.params = params;
|
|
|
|
- return config;
|
|
|
|
- },
|
|
|
|
- function(error) {
|
|
|
|
- return Promise.reject(error);
|
|
|
|
- }
|
|
|
|
-);
|
|
|
|
-export const refreshToken = async (scopeType, scopeId) => {
|
|
|
|
- console.log(getToken());
|
|
|
|
- console.log('refreshToken过期正在去换取开始~~~');
|
|
|
|
- const refreshToken = getRefreshToken();
|
|
|
|
- const result = await axios
|
|
|
|
- .post(
|
|
|
|
- getAjaxUrl() + `${ServicePath.AUTH_SERVICE}/oauth/token`,
|
|
|
|
- qs.stringify({
|
|
|
|
- grant_type: 'refresh_token',
|
|
|
|
- refresh_token: refreshToken,
|
|
|
|
- client_id: 'AI_FRONT',
|
|
|
|
- client_secret: '23dfd110-6864-4d53-a7fb-8e671687a7bf',
|
|
|
|
- scopeType,
|
|
|
|
- scopeId,
|
|
|
|
- }),
|
|
|
|
- {
|
|
|
|
- headers: {
|
|
|
|
- Authorization: 'Basic QUlfRlJPTlQ6MjNkZmQxMTAtNjg2NC00ZDUzLWE3ZmItOGU2NzE2ODdhN2Jm',
|
|
|
|
- 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
|
- __ai_refresh_token: refreshToken,
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- )
|
|
|
|
- .then(res => {
|
|
|
|
- console.log('refreshToken过期换取成功');
|
|
|
|
- localStorage.setItem('AI.token', res.data.access_token ? 'Bearer ' + res.data.access_token : '');
|
|
|
|
- localStorage.setItem('AI.refreshToken', res.data.refresh_token);
|
|
|
|
- localStorage.setItem('AI.expiresIn', res.data.expires_in); //储存过期时间(秒)
|
|
|
|
- console.dir('新' + res.data.access_token);
|
|
|
|
- onAccessTokenFetched();
|
|
|
|
- isRefreshing = true;
|
|
|
|
- return true;
|
|
|
|
- })
|
|
|
|
- .catch(error => {
|
|
|
|
- console.log('refreshToken过期换取失败' + error);
|
|
|
|
- // onAccessTokenFetched();
|
|
|
|
- // isRefreshing = true;
|
|
|
|
- handleLoginTimeout();
|
|
|
|
- return false;
|
|
|
|
- });
|
|
|
|
- return result;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-/**获取签名参数 */
|
|
|
|
-function getSignatureParams({ params, isOld, basePath, urlPath }) {
|
|
|
|
- let timeDeviation = localStorage.getItem('AI.timeDeviation');
|
|
|
|
- const nowDate = new Date().getTime();
|
|
|
|
- if (!timeDeviation) {
|
|
|
|
- const serverTime = getServerTime();
|
|
|
|
- timeDeviation = serverTime - nowDate;
|
|
|
|
- localStorage.setItem('AI.timeDeviation', timeDeviation);
|
|
|
|
- }
|
|
|
|
- const url = getUrlPath(isOld, basePath, urlPath);
|
|
|
|
- delete params['sign'];
|
|
|
|
- params['signTimestamp'] = nowDate + Number(timeDeviation);
|
|
|
|
- const sign = generateSignature(params, url);
|
|
|
|
- params['sign'] = sign;
|
|
|
|
- return params;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/***
|
|
|
|
- + * url 签名
|
|
|
|
- + */
|
|
|
|
-function generateSignature(params, urlPath) {
|
|
|
|
- const urlInfos = urlPath.split('?');
|
|
|
|
- const urlParams = qs.parse(urlInfos[1]);
|
|
|
|
- let sign = '';
|
|
|
|
- params = Object.assign({}, params, urlParams);
|
|
|
|
- const orderParams = {};
|
|
|
|
- Object.keys(params)
|
|
|
|
- .sort()
|
|
|
|
- .forEach(function(key) {
|
|
|
|
- if (!_.isNull(params[key]) && !_.isUndefined(params[key])) {
|
|
|
|
- orderParams[key] = params[key];
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- let secretParams = '';
|
|
|
|
- for (let key in orderParams) {
|
|
|
|
- if (Array.isArray(orderParams[key])) {
|
|
|
|
- let sortArray = params[key].sort();
|
|
|
|
- for (let i = 0; i < sortArray.length; i++) {
|
|
|
|
- secretParams = secretParams ? `${secretParams}&${key}=${sortArray[i]}` : `${key}=${sortArray[i]}`;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- secretParams = secretParams ? `${secretParams}&${key}=${orderParams[key]}` : `${key}=${orderParams[key]}`;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const secretText = `${urlInfos[0]}?${secretParams}`;
|
|
|
|
- const secretKey = '5ebe2294ecd0e0f08eab7690d2a6ee69';
|
|
|
|
- sign = encryptByDES(secretText, secretKey);
|
|
|
|
- return sign;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-function encryptByDES(message, key) {
|
|
|
|
- const keyHex = cryptoJS.enc.Utf8.parse(key);
|
|
|
|
- const encrypted = cryptoJS.DES.encrypt(message, keyHex, { mode: cryptoJS.mode.ECB, padding: cryptoJS.pad.Pkcs7 });
|
|
|
|
- return encrypted.toString();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-function getServerTime() {
|
|
|
|
- var xhr = null;
|
|
|
|
- if (window.XMLHttpRequest) {
|
|
|
|
- xhr = new window.XMLHttpRequest();
|
|
|
|
- } else {
|
|
|
|
- xhr = new ActiveObject('Microsoft');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- xhr.open('GET', '/', false);
|
|
|
|
- xhr.send(null);
|
|
|
|
- var date = xhr.getResponseHeader('Date');
|
|
|
|
- date = new Date(date).getTime();
|
|
|
|
- return date;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/** 退出登录(超时后跳到嵌入iframe登录页面时,iframe页面自动重定向了)*/
|
|
|
|
-function logOut() {
|
|
|
|
- const token = getToken();
|
|
|
|
- removeLoginData();
|
|
|
|
- axiosInstance({
|
|
|
|
- basePath: 'relative',
|
|
|
|
- url: `/aiSquare/openApi/uc/oauth/logout?token=${token}`,
|
|
|
|
- method: 'get',
|
|
|
|
- });
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * axios 拦截
|
|
|
|
- */
|
|
|
|
-axiosInstance.interceptors.response.use(
|
|
|
|
- response => handleResponse(response),
|
|
|
|
- error => handleError(error)
|
|
|
|
-);
|
|
|
|
-
|
|
|
|
-export default axiosInstance;
|
|
|
|
|
|
+// @flow
|
|
|
|
+/**
|
|
|
|
+ * @name utils/request.js
|
|
|
|
+ * @fileOverview 封装异步请求调用
|
|
|
|
+ * @author liyi
|
|
|
|
+ */
|
|
|
|
+import axios from 'axios';
|
|
|
|
+import _ from 'lodash';
|
|
|
|
+import qs from 'qs';
|
|
|
|
+import {
|
|
|
|
+ getApiUrl,
|
|
|
|
+ getNewApiUrl,
|
|
|
|
+ getApiUrlByServiceType,
|
|
|
|
+ getNewApiUrlByServiceType,
|
|
|
|
+ ServicePath,
|
|
|
|
+ getAjaxUrl,
|
|
|
|
+ getUrlPath,
|
|
|
|
+} from 'utils/constants';
|
|
|
|
+import NProgress from 'nprogress';
|
|
|
|
+import 'nprogress/nprogress.css';
|
|
|
|
+import { removeLoginData, getRefreshToken, getToken, getCurrentContext } from 'utils/authPermit';
|
|
|
|
+import { notification, Modal } from 'antd';
|
|
|
|
+import cryptoJS from 'crypto-js';
|
|
|
|
+import { hasFeatureAuths } from 'components/auth/switchAuth';
|
|
|
|
+
|
|
|
|
+let isRefreshing = true;
|
|
|
|
+let subscribers = [];
|
|
|
|
+axios.defaults.retry = 4;
|
|
|
|
+axios.defaults.retryDelay = 10000;
|
|
|
|
+//let globalModal = null;
|
|
|
|
+const tplApiUrl = _.template(getApiUrl());
|
|
|
|
+const tplNewApiUrl = _.template(getNewApiUrl());
|
|
|
|
+const newServiceNames = [
|
|
|
|
+ 'codemodel',
|
|
|
|
+ 'project',
|
|
|
|
+ 'dsem',
|
|
|
|
+ 'ocr',
|
|
|
|
+ 'appscene',
|
|
|
|
+ 'ammc',
|
|
|
|
+ 'soc',
|
|
|
|
+ 'sic',
|
|
|
|
+ 'biz',
|
|
|
|
+ 'rcc',
|
|
|
|
+ 'scc',
|
|
|
|
+ 'labels',
|
|
|
|
+ 'mc',
|
|
|
|
+ 'route',
|
|
|
|
+ 'upload',
|
|
|
|
+ 'uc',
|
|
|
|
+ 'learning',
|
|
|
|
+ 'job-manage',
|
|
|
|
+ 'job-serve',
|
|
|
|
+ 'guide-train',
|
|
|
|
+ 'gitlab',
|
|
|
|
+ 'data-pre',
|
|
|
|
+ 'streaming-reasoning',
|
|
|
|
+ 'tp',
|
|
|
|
+];
|
|
|
|
+NProgress.configure({
|
|
|
|
+ showSpinner: true,
|
|
|
|
+ easing: 'ease',
|
|
|
|
+ speed: 500,
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 检测请求响应状态码,检测请求结果状态,错误时抛出异常
|
|
|
|
+ * @param {*} response
|
|
|
|
+ */
|
|
|
|
+/* eslint-disable prefer-promise-reject-errors */
|
|
|
|
+function handleResponse(response) {
|
|
|
|
+ NProgress.done();
|
|
|
|
+ if (response && response.status >= 200 && response.status < 300) {
|
|
|
|
+ const { data: result } = response;
|
|
|
|
+ if (
|
|
|
|
+ (result.code && result.code > 0) ||
|
|
|
|
+ result.success === true ||
|
|
|
|
+ result.code === '1' ||
|
|
|
|
+ typeof result.code === 'string'
|
|
|
|
+ ) {
|
|
|
|
+ const authorization = response.headers.authorization || response.headers.Authorization;
|
|
|
|
+ if (authorization) {
|
|
|
|
+ localStorage.setItem('AI.token', authorization);
|
|
|
|
+ }
|
|
|
|
+ return Promise.resolve({
|
|
|
|
+ success: true,
|
|
|
|
+ code: result.code,
|
|
|
|
+ message: result.message,
|
|
|
|
+ data: _.get(result, 'data', result.value || ''),
|
|
|
|
+ pagination: result.pagination,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if ((result.code && result.code < 0) || result.success === false) {
|
|
|
|
+ return Promise.reject({
|
|
|
|
+ success: result.success,
|
|
|
|
+ code: result.code,
|
|
|
|
+ message: result.message,
|
|
|
|
+ error: result.error || result.errors || '',
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ return Promise.resolve({
|
|
|
|
+ data: _.get(result, 'data', result.value) || response.data,
|
|
|
|
+ datalearn: response.data, //学件中心接口返回使用
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ return Promise.reject({
|
|
|
|
+ success: false,
|
|
|
|
+ code: _.get(response || {}, 'status', -1),
|
|
|
|
+ message: _.get(response || {}, 'statusText', '请求异常'),
|
|
|
|
+ error: _.get(response || {}, 'statusText', '请求异常'),
|
|
|
|
+ data: _.get(response, 'result.data', {}),
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+/* eslint-disable prefer-promise-reject-errors */
|
|
|
|
+
|
|
|
|
+function handleError(error) {
|
|
|
|
+ NProgress.done();
|
|
|
|
+ const { statusText, status } = error.response || {};
|
|
|
|
+ let errInfo = _.get(error.response || {}, ['data', 'message']) || error.message || '请求服务出错';
|
|
|
|
+ const errCode = _.get(error.response || {}, ['data', 'code']) || error.code || -1;
|
|
|
|
+ // 请求资源不存在
|
|
|
|
+ if (status === 404) errInfo = `请求的资源[${_.get(error.response, ['config', 'url'])}]不存在!`;
|
|
|
|
+ if (errCode === '4016' || errCode === '4019') {
|
|
|
|
+ if (isRefreshing) {
|
|
|
|
+ let { role, id } = getCurrentContext();
|
|
|
|
+ refreshToken(role, id);
|
|
|
|
+ }
|
|
|
|
+ isRefreshing = false;
|
|
|
|
+ let config = error.config;
|
|
|
|
+ const retryOriginalRequest = new Promise(resolve => {
|
|
|
|
+ addSubscriber(() => {
|
|
|
|
+ resolve(nextAjax(config));
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ return retryOriginalRequest;
|
|
|
|
+ }
|
|
|
|
+ //更新服务端客户端时间差
|
|
|
|
+ if (errCode === '1310002') {
|
|
|
|
+ const nowDate = new Date().getTime();
|
|
|
|
+ const serverTime = getServerTime();
|
|
|
|
+ const timeDeviation = serverTime - nowDate;
|
|
|
|
+ localStorage.setItem('AI.timeDeviation', timeDeviation);
|
|
|
|
+ }
|
|
|
|
+ // 请求超时打断
|
|
|
|
+ if (errCode === 'ECONNABORTED') {
|
|
|
|
+ errInfo = '服务连接失败或请求超时!';
|
|
|
|
+ }
|
|
|
|
+ /* eslint-disable */
|
|
|
|
+ if (status === 401 && !_.includes(window.location.pathname, '/login')) {
|
|
|
|
+ handleLoginTimeout('授权失败');
|
|
|
|
+ } else if (errCode === '4035' || errCode === '4018') {
|
|
|
|
+ handleLoginTimeout('登录超时');
|
|
|
|
+ } else {
|
|
|
|
+ notification.error({
|
|
|
|
+ key: 'SYSTEM_ERROR',
|
|
|
|
+ message: '系统错误',
|
|
|
|
+ description: errInfo,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ return Promise.reject({
|
|
|
|
+ success: false,
|
|
|
|
+ code: errCode,
|
|
|
|
+ message: errInfo || statusText,
|
|
|
|
+ error: errInfo || statusText,
|
|
|
|
+ data: _.get(error.response, 'data.data', {}),
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+/* eslint-disable prefer-promise-reject-errors */
|
|
|
|
+function onAccessTokenFetched() {
|
|
|
|
+ subscribers.forEach(callback => {
|
|
|
|
+ callback();
|
|
|
|
+ });
|
|
|
|
+ subscribers = [];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function addSubscriber(callback) {
|
|
|
|
+ console.dir('callback:加入' + callback);
|
|
|
|
+ subscribers.push(callback);
|
|
|
|
+}
|
|
|
|
+const nextAjax = config => {
|
|
|
|
+ const token = getToken();
|
|
|
|
+ console.dir('2次请求' + token);
|
|
|
|
+ config.headers.Authorization = token; //将token设置成请求头
|
|
|
|
+ return axiosInstance(config);
|
|
|
|
+};
|
|
|
|
+/**
|
|
|
|
+ * 处理登录超时/授权失败
|
|
|
|
+ */
|
|
|
|
+const handleLoginTimeout = (errorMsg = '登录超时') => {
|
|
|
|
+ logOut();
|
|
|
|
+ let secondsToGo = 5;
|
|
|
|
+ const modal = Modal.warn({
|
|
|
|
+ title: errorMsg,
|
|
|
|
+ content: `系统${errorMsg},${secondsToGo} 秒后自动跳转至登录页面!`,
|
|
|
|
+ okText: '立即跳转至登录页面',
|
|
|
|
+ onOk: () => {
|
|
|
|
+ clearInterval(timer);
|
|
|
|
+ modal.destroy();
|
|
|
|
+ window.location.reload();
|
|
|
|
+ },
|
|
|
|
+ });
|
|
|
|
+ const timer = setInterval(() => {
|
|
|
|
+ secondsToGo -= 1;
|
|
|
|
+ if (modal.update) {
|
|
|
|
+ modal.update({
|
|
|
|
+ content: `${errorMsg},${secondsToGo} 秒后自动跳转至登录页面!`,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }, 1000);
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ clearInterval(timer);
|
|
|
|
+ modal.destroy();
|
|
|
|
+ const token = getToken();
|
|
|
|
+ window.location.reload();
|
|
|
|
+ }, secondsToGo * 1000);
|
|
|
|
+ return modal;
|
|
|
|
+};
|
|
|
|
+/**
|
|
|
|
+ * 创建axios实例,设置默认api请求跟路径、超时时间,请求头content-type
|
|
|
|
+ */
|
|
|
|
+const axiosInstance = axios.create({
|
|
|
|
+ timeout: 1200000,
|
|
|
|
+ headers: {
|
|
|
|
+ 'Content-Type': 'application/json;charset=UTF-8',
|
|
|
|
+ Accept: 'application/json',
|
|
|
|
+ },
|
|
|
|
+});
|
|
|
|
+/**
|
|
|
|
+ * axios 拦截
|
|
|
|
+ * TODO 通过config为每次api请求调用添加token
|
|
|
|
+ */
|
|
|
|
+axiosInstance.interceptors.request.use(
|
|
|
|
+ function(config) {
|
|
|
|
+ const token = getToken();
|
|
|
|
+ const ssoType = config.url.indexOf('/authc/sso') !== -1 || config.url.indexOf('/oauth/token') !== -1 ? true : false;
|
|
|
|
+ if (token && !ssoType) {
|
|
|
|
+ //判断token是否存在
|
|
|
|
+ config.headers.Authorization = token; //将token设置成请求头
|
|
|
|
+ }
|
|
|
|
+ //拦截所有AI图像、文字识别的参数,赋值store供界面显示
|
|
|
|
+ if (config.dispatch) {
|
|
|
|
+ //SET_REQUEST_CONFIG
|
|
|
|
+ config.dispatch(platFormActions.setRequestConfig(config));
|
|
|
|
+ }
|
|
|
|
+ const isOld = _.indexOf(newServiceNames, config.basePath) === -1 && config.url !== '/oauth/token';
|
|
|
|
+ const basePath = config.basePath || ServicePath.MODELING_SERVICE;
|
|
|
|
+ const urlPath = config.url;
|
|
|
|
+ //专门为切换网关访问场景IP
|
|
|
|
+ if (config.serviceType) {
|
|
|
|
+ let upServiceType = _.toUpper(config.serviceType);
|
|
|
|
+ config.baseURL = isOld
|
|
|
|
+ ? getApiUrlByServiceType(upServiceType, basePath)
|
|
|
|
+ : getNewApiUrlByServiceType(upServiceType, basePath);
|
|
|
|
+ // mc 服务网关地址切换
|
|
|
|
+ } else if (config.serviceType2Mc) {
|
|
|
|
+ let upServiceType2Mc = _.toUpper(config.serviceType2Mc);
|
|
|
|
+ config.baseURL = isOld
|
|
|
|
+ ? getApiUrlByServiceType(upServiceType2Mc, basePath, true)
|
|
|
|
+ : getNewApiUrlByServiceType(upServiceType2Mc, basePath, true);
|
|
|
|
+ } else {
|
|
|
|
+ if (config.basePath === 'relative') {
|
|
|
|
+ config.baseURL = '/';
|
|
|
|
+ } else {
|
|
|
|
+ config.baseURL = isOld ? tplApiUrl({ BASE_PATH: basePath }) : tplNewApiUrl({ BASE_PATH: basePath });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //updateExpiredTime();
|
|
|
|
+ if (!config.sync && _.isEmpty({})) {
|
|
|
|
+ NProgress.start();
|
|
|
|
+ }
|
|
|
|
+ let params = config.params || {};
|
|
|
|
+ if (hasFeatureAuths('root.app.enableSignature')) {
|
|
|
|
+ params = getSignatureParams({ params, isOld, basePath, urlPath });
|
|
|
|
+ }
|
|
|
|
+ config.params = params;
|
|
|
|
+ config.data = config.data || {};
|
|
|
|
+ return config;
|
|
|
|
+ },
|
|
|
|
+ function(error) {
|
|
|
|
+ return Promise.reject(error);
|
|
|
|
+ }
|
|
|
|
+);
|
|
|
|
+export const refreshToken = async (scopeType, scopeId) => {
|
|
|
|
+ console.log(getToken());
|
|
|
|
+ console.log('refreshToken过期正在去换取开始~~~');
|
|
|
|
+ const refreshToken = getRefreshToken();
|
|
|
|
+ const result = await axios
|
|
|
|
+ .post(
|
|
|
|
+ getAjaxUrl() + `${ServicePath.AUTH_SERVICE}/oauth/token`,
|
|
|
|
+ qs.stringify({
|
|
|
|
+ grant_type: 'refresh_token',
|
|
|
|
+ refresh_token: refreshToken,
|
|
|
|
+ client_id: 'AI_FRONT',
|
|
|
|
+ client_secret: '23dfd110-6864-4d53-a7fb-8e671687a7bf',
|
|
|
|
+ scopeType,
|
|
|
|
+ scopeId,
|
|
|
|
+ }),
|
|
|
|
+ {
|
|
|
|
+ headers: {
|
|
|
|
+ Authorization: 'Basic QUlfRlJPTlQ6MjNkZmQxMTAtNjg2NC00ZDUzLWE3ZmItOGU2NzE2ODdhN2Jm',
|
|
|
|
+ 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
|
+ __ai_refresh_token: refreshToken,
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ )
|
|
|
|
+ .then(res => {
|
|
|
|
+ console.log('refreshToken过期换取成功');
|
|
|
|
+ localStorage.setItem('AI.token', res.data.access_token ? 'Bearer ' + res.data.access_token : '');
|
|
|
|
+ localStorage.setItem('AI.refreshToken', res.data.refresh_token);
|
|
|
|
+ localStorage.setItem('AI.expiresIn', res.data.expires_in); //储存过期时间(秒)
|
|
|
|
+ console.dir('新' + res.data.access_token);
|
|
|
|
+ onAccessTokenFetched();
|
|
|
|
+ isRefreshing = true;
|
|
|
|
+ return true;
|
|
|
|
+ })
|
|
|
|
+ .catch(error => {
|
|
|
|
+ console.log('refreshToken过期换取失败' + error);
|
|
|
|
+ // onAccessTokenFetched();
|
|
|
|
+ // isRefreshing = true;
|
|
|
|
+ handleLoginTimeout();
|
|
|
|
+ return false;
|
|
|
|
+ });
|
|
|
|
+ return result;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/**获取签名参数 */
|
|
|
|
+function getSignatureParams({ params, isOld, basePath, urlPath }) {
|
|
|
|
+ let timeDeviation = localStorage.getItem('AI.timeDeviation');
|
|
|
|
+ const nowDate = new Date().getTime();
|
|
|
|
+ if (!timeDeviation) {
|
|
|
|
+ const serverTime = getServerTime();
|
|
|
|
+ timeDeviation = serverTime - nowDate;
|
|
|
|
+ localStorage.setItem('AI.timeDeviation', timeDeviation);
|
|
|
|
+ }
|
|
|
|
+ const url = getUrlPath(isOld, basePath, urlPath);
|
|
|
|
+ delete params['sign'];
|
|
|
|
+ params['signTimestamp'] = nowDate + Number(timeDeviation);
|
|
|
|
+ const sign = generateSignature(params, url);
|
|
|
|
+ params['sign'] = sign;
|
|
|
|
+ return params;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/***
|
|
|
|
+ + * url 签名
|
|
|
|
+ + */
|
|
|
|
+function generateSignature(params, urlPath) {
|
|
|
|
+ const urlInfos = urlPath.split('?');
|
|
|
|
+ const urlParams = qs.parse(urlInfos[1]);
|
|
|
|
+ let sign = '';
|
|
|
|
+ params = Object.assign({}, params, urlParams);
|
|
|
|
+ const orderParams = {};
|
|
|
|
+ Object.keys(params)
|
|
|
|
+ .sort()
|
|
|
|
+ .forEach(function(key) {
|
|
|
|
+ if (!_.isNull(params[key]) && !_.isUndefined(params[key])) {
|
|
|
|
+ orderParams[key] = params[key];
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ let secretParams = '';
|
|
|
|
+ for (let key in orderParams) {
|
|
|
|
+ if (Array.isArray(orderParams[key])) {
|
|
|
|
+ let sortArray = params[key].sort();
|
|
|
|
+ for (let i = 0; i < sortArray.length; i++) {
|
|
|
|
+ secretParams = secretParams ? `${secretParams}&${key}=${sortArray[i]}` : `${key}=${sortArray[i]}`;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ secretParams = secretParams ? `${secretParams}&${key}=${orderParams[key]}` : `${key}=${orderParams[key]}`;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const secretText = `${urlInfos[0]}?${secretParams}`;
|
|
|
|
+ const secretKey = '5ebe2294ecd0e0f08eab7690d2a6ee69';
|
|
|
|
+ sign = encryptByDES(secretText, secretKey);
|
|
|
|
+ return sign;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function encryptByDES(message, key) {
|
|
|
|
+ const keyHex = cryptoJS.enc.Utf8.parse(key);
|
|
|
|
+ const encrypted = cryptoJS.DES.encrypt(message, keyHex, { mode: cryptoJS.mode.ECB, padding: cryptoJS.pad.Pkcs7 });
|
|
|
|
+ return encrypted.toString();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function getServerTime() {
|
|
|
|
+ var xhr = null;
|
|
|
|
+ if (window.XMLHttpRequest) {
|
|
|
|
+ xhr = new window.XMLHttpRequest();
|
|
|
|
+ } else {
|
|
|
|
+ xhr = new ActiveObject('Microsoft');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ xhr.open('GET', '/', false);
|
|
|
|
+ xhr.send(null);
|
|
|
|
+ var date = xhr.getResponseHeader('Date');
|
|
|
|
+ date = new Date(date).getTime();
|
|
|
|
+ return date;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/** 退出登录(超时后跳到嵌入iframe登录页面时,iframe页面自动重定向了)*/
|
|
|
|
+function logOut() {
|
|
|
|
+ const token = getToken();
|
|
|
|
+ removeLoginData();
|
|
|
|
+ axiosInstance({
|
|
|
|
+ basePath: 'relative',
|
|
|
|
+ url: `/aiSquare/openApi/uc/oauth/logout?token=${token}`,
|
|
|
|
+ method: 'get',
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * axios 拦截
|
|
|
|
+ */
|
|
|
|
+axiosInstance.interceptors.response.use(
|
|
|
|
+ response => handleResponse(response),
|
|
|
|
+ error => handleError(error)
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+export default axiosInstance;
|