Commit e0f56e121af41e75b4b74ecd57a42600cc4e6202

Authored by 徐烜
1 parent e4c8239d

根据客户反馈,需要在计划调度-调度执勤日报中增加功能:

1、临加班次添加
2、连续班次发车间隔平均
src/main/java/com/bsth/entity/schedule/SchedulePlanInfo.java
@@ -159,7 +159,7 @@ public class SchedulePlanInfo extends BEntity { @@ -159,7 +159,7 @@ public class SchedulePlanInfo extends BEntity {
159 // ) 159 // )
160 // private SchedulePlan schedulePlan; 160 // private SchedulePlan schedulePlan;
161 161
162 - @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) 162 + @ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
163 private SchedulePlan schedulePlan; 163 private SchedulePlan schedulePlan;
164 164
165 public SchedulePlanInfo() {} 165 public SchedulePlanInfo() {}
src/main/resources/static/pages/scheduleApp/module/common/dts2/scheduleplan/saPlanInfoView.js
1 /** 1 /**
  2 + * 指令说明:
2 * saPlanInfoView指令,排班明细显示指令(以类似时刻表的形式显示) 3 * saPlanInfoView指令,排班明细显示指令(以类似时刻表的形式显示)
  4 + * 属性:1、name 名字(必填)一般为 "saPlanView"
  5 + * 2、ng-model 绑定的外部数据源,为后台返回的 PlanInfoEditInfo类
  6 + * 方法:1、cell_db_click 表格单元格双击事件,
  7 + * 参数1:双击的单元格数据,对应后台SchedulePlanInfo类
  8 + * 2、toolbar_dlp_btn_click 工具栏栏班路牌按钮点击事件,无参数
  9 + * 3、toolbar_tadd_btn_click 工具烂添加班次按钮点击事件,
  10 + * 参数1:参考的已选中的单元格数据,对应后台SchedulePlanInfo类
  11 + * 参数2:参考的已选中的单元格数据对应的rowIndex
  12 + * 参数3:参考的已选中的单元格数据对应的colIndex
  13 + * 参数4:所有班次数据,对应ds_contents
  14 + *
  15 + * TODO:注意:SchedulePlanInfo的数据不是完整的,是etl返回的界面显示用的数据,之后可能需要回查数据库获取所有的完整数据
3 */ 16 */
4 angular.module('ScheduleApp').directive( 17 angular.module('ScheduleApp').directive(
5 'saPlaninfoview', 18 'saPlaninfoview',
6 [ 19 [
7 - '$compile',  
8 - '$window',  
9 - '$timeout',  
10 - function($compile, $window, $timeout) { 20 + // '$compile',
  21 + // '$window',
  22 + // '$timeout',
  23 + 'SchedulePlanInfoManageService_g',
  24 + '$q',
  25 + function(
  26 + // $compile, $window, $timeout,
  27 + spInfoService,
  28 + $q
  29 + ) {
11 return { 30 return {
12 restrict: 'E', 31 restrict: 'E',
13 templateUrl: '/pages/scheduleApp/module/common/dts2/scheduleplan/saPlanInfoViewTemplate.html', 32 templateUrl: '/pages/scheduleApp/module/common/dts2/scheduleplan/saPlanInfoViewTemplate.html',
14 scope: { // 独立作用域 33 scope: { // 独立作用域
15 - ds: "=ngModel",  
16 - celldbclickFn: "&celldbclick",  
17 - toolbarLpLbClickFn: "&toolbarlplbclick" 34 + ds: '=ngModel', // 外部数据源,对应后台PlanInfoEditInfo类
  35 + cellDbClickFn: "&cellDbClick", // 绑定的回调函数属性(单元格双击事件)
  36 + toolBarBtn1ClickFn: "&toolbarDlpBtnClick", // 绑定的回调函数属性(工具栏,栏班路牌按钮点击事件)
  37 + toolBarBtn2ClickFn: "&toolbarTaddBtnClick" // 绑定的回调函数属性(工具栏,添加班次按钮点击事件)
18 }, 38 },
19 controllerAs: "$saPlanInfoViewCtrl", 39 controllerAs: "$saPlanInfoViewCtrl",
20 bindToController: true, 40 bindToController: true,
21 controller: function() { 41 controller: function() {
22 var self = this; 42 var self = this;
  43 +
  44 + //-------------- 内部controller绑定的数据(如下) ----------------//
  45 + // 对应后台 PlanInfoEditInfo.header
  46 + self.ds_header = [];
  47 + // 对应后台 PlanInfoEditInfo.contents
  48 + self.ds_contents = [];
  49 +
23 // .ttInfo_detail高度 50 // .ttInfo_detail高度
24 self.ttInfo_detail_height = 800; 51 self.ttInfo_detail_height = 800;
25 - // ds绑定的数据-路牌扩展数据  
26 - self.ds_ext_lp_info = {"路牌名字" : {allLb : "关联的班次是否全部烂班(true/false)"}};  
27 - // ds绑定的数据-线路扩展数据  
28 - self.ds_ext_xl_info = {"dir0_qdzName" : "上线起点站名字", "dir0_tip_width" : "上行图标宽度", 52 +
  53 + // 路牌扩展数据 {"路牌名字" : {allLb : "关联的班次是否全部烂班(true/false)"}}
  54 + self.ext_lp_info = {};
  55 +
  56 + // 线路扩展数据
  57 + self.ext_xl_info = {"dir0_qdzName" : "上线起点站名字", "dir0_tip_width" : "上行图标宽度",
29 "dir1_qdzName" : "下行起点站名字", "dir1_tip_width" : "下行图标宽度"}; 58 "dir1_qdzName" : "下行起点站名字", "dir1_tip_width" : "下行图标宽度"};
30 - // ds绑定的数据-标题扩展数据1  
31 - self.ds_head_info1 = ["路牌", "驾驶员", "自编号", "车牌号"];  
32 - // ds绑定的数据-标题扩展数据2  
33 - self.ds_head_info2 = []; 59 +
  60 + // 表格头部的标题文字1
  61 + self.header_info1 = ["路牌", "驾驶员", "自编号", "车牌号"];
  62 + // 表格头部的标题文字2
  63 + self.header_info2 = [];
  64 +
  65 + /**
  66 + * 选中的班次信息map。
  67 + * key: 行索引_列索引
  68 + * value: schedulePlanInfo类
  69 + */
  70 + self.sel_detail_maps = {};
  71 +
34 72
35 // TODO:后面可能还有其他扩展信息 73 // TODO:后面可能还有其他扩展信息
36 74
  75 + //-------------- 内部controller绑定的数据(如上) ----------------//
  76 +
37 }, 77 },
38 /** 78 /**
39 * compile阶段,angular还没有编译模版,根据需要可以修改模版dom 79 * compile阶段,angular还没有编译模版,根据需要可以修改模版dom
@@ -48,148 +88,365 @@ angular.module('ScheduleApp').directive( @@ -48,148 +88,365 @@ angular.module('ScheduleApp').directive(
48 throw new Error("saPlanInfoView指令 name属性required"); 88 throw new Error("saPlanInfoView指令 name属性required");
49 } 89 }
50 90
51 - var $attr_celldbclick = tAttrs["celldbclick"]; // 单元格双击事件名  
52 - var $atrr_toolbarlplbclick = tAttrs["toolbarlplbclick"]; // 工具栏路牌烂班点击事件 91 + var $attr_cell_db_click = tAttrs["cellDbClick"];
  92 + var $attr_toolbar_dlp_btn_click = tAttrs["toolbarDlpBtnClick"];
  93 + var $attr_toolbar_tadd_btn_click = tAttrs["toolbarTaddBtnClick"];
53 94
54 // 内部controlAs名字 95 // 内部controlAs名字
55 var ctrlAs = '$saPlanInfoViewCtrl'; 96 var ctrlAs = '$saPlanInfoViewCtrl';
56 97
  98 + //------------------ 内部处理函数(以下)------------------//
  99 + // 计算路牌扩展数据
  100 + var _calculate_ext_lp_info = function(scope) {
  101 +
  102 + angular.forEach(scope[ctrlAs]["ds_contents"], function(value) {
  103 + var _lpName = value[0]["lpName"];
  104 + scope[ctrlAs]["ext_lp_info"][_lpName] = {allLb : false};
  105 + var _bcCounts = 0; // 班次总数
  106 + var _lbBcCounts = 0; // 烂班班次总数
  107 + angular.forEach(value, function(bc) {
  108 + if (bc.id) {
  109 + _bcCounts ++;
  110 + if (bc.status === -1) {
  111 + _lbBcCounts ++;
  112 + }
  113 + }
  114 + });
  115 + if (_bcCounts > 0 && _bcCounts === _lbBcCounts) {
  116 + scope[ctrlAs]["ext_lp_info"][_lpName].allLb = true;
  117 + }
  118 + });
  119 +
  120 + };
  121 +
  122 + // 计算线路扩展数据
  123 + var _calculate_ext_xl_info = function(scope) {
  124 + scope[ctrlAs]["ext_xl_info"] = {};
  125 + scope[ctrlAs]["ext_xl_info"].dir0_qdzName = "";
  126 + scope[ctrlAs]["ext_xl_info"].dir1_qdzName = "";
  127 + scope[ctrlAs]["ext_xl_info"].dir0_tip_width = 50;
  128 + scope[ctrlAs]["ext_xl_info"].dir1_tip_width = 50;
  129 +
  130 + angular.forEach(scope[ctrlAs]["ds_contents"], function(value) {
  131 + if (scope[ctrlAs]["ext_xl_info"].dir0_qdzName
  132 + && scope[ctrlAs]["ext_xl_info"].dir1_qdzName) {
  133 + return;
  134 + }
  135 + angular.forEach(value, function (bc) {
  136 + if (bc.id && bc.bcType === 'normal') {
  137 + if (bc.xlDir === '0' && bc.qdzName && !scope[ctrlAs]["ext_xl_info"].dir0_qdzName) {
  138 + scope[ctrlAs]["ext_xl_info"].dir0_qdzName = bc.qdzName;
  139 + scope[ctrlAs]["ext_xl_info"].dir0_tip_width += bc.qdzName.length * 15;
  140 + } else if (bc.xlDir === '1' && bc.qdzName && !scope[ctrlAs]["ext_xl_info"].dir1_qdzName) {
  141 + scope[ctrlAs]["ext_xl_info"].dir1_qdzName = bc.qdzName;
  142 + scope[ctrlAs]["ext_xl_info"].dir1_tip_width += bc.qdzName.length * 15;
  143 + }
  144 + }
  145 +
  146 + })
  147 + });
  148 +
  149 + };
  150 +
  151 + // 计算表格头部的标题文字
  152 + var _calculate_header_info = function(scope) {
  153 + scope[ctrlAs]["header_info1"] = ["路牌", "驾驶员", "自编号", "车牌号"];
  154 + angular.forEach(scope[ctrlAs]["ds_header"], function(header) {
  155 + if (header !== '路牌' && header !== '驾驶员' && header !== '自编号' && header !== '车牌号') {
  156 + scope[ctrlAs]["header_info2"].push(header);
  157 + }
  158 + });
  159 +
  160 + // 修正header_info2标题数组
  161 + // 2个班次一组 [上行group_no,下行group_no],从1开始
  162 + var group_num = 1;
  163 + var group_num_array = [1, 1];
  164 + for (var i = 0; i < scope[ctrlAs]["header_info2"].length; i++) {
  165 + var head = scope[ctrlAs]["header_info2"][i];
  166 + if (head === scope[ctrlAs]["ext_xl_info"].dir0_qdzName) {
  167 + scope[ctrlAs]["header_info2"][i] = head.substr(0, 1) + group_num_array[0];
  168 + } else {
  169 + scope[ctrlAs]["header_info2"][i] = head.substr(0, 1) + group_num_array[1];
  170 + group_num ++ ;
  171 + group_num_array = [group_num, group_num];
  172 + }
  173 +
  174 + // TODO:如果是环线的话,目前group_num都是1,后面如果有变化再修正
  175 + }
  176 +
  177 + };
  178 + // 计算组件总高度
  179 + var _calculate_ttInfo_detail_height = function(scope) {
  180 + scope[ctrlAs]["ttInfo_detail_height"] = 0;
  181 +
  182 + var toolbar_height = 31; // 工具栏高度(参见template css)
  183 + var tt_table_head_height = 36; // 表格标题高度(参见template css)
  184 + var table_info_height = 30; // 表格行高度(参见template css)
  185 + var table_extra_height = 30; // 表格修正高度
  186 +
  187 + scope[ctrlAs]["ttInfo_detail_height"] =
  188 + toolbar_height
  189 + + tt_table_head_height
  190 + + table_info_height * scope[ctrlAs]["ds_contents"].length
  191 + + table_extra_height;
  192 + };
  193 +
  194 + // 平均化班次间隔(最后一个班次与第一个班次的分钟差 除以 总班次数)
  195 + var _average_headway = function(bcList) {
  196 + // 按时间从早到晚排序班次
  197 + bcList.sort(function(a, b) {
  198 + var a_moment = moment("2000-01-01 " + a.fcsj, "YYYY-MM-DD HH:mm");
  199 + var b_moment = moment("2000-01-01 " + b.fcsj, "YYYY-MM-DD HH:mm");
  200 +
  201 + return a_moment.valueOf() - b_moment.valueOf();
  202 + });
  203 +
  204 + var _first_bc_moment = moment("2000-01-01 " + bcList[0].fcsj, "YYYY-MM-DD HH:mm");
  205 + var _last_bc_moment = moment("2000-01-01 " + bcList[bcList.length - 1].fcsj, "YYYY-MM-DD HH:mm");
  206 +
  207 + var _diff_minute = _last_bc_moment.diff(_first_bc_moment, 'minute');
  208 +
  209 + var _a1 = Math.floor(_diff_minute / (bcList.length - 1)); // 商数
  210 + // first班次,last班次不变,只改变中间班次的发车时间,所以间隔的余数用不到
  211 + // var _a2 = _diff_minute % (bcList.length - 1); // 余数
  212 +
  213 + angular.forEach(bcList, function(value, index) {
  214 + if (index > 0 && index < bcList.length - 1) {
  215 + var _pre_fc_sj_moment = moment("2000-01-01 " + bcList[index - 1].fcsj, "YYYY-MM-DD HH:mm");
  216 + var _cur_fc_sj_moment = _pre_fc_sj_moment.add(_a1, 'm');
  217 + value.fcsj = _cur_fc_sj_moment.format("HH:mm");
  218 + }
  219 + });
  220 +
  221 + // 删除第一个和最后一个班次信息(没有改变发车时间)
  222 + bcList.shift();
  223 + bcList.pop();
  224 +
  225 + };
  226 +
  227 + // 批量保存班次
  228 + var _batch_save_bc = function(bcList) {
  229 + var SchedulePlanInfo = spInfoService.rest;
  230 +
  231 + var deferred = $q.defer();
  232 +
  233 + var success_counts = 0; // 成功数
  234 + var error_counts = 0; // 失败数
  235 +
  236 + for (var n = 0; n < bcList.length; n++) {
  237 + (function(index) {
  238 + SchedulePlanInfo.get({id: bcList[index].id},
  239 + function(value) {
  240 + if (value.status === 'ERROR') {
  241 + error_counts ++;
  242 + if (success_counts + error_counts === bcList.length) {
  243 + deferred.reject("更新异常!");
  244 + }
  245 + } else {
  246 + value.fcsj = bcList[index].fcsj;
  247 + value["$save"](
  248 + function(value2) {
  249 + if (value2.status === 'ERROR') {
  250 + error_counts ++;
  251 + if (success_counts + error_counts === bcList.length) {
  252 + deferred.reject("更新异常!");
  253 + }
  254 + } else {
  255 + success_counts ++;
  256 + bcList[index].modifyCount = value2.data.modifyCount;
  257 + if (success_counts + error_counts === bcList.length) {
  258 + deferred.resolve();
  259 + }
  260 + }
  261 + },
  262 + function() {
  263 + error_counts ++;
  264 + if (success_counts + error_counts === bcList.length) {
  265 + deferred.reject("更新异常!");
  266 + }
  267 + });
  268 + }
  269 +
  270 + },
  271 + function() {
  272 + error_counts ++;
  273 + if (success_counts + error_counts === bcList.length) {
  274 + deferred.reject("更新异常!");
  275 + }
  276 + });
  277 +
  278 + })(n);
  279 + }
  280 +
  281 + return deferred.promise;
  282 + };
  283 +
  284 + //------------------ 内部处理函数(以上)------------------//
  285 +
  286 +
57 return { 287 return {
58 pre: function(scope, element, attr) { 288 pre: function(scope, element, attr) {
59 // TODO: 289 // TODO:
60 290
61 }, 291 },
  292 +
62 post: function(scope, element, attr) { 293 post: function(scope, element, attr) {
63 - // TODO:  
64 294
65 - // ------------------- dom事件处理function -----------------//  
66 - scope[ctrlAs].$$cell_click = function(rowindex, colindex, cell) {  
67 - console.log("click " + "row=" + rowindex + ",col=" + colindex);  
68 - if (cell.id) { // 有排班明细id的cell才能操作  
69 - cell.sel = !cell.sel; // 是否选中toggle 295 +
  296 + // ------------------- dom事件处理function(以下) -----------------//
  297 +
  298 + scope[ctrlAs].$$cell_click = function(rowIndex, colIndex, schedulePlanInfo) {
  299 + // console.log("click " + "row=" + rowIndex + ",col=" + colIndex);
  300 + if (schedulePlanInfo.id) { // 有排班明细id的cell才能操作
  301 + var sel_detail_maps = scope[ctrlAs]["sel_detail_maps"];
  302 + var key = rowIndex + "_" + colIndex;
  303 + if (sel_detail_maps[key]) { // 是否选中toggle
  304 + delete sel_detail_maps[key];
  305 + } else {
  306 + sel_detail_maps[key] = schedulePlanInfo;
  307 + }
70 } 308 }
71 309
72 }; 310 };
73 - scope[ctrlAs].$$cell_dbclick = function(rowindex, colindex, cell) {  
74 - if (cell.id) { // 有排班明细id的cell才能操作  
75 - if ($attr_celldbclick) {  
76 - // 注意调用方法  
77 - scope[ctrlAs].celldbclickFn()(rowindex, colindex); 311 + scope[ctrlAs].$$cell_db_click = function(rowIndex, colIndex, schedulePlanInfo) {
  312 + // console.log("dbClick " + "row=" + rowIndex + ",col=" + colIndex);
  313 + if (schedulePlanInfo.id) { // 有排班明细id的schedulePlanInfo才能操作
  314 + if ($attr_cell_db_click) {
  315 + // 调用指令绑定的方法(注意调用的方式,参看指令说明)
  316 + scope[ctrlAs]["cellDbClickFn"]()(schedulePlanInfo);
78 } 317 }
79 } 318 }
80 }; 319 };
81 - // 工具栏单击事件  
82 - scope[ctrlAs].$$toolbar1_dbclick = function() {  
83 - if ($atrr_toolbarlplbclick) {  
84 - scope[ctrlAs].toolbarLpLbClickFn()(); 320 +
  321 + // 工具栏按钮点击事件(取消选择)
  322 + scope[ctrlAs].$$toolbar_cs_btn_click = function() {
  323 + scope[ctrlAs]["sel_detail_maps"] = {};
  324 + };
  325 +
  326 + // 工具栏按钮单击事件(路牌烂班)
  327 + scope[ctrlAs].$$toolbar_dlp_btn_click = function() {
  328 + if ($attr_toolbar_dlp_btn_click) {
  329 + // 调用指令绑定的方法(注意调用的方式,参看指令说明)
  330 + scope[ctrlAs]["toolBarBtn1ClickFn"]()();
85 } 331 }
86 332
87 }; 333 };
  334 + // 工具栏按钮单击事件(添加班次)
  335 + scope[ctrlAs].$$toolbar_tadd_btn_click = function() {
  336 + if ($attr_toolbar_tadd_btn_click) {
  337 + // 计算参考的班次
  338 + var _ref_schedulePlanInfo = null;
88 339
89 - // ------------------- 监控function ------------------//  
90 - // 监控 ds: "=ngModel" 数据  
91 - scope.$watch(  
92 - function() {  
93 - return scope[ctrlAs].ds;  
94 - },  
95 - function(newValue) {  
96 - // 创建ds绑定的数据-路牌扩展数据  
97 - if (newValue["contents"]) {  
98 - angular.forEach(newValue["contents"], function(value) {  
99 - var _lpName = value[0]["lpName"];  
100 - scope[ctrlAs]["ds_ext_lp_info"][_lpName] = {allLb : false};  
101 - var _bcCounts = 0; // 班次总数  
102 - var _lbBcCounts = 0; // 烂班班次总数  
103 - angular.forEach(value, function(bc) {  
104 - if (bc.id) {  
105 - _bcCounts ++;  
106 - if (bc.status == -1) {  
107 - _lbBcCounts ++;  
108 - }  
109 - }  
110 - });  
111 - if (_bcCounts > 0 && _bcCounts == _lbBcCounts) {  
112 - scope[ctrlAs]["ds_ext_lp_info"][_lpName].allLb = true;  
113 - }  
114 - }); 340 + var _sel_count = 0;
  341 + var _sel_key = null;
  342 + angular.forEach(scope[ctrlAs]["sel_detail_maps"], function(value, key) {
  343 + _sel_count ++;
  344 + _sel_key = key;
  345 + _ref_schedulePlanInfo = value;
  346 + });
  347 +
  348 + if (_sel_count !== 1) {
  349 + alert("请仅选择一个班次用于参考!");
  350 + return;
115 } 351 }
116 352
117 - // 创建ds绑定数据-线路扩展数据  
118 - scope[ctrlAs]["ds_ext_xl_info"] = {};  
119 - scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName = "";  
120 - scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName = "";  
121 - scope[ctrlAs]["ds_ext_xl_info"].dir0_tip_width = 50;  
122 - scope[ctrlAs]["ds_ext_xl_info"].dir1_tip_width = 50;  
123 - if (newValue["contents"]) {  
124 - angular.forEach(newValue["contents"], function(value) {  
125 - if (scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName  
126 - && scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName) {  
127 - return;  
128 - }  
129 - angular.forEach(value, function (bc) {  
130 - if (bc.id && bc.bcType == 'normal') {  
131 - if (bc.xlDir == '0' && bc.qdzName && !scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName) {  
132 - scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName = bc.qdzName;  
133 - scope[ctrlAs]["ds_ext_xl_info"].dir0_tip_width += bc.qdzName.length * 15;  
134 - } else if (bc.xlDir == '1' && bc.qdzName && !scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName) {  
135 - scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName = bc.qdzName;  
136 - scope[ctrlAs]["ds_ext_xl_info"].dir1_tip_width += bc.qdzName.length * 15;  
137 - }  
138 - } 353 + // // 获取参考班次对应路牌的所有班次
  354 + // var _sel_lp_trips = [];
  355 + // angular.forEach(scope[ctrlAs]["ds_contents"][_sel_rowIndex], function(value) {
  356 + // if (value.id) {
  357 + // _sel_lp_trips.push(value);
  358 + // }
  359 + // });
139 360
140 - })  
141 - });  
142 - } 361 + // 获取参考班次对应的rowIndex,colIndex
  362 + var _sel_rowIndex = parseInt(_sel_key.split("_")[0]);
  363 + var _sel_colIndex = parseInt(_sel_key.split("_")[1]);
143 364
144 - // 计算 .ttInfo_detail高度  
145 - scope[ctrlAs]["ttInfo_detail_height"] = 0;  
146 - var toolbar_height = 31; // 工具栏高度(参见template css)  
147 - var tt_table_head_height = 36; // 表格标题高度(参见template css)  
148 - var table_info_height = 30; // 表格行高度(参见template css)  
149 - var table_extra_height = 30; // 表格修正高度  
150 - if (newValue["contents"]) {  
151 - scope[ctrlAs]["ttInfo_detail_height"] =  
152 - toolbar_height +  
153 - tt_table_head_height +  
154 - table_info_height * newValue["contents"].length +  
155 - table_extra_height; 365 + // 调用指令绑定的方法(注意调用的方式,参看指令说明)
  366 + scope[ctrlAs]["toolBarBtn2ClickFn"]()(
  367 + _ref_schedulePlanInfo,
  368 + _sel_rowIndex,
  369 + _sel_colIndex,
  370 + scope[ctrlAs]["ds_contents"]);
  371 + }
  372 + };
  373 +
  374 + // 工具栏按钮单击事件(均衡发车间隔)
  375 + scope[ctrlAs].$$toolbar_average_headway_btn_click = function() {
  376 + var sel_detail_list = [];
  377 + angular.forEach(scope[ctrlAs]["sel_detail_maps"], function(value) {
  378 + sel_detail_list.push(value);
  379 + });
  380 + if (sel_detail_list.length < 3) {
  381 + alert("请至少选择三个班次!");
  382 + return;
  383 + }
  384 + // 判断选中的班次是否是同方向
  385 + var sel_detail_xldir = sel_detail_list[0]["xlDir"];
  386 + var is_single_xldir = true;
  387 + angular.forEach(scope[ctrlAs]["sel_detail_maps"], function(value) {
  388 + if (value["xlDir"] !== sel_detail_xldir) {
  389 + is_single_xldir = false;
156 } 390 }
  391 + });
  392 + if (!is_single_xldir) {
  393 + alert("请选择同方向的班次!");
  394 + return;
  395 + }
157 396
158 - // 创建ds绑定的数据-标题扩展数据2  
159 - scope[ctrlAs]["ds_head_info2"] = [];  
160 - angular.forEach(newValue["header"], function(head) {  
161 - if (head != '路牌' && head != '驾驶员' && head != '自编号' && head != '车牌号') {  
162 - scope[ctrlAs]["ds_head_info2"].push(head);  
163 - } 397 + // 平均化发车间隔
  398 + _average_headway(sel_detail_list);
  399 + // 批量保存班次
  400 + _batch_save_bc(sel_detail_list).then(
  401 + function() {
  402 + alert("调整成功!");
  403 + },
  404 + function(err) {
  405 + alert(err);
164 }); 406 });
165 - // 2个班次一组 [上行group_no,下行group_no],从1开始  
166 - var group_num = 1;  
167 - var group_num_array = [1, 1];  
168 - for (var i = 0; i < scope[ctrlAs]["ds_head_info2"].length; i++) {  
169 - var head = scope[ctrlAs]["ds_head_info2"][i];  
170 - if (head == scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName) {  
171 - scope[ctrlAs]["ds_head_info2"][i] = head.substr(0, 1) + group_num_array[0];  
172 - } else {  
173 - scope[ctrlAs]["ds_head_info2"][i] = head.substr(0, 1) + group_num_array[1];  
174 - group_num ++ ;  
175 - group_num_array = [group_num, group_num];  
176 - }  
177 407
178 - // TODO:如果是环线的话,目前group_num都是1,后面如果有变化再修正  
179 - } 408 + };
180 409
181 - // TODO: 410 + // ------------------- dom事件处理function(以上) -----------------//
182 411
  412 + // ------------------- 监控function(以下) ------------------//
  413 + // 监控 ds: "=ngModel" 数据
  414 + scope.$watch(
  415 + function() {
  416 + return scope[ctrlAs].ds;
  417 + },
  418 + function(newValue) {
  419 + // 将后台数据赋值到内部对象
  420 + scope[ctrlAs]["ds_header"] = newValue["header"] || [];
  421 + scope[ctrlAs]["ds_contents"] = newValue["contents"] || [];
  422 +
  423 + scope[ctrlAs]["ext_lp_info"] = {};
  424 + scope[ctrlAs]["ext_xl_info"] = {};
  425 + scope[ctrlAs]["header_info1"] = [];
  426 + scope[ctrlAs]["header_info2"] = [];
  427 +
  428 + scope[ctrlAs]["sel_detail_maps"] = {};
  429 +
  430 + // 根据后台数据计算各个内部值
  431 + _calculate_ext_lp_info(scope);
  432 + _calculate_ext_xl_info(scope);
  433 + _calculate_ttInfo_detail_height(scope);
  434 + _calculate_header_info(scope);
183 }, 435 },
184 true 436 true
185 ); 437 );
186 438
  439 +
  440 + // ------------------- 监控function(以上) ------------------//
  441 +
  442 + // TODO:
187 } 443 }
188 444
189 }; 445 };
190 -  
191 } 446 }
  447 +
192 }; 448 };
193 } 449 }
194 ] 450 ]
  451 +
195 ); 452 );
src/main/resources/static/pages/scheduleApp/module/common/dts2/scheduleplan/saPlanInfoViewTemplate.html
@@ -379,15 +379,27 @@ @@ -379,15 +379,27 @@
379 379
380 <div class="toolbar"> 380 <div class="toolbar">
381 <div style="float: left"> 381 <div style="float: left">
382 - <a href="javascript:" style="padding-right: 5px;" ng-click="$saPlanInfoViewCtrl.$$toolbar1_dbclick()"> 382 + <a href="javascript:" style="padding-right: 5px;" ng-click="$saPlanInfoViewCtrl.$$toolbar_dlp_btn_click()">
383 <i class="fa fa-th-list" aria-hidden="true"></i> 383 <i class="fa fa-th-list" aria-hidden="true"></i>
384 路牌烂班 384 路牌烂班
385 </a> 385 </a>
  386 + <a href="javascript:" style="padding-right: 5px;" ng-click="$saPlanInfoViewCtrl.$$toolbar_tadd_btn_click()">
  387 + <i class="fa fa-th-list" aria-hidden="true"></i>
  388 + 添加班次
  389 + </a>
  390 + <a href="javascript:" style="padding-right: 5px;" ng-click="$saPlanInfoViewCtrl.$$toolbar_average_headway_btn_click()">
  391 + <i class="fa fa-th-list" aria-hidden="true"></i>
  392 + 均衡班次间隔
  393 + </a>
  394 + <a href="javascript:" style="padding-right: 5px;" ng-click="$saPlanInfoViewCtrl.$$toolbar_cs_btn_click()">
  395 + <i class="fa fa-th-list" aria-hidden="true"></i>
  396 + 取消选择
  397 + </a>
386 </div> 398 </div>
387 399
388 <div style="float: right; padding-right: 10px;"> 400 <div style="float: right; padding-right: 10px;">
389 - <div style="display: inline-block;background: #81b9e9;color: white;text-align: center;height: 25px;line-height: 25px;width: {{$saPlanInfoViewCtrl.ds_ext_xl_info.dir0_tip_width}}px;">上行-{{$saPlanInfoViewCtrl.ds_ext_xl_info.dir0_qdzName}}</div>  
390 - <div style="display: inline-block;background: white;color: black;text-align: center;height: 25px;line-height: 25px;width: {{$saPlanInfoViewCtrl.ds_ext_xl_info.dir1_tip_width}}px;">下行-{{$saPlanInfoViewCtrl.ds_ext_xl_info.dir1_qdzName}}</div> 401 + <div style="display: inline-block;background: #81b9e9;color: white;text-align: center;height: 25px;line-height: 25px;width: {{$saPlanInfoViewCtrl.ext_xl_info.dir0_tip_width}}px;">上行-{{$saPlanInfoViewCtrl.ext_xl_info.dir0_qdzName}}</div>
  402 + <div style="display: inline-block;background: white;color: black;text-align: center;height: 25px;line-height: 25px;width: {{$saPlanInfoViewCtrl.ext_xl_info.dir1_tip_width}}px;">下行-{{$saPlanInfoViewCtrl.ext_xl_info.dir1_qdzName}}</div>
391 <div style="display: inline-block;background: #337ab7;color: white;text-align: center;height: 25px;line-height: 25px;width: 90px;">出场班次</div> 403 <div style="display: inline-block;background: #337ab7;color: white;text-align: center;height: 25px;line-height: 25px;width: 90px;">出场班次</div>
392 <div style="display: inline-block;background: #4e6477;color: white;text-align: center;height: 25px;line-height: 25px;width: 90px;">进场班次</div> 404 <div style="display: inline-block;background: #4e6477;color: white;text-align: center;height: 25px;line-height: 25px;width: 90px;">进场班次</div>
393 <div style="display: inline-block;background: #df0808;color: white;text-align: center;height: 25px;line-height: 25px;width: 90px;">烂班班次</div> 405 <div style="display: inline-block;background: #df0808;color: white;text-align: center;height: 25px;line-height: 25px;width: 90px;">烂班班次</div>
@@ -431,10 +443,10 @@ @@ -431,10 +443,10 @@
431 序号 443 序号
432 </dt> 444 </dt>
433 445
434 - <dt ng-repeat="head1 in $saPlanInfoViewCtrl.ds_head_info1 track by $index"> 446 + <dt ng-repeat="head1 in $saPlanInfoViewCtrl.header_info1 track by $index">
435 {{head1}} 447 {{head1}}
436 </dt> 448 </dt>
437 - <dt ng-repeat="head2 in $saPlanInfoViewCtrl.ds_head_info2 track by $index"> 449 + <dt ng-repeat="head2 in $saPlanInfoViewCtrl.header_info2 track by $index">
438 {{head2}} 450 {{head2}}
439 </dt> 451 </dt>
440 452
@@ -442,7 +454,7 @@ @@ -442,7 +454,7 @@
442 </div> 454 </div>
443 455
444 <div class="tt_table_body" style="z-index: 100; background: white;"> 456 <div class="tt_table_body" style="z-index: 100; background: white;">
445 - <dl ng-repeat="info in $saPlanInfoViewCtrl.ds.contents track by $index" 457 + <dl ng-repeat="info in $saPlanInfoViewCtrl.ds_contents track by $index"
446 ng-init="rowIndex = $index"> 458 ng-init="rowIndex = $index">
447 459
448 <dd> 460 <dd>
@@ -452,26 +464,26 @@ @@ -452,26 +464,26 @@
452 <dd ng-repeat="cell in info track by $index" 464 <dd ng-repeat="cell in info track by $index"
453 ng-init="colIndex = $index" 465 ng-init="colIndex = $index"
454 ng-if="$index == 0" 466 ng-if="$index == 0"
455 - ng-class="{islb : $saPlanInfoViewCtrl.ds_ext_lp_info[info[0].lpName].allLb}"> 467 + ng-class="{islb : $saPlanInfoViewCtrl.ext_lp_info[info[0].lpName].allLb}">
456 {{cell.lpName}} 468 {{cell.lpName}}
457 </dd> 469 </dd>
458 <dd ng-repeat="cell in info track by $index" 470 <dd ng-repeat="cell in info track by $index"
459 ng-init="colIndex = $index" 471 ng-init="colIndex = $index"
460 ng-if="$index == 1" 472 ng-if="$index == 1"
461 - ng-class="{islb : $saPlanInfoViewCtrl.ds_ext_lp_info[info[0].lpName].allLb}"> 473 + ng-class="{islb : $saPlanInfoViewCtrl.ext_lp_info[info[0].lpName].allLb}">
462 {{cell.jName}} 474 {{cell.jName}}
463 </dd> 475 </dd>
464 <dd ng-repeat="cell in info track by $index" 476 <dd ng-repeat="cell in info track by $index"
465 ng-init="colIndex = $index" 477 ng-init="colIndex = $index"
466 ng-if="$index == 2" 478 ng-if="$index == 2"
467 - ng-class="{islb : $saPlanInfoViewCtrl.ds_ext_lp_info[info[0].lpName].allLb}"> 479 + ng-class="{islb : $saPlanInfoViewCtrl.ext_lp_info[info[0].lpName].allLb}">
468 {{cell.clZbh}} 480 {{cell.clZbh}}
469 </dd> 481 </dd>
470 482
471 <dd ng-repeat="cell in info track by $index" 483 <dd ng-repeat="cell in info track by $index"
472 ng-init="colIndex = $index" 484 ng-init="colIndex = $index"
473 ng-if="$index == 3" style="border-right: 2px solid #96b9d7;" 485 ng-if="$index == 3" style="border-right: 2px solid #96b9d7;"
474 - ng-class="{islb : $saPlanInfoViewCtrl.ds_ext_lp_info[info[0].lpName].allLb}"> 486 + ng-class="{islb : $saPlanInfoViewCtrl.ext_lp_info[info[0].lpName].allLb}">
475 {{cell.clZbh}} 487 {{cell.clZbh}}
476 </dd> 488 </dd>
477 489
@@ -479,7 +491,7 @@ @@ -479,7 +491,7 @@
479 </div> 491 </div>
480 492
481 <div class="tt_table_body"> 493 <div class="tt_table_body">
482 - <dl ng-repeat="info in $saPlanInfoViewCtrl.ds.contents track by $index" 494 + <dl ng-repeat="info in $saPlanInfoViewCtrl.ds_contents track by $index"
483 ng-init="rowIndex = $index"> 495 ng-init="rowIndex = $index">
484 496
485 <dd> 497 <dd>
@@ -502,12 +514,12 @@ @@ -502,12 +514,12 @@
502 <dd ng-repeat="cell in info track by $index" 514 <dd ng-repeat="cell in info track by $index"
503 ng-init="colIndex = $index" 515 ng-init="colIndex = $index"
504 ng-click="$saPlanInfoViewCtrl.$$cell_click(rowIndex, colIndex, cell)" 516 ng-click="$saPlanInfoViewCtrl.$$cell_click(rowIndex, colIndex, cell)"
505 - ng-dblclick="$saPlanInfoViewCtrl.$$cell_dbclick(rowIndex, colIndex, cell)" 517 + ng-dblclick="$saPlanInfoViewCtrl.$$cell_db_click(rowIndex, colIndex, cell)"
506 ng-if="$index > 3" 518 ng-if="$index > 3"
507 ng-class="{ 519 ng-class="{
508 lpName: true, 520 lpName: true,
509 error: false, 521 error: false,
510 - active: cell.sel, 522 + active: $saPlanInfoViewCtrl.sel_detail_maps[rowIndex + '_' + colIndex],
511 isDir_0: cell.xlDir == '0', 523 isDir_0: cell.xlDir == '0',
512 isDir_1: cell.xlDir == '1', 524 isDir_1: cell.xlDir == '1',
513 ists: false, 525 ists: false,
src/main/resources/static/pages/scheduleApp/module/common/prj-common-directive.js
@@ -6609,41 +6609,81 @@ angular.module(&#39;ScheduleApp&#39;).directive( @@ -6609,41 +6609,81 @@ angular.module(&#39;ScheduleApp&#39;).directive(
6609 ] 6609 ]
6610 ); 6610 );
6611 /** 6611 /**
  6612 + * 指令说明:
6612 * saPlanInfoView指令,排班明细显示指令(以类似时刻表的形式显示) 6613 * saPlanInfoView指令,排班明细显示指令(以类似时刻表的形式显示)
  6614 + * 属性:1、name 名字(必填)一般为 "saPlanView"
  6615 + * 2、ng-model 绑定的外部数据源,为后台返回的 PlanInfoEditInfo类
  6616 + * 方法:1、cell_db_click 表格单元格双击事件,
  6617 + * 参数1:双击的单元格数据,对应后台SchedulePlanInfo类
  6618 + * 2、toolbar_dlp_btn_click 工具栏栏班路牌按钮点击事件,无参数
  6619 + * 3、toolbar_tadd_btn_click 工具烂添加班次按钮点击事件,
  6620 + * 参数1:参考的已选中的单元格数据,对应后台SchedulePlanInfo类
  6621 + * 参数2:参考的已选中的单元格数据对应的rowIndex
  6622 + * 参数3:参考的已选中的单元格数据对应的colIndex
  6623 + * 参数4:所有班次数据,对应ds_contents
  6624 + *
  6625 + * TODO:注意:SchedulePlanInfo的数据不是完整的,是etl返回的界面显示用的数据,之后可能需要回查数据库获取所有的完整数据
6613 */ 6626 */
6614 angular.module('ScheduleApp').directive( 6627 angular.module('ScheduleApp').directive(
6615 'saPlaninfoview', 6628 'saPlaninfoview',
6616 [ 6629 [
6617 - '$compile',  
6618 - '$window',  
6619 - '$timeout',  
6620 - function($compile, $window, $timeout) { 6630 + // '$compile',
  6631 + // '$window',
  6632 + // '$timeout',
  6633 + 'SchedulePlanInfoManageService_g',
  6634 + '$q',
  6635 + function(
  6636 + // $compile, $window, $timeout,
  6637 + spInfoService,
  6638 + $q
  6639 + ) {
6621 return { 6640 return {
6622 restrict: 'E', 6641 restrict: 'E',
6623 templateUrl: '/pages/scheduleApp/module/common/dts2/scheduleplan/saPlanInfoViewTemplate.html', 6642 templateUrl: '/pages/scheduleApp/module/common/dts2/scheduleplan/saPlanInfoViewTemplate.html',
6624 scope: { // 独立作用域 6643 scope: { // 独立作用域
6625 - ds: "=ngModel",  
6626 - celldbclickFn: "&celldbclick",  
6627 - toolbarLpLbClickFn: "&toolbarlplbclick" 6644 + ds: '=ngModel', // 外部数据源,对应后台PlanInfoEditInfo类
  6645 + cellDbClickFn: "&cellDbClick", // 绑定的回调函数属性(单元格双击事件)
  6646 + toolBarBtn1ClickFn: "&toolbarDlpBtnClick", // 绑定的回调函数属性(工具栏,栏班路牌按钮点击事件)
  6647 + toolBarBtn2ClickFn: "&toolbarTaddBtnClick" // 绑定的回调函数属性(工具栏,添加班次按钮点击事件)
6628 }, 6648 },
6629 controllerAs: "$saPlanInfoViewCtrl", 6649 controllerAs: "$saPlanInfoViewCtrl",
6630 bindToController: true, 6650 bindToController: true,
6631 controller: function() { 6651 controller: function() {
6632 var self = this; 6652 var self = this;
  6653 +
  6654 + //-------------- 内部controller绑定的数据(如下) ----------------//
  6655 + // 对应后台 PlanInfoEditInfo.header
  6656 + self.ds_header = [];
  6657 + // 对应后台 PlanInfoEditInfo.contents
  6658 + self.ds_contents = [];
  6659 +
6633 // .ttInfo_detail高度 6660 // .ttInfo_detail高度
6634 self.ttInfo_detail_height = 800; 6661 self.ttInfo_detail_height = 800;
6635 - // ds绑定的数据-路牌扩展数据  
6636 - self.ds_ext_lp_info = {"路牌名字" : {allLb : "关联的班次是否全部烂班(true/false)"}};  
6637 - // ds绑定的数据-线路扩展数据  
6638 - self.ds_ext_xl_info = {"dir0_qdzName" : "上线起点站名字", "dir0_tip_width" : "上行图标宽度", 6662 +
  6663 + // 路牌扩展数据 {"路牌名字" : {allLb : "关联的班次是否全部烂班(true/false)"}}
  6664 + self.ext_lp_info = {};
  6665 +
  6666 + // 线路扩展数据
  6667 + self.ext_xl_info = {"dir0_qdzName" : "上线起点站名字", "dir0_tip_width" : "上行图标宽度",
6639 "dir1_qdzName" : "下行起点站名字", "dir1_tip_width" : "下行图标宽度"}; 6668 "dir1_qdzName" : "下行起点站名字", "dir1_tip_width" : "下行图标宽度"};
6640 - // ds绑定的数据-标题扩展数据1  
6641 - self.ds_head_info1 = ["路牌", "驾驶员", "自编号", "车牌号"];  
6642 - // ds绑定的数据-标题扩展数据2  
6643 - self.ds_head_info2 = []; 6669 +
  6670 + // 表格头部的标题文字1
  6671 + self.header_info1 = ["路牌", "驾驶员", "自编号", "车牌号"];
  6672 + // 表格头部的标题文字2
  6673 + self.header_info2 = [];
  6674 +
  6675 + /**
  6676 + * 选中的班次信息map。
  6677 + * key: 行索引_列索引
  6678 + * value: schedulePlanInfo类
  6679 + */
  6680 + self.sel_detail_maps = {};
  6681 +
6644 6682
6645 // TODO:后面可能还有其他扩展信息 6683 // TODO:后面可能还有其他扩展信息
6646 6684
  6685 + //-------------- 内部controller绑定的数据(如上) ----------------//
  6686 +
6647 }, 6687 },
6648 /** 6688 /**
6649 * compile阶段,angular还没有编译模版,根据需要可以修改模版dom 6689 * compile阶段,angular还没有编译模版,根据需要可以修改模版dom
@@ -6658,148 +6698,365 @@ angular.module(&#39;ScheduleApp&#39;).directive( @@ -6658,148 +6698,365 @@ angular.module(&#39;ScheduleApp&#39;).directive(
6658 throw new Error("saPlanInfoView指令 name属性required"); 6698 throw new Error("saPlanInfoView指令 name属性required");
6659 } 6699 }
6660 6700
6661 - var $attr_celldbclick = tAttrs["celldbclick"]; // 单元格双击事件名  
6662 - var $atrr_toolbarlplbclick = tAttrs["toolbarlplbclick"]; // 工具栏路牌烂班点击事件 6701 + var $attr_cell_db_click = tAttrs["cellDbClick"];
  6702 + var $attr_toolbar_dlp_btn_click = tAttrs["toolbarDlpBtnClick"];
  6703 + var $attr_toolbar_tadd_btn_click = tAttrs["toolbarTaddBtnClick"];
6663 6704
6664 // 内部controlAs名字 6705 // 内部controlAs名字
6665 var ctrlAs = '$saPlanInfoViewCtrl'; 6706 var ctrlAs = '$saPlanInfoViewCtrl';
6666 6707
  6708 + //------------------ 内部处理函数(以下)------------------//
  6709 + // 计算路牌扩展数据
  6710 + var _calculate_ext_lp_info = function(scope) {
  6711 +
  6712 + angular.forEach(scope[ctrlAs]["ds_contents"], function(value) {
  6713 + var _lpName = value[0]["lpName"];
  6714 + scope[ctrlAs]["ext_lp_info"][_lpName] = {allLb : false};
  6715 + var _bcCounts = 0; // 班次总数
  6716 + var _lbBcCounts = 0; // 烂班班次总数
  6717 + angular.forEach(value, function(bc) {
  6718 + if (bc.id) {
  6719 + _bcCounts ++;
  6720 + if (bc.status === -1) {
  6721 + _lbBcCounts ++;
  6722 + }
  6723 + }
  6724 + });
  6725 + if (_bcCounts > 0 && _bcCounts === _lbBcCounts) {
  6726 + scope[ctrlAs]["ext_lp_info"][_lpName].allLb = true;
  6727 + }
  6728 + });
  6729 +
  6730 + };
  6731 +
  6732 + // 计算线路扩展数据
  6733 + var _calculate_ext_xl_info = function(scope) {
  6734 + scope[ctrlAs]["ext_xl_info"] = {};
  6735 + scope[ctrlAs]["ext_xl_info"].dir0_qdzName = "";
  6736 + scope[ctrlAs]["ext_xl_info"].dir1_qdzName = "";
  6737 + scope[ctrlAs]["ext_xl_info"].dir0_tip_width = 50;
  6738 + scope[ctrlAs]["ext_xl_info"].dir1_tip_width = 50;
  6739 +
  6740 + angular.forEach(scope[ctrlAs]["ds_contents"], function(value) {
  6741 + if (scope[ctrlAs]["ext_xl_info"].dir0_qdzName
  6742 + && scope[ctrlAs]["ext_xl_info"].dir1_qdzName) {
  6743 + return;
  6744 + }
  6745 + angular.forEach(value, function (bc) {
  6746 + if (bc.id && bc.bcType === 'normal') {
  6747 + if (bc.xlDir === '0' && bc.qdzName && !scope[ctrlAs]["ext_xl_info"].dir0_qdzName) {
  6748 + scope[ctrlAs]["ext_xl_info"].dir0_qdzName = bc.qdzName;
  6749 + scope[ctrlAs]["ext_xl_info"].dir0_tip_width += bc.qdzName.length * 15;
  6750 + } else if (bc.xlDir === '1' && bc.qdzName && !scope[ctrlAs]["ext_xl_info"].dir1_qdzName) {
  6751 + scope[ctrlAs]["ext_xl_info"].dir1_qdzName = bc.qdzName;
  6752 + scope[ctrlAs]["ext_xl_info"].dir1_tip_width += bc.qdzName.length * 15;
  6753 + }
  6754 + }
  6755 +
  6756 + })
  6757 + });
  6758 +
  6759 + };
  6760 +
  6761 + // 计算表格头部的标题文字
  6762 + var _calculate_header_info = function(scope) {
  6763 + scope[ctrlAs]["header_info1"] = ["路牌", "驾驶员", "自编号", "车牌号"];
  6764 + angular.forEach(scope[ctrlAs]["ds_header"], function(header) {
  6765 + if (header !== '路牌' && header !== '驾驶员' && header !== '自编号' && header !== '车牌号') {
  6766 + scope[ctrlAs]["header_info2"].push(header);
  6767 + }
  6768 + });
  6769 +
  6770 + // 修正header_info2标题数组
  6771 + // 2个班次一组 [上行group_no,下行group_no],从1开始
  6772 + var group_num = 1;
  6773 + var group_num_array = [1, 1];
  6774 + for (var i = 0; i < scope[ctrlAs]["header_info2"].length; i++) {
  6775 + var head = scope[ctrlAs]["header_info2"][i];
  6776 + if (head === scope[ctrlAs]["ext_xl_info"].dir0_qdzName) {
  6777 + scope[ctrlAs]["header_info2"][i] = head.substr(0, 1) + group_num_array[0];
  6778 + } else {
  6779 + scope[ctrlAs]["header_info2"][i] = head.substr(0, 1) + group_num_array[1];
  6780 + group_num ++ ;
  6781 + group_num_array = [group_num, group_num];
  6782 + }
  6783 +
  6784 + // TODO:如果是环线的话,目前group_num都是1,后面如果有变化再修正
  6785 + }
  6786 +
  6787 + };
  6788 + // 计算组件总高度
  6789 + var _calculate_ttInfo_detail_height = function(scope) {
  6790 + scope[ctrlAs]["ttInfo_detail_height"] = 0;
  6791 +
  6792 + var toolbar_height = 31; // 工具栏高度(参见template css)
  6793 + var tt_table_head_height = 36; // 表格标题高度(参见template css)
  6794 + var table_info_height = 30; // 表格行高度(参见template css)
  6795 + var table_extra_height = 30; // 表格修正高度
  6796 +
  6797 + scope[ctrlAs]["ttInfo_detail_height"] =
  6798 + toolbar_height
  6799 + + tt_table_head_height
  6800 + + table_info_height * scope[ctrlAs]["ds_contents"].length
  6801 + + table_extra_height;
  6802 + };
  6803 +
  6804 + // 平均化班次间隔(最后一个班次与第一个班次的分钟差 除以 总班次数)
  6805 + var _average_headway = function(bcList) {
  6806 + // 按时间从早到晚排序班次
  6807 + bcList.sort(function(a, b) {
  6808 + var a_moment = moment("2000-01-01 " + a.fcsj, "YYYY-MM-DD HH:mm");
  6809 + var b_moment = moment("2000-01-01 " + b.fcsj, "YYYY-MM-DD HH:mm");
  6810 +
  6811 + return a_moment.valueOf() - b_moment.valueOf();
  6812 + });
  6813 +
  6814 + var _first_bc_moment = moment("2000-01-01 " + bcList[0].fcsj, "YYYY-MM-DD HH:mm");
  6815 + var _last_bc_moment = moment("2000-01-01 " + bcList[bcList.length - 1].fcsj, "YYYY-MM-DD HH:mm");
  6816 +
  6817 + var _diff_minute = _last_bc_moment.diff(_first_bc_moment, 'minute');
  6818 +
  6819 + var _a1 = Math.floor(_diff_minute / (bcList.length - 1)); // 商数
  6820 + // first班次,last班次不变,只改变中间班次的发车时间,所以间隔的余数用不到
  6821 + // var _a2 = _diff_minute % (bcList.length - 1); // 余数
  6822 +
  6823 + angular.forEach(bcList, function(value, index) {
  6824 + if (index > 0 && index < bcList.length - 1) {
  6825 + var _pre_fc_sj_moment = moment("2000-01-01 " + bcList[index - 1].fcsj, "YYYY-MM-DD HH:mm");
  6826 + var _cur_fc_sj_moment = _pre_fc_sj_moment.add(_a1, 'm');
  6827 + value.fcsj = _cur_fc_sj_moment.format("HH:mm");
  6828 + }
  6829 + });
  6830 +
  6831 + // 删除第一个和最后一个班次信息(没有改变发车时间)
  6832 + bcList.shift();
  6833 + bcList.pop();
  6834 +
  6835 + };
  6836 +
  6837 + // 批量保存班次
  6838 + var _batch_save_bc = function(bcList) {
  6839 + var SchedulePlanInfo = spInfoService.rest;
  6840 +
  6841 + var deferred = $q.defer();
  6842 +
  6843 + var success_counts = 0; // 成功数
  6844 + var error_counts = 0; // 失败数
  6845 +
  6846 + for (var n = 0; n < bcList.length; n++) {
  6847 + (function(index) {
  6848 + SchedulePlanInfo.get({id: bcList[index].id},
  6849 + function(value) {
  6850 + if (value.status === 'ERROR') {
  6851 + error_counts ++;
  6852 + if (success_counts + error_counts === bcList.length) {
  6853 + deferred.reject("更新异常!");
  6854 + }
  6855 + } else {
  6856 + value.fcsj = bcList[index].fcsj;
  6857 + value["$save"](
  6858 + function(value2) {
  6859 + if (value2.status === 'ERROR') {
  6860 + error_counts ++;
  6861 + if (success_counts + error_counts === bcList.length) {
  6862 + deferred.reject("更新异常!");
  6863 + }
  6864 + } else {
  6865 + success_counts ++;
  6866 + bcList[index].modifyCount = value2.data.modifyCount;
  6867 + if (success_counts + error_counts === bcList.length) {
  6868 + deferred.resolve();
  6869 + }
  6870 + }
  6871 + },
  6872 + function() {
  6873 + error_counts ++;
  6874 + if (success_counts + error_counts === bcList.length) {
  6875 + deferred.reject("更新异常!");
  6876 + }
  6877 + });
  6878 + }
  6879 +
  6880 + },
  6881 + function() {
  6882 + error_counts ++;
  6883 + if (success_counts + error_counts === bcList.length) {
  6884 + deferred.reject("更新异常!");
  6885 + }
  6886 + });
  6887 +
  6888 + })(n);
  6889 + }
  6890 +
  6891 + return deferred.promise;
  6892 + };
  6893 +
  6894 + //------------------ 内部处理函数(以上)------------------//
  6895 +
  6896 +
6667 return { 6897 return {
6668 pre: function(scope, element, attr) { 6898 pre: function(scope, element, attr) {
6669 // TODO: 6899 // TODO:
6670 6900
6671 }, 6901 },
  6902 +
6672 post: function(scope, element, attr) { 6903 post: function(scope, element, attr) {
6673 - // TODO:  
6674 6904
6675 - // ------------------- dom事件处理function -----------------//  
6676 - scope[ctrlAs].$$cell_click = function(rowindex, colindex, cell) {  
6677 - console.log("click " + "row=" + rowindex + ",col=" + colindex);  
6678 - if (cell.id) { // 有排班明细id的cell才能操作  
6679 - cell.sel = !cell.sel; // 是否选中toggle 6905 +
  6906 + // ------------------- dom事件处理function(以下) -----------------//
  6907 +
  6908 + scope[ctrlAs].$$cell_click = function(rowIndex, colIndex, schedulePlanInfo) {
  6909 + // console.log("click " + "row=" + rowIndex + ",col=" + colIndex);
  6910 + if (schedulePlanInfo.id) { // 有排班明细id的cell才能操作
  6911 + var sel_detail_maps = scope[ctrlAs]["sel_detail_maps"];
  6912 + var key = rowIndex + "_" + colIndex;
  6913 + if (sel_detail_maps[key]) { // 是否选中toggle
  6914 + delete sel_detail_maps[key];
  6915 + } else {
  6916 + sel_detail_maps[key] = schedulePlanInfo;
  6917 + }
6680 } 6918 }
6681 6919
6682 }; 6920 };
6683 - scope[ctrlAs].$$cell_dbclick = function(rowindex, colindex, cell) {  
6684 - if (cell.id) { // 有排班明细id的cell才能操作  
6685 - if ($attr_celldbclick) {  
6686 - // 注意调用方法  
6687 - scope[ctrlAs].celldbclickFn()(rowindex, colindex); 6921 + scope[ctrlAs].$$cell_db_click = function(rowIndex, colIndex, schedulePlanInfo) {
  6922 + // console.log("dbClick " + "row=" + rowIndex + ",col=" + colIndex);
  6923 + if (schedulePlanInfo.id) { // 有排班明细id的schedulePlanInfo才能操作
  6924 + if ($attr_cell_db_click) {
  6925 + // 调用指令绑定的方法(注意调用的方式,参看指令说明)
  6926 + scope[ctrlAs]["cellDbClickFn"]()(schedulePlanInfo);
6688 } 6927 }
6689 } 6928 }
6690 }; 6929 };
6691 - // 工具栏单击事件  
6692 - scope[ctrlAs].$$toolbar1_dbclick = function() {  
6693 - if ($atrr_toolbarlplbclick) {  
6694 - scope[ctrlAs].toolbarLpLbClickFn()(); 6930 +
  6931 + // 工具栏按钮点击事件(取消选择)
  6932 + scope[ctrlAs].$$toolbar_cs_btn_click = function() {
  6933 + scope[ctrlAs]["sel_detail_maps"] = {};
  6934 + };
  6935 +
  6936 + // 工具栏按钮单击事件(路牌烂班)
  6937 + scope[ctrlAs].$$toolbar_dlp_btn_click = function() {
  6938 + if ($attr_toolbar_dlp_btn_click) {
  6939 + // 调用指令绑定的方法(注意调用的方式,参看指令说明)
  6940 + scope[ctrlAs]["toolBarBtn1ClickFn"]()();
6695 } 6941 }
6696 6942
6697 }; 6943 };
  6944 + // 工具栏按钮单击事件(添加班次)
  6945 + scope[ctrlAs].$$toolbar_tadd_btn_click = function() {
  6946 + if ($attr_toolbar_tadd_btn_click) {
  6947 + // 计算参考的班次
  6948 + var _ref_schedulePlanInfo = null;
6698 6949
6699 - // ------------------- 监控function ------------------//  
6700 - // 监控 ds: "=ngModel" 数据  
6701 - scope.$watch(  
6702 - function() {  
6703 - return scope[ctrlAs].ds;  
6704 - },  
6705 - function(newValue) {  
6706 - // 创建ds绑定的数据-路牌扩展数据  
6707 - if (newValue["contents"]) {  
6708 - angular.forEach(newValue["contents"], function(value) {  
6709 - var _lpName = value[0]["lpName"];  
6710 - scope[ctrlAs]["ds_ext_lp_info"][_lpName] = {allLb : false};  
6711 - var _bcCounts = 0; // 班次总数  
6712 - var _lbBcCounts = 0; // 烂班班次总数  
6713 - angular.forEach(value, function(bc) {  
6714 - if (bc.id) {  
6715 - _bcCounts ++;  
6716 - if (bc.status == -1) {  
6717 - _lbBcCounts ++;  
6718 - }  
6719 - }  
6720 - });  
6721 - if (_bcCounts > 0 && _bcCounts == _lbBcCounts) {  
6722 - scope[ctrlAs]["ds_ext_lp_info"][_lpName].allLb = true;  
6723 - }  
6724 - }); 6950 + var _sel_count = 0;
  6951 + var _sel_key = null;
  6952 + angular.forEach(scope[ctrlAs]["sel_detail_maps"], function(value, key) {
  6953 + _sel_count ++;
  6954 + _sel_key = key;
  6955 + _ref_schedulePlanInfo = value;
  6956 + });
  6957 +
  6958 + if (_sel_count !== 1) {
  6959 + alert("请仅选择一个班次用于参考!");
  6960 + return;
6725 } 6961 }
6726 6962
6727 - // 创建ds绑定数据-线路扩展数据  
6728 - scope[ctrlAs]["ds_ext_xl_info"] = {};  
6729 - scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName = "";  
6730 - scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName = "";  
6731 - scope[ctrlAs]["ds_ext_xl_info"].dir0_tip_width = 50;  
6732 - scope[ctrlAs]["ds_ext_xl_info"].dir1_tip_width = 50;  
6733 - if (newValue["contents"]) {  
6734 - angular.forEach(newValue["contents"], function(value) {  
6735 - if (scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName  
6736 - && scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName) {  
6737 - return;  
6738 - }  
6739 - angular.forEach(value, function (bc) {  
6740 - if (bc.id && bc.bcType == 'normal') {  
6741 - if (bc.xlDir == '0' && bc.qdzName && !scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName) {  
6742 - scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName = bc.qdzName;  
6743 - scope[ctrlAs]["ds_ext_xl_info"].dir0_tip_width += bc.qdzName.length * 15;  
6744 - } else if (bc.xlDir == '1' && bc.qdzName && !scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName) {  
6745 - scope[ctrlAs]["ds_ext_xl_info"].dir1_qdzName = bc.qdzName;  
6746 - scope[ctrlAs]["ds_ext_xl_info"].dir1_tip_width += bc.qdzName.length * 15;  
6747 - }  
6748 - } 6963 + // // 获取参考班次对应路牌的所有班次
  6964 + // var _sel_lp_trips = [];
  6965 + // angular.forEach(scope[ctrlAs]["ds_contents"][_sel_rowIndex], function(value) {
  6966 + // if (value.id) {
  6967 + // _sel_lp_trips.push(value);
  6968 + // }
  6969 + // });
6749 6970
6750 - })  
6751 - });  
6752 - } 6971 + // 获取参考班次对应的rowIndex,colIndex
  6972 + var _sel_rowIndex = parseInt(_sel_key.split("_")[0]);
  6973 + var _sel_colIndex = parseInt(_sel_key.split("_")[1]);
6753 6974
6754 - // 计算 .ttInfo_detail高度  
6755 - scope[ctrlAs]["ttInfo_detail_height"] = 0;  
6756 - var toolbar_height = 31; // 工具栏高度(参见template css)  
6757 - var tt_table_head_height = 36; // 表格标题高度(参见template css)  
6758 - var table_info_height = 30; // 表格行高度(参见template css)  
6759 - var table_extra_height = 30; // 表格修正高度  
6760 - if (newValue["contents"]) {  
6761 - scope[ctrlAs]["ttInfo_detail_height"] =  
6762 - toolbar_height +  
6763 - tt_table_head_height +  
6764 - table_info_height * newValue["contents"].length +  
6765 - table_extra_height; 6975 + // 调用指令绑定的方法(注意调用的方式,参看指令说明)
  6976 + scope[ctrlAs]["toolBarBtn2ClickFn"]()(
  6977 + _ref_schedulePlanInfo,
  6978 + _sel_rowIndex,
  6979 + _sel_colIndex,
  6980 + scope[ctrlAs]["ds_contents"]);
  6981 + }
  6982 + };
  6983 +
  6984 + // 工具栏按钮单击事件(均衡发车间隔)
  6985 + scope[ctrlAs].$$toolbar_average_headway_btn_click = function() {
  6986 + var sel_detail_list = [];
  6987 + angular.forEach(scope[ctrlAs]["sel_detail_maps"], function(value) {
  6988 + sel_detail_list.push(value);
  6989 + });
  6990 + if (sel_detail_list.length < 3) {
  6991 + alert("请至少选择三个班次!");
  6992 + return;
  6993 + }
  6994 + // 判断选中的班次是否是同方向
  6995 + var sel_detail_xldir = sel_detail_list[0]["xlDir"];
  6996 + var is_single_xldir = true;
  6997 + angular.forEach(scope[ctrlAs]["sel_detail_maps"], function(value) {
  6998 + if (value["xlDir"] !== sel_detail_xldir) {
  6999 + is_single_xldir = false;
6766 } 7000 }
  7001 + });
  7002 + if (!is_single_xldir) {
  7003 + alert("请选择同方向的班次!");
  7004 + return;
  7005 + }
6767 7006
6768 - // 创建ds绑定的数据-标题扩展数据2  
6769 - scope[ctrlAs]["ds_head_info2"] = [];  
6770 - angular.forEach(newValue["header"], function(head) {  
6771 - if (head != '路牌' && head != '驾驶员' && head != '自编号' && head != '车牌号') {  
6772 - scope[ctrlAs]["ds_head_info2"].push(head);  
6773 - } 7007 + // 平均化发车间隔
  7008 + _average_headway(sel_detail_list);
  7009 + // 批量保存班次
  7010 + _batch_save_bc(sel_detail_list).then(
  7011 + function() {
  7012 + alert("调整成功!");
  7013 + },
  7014 + function(err) {
  7015 + alert(err);
6774 }); 7016 });
6775 - // 2个班次一组 [上行group_no,下行group_no],从1开始  
6776 - var group_num = 1;  
6777 - var group_num_array = [1, 1];  
6778 - for (var i = 0; i < scope[ctrlAs]["ds_head_info2"].length; i++) {  
6779 - var head = scope[ctrlAs]["ds_head_info2"][i];  
6780 - if (head == scope[ctrlAs]["ds_ext_xl_info"].dir0_qdzName) {  
6781 - scope[ctrlAs]["ds_head_info2"][i] = head.substr(0, 1) + group_num_array[0];  
6782 - } else {  
6783 - scope[ctrlAs]["ds_head_info2"][i] = head.substr(0, 1) + group_num_array[1];  
6784 - group_num ++ ;  
6785 - group_num_array = [group_num, group_num];  
6786 - }  
6787 7017
6788 - // TODO:如果是环线的话,目前group_num都是1,后面如果有变化再修正  
6789 - } 7018 + };
6790 7019
6791 - // TODO: 7020 + // ------------------- dom事件处理function(以上) -----------------//
6792 7021
  7022 + // ------------------- 监控function(以下) ------------------//
  7023 + // 监控 ds: "=ngModel" 数据
  7024 + scope.$watch(
  7025 + function() {
  7026 + return scope[ctrlAs].ds;
  7027 + },
  7028 + function(newValue) {
  7029 + // 将后台数据赋值到内部对象
  7030 + scope[ctrlAs]["ds_header"] = newValue["header"] || [];
  7031 + scope[ctrlAs]["ds_contents"] = newValue["contents"] || [];
  7032 +
  7033 + scope[ctrlAs]["ext_lp_info"] = {};
  7034 + scope[ctrlAs]["ext_xl_info"] = {};
  7035 + scope[ctrlAs]["header_info1"] = [];
  7036 + scope[ctrlAs]["header_info2"] = [];
  7037 +
  7038 + scope[ctrlAs]["sel_detail_maps"] = {};
  7039 +
  7040 + // 根据后台数据计算各个内部值
  7041 + _calculate_ext_lp_info(scope);
  7042 + _calculate_ext_xl_info(scope);
  7043 + _calculate_ttInfo_detail_height(scope);
  7044 + _calculate_header_info(scope);
6793 }, 7045 },
6794 true 7046 true
6795 ); 7047 );
6796 7048
  7049 +
  7050 + // ------------------- 监控function(以上) ------------------//
  7051 +
  7052 + // TODO:
6797 } 7053 }
6798 7054
6799 }; 7055 };
6800 -  
6801 } 7056 }
  7057 +
6802 }; 7058 };
6803 } 7059 }
6804 ] 7060 ]
  7061 +
6805 ); 7062 );
src/main/resources/static/pages/scheduleApp/module/common/prj-common-ui-route-state.js
@@ -1027,6 +1027,28 @@ ScheduleApp.config([ @@ -1027,6 +1027,28 @@ ScheduleApp.config([
1027 }); 1027 });
1028 }] 1028 }]
1029 } 1029 }
  1030 + })
  1031 +
  1032 + .state("schedulePlanReportExtManageListEdit_addTrip", { // 添加班次
  1033 + url: '/schedulePlanReportExtManageListEdit_addTrip',
  1034 + params: {schedulePlanInfo: null, rowIndex: null, colIndex: null, allSchedulePlanInfoList: null},
  1035 + views: {
  1036 + "": {templateUrl: 'pages/scheduleApp/module/core/schedulePlanManage/report/ext/edit-addTrip.html'}
  1037 + },
  1038 + resolve: {
  1039 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  1040 + return $ocLazyLoad.load({
  1041 + name: 'schedulePlanManage_module',
  1042 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  1043 + files: [
  1044 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  1045 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  1046 + "pages/scheduleApp/module/core/schedulePlanManage/report/ext/module.js"
  1047 + ]
  1048 + });
  1049 + }]
  1050 + }
  1051 +
1030 }); 1052 });
1031 1053
1032 1054
src/main/resources/static/pages/scheduleApp/module/core/schedulePlanManage/report/ext/edit-addTrip.html 0 → 100644
  1 +<div ng-controller="SchedulePlanReportExtManageListEditCtrl_addTrip as ctrl">
  2 + <div class="page-head">
  3 + <div class="page-title">
  4 + <h1>添加班次信息</h1>
  5 + </div>
  6 + </div>
  7 +
  8 + <ul class="page-breadcrumb breadcrumb">
  9 + <li>
  10 + <a href="/pages/home.html" data-pjax>首页</a>
  11 + <i class="fa fa-circle"></i>
  12 + </li>
  13 + <li>
  14 + <span class="active">运营计划管理</span>
  15 + <i class="fa fa-circle"></i>
  16 + </li>
  17 + <li>
  18 + <a ui-sref="schedulePlanReportExtManage">调度值勤日报</a>
  19 + <i class="fa fa-circle"></i>
  20 + </li>
  21 + <li>
  22 + <span class="active">添加班次信息</span>
  23 + </li>
  24 + </ul>
  25 +
  26 + <div class="portlet light bordered">
  27 + <div class="portlet-title">
  28 + <div class="caption caption-subject font-red-sunglo bold uppercase">
  29 + <span ng-bind="ctrl.headInfo.xlName"></span>
  30 + 当前排班日期
  31 + <span ng-bind="ctrl.schedulePlanInfoForSave.scheduleDate | date: 'yyyy年MM月dd日'"></span>
  32 + </div>
  33 + </div>
  34 +
  35 + <div class="portlet-body form">
  36 + <form ng-submit="ctrl.submit()" class="form-horizontal" novalidate name="myForm">
  37 + <div class="form-body">
  38 + <div class="form-group has-success has-feedback">
  39 + <label class="col-md-2 control-label">线路:</label>
  40 + <div class="col-md-3">
  41 + <input type="text" class="form-control"
  42 + ng-value="ctrl.headInfo.xlName"
  43 + readonly/>
  44 + </div>
  45 +
  46 + </div>
  47 + <div class="form-group has-success has-feedback">
  48 + <label class="col-md-2 control-label">路牌:</label>
  49 + <div class="col-md-3">
  50 + <input type="text" class="form-control"
  51 + ng-value="ctrl.headInfo.lpName"
  52 + readonly/>
  53 + </div>
  54 +
  55 + </div>
  56 + <div class="form-group has-success has-feedback">
  57 + <label class="col-md-2 control-label">驾驶员:</label>
  58 + <div class="col-md-3">
  59 + <input type="text" class="form-control"
  60 + ng-value="ctrl.headInfo.jName"
  61 + readonly/>
  62 + </div>
  63 +
  64 + </div>
  65 +
  66 + <div class="form-group has-success has-feedback">
  67 + <label class="col-md-2 control-label">自编号:</label>
  68 + <div class="col-md-3">
  69 + <input type="text" class="form-control"
  70 + ng-value="ctrl.headInfo.clZbh"
  71 + readonly/>
  72 + </div>
  73 +
  74 + </div>
  75 +
  76 + <div class="form-group has-success has-feedback">
  77 + <label class="col-md-2 control-label">车牌号:</label>
  78 + <div class="col-md-3">
  79 + <input type="text" class="form-control"
  80 + ng-value="ctrl.headInfo.clCph"
  81 + readonly/>
  82 + </div>
  83 +
  84 + </div>
  85 +
  86 + <!--<div class="form-group has-success has-feedback">-->
  87 + <!--<label class="col-md-2 control-label">方向*:</label>-->
  88 + <!--<div class="col-md-3">-->
  89 + <!--<sa-Radiogroup model="ctrl.TimeTableDetailForSave.xlDir" dicgroup="LineTrend" name="xlDir" required></sa-Radiogroup>-->
  90 + <!--</div>-->
  91 + <!--&lt;!&ndash; 隐藏块,显示验证信息 &ndash;&gt;-->
  92 + <!--<div class="alert alert-danger well-sm" ng-show="myForm.xlDir.$error.required">-->
  93 + <!--请选择线路上下行-->
  94 + <!--</div>-->
  95 +
  96 + <!--</div>-->
  97 +
  98 + <div class="form-group has-success has-feedback">
  99 + <label class="col-md-2 control-label">起点站:</label>
  100 + <div class="col-md-3">
  101 + <input type="text" class="form-control"
  102 + ng-value="ctrl.schedulePlanInfoForSave.qdzName"
  103 + readonly/>
  104 + </div>
  105 +
  106 + </div>
  107 +
  108 + <div class="form-group has-success has-feedback">
  109 + <label class="col-md-2 control-label">终点站:</label>
  110 + <div class="col-md-3">
  111 + <input type="text" class="form-control"
  112 + ng-value="ctrl.schedulePlanInfoForSave.zdzName"
  113 + readonly/>
  114 + </div>
  115 +
  116 + </div>
  117 +
  118 + <div class="form-group has-success has-feedback">
  119 + <label class="col-md-2 control-label">发车时间*:</label>
  120 + <div class="col-md-3">
  121 + <input type="text" class="form-control" name="fcsj"
  122 + ng-model="ctrl.schedulePlanInfoForSave.fcsj"
  123 + ng-pattern="ctrl.time_regex"
  124 + required />
  125 + </div>
  126 + <!-- 隐藏块,显示验证信息 -->
  127 + <div class="alert alert-danger well-sm" ng-show="myForm.fcsj.$error.required">
  128 + 发车时间必须填写
  129 + </div>
  130 + <div class="alert alert-danger well-sm" ng-show="myForm.fcsj.$error.pattern">
  131 + 时间格式错误,应该是格式hh:mm,如:06:39
  132 + </div>
  133 +
  134 + </div>
  135 +
  136 + <div class="form-group has-success has-feedback">
  137 + <label class="col-md-2 control-label">计划里程*:</label>
  138 + <div class="col-md-3">
  139 + <input type="text" class="form-control" name="jhlc"
  140 + ng-model="ctrl.schedulePlanInfoForSave.jhlc" required ng-pattern="ctrl.float_regex"
  141 + />
  142 + </div>
  143 + <!-- 隐藏块,显示验证信息 -->
  144 + <div class="alert alert-danger well-sm" ng-show="myForm.jhlc.$error.required">
  145 + 计划里程必须填写
  146 + </div>
  147 + <div class="alert alert-danger well-sm" ng-show="myForm.jhlc.$error.pattern">
  148 + 输入数字
  149 + </div>
  150 +
  151 + </div>
  152 + <div class="form-group has-success has-feedback">
  153 + <label class="col-md-2 control-label">班次历时*:</label>
  154 + <div class="col-md-3">
  155 + <input type="text" class="form-control" name="bcsj"
  156 + ng-model="ctrl.schedulePlanInfoForSave.bcsj" required ng-pattern="ctrl.number_regex"
  157 + />
  158 + </div>
  159 + <!-- 隐藏块,显示验证信息 -->
  160 + <div class="alert alert-danger well-sm" ng-show="myForm.bcsj.$error.required">
  161 + 班次时间必须填写
  162 + </div>
  163 + <div class="alert alert-danger well-sm" ng-show="myForm.bcsj.$error.pattern">
  164 + 输入整数
  165 + </div>
  166 +
  167 + </div>
  168 +
  169 + <div class="form-group has-success has-feedback">
  170 + <label class="col-md-2 control-label">班次类型*:</label>
  171 + <div class="col-md-3">
  172 + <sa-Select5 name="bcType"
  173 + model="ctrl.schedulePlanInfoForSave"
  174 + cmaps="{'bcType': 'code'}"
  175 + dcname="bcType"
  176 + icname="code"
  177 + dsparams="{{ {type: 'dic', param: 'ScheduleType' } | json }}"
  178 + iterobjname="item"
  179 + iterobjexp="item.name"
  180 + searchph="请选择班次类型..."
  181 + searchexp="this.name"
  182 + required
  183 + >
  184 + </sa-Select5>
  185 + </div>
  186 + <!-- 隐藏块,显示验证信息 -->
  187 + <div class="alert alert-danger well-sm" ng-show="myForm.bcType.$error.required">
  188 + 班次类型必须选择
  189 + </div>
  190 +
  191 + </div>
  192 +
  193 + </div>
  194 +
  195 + <div class="form-actions">
  196 + <div class="row">
  197 + <div class="col-md-offset-3 col-md-4">
  198 + <button type="submit" class="btn green"
  199 + ng-disabled="!myForm.$valid"><i class="fa fa-check"></i> 提交</button>
  200 + <a type="button" class="btn default"
  201 + href="javascript:" ng-click="ctrl.cancel()" ><i class="fa fa-times"></i> 取消</a>
  202 + </div>
  203 + </div>
  204 + </div>
  205 + </form>
  206 +
  207 + </div>
  208 + </div>
  209 +
  210 +
  211 +
  212 +
  213 +</div>
  214 +
src/main/resources/static/pages/scheduleApp/module/core/schedulePlanManage/report/ext/list.html
@@ -25,8 +25,11 @@ @@ -25,8 +25,11 @@
25 </div> 25 </div>
26 26
27 <div class="fixDiv" ng-if="ctrl.viewId == 1"> 27 <div class="fixDiv" ng-if="ctrl.viewId == 1">
28 - <sa-Planinfoview name="saPlanView" ng-model="ctrl.saPlanInfoViewData.infos" ng-model-options="{ getterSetter: true }"  
29 - celldbclick="ctrl.singleEditBcDetail" toolbarlplbclick="ctrl.routeToLpLbView"> 28 + <sa-Planinfoview name="saPlanView"
  29 + ng-model="ctrl.saPlanInfoViewData.infos" ng-model-options="{ getterSetter: true }"
  30 + cell_db_click="ctrl.singleEditBcDetail"
  31 + toolbar_dlp_btn_click="ctrl.routeToLpLbView"
  32 + toolbar_tadd_btn_click="ctrl.routeToAddTripView">
30 </sa-Planinfoview> 33 </sa-Planinfoview>
31 </div> 34 </div>
32 35
src/main/resources/static/pages/scheduleApp/module/core/schedulePlanManage/report/ext/module.js
@@ -352,13 +352,10 @@ angular.module(&#39;ScheduleApp&#39;).controller( @@ -352,13 +352,10 @@ angular.module(&#39;ScheduleApp&#39;).controller(
352 /** 352 /**
353 * 单独修改班次明细。 353 * 单独修改班次明细。
354 */ 354 */
355 - self.singleEditBcDetail = function(rowNum, colNum) {  
356 -  
357 - console.log(rowNum + "," + colNum);  
358 - 355 + self.singleEditBcDetail = function(schedulePlanInfo) {
359 $state.go('schedulePlanReportExtManageListEdit', 356 $state.go('schedulePlanReportExtManageListEdit',
360 { 357 {
361 - spInfoId: self.saPlanInfoViewData.infos.contents[rowNum][colNum]["id"] 358 + spInfoId: schedulePlanInfo["id"]
362 }); 359 });
363 }; 360 };
364 361
@@ -371,6 +368,18 @@ angular.module(&#39;ScheduleApp&#39;).controller( @@ -371,6 +368,18 @@ angular.module(&#39;ScheduleApp&#39;).controller(
371 }); 368 });
372 }; 369 };
373 370
  371 + /**
  372 + * route到添加班次view。
  373 + */
  374 + self.routeToAddTripView = function(schedulePlanInfo, rowIndex, colIndex, allSchedulePlanInfoList) {
  375 + $state.go('schedulePlanReportExtManageListEdit_addTrip', {
  376 + schedulePlanInfo: schedulePlanInfo,
  377 + rowIndex: rowIndex,
  378 + colIndex: colIndex,
  379 + allSchedulePlanInfoList: allSchedulePlanInfoList
  380 + });
  381 + };
  382 +
374 } 383 }
375 384
376 ] 385 ]
@@ -660,4 +669,237 @@ angular.module(&#39;ScheduleApp&#39;).controller( @@ -660,4 +669,237 @@ angular.module(&#39;ScheduleApp&#39;).controller(
660 ] 669 ]
661 ); 670 );
662 671
  672 +// edit-addTrip页面
  673 +angular.module('ScheduleApp').controller(
  674 + 'SchedulePlanReportExtManageListEditCtrl_addTrip',
  675 + [
  676 + 'SchedulePlanInfoManageService_g',
  677 + 'BusInfoManageService_g',
  678 + '$stateParams',
  679 + '$state',
  680 + '$q',
  681 + function(spInfoService, carService, $stateParams, $state, $q) {
  682 + var self = this;
  683 +
  684 + // 参考的班次对象
  685 + var _ref_schedulePlanInfo = $stateParams.schedulePlanInfo;
  686 + // 参考班次对应的rowIndex,colIndex
  687 + var _ref_rowIndex = $stateParams.rowIndex;
  688 + var _ref_colIndex = $stateParams.colIndex;
  689 + // 所有的班次对象对应ds
  690 + var _ref_allSchedulePlanInfoList = $stateParams.allSchedulePlanInfoList;
  691 +
  692 + console.log(_ref_allSchedulePlanInfoList);
  693 +
  694 + // 其他的显示数据
  695 + self.headInfo = {
  696 + xlName: '', // 线路名称
  697 + lpName: '', // 路牌名称
  698 + jName: '', // 驾驶员
  699 + clZbh: '', // 自编号
  700 + clCph: '', // 车牌号
  701 + };
  702 +
  703 + // 排班明细对象
  704 + var SchedulePlanInfo = spInfoService.rest;
  705 + // 车辆信息对象
  706 + var Cars = carService.rest;
  707 +
  708 + // 保存的排班明细数据
  709 + self.schedulePlanInfoForSave = {};
  710 + // 获取数据
  711 + SchedulePlanInfo.get({id: _ref_schedulePlanInfo.id}, function(value) {
  712 + self.schedulePlanInfoForSave = value;
  713 +
  714 + self.headInfo['xlName'] = value['xlName'];
  715 + self.headInfo['lpName'] = value['lpName'];
  716 + self.headInfo['jName'] = value['jName'];
  717 + self.headInfo['clZbh'] = value['clZbh'];
  718 +
  719 + Cars.get({id: value.cl}, function(value2) {
  720 + self.headInfo['clCph'] = value2['carPlate'];
  721 + });
  722 + });
  723 +
  724 + // 时间正则表达式(格式hh:mm,如:06:39)
  725 + self.time_regex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
  726 + // 整数
  727 + self.number_regex = /^-?\d+$/;
  728 + // 小数
  729 + self.float_regex = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/;
  730 +
  731 + // 批量修正发车顺序号
  732 + self.batch_change_fc_no = function(bcIdList) {
  733 + var deferred = $q.defer();
  734 +
  735 + if (bcIdList && bcIdList.length > 0) {
  736 + var success_counts = 0; // 成功数
  737 + var error_counts = 0; // 失败数
  738 + for (var n = 0; n < bcIdList.length; n++) {
  739 + (function(index) {
  740 + SchedulePlanInfo.get({id: bcIdList[index]},
  741 + function(value) {
  742 + if (value.status === 'ERROR') {
  743 + error_counts ++;
  744 + if (success_counts + error_counts == bcIdList.length) {
  745 + deferred.reject("更新异常!");
  746 + }
  747 + } else {
  748 + // 注意:修改fc_no不算更新过,所以modifyCount减1,如果是null就是-1
  749 + value.fcno = value.fcno + 1;
  750 + value.modifyCount = value.modifyCount == null ? -1 : (value.modifyCount - 1);
  751 + value["$save"](
  752 + function(value2) {
  753 + if (value2.status === 'ERROR') {
  754 + error_counts ++;
  755 + if (success_counts + error_counts === bcIdList.length) {
  756 + deferred.reject("更新异常!");
  757 + }
  758 + } else {
  759 + success_counts ++;
  760 + if (success_counts + error_counts === bcIdList.length) {
  761 + deferred.resolve();
  762 + }
  763 + }
  764 + },
  765 + function() {
  766 + error_counts ++;
  767 + if (success_counts + error_counts === bcIdList.length) {
  768 + deferred.reject("更新异常!");
  769 + }
  770 + });
  771 + }
  772 +
  773 + },
  774 + function() {
  775 + error_counts ++;
  776 + if (success_counts + error_counts === bcIdList.length) {
  777 + deferred.reject("更新异常!");
  778 + }
  779 + });
  780 + })(n);
  781 + }
  782 +
  783 + } else {
  784 + deferred.reject("无班次!");
  785 + }
  786 +
  787 + return deferred.promise;
  788 + };
  789 +
  790 + // 提交方法
  791 + self.submit = function() {
  792 + // 1、在当前路牌中插入一个班次,并计算出插入的colIndex和fc_no
  793 + var _insert_rowIndex = _ref_rowIndex;
  794 + var _insert_colIndex = _ref_allSchedulePlanInfoList[0].length; // 默认路牌最后添加一个班次
  795 + var _insert_bc_fc_no = _ref_allSchedulePlanInfoList[0].length - 4 + 1; // 同上
  796 +
  797 + var keepGoing = true;
  798 + angular.forEach(_ref_allSchedulePlanInfoList[_insert_rowIndex], function(bc, index) {
  799 + if (index > 3) { // 跳过路牌,驾驶员,自编号,车牌号
  800 + if (keepGoing) {
  801 + var _insert_bc_fcsj = moment("2000-01-01 " + self.schedulePlanInfoForSave.fcsj, "YYYY-MM-DD HH:mm");
  802 + var _current_bc_fcsj = moment("2000-01-01 " + bc.fcsj, "YYYY-MM-DD HH:mm");
  803 + if (_insert_bc_fcsj.isBefore(_current_bc_fcsj)) {
  804 + if ((index - 1) > 3 && !_ref_allSchedulePlanInfoList[_insert_rowIndex][index - 1].id) {
  805 + // 如果前面一格有空位index,直接用
  806 + _insert_colIndex = index - 1;
  807 + } else { // 没用空位,占用当前班次位置index
  808 + _insert_colIndex = index;
  809 + }
  810 + _insert_bc_fc_no = _insert_colIndex - 4 + 1;
  811 +
  812 + keepGoing = false;
  813 + }
  814 + }
  815 + }
  816 +
  817 + });
  818 +
  819 + // console.log(_ref_allSchedulePlanInfoList[_insert_rowIndex]);
  820 + // console.log(moment("2000-01-01 " + self.schedulePlanInfoForSave.fcsj, "YYYY-MM-DD HH:mm"));
  821 + // console.log(_insert_colIndex);
  822 + // console.log(_insert_bc_fc_no);
  823 +
  824 + self.schedulePlanInfoForSave.id = null;
  825 + self.schedulePlanInfoForSave.fcno = _insert_bc_fc_no;
  826 +
  827 + // 2,根据插入班次的colIndex,判断其他路牌班次的fcno如何更新
  828 + var _max_bc_colIndex = _ref_allSchedulePlanInfoList[0].length - 1;
  829 + if (_insert_colIndex > _max_bc_colIndex) {
  830 + // 2-0,如果colIndex大于原来数组的length,则其他路牌班次fcno不用修正
  831 + self.schedulePlanInfoForSave["$save"](function() {
  832 + $state.go("schedulePlanReportExtManage");
  833 + });
  834 + } else if (!_ref_allSchedulePlanInfoList[_insert_rowIndex][_insert_colIndex].id) {
  835 + // 2-1、如果当前的格子是空的,直接保存,fcno不用修正
  836 + self.schedulePlanInfoForSave["$save"](function() {
  837 + $state.go("schedulePlanReportExtManage");
  838 + });
  839 + } else {
  840 + // 获取路牌关联的_insert_colIndex班次方向
  841 + var _insert_colIndex_lp_xlDir = null;
  842 + angular.forEach(_ref_allSchedulePlanInfoList, function(lpBcList) {
  843 + if (!_insert_colIndex_lp_xlDir) {
  844 + angular.forEach(lpBcList, function(bc, colIndex) {
  845 + if (colIndex === _insert_colIndex) {
  846 + if (bc.id) {
  847 + _insert_colIndex_lp_xlDir = bc.xlDir;
  848 + }
  849 + }
  850 + });
  851 + }
  852 + });
  853 +
  854 + // 批量更新的班次id
  855 + var _batch_update_id_list = [];
  856 +
  857 + // 2-2,如果colIndex关联的其他路牌班次方向与插入班次一致,则将其他路牌大于colIndex的班次fcno加1
  858 + if (self.schedulePlanInfoForSave.xlDir === _insert_colIndex_lp_xlDir) {
  859 + angular.forEach(_ref_allSchedulePlanInfoList, function(lpBcList) {
  860 + angular.forEach(lpBcList, function(bc, colIndex) {
  861 + if (colIndex > _insert_colIndex) {
  862 + if (bc.id) {
  863 + _batch_update_id_list.push(bc.id);
  864 + }
  865 + }
  866 + });
  867 + });
  868 + } else { // 2-3,如果colIndex关联的其他路牌班次方向与插入班次不一致,则将其他路牌大于等于colIndex的班次fcno加1
  869 + angular.forEach(_ref_allSchedulePlanInfoList, function(lpBcList) {
  870 + angular.forEach(lpBcList, function(bc, colIndex) {
  871 + if(colIndex >= _insert_colIndex) {
  872 + if (bc.id) {
  873 + _batch_update_id_list.push(bc.id);
  874 + }
  875 + }
  876 + });
  877 + });
  878 + }
  879 +
  880 + // 保存
  881 + self.schedulePlanInfoForSave["$save"](function() {
  882 + self.batch_change_fc_no(_batch_update_id_list).then(
  883 + function() {
  884 + $state.go("schedulePlanReportExtManage");
  885 + },
  886 + function(err) {
  887 + alert(err);
  888 + });
  889 + });
  890 +
  891 + }
  892 +
  893 + };
  894 + // 取消方法
  895 + self.cancel = function() {
  896 + $state.go("schedulePlanReportExtManage");
  897 + };
  898 +
  899 + }
  900 + ]
  901 +);
  902 +
  903 +
  904 +
663 905
src/main/resources/static/pages/scheduleApp/module/core/schedulePlanManage/report/ext/route.js
@@ -91,6 +91,28 @@ ScheduleApp.config([ @@ -91,6 +91,28 @@ ScheduleApp.config([
91 }); 91 });
92 }] 92 }]
93 } 93 }
  94 + })
  95 +
  96 + .state("schedulePlanReportExtManageListEdit_addTrip", { // 添加班次
  97 + url: '/schedulePlanReportExtManageListEdit_addTrip',
  98 + params: {schedulePlanInfo: null, rowIndex: null, colIndex: null, allSchedulePlanInfoList: null},
  99 + views: {
  100 + "": {templateUrl: 'pages/scheduleApp/module/core/schedulePlanManage/report/ext/edit-addTrip.html'}
  101 + },
  102 + resolve: {
  103 + deps: ['$ocLazyLoad', function($ocLazyLoad) {
  104 + return $ocLazyLoad.load({
  105 + name: 'schedulePlanManage_module',
  106 + insertBefore: '#ng_load_plugins_before', // 动态载入模块时放置的位置
  107 + files: [
  108 + "assets/bower_components/angular-ui-select/dist/select.min.css",
  109 + "assets/bower_components/angular-ui-select/dist/select.min.js",
  110 + "pages/scheduleApp/module/core/schedulePlanManage/report/ext/module.js"
  111 + ]
  112 + });
  113 + }]
  114 + }
  115 +
94 }); 116 });
95 117
96 118