zoukankan      html  css  js  c++  java
  • 基于angularJS搭建的管理系统

     前言

    angularJS搭建的系统,是一年前用的技术栈,有些地方比较过时,这里只是介绍实现思路

    前端架构

     

    工程目录

    项目浅析

    项目依赖包配置package.json

     1 {
     2   "name": "crm-gulp",
     3   "version": "1.0.0",
     4   "description": "crm-gulp",
     5   "main": "index.js",
     6   "dependencies": {
     7     "gulp": "^3.9.0",
     8     "gulp-autoprefixer": "^3.1.0",
     9     "gulp-concat-json": "^1.0.0",
    10     "gulp-modify": "^0.1.1",
    11     "gulp-replace": "^0.5.4"
    12   },
    13   "devDependencies": {
    14     "gulp-compass": "^2.1.0",
    15     "gulp-concat": "^2.6.0",
    16     "gulp-connect": "^2.3.1",
    17     "gulp-merge-json": "^0.6.0",
    18     "gulp-minify-css": "^1.2.1",
    19     "gulp-ng-annotate": "^2.0.0",
    20     "gulp-uglify": "^1.4.2"
    21   },
    22   "author": "tom.h",
    23   "license": "MIT"
    24 }
    View Code

    Sass配置 config.rb

    require 'compass/import-once/activate'
    # Require any additional compass plugins here.
    
    # Set this to the root of your project when deployed:
    http_path = "/"
    css_dir = "css"
    sass_dir = "sass"
    images_dir = "images"
    javascripts_dir = "js"
    
    # You can select your preferred output style here (can be overridden via the command line):
    # output_style = :expanded or :nested or :compact or :compressed
    output_style = :compact
    
    # To enable relative paths to assets via compass helper functions. Uncomment:
    relative_assets = true
    
    # To disable debugging comments that display the original location of your selectors. Uncomment:
    # line_comments = false
    
    
    # If you prefer the indented syntax, you might want to regenerate this
    # project again passing --syntax sass, or you can uncomment this:
    # preferred_syntax = :sass
    # and then run:
    # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
    View Code

    页面打包配置 gulp

    var isDebug = false;
    var gulp = require('gulp');
    var compass = require('gulp-compass');
    var concat = require('gulp-concat');
    var uglifyjs = require('gulp-uglify');
    var minifycss = require('gulp-minify-css');
    var replace = require('gulp-replace');
    var autoprefixer = require('gulp-autoprefixer');
    var connect = require('gulp-connect');
    var ngAnnotate = require('gulp-ng-annotate');
    var concatJson = require("gulp-concat-json");
    var modify = require('gulp-modify');
    
    var baseCss = [
        './libs/bootstrap-3.3.6/css/bootstrap.css',
        './libs/font-awesome-3.0.2/css/font-awesome.css',
        './libs/bootstrap-datetimepicker/bootstrap-datetimepicker.css',
        './libs/angular-select-0.16.1/select.css',
        './libs/angular-ui-tree-2.13.0/angular-ui-tree.min.css',
        './libs/jquery-color/css/colpick.css',
    
        './libs/components/angular-datetimepicker/v1.1/dist/css/angular-datetimepicker.css',
        './libs/components/angular-grid/v1.2/dist/css/angular-grid.css',
        './libs/components/angular-confirm/dist/css/angular-confirm.css',
        './libs/components/angular-message/dist/css/angular-message.css',
        './libs/components/angular-pagination/v1.1/dist/css/angular-pagination.css',
        './libs/components/angular-checkbox/dist/css/angular-checkbox.css',
        './libs/components/angular-itempicker/dist/css/angular-itempicker.css',
        './libs/components/angular-autocomplete/dist/css/angular-autocomplete.css',
        './libs/components/angular-colorpick/dist/css/angular-colorpick.css',
    
        './css/layout/ui.css',
        './css/wrapper/wrapper.css'
    ];
    var libsJs = [
        './libs/jquery-cookie-1.4.1/jquery-cookie.js',
        './libs/requireJS-2.1.22/require.js',
        './libs/require-template/require-text.js',
        './libs/require-template/require-html.js',
        './libs/requireCss-0.1.8/css.js',
        './libs/angular-require-1.3.0/angular-require.js',
        './libs/angular-ui-tree-2.13.0/angular-ui-tree.js',
        './libs/angular-1.4.8/angular-messages.js',
        './libs/angular-file-upload/FileAPI.js',
        './libs/angular-file-upload/ng-file-upload-shim.js',
        './libs/angular-file-upload/ng-file-upload.js',
        './libs/underscore-1.8.3/underscore.js',
        './libs/bootstrap-datetimepicker/bootstrap-datetimepicker.js',
        './libs/bootstrap-datetimepicker/bootstrap-datetimepicker.zh-CN.js',
        './libs/angular-sanitize-1.4.6/angular-sanitize.js',
        './libs/angular-select-0.16.1/select.js',
        './libs/angular-bootstrap-1.3.2/ui-bootstrap-tpls-1.3.2.js',
        './libs/ui-router-0.2.18/angular-ui-router.js',
        './libs/jQuery-Autocomplete-1.2.24/jquery.autocomplete.js',
        './libs/jquery-color/js/colpick.js',
    
        './libs/components/angular-datetime/dist/js/angular-datetime.js',
        './libs/components/angular-permission/dist/js/angular-permission.js',
        './libs/components/angular-datetimepicker/v1.1/dist/js/angular-datetimepicker.js',
        './libs/components/angular-datetimepickerGroup/dist/js/angular-datetimepickerGroup.js',
        './libs/components/angular-grid/v1.2/dist/js/angular-grid.js',
        './libs/components/angular-confirm/dist/js/angular-confirm.js',
        './libs/components/angular-message/dist/js/angular-message.js',
        './libs/components/angular-pagination/v1.1/dist/js/angular-pagination.js',
        './libs/components/angular-checkbox/dist/js/angular-checkbox.js',
        './libs/components/angular-itempicker/dist/js/angular-itempicker.js',
        './libs/components/angular-autocomplete/dist/js/angular-autocomplete.js',
        './libs/components/angular-colorpick/dist/js/angular-colorpick.js',
        './libs/components/angular-breadcrumb/angular-breadcrumb.js',
    
        './libs/angular-shims-placeholder/angular-shims-placeholder.js',
        './libs/jquery-md5/jquery.md5.js'
    ];
    gulp.task('compass', function() {
        return gulp.src('./sass/**/*.scss')
            .pipe(compass({
                config_file: './config.rb',
                css: './css',
                sass: './sass',
                image: './images'
            }))
            .pipe(autoprefixer({
                browsers: ['Firefox >= 1', 'Chrome >= 1', 'ie >= 7'],
                cascade: true
            }))
            .pipe(minifycss())
            .pipe(gulp.dest('./css'));
    });
    gulp.task('customDateTimepicker', function() {
        return gulp.src('./libs/bootstrap-datetimepicker/bootstrap-datetimepicker.js')
            .pipe(replace("'icon-arrow-left'", "'icon-caret-left'"))
            .pipe(replace("'icon-arrow-right'", "'icon-caret-right'"))
            .pipe(gulp.dest('./libs/bootstrap-datetimepicker/'));
    });
    gulp.task('customSelect2', function() {
        return gulp.src('./libs/angular-select/select.js')
            .pipe(replace("glyphicon glyphicon-remove", "'icon-remove'"))
            .pipe(gulp.dest('./libs/angular-select/'));
    });
    gulp.task('concatBaseCss', function() {
        return gulp.src(baseCss)
            .pipe(minifycss())
            .pipe(concat('base.css'))
            .pipe(gulp.dest('./css/'));
    });
    gulp.task('concatLibsJs', function() {
        var _pipe = gulp.src(libsJs)
            .pipe(concat('libs.js'));
        if (!isDebug) {
            _pipe.pipe(uglifyjs());
        }
        _pipe.pipe(gulp.dest('./libs/'));
        return _pipe;
    });
    gulp.task('concatBaseJS', ['combineRouter'], function() {
        var _pipe = gulp.src(['./js/base/app/app.js', './js/base/router/routerData.js', './js/base/*/**.js'])
            .pipe(concat('base.js'));
        if (!isDebug) {
            _pipe.pipe(uglifyjs());
        }
        _pipe.pipe(gulp.dest('./js/base/'));
        return _pipe;
    
    });
    
    gulp.task('replace',function(){
       gulp.src('./template/index.jsp')
           .pipe(replace('{{version}}', (new Date()).getTime()))   //替换地址 
           .pipe(gulp.dest('../WEB-INF/views/'))
    });
    
    gulp.task('connect', function() {
        connect.server({
            root: '../',
            port: 1212,
            host: 'localhost'
        });
    });
    /*合并各个模块的路由*/
    gulp.task("combineRouter", function() {
        var tempNames = [],
            tempUrls = [];
        return gulp.src('./modules/**/*/router/router.json')
            .pipe(concatJson("routerData.js"))
            .pipe(modify({
                fileModifier: function(file, contents) {
                    var name = contents.match(/"name":(W?)"(w+)/)[2];
                    var url = contents.match(/"url":(W?)"(/w+)/)[2];
                    var tip;
                    if (tempNames.indexOf(name) >= 0) {
                        tip = 'file:' + file.path + ' routeName ' + tempNames + ' is conflict', "color:red";
                        console.log(tip.warn);
                    } else {
                        tempNames.push(name);
                    }
                    if (tempUrls.indexOf(url) >= 0) {
                        tip = 'file:' + file.path + ' routeUrl ' + url + ' is conflict', "color:red"
                        console.warn(tip.warn);
                    } else {
                        tempUrls.push(url);
                    }
                    return contents;
                }
            }))
            .pipe(modify({
                fileModifier: function(file, contents) {
                    return "var ROUTER_DATA = " + contents;
                }
            }))
            .pipe(gulp.dest('./js/base/router/'));
    });
    gulp.task('start', function() {
        gulp.watch('./sass/**/*.scss', ['compass']);
        gulp.watch(['./libs/**/*.css', './css/layout/*.css'], ['concatBaseCss']);
        gulp.watch(['./js/base/*/**.js', './modules/*/**/router/**.json'], ['concatBaseJS']);
        gulp.watch('./template/*.jsp', ['replace']);
        gulp.watch(libsJs, ['concatLibsJs']);
        gulp.start('concatBaseCss');
        gulp.start('concatLibsJs');
        gulp.start('concatBaseJS');
        gulp.start('replace');
        gulp.start('connect');
    });
    gulp.task('default', ['start']);
    View Code

    路由配置 rotuer.js

    app.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', '$requireProvider', function($stateProvider, $locationProvider, $urlRouterProvider, $requireProvider) {
        var routerModules = ROUTER_DATA;
        var version = BaseInfo.VERSION || "1.0";
        var setRouterItem = function(rootRouter, item) {
            var path = item.path || rootRouter.path;
            var tempDepsArray = item.deps || [];
            var tempJsArray = item.js || [];
            var tempCssArray = item.css || [];
            var jsResultArray = [];
            var cssResultArray = [];
            var tplResultArray = [];
            for (var j = 0; j < tempJsArray.length; j++) {
                jsResultArray.push(path + tempJsArray[j] + "?v=" + version);
            }
            for (var i = 0; i < tempCssArray.length; i++) {
                cssResultArray.push("css!" + path + tempCssArray[i] + "?v=" + version);
            }
            for (var i = 0; i < tempDepsArray.length; i++) {
                if (/.*.js$/.test(tempDepsArray[i])) {
                    jsResultArray.push(tempDepsArray[i] + "?v=" + version);
                }
                if (/.*.css/.test(tempDepsArray[i])) {
                    cssResultArray.push("css!" + tempDepsArray[i] + "?v=" + version);
                }
                if (/.*.tpl/.test(tempDepsArray[i])) {
                    tplResultArray.push("html!" + tempDepsArray[i] + "?v=" + version);
                }
            }
            var stateOptions = {
                "url": item.url,
                "templateUrl": path + item.templateUrl + "?v=" + version,
                "customParams": item.customParams,
                "resolve": {
                    deps: $requireProvider.require(tplResultArray),
                    js: $requireProvider.requireJS(jsResultArray),
                    css: $requireProvider.requireCSS(cssResultArray)
                }
            };
            $stateProvider.state(item.name, stateOptions);
        };
        var constructChildPage = function(rootRouter, childPages) {
            for (var i = 0; i < childPages.length; i++) {
                setRouterItem(rootRouter, childPages[i]);
                if (childPages[i].childPages) {
                    constructChildPage(rootRouter, childPages[i].childPages);
                }
            }
        };
        var setRouter = function() {
            for (var i = 0; i < routerModules.length; i++) {
                setRouterItem(routerModules[i], routerModules[i]);
                if (routerModules[i].childPages) {
                    constructChildPage(routerModules[i], routerModules[i].childPages);
                }
            }
    
        };
        setRouter();
        $urlRouterProvider.otherwise("/activityCalendar/weekView");
    }]);
    View Code

     文件依赖

    <!DOCTYPE html>
    <html lang="zh-CN">
    
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta charset="UTF-8">
        <meta name="renderer" content="webkit">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no">
        <title>客户关系管理平台</title>
        <link rel="stylesheet" href="/assets/css/base.css" />
        <link rel="shortcut icon" href="/assets/favicon.ico">
        <script src="/assets/libs/jquery-1.11.1/jquery.min.js"></script>
        <script src="/assets/libs/echarts/echarts.min.js"></script>
        <script src="/assets/libs/angular-1.4.8/angular.min.js"></script>
        <script src="/assets/libs/libs.js"></script>
        <script>
            var BaseInfo = {
                //左侧菜单
                MENU_LIST: [{"name":"活动日历","code":"act_calendar","children":[{"name":"日历视图","code":"act_calendar_view","children":[]},{"name":"活动列表视图","code":"act_calendar_actlist_view","children":[]}]},{"name":"营销中心","code":"market_center","children":[{"name":"创建活动","code":"market_center_create_act","children":[]},{"name":"常用人群模板","code":"market_center_crowd_tpl","children":[]},{"name":"策略标签管理","code":"market_center_strategy_tag","children":[]},{"name":"营销控制项","code":"market_center_sale_manage","children":[]},{"name":"渠道审批列表","code":"market_center_channel_approval","children":[]}]},{"name":"会员中心","code":"vip_center","children":[{"name":"营销人群管理","code":"vip_center_sale_crowd_manage","children":[]},{"name":"会员透视分析","code":"vip_center_perspective_analyse","children":[]},{"name":"人群组管理","code":"vip_center_crowd_group_manage","children":[]}]},{"name":"内容库","code":"content_center","children":[{"name":"内容管理","code":"content_center_content_manage","children":[]},{"name":"短句管理","code":"content_center_phrase_manage","children":[]}]},{"name":"报表中心","code":"report_center","children":[{"name":"策略视图","code":"report_center_strategy_view","children":[]},{"name":"营销活动分析","code":"report_center_sale_act_analyse","children":[]},{"name":"活动发送管理","code":"report_center_act_send_manage","children":[]},{"name":"消息进程管理","code":"report_center_msg_process_manage","children":[]},{"name":"优惠券发送管理","code":"report_center_coupon_send_manage","children":[]}]},{"name":"系统管理","code":"sys_manage","children":[{"name":"用户管理","code":"sys_manage_user_manage","children":[]},{"name":"用户组管理","code":"sys_manage_user_group_manage","children":[]},{"name":"角色管理","code":"sys_manage_role_manage","children":[]},{"name":"渠道管理","code":"sys_manage_channel_manage","children":[]},{"name":"超级管理","code":"sys_manage_super_manage","children":[]}]},{"name":"配置项管理","code":"sys_config","children":[{"name":"业务场景","code":"sys_config_biz_scene","children":[]},{"name":"频次控制","code":"sys_config_frequency_capping","children":[]},{"name":"同步人群属性","code":"sys_config_user_property","children":[]},{"name":"默认透视图","code":"sys_config_perspective_manage","children":[]},{"name":"变量参数管理","code":"sys_config_parameters_manage","children":[]},{"name":"push落地页","code":"sys_config_push_land_page","children":[]},{"name":"字数限制","code":"sys_config_words_limit","children":[]},{"name":"高峰时间设置","code":"sys_config_top_hot_time","children":[]},{"name":"push铃声设置","code":"sys_config_push_sound","children":[]},{"name":"浮层运营位","code":"sys_config_floating_layer","children":[]},{"name":"标签管理","code":"sys_config_tag_manage","children":[]},{"name":"监控预警","code":"sys_config_monitor_warn","children":[]}]}],
                //菜单下数据及操作权限
                RESOURCE_PERMISSON: ["approval1", "approval2"],
                //用户基本信息
                USER_INFO: {
                    "loginName": "OA登录名", 
                    "realName" : "真实名",    
                    "roleName": "角色名称",  
                    "groupName": "CRM组"
                },
                //版本号
                VERSION: "5.0"
            }
        </script>
    </head>
    
    <body ng-app="app" ng-controller="appCtrl">
        <!--[if lte IE 8]>
            <div class="browser-tips" id="j-browser-tips">
                <div class="mask"></div>
                <div class="tips-box">
                    <div class="title"><span class="icon-warning-sign icon"></span><span class="text">非常抱歉!由于您的IE浏览器版本过低,该系统不兼容此版本的浏览器!</span></div>
                    <div class="desc">我们强烈建议您使用IE9(或以上)、Chrome、Firefox等主流浏览器。</div>
                    <div class="btn-group">
                        <a class="btn btn-warning btn-continue" href="http://browsehappy.com/" target="_blank"><span class="icon-ok"></span>升级浏览器</a>
                        <div class="btn btn-success btn-close" onclick="self.close()"><span class="icon-remove"></span>关闭</div>
                    </div>
                </div>
            </div>
        <![endif]-->
        <div id="j-navbar" class="sidebar">
            <a class="logo-wrap" href="/#/index"></a>
            <div ui-tree menu class="menu">
                <ul ui-tree-nodes ng-model="menuList">
                    <li class="menu-parent item-parent" data-nodrag data-collapsed="true" ng-class="{'show':!collapsed}" ng-repeat="node in menuList" ui-tree-node ng-include="'nodes_renderer.html'"></li>
                </ul>
            </div>
            <script type="text/ng-template" id="nodes_renderer.html">
                <div ng-if="::node.children.length > 0" class="item" data-nodrag ng-click="toggle();customToggleEvent(this,node);">
                    <span class="icon-angle-left icon-collapsed-status" ng-if="::node.children.length > 0" ng-class="{'icon-angle-left': collapsed,'icon-angle-down': !collapsed}"></span>
                    <span class="item-icon" ng-class="{'icon-folder-close': collapsed,'icon-folder-open': !collapsed}"></span>
                    <span class="item-name" ui-sref-active="active" ng-bind="::node.name" title="{{::node.name}}"></span>
                </div>  
                <a ng-if="::node.children.length===0 && node.code != 'report_center_sale_act_analyse'" menu-id="{{::node.code}}" href="{{node.url}}" data-nodrag ui-sref-active="active" class="item" ng-click="toggle();customToggleEvent(this,node);">  
                    <span class="icon-angle-left icon-collapsed-status" ng-if="::node.children.length > 0" ng-class="{'icon-angle-left': collapsed,'icon-angle-down': !collapsed}"></span>
                    <span class="item-icon" ng-class="{true:'{{::node.icon}}', false: 'icon-folder-close'}[!!node.icon]"></span>
                    <span class="item-name" ng-bind="::node.name" title="{{::node.name}}"></span>
                    <span class="icon-active icon-caret-left"></span>
                </a>
                <a ng-if="::node.children.length===0 && node.code == 'report_center_sale_act_analyse'" target="_blank" menu-id="{{::node.code}}" href="{{node.url}}" data-nodrag ui-sref-active="active" class="item" ng-click="toggle();customToggleEvent(this,node);">  
                    <span class="icon-angle-left icon-collapsed-status" ng-if="::node.children.length > 0" ng-class="{'icon-angle-left': collapsed,'icon-angle-down': !collapsed}"></span>
                    <span class="item-icon" ng-class="{true:'{{::node.icon}}', false: 'icon-folder-close'}[!!node.icon]"></span>
                    <span class="item-name" ng-bind="::node.name" title="{{::node.name}}"></span>
                    <span class="icon-active icon-caret-left"></span>
                </a>
                <ul class=" item-child" ui-tree-nodes ng-model="::node.children" ng-class="{'collapsed': collapsed}">
                    <li ng-repeat="node in node.children" ui-tree-node ng-include="'nodes_renderer.html'"></li>
                </ul>
            </script>
        </div>
        <div id="j-main-view" class="main-view">
            <div class="topbar">
                <button slider-btn type="button" class="btn btn-success btn-collapse"><span class="icon-list"></span></button>
     
                <breadcrumbs></breadcrumbs>
                
                <span class="user-info">
                    <span class="username">
                        <span class="icon-user"></span>
                <span ng-bind="::userInfo.loginName"></span>(<span class="green" ng-bind="::userInfo.groupName"></span>)
                </span> 
                <a ng-click="logout()" confirm="您确定退出登录吗?" confirm-ok="确定" confirm-cancel="取消" confirm-ok-color="success" confirm-title="退出登录" class="logout" href="javascript:void(0);"><span class="icon-signout"></span>退出</a>
                </span>
            </div>
            <div class="pages">
                <div class="inner" ui-view>
                </div>
            </div>
        </div>
    </body>
    <script src="/assets/js/base/base.js"></script>
    
    </html>
    View Code

    模块解析

     

  • 相关阅读:
    转载:iOS开发的22个奇谲巧技
    解决pathForResource返回nil, 无法读取plist文件问题
    小项目三:登陆窗口
    小项目一: UIButton的使用
    转载:iOS 8 自适应 Cell
    转载:iOS 8 AutoLayout与Size Class自悟
    转载:总结iOS 8和Xcode 6的各种坑
    [转]Xcode6中如何添加pch文件
    UIButton和UIImageView的区别
    控件的属性
  • 原文地址:https://www.cnblogs.com/peace1/p/angularJSProjectSystem.html
Copyright © 2011-2022 走看看