app.js 16.3 KB
//
// app module for online DPMS
//
var app = angular.module('app', ['ui.tree', 'ui.bootstrap', 'ui.bootstrap.tpls', 'ui.event', 'pascalprecht.translate', 'ngMessages', 'ui.utils',
    'ngRoute', 'ngCookies', 'ngSanitize', 'ct.ui.router.extras', 'chieffancypants.loadingBar', 'ngDraggable', 'ngFileUpload', 'LocalStorageModule', 'exceptionless',
    'app.config', 'app.common', 'app.webservices', 'app.framework', 'app.vat', 'app.invoice', 'app.cit', 'app.assetsManage', 'pasvaz.bindonce', 'app.vatDashboard', 'app.vatDongfeng', 'vs-repeat', 'ivh.treeview', 'angular-cache',
    'app.cache', 'angularBootstrapNavTree', 'ngAnimate', 'cgNotify', 'dx', 'ngNumeraljs', 'app.noPermissionPage'])
    //run blocks are executed after the injector is created and are the first
    //methods that are executed in any Angular app.
    .run(['$log', '$http', 'CacheFactory', 'userService', 'loginContext', '$rootScope', 'vatSessionService', '$q', function ($log, $http, CacheFactory, userService, loginContext, $rootScope, vatSessionService, $q) {
        $log.debug('app.run()...');

        $rootScope.vatPermission = constant.vatPermission;

        // 控制用户机构维度上的权限
        $rootScope.checkUserOrganizationPermissionList = function (permissionCodeList) {
            var deferred = $q.defer();
            var promise = deferred.promise;
            var model = {};

            var orgID = vatSessionService.project.organizationID;

            userService.getUserPermissionNew(loginContext.userName, function (data) {
                permissionCodeList.forEach(function (permissionCode) {
                    var ret = window.PWC.isHaveOrganizationPermission(orgID, permissionCode, data);
                    model[permissionCode] = ret;
                });

                deferred.resolve(model);
            });

            var successFunction = function (fn) {
                promise.then(function (model) {
                    fn(model);
                });
                return this;
            }

            return {
                success: successFunction,
            };
        };


        $rootScope.checkUserOrganizationPermissionList([]);

        $rootScope.checkUserPermissionList = function (permissionCodeList) {
            var deferred = $q.defer();
            var promise = deferred.promise;
            var model = {};
            // 这种方式 重新登录,并发去后台 取数据 会出现问题
            //userService.getUserPermission(loginContext.userName).success(function (data) {
            //    permissionCodeList.forEach(function (permissionCode) {
            //        var ret = window.PWC.isHavePermission(permissionCode, data);
            //        model[permissionCode] = ret;
            //    });

            //    deferred.resolve(model);
            //});

            userService.getUserPermissionNew(loginContext.userName, function (data) {
                permissionCodeList.forEach(function (permissionCode) {
                    var ret = window.PWC.isHavePermission(permissionCode, data);
                    model[permissionCode] = ret;
                });

                deferred.resolve(model);
            });

            var successFunction = function (fn) {
                promise.then(function (model) {
                    fn(model);
                });
                return this;
            }

            return {
                success: successFunction,
            };
        };
        $http.defaults.headers.common['X-XSRF-Token'] =
            angular.element('input[name="__RequestVerificationToken"]').attr('value');


    }])
    // We always place constant at the beginning of all configuration blocks.
    .constant('application', {
        // the current logged on user
        currentUser: {},
        // convert date to display time based on current user
        toDisplayTimeString: function (dateTime) {
            if (!_.isDate(dateTime)) {
                throw new TypeError('"dateTime" should be "Date" type!');
            }
            return dateTime.toString('h:mmtt').toLowerCase();
        },
        // define angular events for $broadcast/$emit and $on
        events: {
            beforeUnload: 'event:beforeUnload',
            navigateToTab: 'event:navigateToTab',
            showNotificationBar: 'event:showNotificationBar'
        }
    })
    // only providers and constants should be injected in config block
    .config(['$logProvider', '$translateProvider', '$translatePartialLoaderProvider', 'region', '$compileProvider',
        function ($logProvider, $translateProvider, $translatePartialLoaderProvider, region, $compileProvider) {
            'use strict';

            // to disable various debug runtime information in the compiler to DOM elements.
            $compileProvider.debugInfoEnabled(false);
            // enable output $log.debug by default
            $logProvider.debugEnabled(true);

            // angular-translate configuration
            var configurateTranslation = function () {

                $translateProvider.useLoader('$translatePartialLoader', {
                    // the translation table are organized by language and module under folder 'app/i18n/'
                    urlTemplate: '/app-resources/i18n/{lang}/{part}.json'
                });

                region = window.localStorage.langTemp || region;
                $translateProvider
                    .preferredLanguage(region)
                    .fallbackLanguage(region);

                //https://github.com/Contactis/translations-manager/issues/7
                //https://angular-translate.github.io/docs/#/guide/19_security
                $translateProvider.useSanitizeValueStrategy('escape');
            };

            configurateTranslation();
        }
    ])
    // IE10 fires input event when a placeholder is defined so that form element is in dirty instead of pristine state 
    // refer to: https://github.com/angular/angular.js/issues/2614
    .config(['$provide', function ($provide) {
        $provide.decorator('$sniffer', ['$delegate', function ($sniffer) {
            var msieVersion = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
            var hasEvent = $sniffer.hasEvent;
            $sniffer.hasEvent = function (event) {
                if (event === 'input' && msieVersion === 10) {
                    return false;
                }
                hasEvent.call(this, event);
            };
            return $sniffer;
        }]);
    }])
    .config(['$ExceptionlessClient', 'exceptionlessServerURL', function ($ExceptionlessClient, exceptionlessServerURL) {
        if (!PWC.isNullOrEmpty(exceptionlessServerURL)) {
            $ExceptionlessClient.config.apiKey = 'HK0XK49LbufV6E4q8HLW7CGncwSBJvdBrJQwUnzw';
            $ExceptionlessClient.config.serverUrl = exceptionlessServerURL;
            $ExceptionlessClient.config.setUserIdentity('0', 'Anonymous');
            $ExceptionlessClient.config.useSessions();
            $ExceptionlessClient.config.defaultTags.push('JavaScript', 'Angular');
        }
    }])
    .config(['CacheFactoryProvider', function (CacheFactoryProvider) {
        var options = {
            storageMode: 'localStorage', // This cache will use `localStorage`.
            storagePrefix: 'atms.'
        };
        if (!window.localStorage) {
            options.storageImpl = localStoragePolyfill;
        }
        angular.extend(CacheFactoryProvider.defaults, options);
    }])
    .config(['ivhTreeviewOptionsProvider', function (ivhTreeviewOptionsProvider) {
        ivhTreeviewOptionsProvider.set({
            defaultSelectedState: false,
            validate: true,
            // Twisties can be images, custom html, or plain text
            twistieCollapsedTpl: '<i class="fa fa-plus" aria-hidden="true"></i>',
            twistieExpandedTpl: '<i class="fa fa-minus" aria-hidden="true"></i>',
            twistieLeafTpl: '<span style="color:white">&#9679;</span>'
        });
    }])
    // refer to: https://github.com/oitozero/ngSweetAlert
    .factory('SweetAlert', ['$rootScope', '$log', '$translate', function ($rootScope, $log, $translate) {
        $log.debug('SweetAlert.run()...');
        var swal = window.swal;
        //public methods
        var self = {

            swal: function (arg1, arg2, arg3) {
                $rootScope.$evalAsync(function () {
                    if (typeof (arg2) === 'function') {
                        swal(arg1, function (isConfirm) {
                            $rootScope.$evalAsync(function () {
                                arg2(isConfirm);
                            });
                        }, arg3);
                    } else {
                        swal(arg1, arg2, arg3);
                    }
                });
            },
            success: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'success');

                    swal({
                        title: title,
                        text: message,
                        type: "success",
                        confirmButtonText: $translate.instant('Confirm'),
                    });
                });
            },
            error: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'error');
                    swal({
                        title: title,
                        text: message,
                        type: "error",
                        confirmButtonText: $translate.instant('Confirm'),
                    });

                });
            },
            warning: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'warning');
                    swal({
                        title: title,
                        text: message,
                        type: "warning",
                        confirmButtonText: $translate.instant('Confirm'),
                    });
                });
            },
            info: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'info');
                    swal({
                        title: title,
                        text: message,
                        type: "info",
                        confirmButtonText: $translate.instant('Confirm'),
                    });
                });
            }
        };

        return self;
    }])
    //turn off angular-loading-bar spinner
    //refer to https://github.com/chieffancypants/angular-loading-bar
    .config(['cfpLoadingBarProvider', function (cfpLoadingBarProvider) {
        cfpLoadingBarProvider.includeSpinner = false;
    }])
    //initialize localStorage
    //refer to https://github.com/grevory/angular-local-storage#get-started
    .config(['localStorageServiceProvider', function (localStorageServiceProvider) {
        localStorageServiceProvider.setPrefix('pwcdashboard').setStorageType('sessionStorage');
    }])
    // Provide the localization function for application and support async load translation table by parts on demand.
    // Note: When trying to adding new translation resource into .json file, please check if the same KEY is existing 
    // in .json files under i18n folder. Because if two parts have the same property, the property value will be overwrited 
    // by the loaded last part.
    // for example,
    // We load app.json first and then load patient.json. "app.json" file contains a property {"Text" : "Test"} 
    // and "patient.json" file contains property {"Text" : "Overwrite Test"} the "Text" on view will be translated to 
    // be "Overwrite Test".
    .factory('appTranslation', ['$log', '$translatePartialLoader', '$translate',
        function ($log, $translatePartialLoader, $translate) {
            'use strict';
            $log.debug('appTranslation.ctor()...');

            var translation = {
                // part names for modules
                // AppPart is for the translation of application level, not for a module for a business logic.
                appPart: 'app',
                vat: 'vat',
                cit: 'cit',
                taxDocumentList: 'taxDocumentList',
                noPermissionPage: 'noPermissionPage',
                /// <summary>
                /// async load translation tables into application for specified part names that required for the view.
                /// </summary>
                /// <param name="partNames">part names of array type</param>
                load: function (partNames) {
                    if (!angular.isArray(partNames)) {
                        throw new TypeError('"partNames" should be an array!');
                    }

                    partNames.forEach(function (name) {
                        $translatePartialLoader.addPart(name);
                    });

                    $translate.refresh();
                },
                loadAll: function () {
                    _.map(_.values(translation), function (part) {
                        if (_.isString(part)) {
                            $translatePartialLoader.addPart(part);
                        }
                    });
                    $translate.refresh();
                }
            };
            return translation;
        }
    ])
    .controller('AppController', ['$rootScope','$scope', '$log', '$location', '$translate', '$translatePartialLoader',
        '$window', 'appRoute', 'application', 'appTranslation', '$timeout', '$uibModal', 'loginContext', '$ExceptionlessClient', 'signalRSvc',
        'exceptionlessServerURL', function ($rootScope,$scope, $log, $location, $translate, $translatePartialLoader, $window, appRoute,
            application, appTranslation, $timeout, $uibModal, loginContext, $ExceptionlessClient, signalRSvc, exceptionlessServerURL) {
            'use strict';
            $log.debug('AppController.ctor()...');

            $scope.localName = loginContext.localName;

            if (!PWC.isNullOrEmpty(exceptionlessServerURL)) {
                $ExceptionlessClient.config.setUserIdentity(loginContext.userId, loginContext.localName);
                $ExceptionlessClient.config.useSessions();
            }

            $scope.$on('$locationChangeSuccess', function () {
                $scope.actualLocation = $location.path();
            });

            $scope.$watch(function () { return $location.path() }, function (newLocation) {
                if ($scope.actualLocation === newLocation) {
                    // back or forward
                    $log.debug('Go back or go forward to view browser history. Url: ' + newLocation);
                }
            });

            $scope.$on('$stateChangeSuccess',
                function () {
                    $log.debug('$stateChangeSuccess: ');
                });

            var langs = {};
            try {
                var obj= JSON.parse(window.localStorage.lang);
                if(typeof obj == 'object' && obj ){
                    langs = obj;
                }
            } catch(e) {}
            var region = langs[loginContext.userName] || 'en-us';
            var flag = window.localStorage.langTemp;
            $rootScope.changeLanguage = function(lang){
                $translate.use(lang);
                appTranslation.loadAll();
                $rootScope.currentLanguage = lang;
                $rootScope.currentLanguageDesc = $rootScope.currentLanguage == 'en-us' ? 'Switch to Chinese':'切换至英文';
                langs[loginContext.userName] = lang;
                window.localStorage.lang = JSON.stringify(langs);
                window.localStorage.langTemp = lang;
                if(flag !== window.localStorage.langTemp){
                    window.location.reload();
                }
            };
            $rootScope.changeLanguage(region);

            // publish unbeforeunload event to child scopes
            $scope.onbeforeunload = function () {
                $scope.$broadcast(application.events.beforeUnload);
            };

            $scope.main = function () {
                $location.path('/main');
                $location.url('main');
            };

            $scope.createDemo = function () {
                $location.path('/accountDemo');
                $location.url($location.path());
            };

            appTranslation.loadAll();

            signalRSvc.initialize();
        }
    ]);