MyIndex.js 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  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. debugger;
  164. unitList.sort( sortF );
  165. var flag = true;
  166. for( var i = 0; i<unitList.length; i++ ){
  167. var unit = unitList[i];
  168. if( unit.level == 1 ){
  169. this.actions.listScheduleByTopUnit( unit.distinguishedName, function( json ){
  170. if( json.data ){
  171. if(callback)callback(json.data);
  172. flag = false;
  173. }
  174. }.bind(this), null, false)
  175. }else{
  176. this.actions.listScheduleByUnit( unit.distinguishedName, function( json ){
  177. if( json.data && json.data.length > 0 ){
  178. if(callback)callback(json.data);
  179. flag = false;
  180. }
  181. }.bind(this), null, false)
  182. }
  183. if( !flag )break;
  184. }
  185. }.bind(this), null, false );
  186. //this.actions.listUnitWithPerson( function( json ){
  187. // debugger;
  188. // var unitList = json.data;
  189. // if( unitList.length > 0 ){
  190. // this.actions.listScheduleByUnit( unitList[0].distinguishedName, function( json ){
  191. // debugger;
  192. // if( json.data && json.data.length > 0 ){
  193. // if(callback)callback(json.data);
  194. // }else{
  195. // this.actions.listScheduleByTopUnit( json.data[0].topUnit, function( json ){
  196. // debugger;
  197. // if(callback)callback(json.data);
  198. // }.bind(this))
  199. // }
  200. // }.bind(this))
  201. // }else{
  202. // if(callback)callback();
  203. // }
  204. //}.bind(this), null, data, false)
  205. },
  206. showSchedule: function( ){
  207. if( this.scheduleNode ){
  208. this.scheduleNode.setStyle("display","block");
  209. this.scheduleNode.position({
  210. relativeTo: this.titleScheduleIconNode,
  211. position: 'bottomLeft',
  212. edge: 'upperCenter',
  213. offset:{
  214. x : -60,
  215. y : 0
  216. }
  217. });
  218. }else{
  219. this.getScheduleData(function( data ){
  220. if( !data || data.length == 0 ){
  221. this.app.notice( this.lp.unfindSchedule,"error");
  222. }else{
  223. this.scheduleNode = new Element("div", {"styles": this.css.scheduleNode}).inject(this.node);
  224. this.scheduleNode.position({
  225. relativeTo: this.titleScheduleIconNode,
  226. position: 'bottomLeft',
  227. edge: 'upperCenter',
  228. offset:{
  229. x : -60,
  230. y : 0
  231. }
  232. });
  233. this.scheduleNode.addEvent("mousedown", function(e){e.stopPropagation();});
  234. document.body.addEvent("mousedown", function(){ this.scheduleNode.setStyle("display","none")}.bind(this));
  235. var d = data[0];
  236. var table = new Element("table", {
  237. "width" : "100%", "border" : "0", "cellpadding" : "5", "cellspacing" : "0", "styles" : this.css.filterTable, "class" : "filterTable"
  238. }).inject( this.scheduleNode );
  239. var tr = new Element("tr").inject(table);
  240. new Element("td",{ "text" : this.lp.scheduleTable , "styles" : this.css.scheduleTdHead, "colspan" : "2" }).inject(tr);
  241. var tr = new Element("tr").inject(table);
  242. new Element("td",{ "text" : this.lp.schedule.workTime + ":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  243. new Element("td",{ "text" : d.onDutyTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  244. var tr = new Element("tr").inject(table);
  245. new Element("td",{ "text" : this.lp.schedule.offTime +":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  246. new Element("td",{ "text" : d.offDutyTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  247. var tr = new Element("tr").inject(table);
  248. new Element("td",{ "text" : this.lp.schedule.lateTime + ":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  249. new Element("td",{ "text" : d.lateStartTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  250. var tr = new Element("tr").inject(table);
  251. new Element("td",{ "text" : this.lp.schedule.leaveEarlyTime + ":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  252. new Element("td",{ "text" : d.leaveEarlyStartTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  253. var tr = new Element("tr").inject(table);
  254. new Element("td",{ "text" : this.lp.schedule.absenteeismTime+":" , "styles" : this.css.scheduleTdTitle }).inject(tr);
  255. new Element("td",{ "text" : d.absenceStartTime || "" , "styles" : this.css.scheduleTdValue }).inject(tr);
  256. }
  257. }.bind(this))
  258. }
  259. },
  260. reloadContent : function(){
  261. this.calendarArea.empty();
  262. this.statusColorArea.empty();
  263. this.pieChartArea.empty();
  264. this.lineChartArea.empty();
  265. this.loadData();
  266. },
  267. loadContent : function(){
  268. this.loadContentNode();
  269. this.loadData();
  270. this.setNodeScroll();
  271. this.setContentSize();
  272. },
  273. reloadChart : function(){
  274. this.pieChartArea.empty();
  275. this.lineChartArea.empty();
  276. this.loadPieChart();
  277. this.loadLineChart();
  278. },
  279. loadContentNode: function(){
  280. this.elementContentNode = new Element("div.elementContentNode", {
  281. "styles": this.css.elementContentNode
  282. }).inject(this.node);
  283. this.app.addEvent("resize", function(){
  284. this.setContentSize();
  285. this.reloadChart();
  286. }.bind(this));
  287. this.elementContentListNode = new Element("div.elementContentListNode", {
  288. "styles": this.css.elementContentListNode
  289. }).inject(this.elementContentNode);
  290. this.topContentArea = new Element("div.topContentArea",{
  291. "styles" : this.css.topContentArea
  292. }).inject(this.elementContentListNode);
  293. this.calendarArea = new Element("div.calendarArea",{
  294. "styles" : this.css.calendarArea
  295. }).inject(this.topContentArea);
  296. this.statusColorArea = new Element("div.statusColorArea",{
  297. "styles" : this.css.statusColorArea
  298. }).inject(this.topContentArea);
  299. this.pieChartArea = new Element("div.pieChartArea",{
  300. "styles" : this.css.pieChartArea
  301. }).inject(this.topContentArea);
  302. this.middleContentArea = new Element("div.middleContentArea",{
  303. "styles" : this.css.middleContentArea
  304. }).inject(this.elementContentListNode);
  305. this.lineChartArea = new Element("div.lineChartArea",{
  306. "styles" : this.css.lineChartArea
  307. }).inject(this.middleContentArea)
  308. },
  309. loadData : function(){
  310. this.listDetailFilterUser( function( data ){
  311. this.detailData = data || {};
  312. this.anaylyseDetail();
  313. this.loadStatusColorNode();
  314. this.loadPieChart();
  315. this.loadLineChart();
  316. this.loadHolidayData(function(){
  317. this.loadCalendarContent();
  318. //if(!this.titleInforNode)this.loadTitleInforNode();
  319. }.bind(this));
  320. }.bind(this), this.userName, this.year, this.month )
  321. },
  322. loadHolidayData : function( callback ){
  323. if( this.holidayData && this.holidayData[ this.year ] ) {
  324. //this.loadCalendarContent();
  325. if(callback)callback();
  326. }else{
  327. this.listHolidayFilter( function(data){
  328. var dates = {
  329. workdays : [],
  330. holidays : [],
  331. names : []
  332. };
  333. data.each( function(d){
  334. if( !dates.names.contains(d.configName) ){
  335. dates.names.push( d.configName )
  336. }
  337. if( !dates[d.configName] ){
  338. dates[d.configName] = {};
  339. dates[d.configName].holidays = [];
  340. dates[d.configName].workdays = [];
  341. }
  342. if( d.configType == "Holiday" ){
  343. if( d.configDate == this.todayDate ){
  344. this.todayHloidayName = d.configName;
  345. }
  346. dates.holidays.push( d.configDate );
  347. dates[d.configName].holidays.push( d.configDate )
  348. }else{
  349. if( d.configDate == this.todayDate ){
  350. this.todayIsWorkDay = true;
  351. }
  352. dates.workdays.push( d.configDate );
  353. dates[d.configName].workdays.push( d.configDate )
  354. }
  355. });
  356. this.holidayData[this.year] = dates;
  357. if(callback)callback();
  358. }.bind(this), null, this.year)
  359. }
  360. },
  361. loadCalendarContent : function(){
  362. //this.calendarTitle = new Element("div.calendarTitle",{
  363. // "styles" : this.css.calendarTitle,
  364. // "text" : this.lp.index.attendanceCalendar
  365. //}).inject(this.calendarArea)
  366. this.canlendarToolbar = new Element("div.canlendarToolbar",{
  367. "styles" : this.css.canlendarToolbar
  368. }).inject(this.calendarArea);
  369. this.canlendarToolbarText = new Element("div",{
  370. "styles" : this.css.canlendarToolbarText,
  371. "text" : this.lp.index.attendanceCalendar
  372. }).inject(this.canlendarToolbar);
  373. this.calendarDate = this.date.clone();
  374. if( this.isCrossMonth ){
  375. this.calendarRightArrowNode = new Element("div",{
  376. "styles" : this.css.calendarRightArrowNode
  377. }).inject(this.canlendarToolbar);
  378. this.calendarCurrentMonthNode = new Element("div",{
  379. "styles" : this.css.calendarCurrentMonthNode,
  380. "text" : (this.calendarDate.getMonth()+1)+"月"
  381. }).inject(this.canlendarToolbar);
  382. this.calendarLeftArrowNode = new Element("div",{
  383. "styles" : this.css.calendarLeftArrowNode
  384. }).inject(this.canlendarToolbar);
  385. this.calendarLeftArrowNode.addEvents({
  386. //"mouseover": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode_over);}.bind(this),
  387. // "mouseout": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode);}.bind(this),
  388. //"mousedown": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode_down);}.bind(this),
  389. //"mouseup": function(){this.calendarLeftArrowNode.setStyles(this.css.calendarLeftArrowNode_over);}.bind(this),
  390. "click": function(){this.changeCalendarMonthPrev();}.bind(this)
  391. });
  392. this.calendarRightArrowNode.addEvents({
  393. //"mouseover": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode_over);}.bind(this),
  394. //"mouseout": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode);}.bind(this),
  395. //"mousedown": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode_down);}.bind(this),
  396. //"mouseup": function(){this.calendarRightArrowNode.setStyles(this.css.calendarRightArrowNode_over);}.bind(this),
  397. "click": function(){this.changeCalendarMonthNext();}.bind(this)
  398. });
  399. this.switchCalendarArrow( this.calendarDate );
  400. }
  401. //this.loadHolidayNode();
  402. this.calendarNode = new Element("div.calendarNode",{
  403. "styles" : this.css.calendarNode
  404. }).inject(this.calendarArea);
  405. this.calendar = new MWF.xApplication.Attendance.Calendar(this.calendarNode, this,
  406. {
  407. "holiday" :this.holidayData[this.year],
  408. "detail" :this.detailData,
  409. "eventData" : this.eventData
  410. },
  411. {
  412. date : this.date,
  413. cycleStart : this.cycleStartDate,
  414. cycleEnd : this.cycleEndDate
  415. }
  416. );
  417. this.calendar.load();
  418. },
  419. switchCalendarArrow : function( date ){
  420. var firstDate = new Date( date.getFullYear() , date.getMonth() , 1, 0, 0, 0 );
  421. if( firstDate <= this.cycleStartDate ){
  422. this.calendarLeftArrowNode.setStyles( this.css.calendarLeftArrowNode_disable );
  423. this.calendarLeftDisable = true;
  424. }else{
  425. this.calendarLeftArrowNode.setStyles( this.css.calendarLeftArrowNode );
  426. this.calendarLeftDisable = false;
  427. }
  428. //alert( "firstDate="+firstDate.format("db") + " " +"cycleStartDate="+ this.cycleStartDate.format("db"))
  429. var lastDate = new Date( date.getFullYear(),date.getMonth()+1, 0, 23, 59, 59);
  430. if( lastDate >= this.cycleEndDate ){
  431. this.calendarRightArrowNode.setStyles( this.css.calendarRightArrowNode_disable );
  432. this.calendarRightDisable = true;
  433. }else{
  434. this.calendarRightArrowNode.setStyles( this.css.calendarRightArrowNode );
  435. this.calendarRightDisable = false;
  436. }
  437. },
  438. changeCalendarMonthPrev: function(){
  439. if( this.calendarLeftDisable )return ;
  440. jQuery(this.calendarNode).fullCalendar( 'prev' );
  441. this.calendarDate.decrement("month", 1);
  442. this.calendarCurrentMonthNode.set("text",(this.calendarDate.getMonth()+1)+"月");
  443. this.switchCalendarArrow( this.calendarDate );
  444. },
  445. changeCalendarMonthNext: function(){
  446. if( this.calendarRightDisable )return ;
  447. jQuery(this.calendarNode).fullCalendar( 'next' );
  448. this.calendarDate.increment("month", 1);
  449. this.calendarCurrentMonthNode.set("text",(this.calendarDate.getMonth()+1)+"月");
  450. this.switchCalendarArrow( this.calendarDate );
  451. //this.date.increment("month", 1);
  452. //this.setDate( this.date );
  453. //var text = this.date.format(this.app.lp.dateFormatMonth);
  454. //this.titleTextNode.set("text", text);
  455. //this.reloadContent();
  456. },
  457. listHolidayFilter : function( callback, name,year,month ){
  458. /*{'q_Year':'2016','q_Name':'五一劳动节','q_Month':'03'}*/
  459. var filter = {};
  460. if( name )filter.q_Name = name;
  461. if( year )filter.q_Year = year;
  462. if( month ){
  463. filter.q_Month = month.toString().length == 2 ? month : "0"+month;
  464. }else{
  465. filter.q_Month = "(0)"
  466. }
  467. this.actions.listHolidayFilter( filter, function(json){
  468. if( callback )callback(json.data);
  469. }.bind(this))
  470. },
  471. loadHolidayNode : function() {
  472. this.holidayAreaNode = new Element("div.holidayAreaNode",{
  473. "styles" : this.css.holidayAreaNode
  474. }).inject(this.canlendarToolbar);
  475. this.holidayActionNode = new Element("div",{
  476. "styles" : this.css.holidayActionNode
  477. }).inject(this.holidayAreaNode);
  478. this.holidayActionTextNode = new Element("div",{
  479. "styles" : this.css.holidayActionTextNode,
  480. "text" : this.lp.holiday.holidaySchedule
  481. }).inject(this.holidayActionNode);
  482. this.holidayActionIconNode = new Element("div",{
  483. "styles" : this.css.holidayActionIconNode
  484. }).inject(this.holidayActionNode);
  485. this.holidayActionNode.addEvents({
  486. "mouseover": function(){this.holidayActionIconNode.setStyles(this.css.holidayActionIconNode_over);}.bind(this),
  487. "mouseout": function(){this.holidayActionIconNode.setStyles(this.css.holidayActionIconNode);}.bind(this),
  488. "click" : function( ev ){
  489. this.switchHoliday( ev.target );
  490. ev.stopPropagation();
  491. }.bind(this)
  492. })
  493. },
  494. switchHoliday: function( el ){
  495. var _self = this;
  496. var flag = false;
  497. if(this.holidayListNode ){
  498. if(this.holidayListNode.retrieve("year") == this.year){
  499. flag = true;
  500. }else{
  501. this.holidayListNode.destroy();
  502. }
  503. }
  504. if(flag){
  505. var parentNode = el.getParent();
  506. this.holidayListNode.inject(parentNode);
  507. if( this.holidayListNode.getStyle("display") == "block" ){
  508. this.holidayListNode.setStyle("display","none");
  509. }else{
  510. this.holidayListNode.setStyle("display","block");
  511. }
  512. }else{
  513. var holidays = this.holidayData[this.year];
  514. var holidayListNode = this.holidayListNode = new Element("div",{
  515. "styles" : this.css.holidayListNode
  516. });
  517. this.holidayListNode.store("year",this.year);
  518. this.app.content.addEvent("click",function(){
  519. _self.holidayListNode.setStyle("display","none");
  520. });
  521. holidays.names.each(function( n ){
  522. var holidayNode = new Element("div",{
  523. "text" : n,
  524. "styles" : this.css.holidayNode
  525. }).inject(holidayListNode);
  526. holidayNode.store("holidays", holidays[n].holidays );
  527. holidayNode.store("workdays", holidays[n].workdays );
  528. holidayNode.addEvents({
  529. "mouseover" : function(){
  530. this.setStyles(_self.css.holidayNode_over);
  531. },
  532. "mouseout" : function(){
  533. this.setStyles(_self.css.holidayNode);
  534. },
  535. "click" : function(e){
  536. _self.holidayListNode.setStyle("display","none");
  537. var holidays = this.retrieve("holidays");
  538. var workdays = this.retrieve("workdays");
  539. this.setStyles(_self.css.holidayNode);
  540. _self.changeMonthTo( new Date((holidays || workdays )[0]) );
  541. //jQuery(_self.calendarNode).fullCalendar( 'gotoDate', (holidays || workdays )[0] );
  542. e.stopPropagation();
  543. }
  544. })
  545. }.bind(this));
  546. var parentNode = el.getParent();
  547. this.holidayListNode.inject(parentNode);
  548. }
  549. },
  550. loadStatusColorNode : function(){
  551. this.statusColorTable = new Element("table",{
  552. "styles" : this.css.statusColorTable
  553. }).inject(this.statusColorArea);
  554. for(var status in this.statusColor){
  555. var tr = new Element("tr",{
  556. "styles" : this.css.statusColorTr
  557. }).inject(this.statusColorTable);
  558. var td = new Element("td",{
  559. "styles" : this.css.statusColorTd
  560. }).inject(tr);
  561. td.setStyle("background-color",this.statusColor[status]);
  562. var tr = new Element("tr",{
  563. "styles" : this.css.statusTextTr
  564. }).inject(this.statusColorTable);
  565. var td = new Element("td",{
  566. "styles" : this.css.statusTextTd,
  567. "text" : this.lp[status] +this.totalData[status]+"天" + ( this.rateData[status] ? "("+this.rateData[status]+")" : "" )
  568. }).inject(tr)
  569. }
  570. },
  571. loadPieChart : function(){
  572. //this.pieChartTitle = new Element("div.pieChartTitle",{
  573. // "styles" : this.css.pieChartTitle,
  574. // "text" : this.lp.index.pieChart
  575. //}).inject(this.pieChartArea)
  576. this.pieChartNode = new Element("div.pieChartNode",{
  577. "styles" : this.css.pieChartNode
  578. }).inject(this.pieChartArea);
  579. this.pieChart = new MWF.xApplication.Attendance.Echarts(this.pieChartNode, this, this.totalData, this.css);
  580. this.pieChart.load();
  581. },
  582. loadLineChart : function(){
  583. //this.lineChartTitle = new Element("div.lineChartTitle",{
  584. // "styles" : this.css.lineChartTitle,
  585. // "text" : this.lp.index.lineChart
  586. //}).inject(this.lineChartArea)
  587. this.lineChartNode = new Element("div.lineChartNode",{
  588. "styles" : this.css.lineChartNode
  589. }).inject(this.lineChartArea);
  590. //this.lineChart = new MWF.xApplication.Attendance.Echarts(this.lineChartNode, this.app, this.actions, this.css, {"type":"line"});
  591. //this.lineChart.load();
  592. this.lineChart = new MWF.xApplication.Attendance.Echarts(this.lineChartNode, this, this.detailData, {
  593. "type":"line",
  594. "date":this.date,
  595. "cycleStart" : new Date( this.cycleStartDate.getFullYear(), this.cycleStartDate.getMonth(), this.cycleStartDate.getDate() ),
  596. "cycleEnd" : new Date( this.cycleEndDate.getFullYear(), this.cycleEndDate.getMonth(), this.cycleEndDate.getDate() )
  597. });
  598. this.lineChart.load();
  599. },
  600. listDetailFilterUser :function( callback, name, year, month ){
  601. //{'q_empName':'林玲','q_year':'2016','q_month':'03'}
  602. var filter = {};
  603. if( name )filter.q_empName = name;
  604. if( year )filter.cycleYear = year;
  605. if( month )filter.cycleMonth = month.toString().length == 2 ? month : "0"+month;
  606. this.actions.listDetailFilterUser( filter, function(json){
  607. var data = json.data || [];
  608. data.sort( function( a, b ){
  609. return parseInt( a.recordDateString.replace(/-/g,"") ) - parseInt( b.recordDateString.replace(/-/g,"") );
  610. //return a.recordDateString - b.recordDateString
  611. });
  612. if( callback )callback(data);
  613. }.bind(this))
  614. },
  615. setContentSize: function(){
  616. var toolbarSize = this.toolbarNode ? this.toolbarNode.getSize() : {"x":0,"y":0};
  617. var titlebarSize = this.titleNode ? this.titleNode.getSize() : {"x":0,"y":0};
  618. var nodeSize = this.node.getSize();
  619. var pt = this.elementContentNode.getStyle("padding-top").toFloat();
  620. var pb = this.elementContentNode.getStyle("padding-bottom").toFloat();
  621. //var filterSize = this.filterNode.getSize();
  622. var filterConditionSize = this.filterConditionNode ? this.filterConditionNode.getSize() : {"x":0,"y":0};
  623. var height = nodeSize.y-toolbarSize.y-pt-pb-filterConditionSize.y-titlebarSize.y;
  624. this.elementContentNode.setStyle("height", ""+height+"px");
  625. },
  626. setNodeScroll: function(){
  627. var _self = this;
  628. MWF.require("MWF.widget.ScrollBar", function(){
  629. new MWF.widget.ScrollBar(this.elementContentNode, {
  630. "indent": false,"style":"xApp_TaskList", "where": "before", "distance": 30, "friction": 4, "axis": {"x": false, "y": true},
  631. "onScroll": function(y){
  632. }
  633. });
  634. }.bind(this));
  635. },
  636. anaylyseDetail : function(){
  637. var events = [];
  638. var totals = {
  639. levelAsked : 0,
  640. noSign : 0,
  641. late : 0,
  642. appealSuccess : 0,
  643. //leaveEarly : 0,
  644. lackOfTime : 0,
  645. abNormalDuty : 0,
  646. normal : 0
  647. };
  648. this.detailData.each( function( d ){
  649. if( this.isAskForLevel(d,"am") ){
  650. events.push( { text:this.lp.levelAsked, start: d.recordDateString, backgroundColor :this.statusColor.levelAsked } );
  651. totals.levelAsked = totals.levelAsked + 0.5
  652. }else if( this.isAppealSuccess(d,"am")){
  653. events.push( { text: this.lp.appealSuccess, start: d.recordDateString, backgroundColor :this.statusColor.appealSuccess } );
  654. totals.appealSuccess = totals.appealSuccess + 0.5
  655. }else if( this.isAbsent(d,"am")){
  656. events.push( { text: this.lp.noSign, start: d.recordDateString, backgroundColor :this.statusColor.noSign } );
  657. totals.noSign = totals.noSign + 0.5
  658. }else if( this.isLate(d,"am")) {
  659. events.push({
  660. text: this.lp.late + ',' + this.lp.signTime + ':' + d.onDutyTime, //+ "迟到时长" + d.lateTimeDuration,
  661. start: d.recordDateString,
  662. backgroundColor: this.statusColor.late
  663. });
  664. totals.late = totals.late + 0.5
  665. }else if( this.isLackOfTime(d,"am")){
  666. events.push( { text: this.lp.lackOfTime + ',' + this.lp.signTime + ':' + d.onDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.lackOfTime } );
  667. totals.lackOfTime = totals.lackOfTime + 0.5
  668. }else if( this.isAbnormalDuty(d,"am")){
  669. events.push( { text: this.lp.abNormalDuty + ',' + this.lp.signTime + ':' + d.onDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.abNormalDuty } );
  670. totals.abNormalDuty = totals.abNormalDuty + 0.5
  671. }else if( this.isHoliday(d, "am") ){
  672. return;
  673. }else if( this.isWeekend(d, "am") ){
  674. return;
  675. }else{
  676. totals.normal = totals.normal + 0.5;
  677. events.push( { text: this.lp.normal + ','+this.lp.signTime +':' + d.onDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.normal } )
  678. }
  679. if( this.isAskForLevel(d,"pm") ){
  680. totals.levelAsked = totals.levelAsked + 0.5;
  681. events.push( { text: '请假或外出报备', start: d.recordDateString, backgroundColor :this.statusColor.levelAsked } )
  682. }else if( this.isAppealSuccess(d,"pm")){
  683. events.push( { text: this.lp.appealSuccess, start: d.recordDateString, backgroundColor :this.statusColor.appealSuccess } );
  684. totals.appealSuccess = totals.appealSuccess + 0.5;
  685. //}else if( this.isLeaveEarlier(d,"pm")) {
  686. // events.push({
  687. // text: '早退,打卡时间:' + d.offDutyTime, // + "早退时长" + d.leaveEarlierTimeDuration,
  688. // start: d.recordDateString,
  689. // backgroundColor: this.statusColor.leaveEarly
  690. // })
  691. // totals.leaveEarly = totals.leaveEarly + 0.5
  692. }else if( this.isAbsent(d,"pm")){
  693. totals.noSign = totals.noSign + 0.5;
  694. events.push( { text: '缺勤', start: d.recordDateString, backgroundColor :this.statusColor.noSign } )
  695. }else if( this.isLackOfTime(d,"pm")){
  696. events.push( { text: this.lp.lackOfTime + ',' + this.lp.signTime + ':' + d.offDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.lackOfTime } );
  697. totals.lackOfTime = totals.lackOfTime + 0.5
  698. }else if( this.isAbnormalDuty(d,"pm")){
  699. events.push( { text: this.lp.abNormalDuty + ',' + this.lp.signTime + ':' + d.offDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.abNormalDuty } );
  700. totals.abNormalDuty = totals.abNormalDuty + 0.5
  701. }else if( this.isHoliday(d, "pm") ){
  702. return;
  703. }else if( this.isWeekend(d, "pm") ){
  704. return;
  705. }else{
  706. totals.normal = totals.normal + 0.5;
  707. events.push( { text: '出勤,打卡时间:'+ d.offDutyTime, start: d.recordDateString, backgroundColor :this.statusColor.normal } )
  708. }
  709. }.bind(this) );
  710. this.totalData = totals;
  711. var total = 0;
  712. for( var n in totals ){
  713. total += totals[n];
  714. }
  715. this.rateData = {
  716. levelAsked : (!totals.levelAsked || !total) ? 0 : ((totals.levelAsked/total * 100).toFixed(2) + "%"),
  717. noSign : (!totals.noSign || !total) ? 0 : ((totals.noSign/total * 100).toFixed(2) + "%"),
  718. late : (!totals.late || !total) ? 0 : ((totals.late/total * 100).toFixed(2) + "%"),
  719. //leaveEarly : (!totals.leaveEarly || !total) ? 0 : ((totals.leaveEarly/total* 100).toFixed(2) + "%"),
  720. lackOfTime : (!totals.lackOfTime || !total) ? 0 : ((totals.lackOfTime/total * 100).toFixed(2) + "%"),
  721. abNormalDuty : (!totals.abNormalDuty || !total) ? 0 : ((totals.abNormalDuty/total* 100).toFixed(2) + "%"),
  722. normal : (!totals.normal || !total) ? 0 : ((totals.normal/total* 100).toFixed(2) + "%"),
  723. appealSuccess : (!totals.appealSuccess || !total) ? 0 : ((totals.appealSuccess/total * 100).toFixed(2) + "%")
  724. };
  725. this.eventData = events;
  726. },
  727. isAppealSuccess : function( d, ap ){
  728. return d.appealStatus == 9
  729. },
  730. isAskForLevel : function( d , ap ){
  731. if( ap == "am" ){
  732. return d.isGetSelfHolidays && ( d.selfHolidayDayTime == "全天" || d.selfHolidayDayTime == "上午" )
  733. }else{
  734. return d.isGetSelfHolidays && ( d.selfHolidayDayTime == "全天" || d.selfHolidayDayTime == "下午" )
  735. }
  736. },
  737. isAbsent : function(d , ap ){
  738. if( ap == "am" ){
  739. return d.isAbsent && ( d.absentDayTime == "全天" || d.absentDayTime == "上午" )
  740. }else{
  741. return d.isAbsent && ( d.absentDayTime == "全天" || d.absentDayTime == "下午" )
  742. }
  743. },
  744. isLate : function(d, ap ){
  745. return d.isLate
  746. },
  747. //isLeaveEarlier : function( d ){
  748. // return d.isLeaveEarlier
  749. //},
  750. isWorkOvertime : function( d, ap){
  751. return d.isWorkOvertime
  752. },
  753. isLackOfTime : function( d, ap){
  754. return d.isLackOfTime
  755. },
  756. isAbnormalDuty : function(d , ap ){
  757. if( ap == "am" ){
  758. return d.isAbnormalDuty && ( d.abnormalDutyDayTime == "全天" || d.abnormalDutyDayTime == "上午" )
  759. }else{
  760. return d.isAbnormalDuty && ( d.abnormalDutyDayTime == "全天" || d.abnormalDutyDayTime == "下午" )
  761. }
  762. },
  763. isHoliday : function( d, ap ){
  764. if( ap == "am" ){
  765. return d.isHoliday && (!d.onDutyTime || d.onDutyTime == "")
  766. }else{
  767. return d.isHoliday && (!d.offDutyTime || d.offDutyTime == "")
  768. }
  769. },
  770. isWeekend : function( d, ap ){
  771. if(d.isWorkday )return false;
  772. if( ap == "am" ){
  773. return d.isWeekend && (!d.onDutyTime || d.onDutyTime == "")
  774. }else{
  775. return d.isWeekend && (!d.offDutyTime || d.offDutyTime == "")
  776. }
  777. },
  778. toFixed: function (num, d) {
  779. var s=num+"";
  780. if(!d)d=0;
  781. if(s.indexOf(".")==-1)s+=".";
  782. s+=new Array(d+1).join("0");
  783. if(new RegExp("^(-|\\+)?(\\d+(\\.\\d{0,"+(d+1)+"})?)\\d*$").test(s)){
  784. var s="0"+RegExp.$2,pm=RegExp.$1,a=RegExp.$3.length,b=true;
  785. if(a==d+2){
  786. a=s.match(/\d/g);
  787. if(parseInt(a[a.length-1])>4){
  788. for(var i=a.length-2;i>=0;i--){
  789. a[i]=parseInt(a[i])+1;
  790. if(a[i]==10){
  791. a[i]=0;
  792. b=i!=1;
  793. }else break;
  794. }
  795. }
  796. s=a.join("").replace(new RegExp("(\\d+)(\\d{"+d+"})\\d$"),"$1.$2");
  797. }if(b)s=s.substr(1);
  798. return (pm+s).replace(/\.$/,"");
  799. }return this+"";
  800. }
  801. });