好好学习,认真工作

基于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

模块解析

 

 

posted on 2018-04-16 11:22  peace_1  阅读(1374)  评论(0编辑  收藏  举报