MyIndex.js 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. MWF.xApplication.Attendance = MWF.xApplication.Attendance || {};
  2. MWF.require("MWF.xAction.org.express.RestActions", null,false);
  3. MWF.xDesktop.requireApp("Attendance", "lp."+MWF.language, null, false);
  4. MWF.xDesktop.requireApp("Attendance", "Common", null, false);
  5. MWF.xApplication.Attendance.MyIndex = new Class({
  6. Extends: MWF.widget.Common,
  7. Implements: [Options, Events],
  8. options: {
  9. "style": "default"
  10. },
  11. statusColor : {
  12. "normal" : "#9acd32", //绿色,正常
  13. "levelAsked":"#4f94cd", //蓝色,请假
  14. "late":"#fede03", //黄色,迟到
  15. //"leaveEarly":"#fe8d03", //橙色,早退
  16. "noSign":"#ee807f", //粉红色,未签到
  17. "appealSuccess" : "#2ac497", //黄绿色,申诉通过
  18. //"lackOfTime" : "#dec674",//工时不足人次
  19. "abNormalDuty" : "#fedcbd"//异常打卡人次
  20. },
  21. initialize: function(node, app, actions, options){
  22. this.setOptions(options);
  23. this.app = app;
  24. this.lp = app.lp;
  25. this.path = "../x_component_Attendance/$MyIndex/";
  26. this.cssPath = "../x_component_Attendance/$MyIndex/"+this.options.style+"/css.wcss";
  27. this._loadCss();
  28. this.actions = actions;
  29. this.node = $(node);
  30. this.holidayData = {};
  31. this.today = new Date();
  32. //this.preMonthDate = new Date();
  33. //this.preMonthDate.decrement("month", 1);
  34. this.setDate();
  35. this.todayDate = this.today.format( this.lp.dateFormatDay );
  36. this.todayHloidayName = "";
  37. this.todayIsWorkDay = false; //是否调修工作日
  38. this.userName = layout.desktop.session.user.distinguishedName;
  39. },
  40. setDate : function( date ){
  41. this.date = date || new Date(); //this.preMonthDate
  42. this.year = this.date.getFullYear().toString();
  43. var month = this.date.getMonth()+1;
  44. this.month = month.toString().length == 2 ? month : "0"+month;
  45. this.getCycleDate();
  46. },
  47. destroy: function(){
  48. this.node.empty();
  49. },
  50. reload: function(){
  51. this.node.empty();
  52. this.load();
  53. },
  54. load: function(){
  55. this.loadTitleNode();
  56. this.loadContent();
  57. },
  58. loadTitleNode : function(){
  59. var text = this.date.format(this.app.lp.dateFormatMonth);
  60. this.titleNode = new Element("div.titleNode",{
  61. "styles" : this.css.titleNode
  62. }).inject(this.node);
  63. //this.titleLeftArrowNode = new Element("div",{
  64. // "styles" : this.css.titleLeftArrowNode
  65. //}).inject(this.titleNode);
  66. this.titleTextNode = new Element("div",{
  67. "styles" : this.css.titleTextNode,
  68. "text" : text
  69. }).inject(this.titleNode);
  70. this.titleTextNode.setStyles( {
  71. "margin-left": "30px",
  72. "cursor" : "default"
  73. } );
  74. //this.titleRightArrowNode = new Element("div",{
  75. // "styles" : this.css.titleRightArrowNode
  76. //}).inject(this.titleNode);
  77. var cycleText = "考勤周期:"+ this.cycleStartDateString + "至" + this.cycleEndDateString;
  78. this.titleCycleTextNode = new Element("div",{
  79. "styles" : this.css.titleCycleTextNode,
  80. "text" : cycleText
  81. }).inject(this.titleNode);
  82. this.titleScheduleIconNode = new Element("div",{
  83. "styles" : this.css.titleScheduleIconNode,
  84. "title" : this.lp.seeSchedule
  85. }).inject(this.titleNode);
  86. //this.titleLeftArrowNode.addEvents({
  87. // "mouseover": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode_over);}.bind(this),
  88. // "mouseout": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode);}.bind(this),
  89. // "mousedown": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode_down);}.bind(this),
  90. // "mouseup": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode_over);}.bind(this),
  91. // "click": function(){this.changeMonthPrev();}.bind(this)
  92. //});
  93. //this.titleRightArrowNode.addEvents({
  94. // "mouseover": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode_over);}.bind(this),
  95. // "mouseout": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode);}.bind(this),
  96. // "mousedown": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode_down);}.bind(this),
  97. // "mouseup": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode_over);}.bind(this),
  98. // "click": function(){this.changeMonthNext();}.bind(this)
  99. //});
  100. //this.titleTextNode.addEvents({
  101. // "mouseover": function(){this.titleTextNode.setStyles(this.css.titleTextNode_over);}.bind(this),
  102. // "mouseout": function(){this.titleTextNode.setStyles(this.css.titleTextNode);}.bind(this),
  103. // "mousedown": function(){this.titleTextNode.setStyles(this.css.titleTextNode_down);}.bind(this),
  104. // "mouseup": function(){this.titleTextNode.setStyles(this.css.titleTextNode_over);}.bind(this),
  105. // "click": function(){this.changeMonthSelect();}.bind(this)
  106. //});
  107. this.titleScheduleIconNode.addEvents({
  108. "mouseover": function(){this.titleScheduleIconNode.setStyles(this.css.titleScheduleIconNode_over);}.bind(this),
  109. "mouseout": function(){this.titleScheduleIconNode.setStyles(this.css.titleScheduleIconNode);}.bind(this),
  110. "mousedown": function(){this.titleScheduleIconNode.setStyles(this.css.titleScheduleIconNode_down);}.bind(this),
  111. "mouseup": function(){this.titleScheduleIconNode.setStyles(this.css.titleScheduleIconNode_over);}.bind(this),
  112. "click": function(){this.showSchedule();}.bind(this)
  113. });
  114. },
  115. changeMonthPrev: function(){
  116. this.date.decrement("month", 1);
  117. this.setDate( this.date );
  118. var text = this.date.format(this.app.lp.dateFormatMonth);
  119. this.titleTextNode.set("text", text);
  120. this.reloadContent();
  121. },
  122. changeMonthNext: function(){
  123. this.date.increment("month", 1);
  124. this.setDate( this.date );
  125. var text = this.date.format(this.app.lp.dateFormatMonth);
  126. this.titleTextNode.set("text", text);
  127. this.reloadContent();
  128. },
  129. changeMonthSelect: function(){
  130. if (!this.monthSelector) this.createMonthSelector();
  131. this.monthSelector.show();
  132. },
  133. createMonthSelector: function(){
  134. this.monthSelector = new MWF.xApplication.Attendance.MonthSelector(this.date, this);
  135. },
  136. changeMonthTo: function(d){
  137. this.setDate( d );
  138. var text = this.date.format(this.app.lp.dateFormatMonth);
  139. this.titleTextNode.set("text", text);
  140. this.reloadContent();
  141. },
  142. getCycleDate : function(){
  143. this.actions.getCyclePerson( this.year, this.month, function( json ){
  144. json.data = json.data || [];
  145. this.cycleStartDateString = json.data.cycleStartDateString;
  146. this.cycleEndDateString = json.data.cycleEndDateString;
  147. this.cycleStartDate = new Date( this.cycleStartDateString );
  148. this.cycleEndDate = new Date( this.cycleEndDateString );
  149. //this.cycleStartDateString = "2016-02-25";
  150. //this.cycleEndDateString = "2016-03-25";
  151. //this.cycleStartDate = new Date( this.cycleStartDateString );
  152. //this.cycleEndDate = new Date( this.cycleEndDateString );
  153. this.isCrossMonth = (this.cycleStartDate.getMonth() != this.cycleEndDate.getMonth());
  154. }.bind(this), null, false )
  155. },
  156. getScheduleData : function( callback ){
  157. var data = {"personList": this.app.getNameFlag(this.userName)};
  158. this.app.orgActions.listUnitSupNestedWithPerson( data, function( json ){
  159. var unitList = json.data;
  160. var sortF = function( a, b ){
  161. return b.level - a.level;
  162. };
  163. unitList.sort( sortF );
  164. var flag = true;
  165. for( var i = 0; i<unitList.length; i++ ){
  166. var unit = unitList[i];
  167. if( unit.level == 1 ){
  168. this.actions.listScheduleByTopUnit( unit.distinguishedName, function( json ){
  169. if( json.data ){
  170. if(callback)callback(json.data);
  171. flag = false;
  172. }
  173. }.bind(this), null, false)
  174. }else{
  175. this.actions.listScheduleByUnit( unit.distinguishedName, function( json ){
  176. if( json.data && json.data.length > 0 ){
  177. if(callback)callback(json.data);
  178. flag = false;
  179. }
  180. }.bind(this), null, false)
  181. }
  182. if( !flag )break;
  183. }
  184. }.bind(this), null, false );
  185. //this.actions.listUnitWithPerson( function( json ){
  186. // debugger;
  187. // var unitList = json.data;
  188. // if( unitList.length > 0 ){
  189. // this.actions.listScheduleByUnit( unitList[0].distinguishedName, function( json ){
  190. // debugger;
  191. // if( json.data && json.data.length > 0 ){
  192. // if(callback)callback(json.data);
  193. // }else{
  194. // this.actions.listScheduleByTopUnit( json.data[0].topUnit, function( json ){
  195. // debugger;
  196. // if(callback)callback(json.data);
  197. // }.bind(this))
  198. // }
  199. // }.bind(this))
  200. // }else{
  201. // if(callback)callback();
  202. // }
  203. //}.bind(this), null, data, false)
  204. },
  205. showSchedule: function( ){
  206. if( this.scheduleNode ){
  207. this.scheduleNode.setStyle("display","block");
  208. this.scheduleNode.position({
  209. relativeTo: this.titleScheduleIconNode,
  210. position: 'bottomLeft',
  211. edge: 'upperCenter',
  212. offset:{
  213. x : -60,
  214. y : 0
  215. }
  216. });
  217. }else{
  218. this.getScheduleData(function( data ){
  219. if( !data || data.length == 0 ){
  220. this.app.notice( this.lp.unfindSchedule,"error");
  221. }else{
  222. this.scheduleNode = new Element("div", {"styles": this.css.scheduleNode}).inject(this.node);
  223. this.scheduleNode.position({
  224. relativeTo: this.titleScheduleIconNode,
  225. position: 'bottomLeft',
  226. edge: 'upperCenter',
  227. offset:{
  228. x : -60,
  229. y : 0
  230. }
  231. });
  232. this.scheduleNode.addEvent("mousedown", function(e){e.stopPropagation();});
  233. document.body.addEvent("mousedown", function(){ this.scheduleNode.setStyle("display","none")}.bind(this));
  234. var d = data[0];
  235. var table = new Element("table", {
  236. "width" : "100%", "border" : "0", "cellpadding" : "5", "cellspacing" : "0", "styles" : this.css.filterTable, "class" : "filterTable"
  237. }).inject( this.scheduleNode );
  238. var tr = new Element("tr").inject(table);
  239. new Element("td",{ "text" : this.lp.scheduleTable , "styles" : this.css.scheduleTdHead, "colspan" : "2" }).inject(tr);
  240. var tr = new Element("tr").inject(table);
  241. new Element("td",{ "text" : this.lp.schedule.workTime + ":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  242. new Element("td",{ "text" : d.onDutyTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  243. var tr = new Element("tr").inject(table);
  244. new Element("td",{ "text" : this.lp.schedule.offTime +":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  245. new Element("td",{ "text" : d.offDutyTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  246. var tr = new Element("tr").inject(table);
  247. new Element("td",{ "text" : this.lp.schedule.lateTime + ":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  248. new Element("td",{ "text" : d.lateStartTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  249. var tr = new Element("tr").inject(table);
  250. new Element("td",{ "text" : this.lp.schedule.leaveEarlyTime + ":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  251. new Element("td",{ "text" : d.leaveEarlyStartTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  252. var tr = new Element("tr").inject(table);
  253. new Element("td",{ "text" : this.lp.schedule.absenteeismTime+":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  254. new Element("td",{ "text" : d.absenceStartTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  255. }
  256. }.bind(this))
  257. }
  258. },
  259. reloadContent : function(){
  260. this.calendarArea.empty();
  261. this.statusColorArea.empty();
  262. this.pieChartArea.empty();
  263. this.lineChartArea.empty();
  264. this.loadData();
  265. },
  266. loadContent : function(){
  267. this.loadContentNode();
  268. this.loadData();
  269. this.setNodeScroll();
  270. this.setContentSize();
  271. },
  272. reloadChart : function(){
  273. this.pieChartArea.empty();
  274. this.lineChartArea.empty();
  275. this.loadPieChart();
  276. this.loadLineChart();
  277. },
  278. loadContentNode: function(){
  279. this.elementContentNode = new Element("div.elementContentNode", {
  280. "styles": this.css.elementContentNode
  281. }).inject(this.node);
  282. this.app.addEvent("resize", function(){
  283. this.setContentSize();
  284. this.reloadChart();
  285. }.bind(this));
  286. this.elementContentListNode = new Element("div.elementContentListNode", {
  287. "styles": this.css.elementContentListNode
  288. }).inject(this.elementContentNode);
  289. this.topContentArea = new Element("div.topContentArea",{
  290. "styles" : this.css.topContentArea
  291. }).inject(this.elementContentListNode);
  292. this.calendarArea = new Element("div.calendarArea",{
  293. "styles" : this.css.calendarArea
  294. }).inject(this.topContentArea);
  295. this.statusColorArea = new Element("div.statusColorArea",{
  296. "styles" : this.css.statusColorArea
  297. }).inject(this.topContentArea);
  298. this.pieChartArea = new Element("div.pieChartArea",{
  299. "styles" : this.css.pieChartArea
  300. }).inject(this.topContentArea);
  301. this.middleContentArea = new Element("div.middleContentArea",{
  302. "styles" : this.css.middleContentArea
  303. }).inject(this.elementContentListNode);
  304. this.lineChartArea = new Element("div.lineChartArea",{
  305. "styles" : this.css.lineChartArea
  306. }).inject(this.middleContentArea)
  307. },
  308. loadData : function(){
  309. this.listDetailFilterUser( function( data ){
  310. this.detailData = data || {};
  311. this.anaylyseDetail();
  312. this.loadStatusColorNode();
  313. this.loadPieChart();
  314. this.loadLineChart();
  315. this.loadHolidayData(function(){
  316. this.loadCalendarContent();
  317. //if(!this.titleInforNode)this.loadTitleInforNode();
  318. }.bind(this));
  319. }.bind(this), this.userName, this.year, this.month )
  320. },
  321. loadHolidayData : function( callback ){
  322. if( this.holidayData && this.holidayData[ this.year ] ) {
  323. //this.loadCalendarContent();
  324. if(callback)callback();
  325. }else{
  326. this.listHolidayFilter( function(data){
  327. var dates = {
  328. workdays : [],
  329. holidays : [],
  330. names : []
  331. };
  332. data.each( function(d){
  333. if( !dates.names.contains(d.configName) ){
  334. dates.names.push( d.configName )
  335. }
  336. if( !dates[d.configName] ){
  337. dates[d.configName] = {};
  338. dates[d.configName].holidays = [];
  339. dates[d.configName].workdays = [];
  340. }
  341. if( d.configType == "Holiday" ){
  342. if( d.configDate == this.todayDate ){
  343. this.todayHloidayName = d.configName;
  344. }
  345. dates.holidays.push( d.configDate );
  346. dates[d.configName].holidays.push( d.configDate )
  347. }else{
  348. if( d.configDate == this.todayDate ){
  349. this.todayIsWorkDay = true;
  350. }
  351. dates.workdays.push( d.configDate );
  352. dates[d.configName].workdays.push( d.configDate )
  353. }
  354. });
  355. this.holidayData[this.year] = dates;
  356. if(callback)callback();
  357. }.bind(this), null, this.year)
  358. }
  359. },
  360. loadCalendarContent : function(){
  361. //this.calendarTitle = new Element("div.calendarTitle",{
  362. // "styles" : this.css.calendarTitle,
  363. // "text" : this.lp.index.attendanceCalendar
  364. //}).inject(this.calendarArea)
  365. this.canlendarToolbar = new Element("div.canlendarToolbar",{
  366. "styles" : this.css.canlendarToolbar
  367. }).inject(this.calendarArea);
  368. this.canlendarToolbarText = new Element("div",{
  369. "styles" : this.css.canlendarToolbarText,
  370. "text" : this.lp.index.attendanceCalendar
  371. }).inject(this.canlendarToolbar);
  372. this.calendarDate = this.date.clone();
  373. if( this.isCrossMonth ){
  374. this.calendarRightArrowNode = new Element("div",{
  375. "styles" : this.css.calendarRightArrowNode
  376. }).inject(this.canlendarToolbar);
  377. this.calendarCurrentMonthNode = new Element("div",{
  378. "styles" : this.css.calendarCurrentMonthNode,
  379. "text" : (this.calendarDate.getMonth()+1)+"月"
  380. }).inject(this.canlendarToolbar);
  381. this.calendarLeftArrowNode = new Element("div",{
  382. "styles" : this.css.calendarLeftArrowNode
  383. }).inject(this.canlendarToolbar);
  384. this.calendarLeftArrowNode.addEvents({
  385. //"mouseover": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode_over);}.bind(this),
  386. // "mouseout": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode);}.bind(this),
  387. //"mousedown": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode_down);}.bind(this),
  388. //"mouseup": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode_over);}.bind(this),
  389. "click": function(){this.changeCalendarMonthPrev();}.bind(this)
  390. });
  391. this.calendarRightArrowNode.addEvents({
  392. //"mouseover": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode_over);}.bind(this),
  393. //"mouseout": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode);}.bind(this),
  394. //"mousedown": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode_down);}.bind(this),
  395. //"mouseup": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode_over);}.bind(this),
  396. "click": function(){this.changeCalendarMonthNext();}.bind(this)
  397. });
  398. this.switchCalendarArrow( this.calendarDate );
  399. }
  400. //this.loadHolidayNode();
  401. this.calendarNode = new Element("div.calendarNode",{
  402. "styles" : this.css.calendarNode
  403. }).inject(this.calendarArea);
  404. this.calendar = new MWF.xApplication.Attendance.Calendar(this.calendarNode, this,
  405. {
  406. "holiday" :this.holidayData[this.year],
  407. "detail" :this.detailData,
  408. "eventData" : this.eventData
  409. },
  410. {
  411. date : this.date,
  412. cycleStart : this.cycleStartDate,
  413. cycleEnd : this.cycleEndDate
  414. }
  415. );
  416. this.calendar.load();
  417. },
  418. switchCalendarArrow : function( date ){
  419. var firstDate = new Date( date.getFullYear() , date.getMonth() , 1, 0, 0, 0 );
  420. if( firstDate <= this.cycleStartDate ){
  421. this.calendarLeftArrowNode.setStyles( this.css.calendarLeftArrowNode_disable );
  422. this.calendarLeftDisable = true;
  423. }else{
  424. this.calendarLeftArrowNode.setStyles( this.css.calendarLeftArrowNode );
  425. this.calendarLeftDisable = false;
  426. }
  427. //alert( "firstDate="+firstDate.format("db") + " " +"cycleStartDate="+ this.cycleStartDate.format("db"))
  428. var lastDate = new Date( date.getFullYear(),date.getMonth()+1, 0, 23, 59, 59);
  429. if( lastDate >= this.cycleEndDate ){
  430. this.calendarRightArrowNode.setStyles( this.css.calendarRightArrowNode_disable );
  431. this.calendarRightDisable = true;
  432. }else{
  433. this.calendarRightArrowNode.setStyles( this.css.calendarRightArrowNode );
  434. this.calendarRightDisable = false;
  435. }
  436. },
  437. changeCalendarMonthPrev: function(){
  438. if( this.calendarLeftDisable )return ;
  439. jQuery(this.calendarNode).fullCalendar( 'prev' );
  440. this.calendarDate.decrement("month", 1);
  441. this.calendarCurrentMonthNode.set("text",(this.calendarDate.getMonth()+1)+"月");
  442. this.switchCalendarArrow( this.calendarDate );
  443. },
  444. changeCalendarMonthNext: function(){
  445. if( this.calendarRightDisable )return ;
  446. jQuery(this.calendarNode).fullCalendar( 'next' );
  447. this.calendarDate.increment("month", 1);
  448. this.calendarCurrentMonthNode.set("text",(this.calendarDate.getMonth()+1)+"月");
  449. this.switchCalendarArrow( this.calendarDate );
  450. //this.date.increment("month", 1);
  451. //this.setDate( this.date );
  452. //var text = this.date.format(this.app.lp.dateFormatMonth);
  453. //this.titleTextNode.set("text", text);
  454. //this.reloadContent();
  455. },
  456. listHolidayFilter : function( callback, name,year,month ){
  457. /*{'q_Year':'2016','q_Name':'五一劳动节','q_Month':'03'}*/
  458. var filter = {};
  459. if( name )filter.q_Name = name;
  460. if( year )filter.q_Year = year;
  461. if( month ){
  462. filter.q_Month = month.toString().length == 2 ? month : "0"+month;
  463. }else{
  464. filter.q_Month = "(0)"
  465. }
  466. this.actions.listHolidayFilter( filter, function(json){
  467. if( callback )callback(json.data);
  468. }.bind(this))
  469. },
  470. loadHolidayNode : function() {
  471. this.holidayAreaNode = new Element("div.holidayAreaNode",{
  472. "styles" : this.css.holidayAreaNode
  473. }).inject(this.canlendarToolbar);
  474. this.holidayActionNode = new Element("div",{
  475. "styles" : this.css.holidayActionNode
  476. }).inject(this.holidayAreaNode);
  477. this.holidayActionTextNode = new Element("div",{
  478. "styles" : this.css.holidayActionTextNode,
  479. "text" : this.lp.holiday.holidaySchedule
  480. }).inject(this.holidayActionNode);
  481. this.holidayActionIconNode = new Element("div",{
  482. "styles" : this.css.holidayActionIconNode
  483. }).inject(this.holidayActionNode);
  484. this.holidayActionNode.addEvents({
  485. "mouseover": function(){this.holidayActionIconNode.setStyles(this.css.holidayActionIconNode_over);}.bind(this),
  486. "mouseout": function(){this.holidayActionIconNode.setStyles(this.css.holidayActionIconNode);}.bind(this),
  487. "click" : function( ev ){
  488. this.switchHoliday( ev.target );
  489. ev.stopPropagation();
  490. }.bind(this)
  491. })
  492. },
  493. switchHoliday: function( el ){
  494. var _self = this;
  495. var flag = false;
  496. if(this.holidayListNode ){
  497. if(this.holidayListNode.retrieve("year") == this.year){
  498. flag = true;
  499. }else{
  500. this.holidayListNode.destroy();
  501. }
  502. }
  503. if(flag){
  504. var parentNode = el.getParent();
  505. this.holidayListNode.inject(parentNode);
  506. if( this.holidayListNode.getStyle("display") == "block" ){
  507. this.holidayListNode.setStyle("display","none");
  508. }else{
  509. this.holidayListNode.setStyle("display","block");
  510. }
  511. }else{
  512. var holidays = this.holidayData[this.year];
  513. var holidayListNode = this.holidayListNode = new Element("div",{
  514. "styles" : this.css.holidayListNode
  515. });
  516. this.holidayListNode.store("year",this.year);
  517. this.app.content.addEvent("click",function(){
  518. _self.holidayListNode.setStyle("display","none");
  519. });
  520. holidays.names.each(function( n ){
  521. var holidayNode = new Element("div",{
  522. "text" : n,
  523. "styles" : this.css.holidayNode
  524. }).inject(holidayListNode);
  525. holidayNode.store("holidays", holidays[n].holidays );
  526. holidayNode.store("workdays", holidays[n].workdays );
  527. holidayNode.addEvents({
  528. "mouseover" : function(){
  529. this.setStyles(_self.css.holidayNode_over);
  530. },
  531. "mouseout" : function(){
  532. this.setStyles(_self.css.holidayNode);
  533. },
  534. "click" : function(e){
  535. _self.holidayListNode.setStyle("display","none");
  536. var holidays = this.retrieve("holidays");
  537. var workdays = this.retrieve("workdays");
  538. this.setStyles(_self.css.holidayNode);
  539. _self.changeMonthTo( new Date((holidays || workdays )[0]) );
  540. //jQuery(_self.calendarNode).fullCalendar( 'gotoDate', (holidays || workdays )[0] );
  541. e.stopPropagation();
  542. }
  543. })
  544. }.bind(this));
  545. var parentNode = el.getParent();
  546. this.holidayListNode.inject(parentNode);
  547. }
  548. },
  549. loadStatusColorNode : function(){
  550. this.statusColorTable = new Element("table",{
  551. "styles" : this.css.statusColorTable
  552. }).inject(this.statusColorArea);
  553. for(var status in this.statusColor){
  554. var tr = new Element("tr",{
  555. "styles" : this.css.statusColorTr
  556. }).inject(this.statusColorTable);
  557. var td = new Element("td",{
  558. "styles" : this.css.statusColorTd
  559. }).inject(tr);
  560. td.setStyle("background-color",this.statusColor[status]);
  561. var tr = new Element("tr",{
  562. "styles" : this.css.statusTextTr
  563. }).inject(this.statusColorTable);
  564. var td = new Element("td",{
  565. "styles" : this.css.statusTextTd,
  566. "text" : this.lp[status] +this.totalData[status]+"天" + ( this.rateData[status] ? "("+this.rateData[status]+")" : "" )
  567. }).inject(tr)
  568. }
  569. },
  570. loadPieChart : function(){
  571. //this.pieChartTitle = new Element("div.pieChartTitle",{
  572. // "styles" : this.css.pieChartTitle,
  573. // "text" : this.lp.index.pieChart
  574. //}).inject(this.pieChartArea)
  575. this.pieChartNode = new Element("div.pieChartNode",{
  576. "styles" : this.css.pieChartNode
  577. }).inject(this.pieChartArea);
  578. this.pieChart = new MWF.xApplication.Attendance.Echarts(this.pieChartNode, this, this.totalData, this.css);
  579. this.pieChart.load();
  580. },
  581. loadLineChart : function(){
  582. //this.lineChartTitle = new Element("div.lineChartTitle",{
  583. // "styles" : this.css.lineChartTitle,
  584. // "text" : this.lp.index.lineChart
  585. //}).inject(this.lineChartArea)
  586. this.lineChartNode = new Element("div.lineChartNode",{
  587. "styles" : this.css.lineChartNode
  588. }).inject(this.lineChartArea);
  589. //this.lineChart = new MWF.xApplication.Attendance.Echarts(this.lineChartNode, this.app, this.actions, this.css, {"type":"line"});
  590. //this.lineChart.load();
  591. this.lineChart = new MWF.xApplication.Attendance.Echarts(this.lineChartNode, this, this.detailData, {
  592. "type":"line",
  593. "date":this.date,
  594. "cycleStart" : new Date( this.cycleStartDate.getFullYear(), this.cycleStartDate.getMonth(), this.cycleStartDate.getDate() ),
  595. "cycleEnd" : new Date( this.cycleEndDate.getFullYear(), this.cycleEndDate.getMonth(), this.cycleEndDate.getDate() )
  596. });
  597. this.lineChart.load();
  598. },
  599. listDetailFilterUser :function( callback, name, year, month ){
  600. //{'q_empName':'林玲','q_year':'2016','q_month':'03'}
  601. var filter = {};
  602. if( name )filter.q_empName = name;
  603. if( year )filter.cycleYear = year;
  604. if( month )filter.cycleMonth = month.toString().length == 2 ? month : "0"+month;
  605. this.actions.listDetailFilterUser( filter, function(json){
  606. var data = json.data || [];
  607. data.sort( function( a, b ){
  608. return parseInt( a.recordDateString.replace(/-/g,"") ) - parseInt( b.recordDateString.replace(/-/g,"") );
  609. //return a.recordDateString - b.recordDateString
  610. });
  611. if( callback )callback(data);
  612. }.bind(this))
  613. },
  614. setContentSize: function(){
  615. var toolbarSize = this.toolbarNode ? this.toolbarNode.getSize() : {"x":0,"y":0};
  616. var titlebarSize = this.titleNode ? this.titleNode.getSize() : {"x":0,"y":0};
  617. var nodeSize = this.node.getSize();
  618. var pt = this.elementContentNode.getStyle("padding-top").toFloat();
  619. var pb = this.elementContentNode.getStyle("padding-bottom").toFloat();
  620. //var filterSize = this.filterNode.getSize();
  621. var filterConditionSize = this.filterConditionNode ? this.filterConditionNode.getSize() : {"x":0,"y":0};
  622. var height = nodeSize.y-toolbarSize.y-pt-pb-filterConditionSize.y-titlebarSize.y;
  623. this.elementContentNode.setStyle("height", ""+height+"px");
  624. },
  625. setNodeScroll: function(){
  626. var _self = this;
  627. MWF.require("MWF.widget.ScrollBar", function(){
  628. new MWF.widget.ScrollBar(this.elementContentNode, {
  629. "indent": false,"style":"xApp_TaskList", "where": "before", "distance": 30, "friction": 4, "axis": {"x": false, "y": true},
  630. "onScroll": function(y){
  631. }
  632. });
  633. }.bind(this));
  634. },
  635. anaylyseDetail : function(){
  636. var events = [];
  637. var totals = {
  638. levelAsked : 0,
  639. noSign : 0,
  640. late : 0,
  641. appealSuccess : 0,
  642. //leaveEarly : 0,
  643. //lackOfTime : 0,
  644. abNormalDuty : 0,
  645. normal : 0
  646. };
  647. this.detailData.each( function( d ){
  648. if( this.isAskForLevel(d,"am") ){
  649. events.push( { text:this.lp.levelAsked, start: d.recordDateString, backgroundColor :this.statusColor.levelAsked } );
  650. totals.levelAsked = totals.levelAsked + 0.5
  651. }else if( this.isAppealSuccess(d,"am")){
  652. events.push( { text: this.lp.appealSuccess, start: d.recordDateString, backgroundColor :this.statusColor.appealSuccess } );
  653. totals.appealSuccess = totals.appealSuccess + 0.5
  654. }else if( this.isAbsent(d,"am")){
  655. events.push( { text: this.lp.noSign, start: d.recordDateString, backgroundColor :this.statusColor.noSign } );
  656. totals.noSign = totals.noSign + 0.5
  657. }else if( this.isLate(d,"am")) {
  658. events.push({
  659. text: this.lp.late + ',' + this.lp.signTime + ':' + d.onDutyTime, //+ "迟到时长" + d.lateTimeDuration,
  660. start: d.recordDateString,
  661. backgroundColor: this.statusColor.late
  662. });
  663. totals.late = totals.late + 0.5
  664. }else if( this.isLackOfTime(d,"am")){
  665. events.push( { text: this.lp.lackOfTime + ',' + this.lp.signTime + ':' + d.onDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.lackOfTime } );
  666. totals.lackOfTime = totals.lackOfTime + 0.5
  667. }else if( this.isAbnormalDuty(d,"am")){
  668. events.push( { text: this.lp.abNormalDuty + ',' + this.lp.signTime + ':' + d.onDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.abNormalDuty } );
  669. totals.abNormalDuty = totals.abNormalDuty + 0.5
  670. }else if( this.isHoliday(d, "am") ){
  671. return;
  672. }else if( this.isWeekend(d, "am") ){
  673. return;
  674. }else{
  675. totals.normal = totals.normal + 0.5;
  676. events.push( { text: this.lp.normal + ','+this.lp.signTime +':' + d.onDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.normal } )
  677. }
  678. if( this.isAskForLevel(d,"pm") ){
  679. totals.levelAsked = totals.levelAsked + 0.5;
  680. events.push( { text: this.lp.index.levelAsked, start: d.recordDateString, backgroundColor :this.statusColor.levelAsked } )
  681. }else if( this.isAppealSuccess(d,"pm")){
  682. events.push( { text: this.lp.appealSuccess, start: d.recordDateString, backgroundColor :this.statusColor.appealSuccess } );
  683. totals.appealSuccess = totals.appealSuccess + 0.5;
  684. //}else if( this.isLeaveEarlier(d,"pm")) {
  685. // events.push({
  686. // text: '早退,打卡时间:' + d.offDutyTime, // + "早退时长" + d.leaveEarlierTimeDuration,
  687. // start: d.recordDateString,
  688. // backgroundColor: this.statusColor.leaveEarly
  689. // })
  690. // totals.leaveEarly = totals.leaveEarly + 0.5
  691. }else if( this.isAbsent(d,"pm")){
  692. totals.noSign = totals.noSign + 0.5;
  693. events.push( { text: this.lp.index.absent, start: d.recordDateString, backgroundColor :this.statusColor.noSign } )
  694. /* }else if( this.isLackOfTime(d,"pm")){
  695. events.push( { text: this.lp.lackOfTime + ',' + this.lp.signTime + ':' + d.offDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.lackOfTime } );
  696. totals.lackOfTime = totals.lackOfTime + 0.5*/
  697. }else if( this.isAbnormalDuty(d,"pm")){
  698. events.push( { text: this.lp.abNormalDuty + ',' + this.lp.signTime + ':' + d.offDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.abNormalDuty } );
  699. totals.abNormalDuty = totals.abNormalDuty + 0.5
  700. }else if( this.isHoliday(d, "pm") ){
  701. return;
  702. }else if( this.isWeekend(d, "pm") ){
  703. return;
  704. }else{
  705. if(!!d.offDutyTime){
  706. totals.normal = totals.normal + 0.5;
  707. events.push( { text: this.lp.index.offDutyTime+ d.offDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.normal } )
  708. }
  709. }
  710. }.bind(this) );
  711. this.totalData = totals;
  712. var total = 0;
  713. for( var n in totals ){
  714. total += totals[n];
  715. }
  716. this.rateData = {
  717. levelAsked : (!totals.levelAsked || !total) ? 0 : ((totals.levelAsked/total * 100).toFixed(2) + "%"),
  718. noSign : (!totals.noSign || !total) ? 0 : ((totals.noSign/total * 100).toFixed(2) + "%"),
  719. late : (!totals.late || !total) ? 0 : ((totals.late/total * 100).toFixed(2) + "%"),
  720. //leaveEarly : (!totals.leaveEarly || !total) ? 0 : ((totals.leaveEarly/total* 100).toFixed(2) + "%"),
  721. //lackOfTime : (!totals.lackOfTime || !total) ? 0 : ((totals.lackOfTime/total * 100).toFixed(2) + "%"),
  722. abNormalDuty : (!totals.abNormalDuty || !total) ? 0 : ((totals.abNormalDuty/total* 100).toFixed(2) + "%"),
  723. normal : (!totals.normal || !total) ? 0 : ((totals.normal/total* 100).toFixed(2) + "%"),
  724. appealSuccess : (!totals.appealSuccess || !total) ? 0 : ((totals.appealSuccess/total * 100).toFixed(2) + "%")
  725. };
  726. this.eventData = events;
  727. },
  728. isAppealSuccess : function( d, ap ){
  729. return d.appealStatus == 9
  730. },
  731. isAskForLevel : function( d , ap ){
  732. if( ap == "am" ){
  733. return d.isGetSelfHolidays && ( d.selfHolidayDayTime == "全天" || d.selfHolidayDayTime == "上午" )
  734. }else{
  735. return d.isGetSelfHolidays && ( d.selfHolidayDayTime == "全天" || d.selfHolidayDayTime == "下午" )
  736. }
  737. },
  738. isAbsent : function(d , ap ){
  739. if( ap == "am" ){
  740. return d.isAbsent && ( d.absentDayTime == "全天" || d.absentDayTime == "上午" )
  741. }else{
  742. return d.isAbsent && ( d.absentDayTime == "全天" || d.absentDayTime == "下午" )
  743. }
  744. },
  745. isLate : function(d, ap ){
  746. return d.isLate
  747. },
  748. //isLeaveEarlier : function( d ){
  749. // return d.isLeaveEarlier
  750. //},
  751. isWorkOvertime : function( d, ap){
  752. return d.isWorkOvertime
  753. },
  754. isLackOfTime : function( d, ap){
  755. return d.isLackOfTime
  756. },
  757. isAbnormalDuty : function(d , ap ){
  758. if( ap == "am" ){
  759. return d.isAbnormalDuty && ( d.abnormalDutyDayTime == "全天" || d.abnormalDutyDayTime == "上午" )
  760. }else{
  761. return d.isAbnormalDuty && ( d.abnormalDutyDayTime == "全天" || d.abnormalDutyDayTime == "下午" )
  762. }
  763. },
  764. isHoliday : function( d, ap ){
  765. if( ap == "am" ){
  766. return d.isHoliday && (!d.onDutyTime || d.onDutyTime == "")
  767. }else{
  768. return d.isHoliday && (!d.offDutyTime || d.offDutyTime == "")
  769. }
  770. },
  771. isWeekend : function( d, ap ){
  772. if(d.isWorkday )return false;
  773. if( ap == "am" ){
  774. return d.isWeekend && (!d.onDutyTime || d.onDutyTime == "")
  775. }else{
  776. return d.isWeekend && (!d.offDutyTime || d.offDutyTime == "")
  777. }
  778. },
  779. toFixed: function (num, d) {
  780. var s=num+"";
  781. if(!d)d=0;
  782. if(s.indexOf(".")==-1)s+=".";
  783. s+=new Array(d+1).join("0");
  784. if(new RegExp("^(-|\\+)?(\\d+(\\.\\d{0,"+(d+1)+"})?)\\d*$").test(s)){
  785. var s="0"+RegExp.$2,pm=RegExp.$1,a=RegExp.$3.length,b=true;
  786. if(a==d+2){
  787. a=s.match(/\d/g);
  788. if(parseInt(a[a.length-1])>4){
  789. for(var i=a.length-2;i>=0;i--){
  790. a[i]=parseInt(a[i])+1;
  791. if(a[i]==10){
  792. a[i]=0;
  793. b=i!=1;
  794. }else break;
  795. }
  796. }
  797. s=a.join("").replace(new RegExp("(\\d+)(\\d{"+d+"})\\d$"),"$1.$2");
  798. }if(b)s=s.substr(1);
  799. return (pm+s).replace(/\.$/,"");
  800. }return this+"";
  801. }
  802. });