webservice.js 7.96 KB
/// <reference path="../../app.js" />

// apiInterceptor is responsible to handle the aspect of each request and response.
webservices.factory('apiInterceptor', ['$q', 'loginContext', '$log', '$window', '$injector','$cookies',
    function ($q, loginContext, $log, $window, $injector,$cookies) {
        'use strict';

        $log.debug('apiInterceptor.ctor()...');

        var apiToken = loginContext.apiToken;
        var tokenType = loginContext.tokenType;
        var webApiHostUrl = loginContext.apiHost + constant.webapi.prefix;
        //for vat api
        var vatWebApiHostUrl = loginContext.vatApiHost + constant.webapi.prefix;

        var redirectToLogOut = loginContext.redirectToLogOutFunction;

        return {
            //token save to services for further usage
            tokenType: tokenType,
            apiToken: function () {
                return apiToken;
            },
            webApiHostUrl: webApiHostUrl,
            //for vat api
            vatWebApiHostUrl: vatWebApiHostUrl,

            // On request success
            request: function (config) {

                // Check if this request is a web api call, we should only update url and header for each web api request.
                // Because angular will use the $http service as well internally, such as ng-include to request a html file from server.
                // Set this config to send request to a different web server will break the functions of angularJS.
                if (config.isWebApiRequest) {
                    config.headers = config.headers || {};
                    config.headers.Authorization = tokenType + ' ' + apiToken;
                    if (config.apiType == 'vat') {
                        config.url = vatWebApiHostUrl + config.url;
                    }
                    else {
                        config.url = webApiHostUrl + config.url;
                    }
                    config.withCredentials = true;

                    //废弃 token有效期会自动判断
                    // before each api call, try to ensure user account has not been expired
                    // otherwise, force user to login again
                    // var $http = $injector.get('$http');
                    // $http.get(loginContext.serverUrl + '/Account/CheckLoginStatus?_=' + (new Date).valueOf(), { isBusyRequest: false }).success(function (data) {
                    //     if (data === false) {
                    //         redirectToLogOut();
                    //     }
                    // });
                }

                return config;
            },
            // On request failure
            requestError: function (rejection) {
                $log.error(rejection); // Contains the data about the error on the request.

                // Return the promise rejection.
                return $q.reject(rejection);
            },
            // On response success
            response: function (response) {
                if (response.status === 401) {
                    redirectToLogOut();
                }
                var tmpToken = response.headers('refreshToken');
                if (!!tmpToken) {
                    apiToken = tmpToken;
                    $log.info('refresh token: ' + apiToken);
                }
                return response || $q.when(response);
            },
            // On response failture
            responseError: function (rejection) {
                $log.error(rejection); // Contains the data about the error.

                if (rejection.status === 401) {
                    redirectToLogOut();
                }

                // Return the promise rejection.
                return $q.reject(rejection);
            }
        };
    }])
.factory('requestNotificationInterceptor', ['$q', '$injector', '$log', function ($q, $injector, $log) {
    'use strict';

    $log.debug('busyRequestNotificationInterceptor.ctor()...');

    var busyRequestNotificationHub;
    var busyRequestUrl = null;
    var requestOntheWay = 0;

    function onRequestStarted(config) {
        if (config.isWebApiRequest && config.isBusyRequest) {
            //$log.debug('busyRequestNotificationInterceptor: Start busy request ' + config.url);
            //busyRequestNotificationHub = busyRequestNotificationHub || $injector.get('busyRequestNotificationHub');
            //busyRequestNotificationHub.requestStarted();
            //busyRequestUrl = config.url;
        }

        if (config && typeof (config.ignoreLoadingBar) !== 'undefined' && !config.ignoreLoadingBar) {
            requestOntheWay++;
        }

        if (requestOntheWay > 0) {
            $('#busy-indicator-container').show();
        }
    }

    function onRequestEnded(config) {
        if (busyRequestUrl && config.url === busyRequestUrl) {
            //$log.debug('busyRequestNotificationInterceptor: Finish busy request ' + config.url);
            //busyRequestNotificationHub = busyRequestNotificationHub || $injector.get('busyRequestNotificationHub');
            //busyRequestNotificationHub.requestEnded();
            //busyRequestUrl = null;
        }

        if (config && typeof (config.ignoreLoadingBar) !== 'undefined' && !config.ignoreLoadingBar) {
            requestOntheWay--;
        }

        if (requestOntheWay <= 0) {
            $('#busy-indicator-container').hide();
        }
    }

    return {
        // On request success
        request: function (config) {
            onRequestStarted(config);
            return config;
        },
        // On request failure
        requestError: function (rejection) {
            onRequestEnded(rejection.config);
            return $q.reject(rejection);
        },
        // On response success
        response: function (response) {
            onRequestEnded(response.config);
            return response || $q.when(response);
        },
        // On response failture
        responseError: function (rejection) {
            onRequestEnded(rejection.config);
            return $q.reject(rejection);
        }
    }
}]);

webservices.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('apiInterceptor');
    $httpProvider.interceptors.push('requestNotificationInterceptor');
}]);

// All web api request should use this service to create its config for request.
webservices.factory('apiConfig', ['$log', 'vatSessionService',
    function ($log, vatSessionService) {

        $log.debug('apiConfig.ctor()...');

        return {
            create: function (config) {
                var cfg = {
                    apiType: 'admin',
                    ignoreLoadingBar: false
                };
                if (config) {
                    cfg = _.extend(cfg, config);
                }

                cfg.isWebApiRequest = true;
                if (config && config.dbName) {
                    cfg.headers = { 'from': config.dbName + '@cn.pwc.com' };
                }
                else {
                    if (vatSessionService.project && vatSessionService.project.dbName) {
                        cfg.headers = { 'from': vatSessionService.project.dbName + '@cn.pwc.com' };
                    }
                }
                return cfg;
            },
            createVat: function (config) {
                var cfg = {
                    apiType: 'vat',
                    ignoreLoadingBar: false
                };
                if (config) {
                    cfg = _.extend(cfg, config);
                }

                cfg.isWebApiRequest = true;
                if (config && config.dbName) {
                    cfg.headers = { 'from': config.dbName + '@cn.pwc.com' };
                }
                else {
                    cfg.headers = { 'from': vatSessionService.project.dbName + '@cn.pwc.com' };
                }
                //$httpProvider.defaults.headers.common['from'] = vatSessionService.project.dbName + '@cn.pwc.com';
                //cfg.headers.from = vatSessionService.project.dbName+'@cn.pwc.com';
                return cfg;
            }
        };
    }]);