UnitDingdingIndex.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  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.UnitDingdingIndex = new Class({
  6. Extends: MWF.widget.Common,
  7. Implements: [Options, Events],
  8. options: {
  9. "style": "default"
  10. },
  11. statusColor : {
  12. "resultNormal" : "#9acd32", //绿色,正常
  13. "leaveEarlyTimes":"#4f94cd", //蓝色,早退
  14. "lateTimes":"#fede03", //黄色,迟到
  15. "notSignedCount":"#ee807f", //粉红色,未签到
  16. "seriousLateTimes" : "#dec674",//严重迟到
  17. "absenteeismTimes" : "#fedcbd"//矿工
  18. },
  19. initialize: function(node, app, actions, options){
  20. this.setOptions(options);
  21. this.app = app;
  22. this.lp = app.lp;
  23. this.path = "../x_component_Attendance/$UnitIndex/";
  24. this.cssPath = "../x_component_Attendance/$UnitIndex/"+this.options.style+"/css.wcss";
  25. this._loadCss();
  26. this.actions = actions;
  27. this.node = $(node);
  28. this.setDate();
  29. this.today = new Date();
  30. this.userName = layout.desktop.session.user.distinguishedName;
  31. this.data = {};
  32. },
  33. setDate : function( date ){
  34. this.date = date || new Date();
  35. this.year = this.date.getFullYear().toString();
  36. var month = this.date.getMonth()+1;
  37. this.month = month.toString().length == 2 ? month : "0"+month;
  38. },
  39. reload: function(){
  40. this.node.empty();
  41. this.load();
  42. },
  43. load: function(){
  44. this.loadTitleNode();
  45. this.loadContent();
  46. },
  47. loadTitleNode : function(){
  48. var text = this.date.format(this.app.lp.dateFormatMonth);
  49. this.titleNode = new Element("div.titleNode",{
  50. "styles" : this.css.titleNode
  51. }).inject(this.node);
  52. this.titleLeftArrowNode = new Element("div",{
  53. "styles" : this.css.titleLeftArrowNode
  54. }).inject(this.titleNode);
  55. this.titleTextNode = new Element("div",{
  56. "styles" : this.css.titleTextNode,
  57. "text" : text
  58. }).inject(this.titleNode);
  59. this.titleRightArrowNode = new Element("div",{
  60. "styles" : this.css.titleRightArrowNode
  61. }).inject(this.titleNode);
  62. this.titleLeftArrowNode.addEvents({
  63. "mouseover": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode_over);}.bind(this),
  64. "mouseout": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode);}.bind(this),
  65. "mousedown": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode_down);}.bind(this),
  66. "mouseup": function(){this.titleLeftArrowNode.setStyles(this.css.titleLeftArrowNode_over);}.bind(this),
  67. "click": function(){this.changeMonthPrev();}.bind(this)
  68. });
  69. this.titleRightArrowNode.addEvents({
  70. "mouseover": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode_over);}.bind(this),
  71. "mouseout": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode);}.bind(this),
  72. "mousedown": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode_down);}.bind(this),
  73. "mouseup": function(){this.titleRightArrowNode.setStyles(this.css.titleRightArrowNode_over);}.bind(this),
  74. "click": function(){this.changeMonthNext();}.bind(this)
  75. });
  76. this.titleTextNode.addEvents({
  77. "mouseover": function(){this.titleTextNode.setStyles(this.css.titleTextNode_over);}.bind(this),
  78. "mouseout": function(){this.titleTextNode.setStyles(this.css.titleTextNode);}.bind(this),
  79. "mousedown": function(){this.titleTextNode.setStyles(this.css.titleTextNode_down);}.bind(this),
  80. "mouseup": function(){this.titleTextNode.setStyles(this.css.titleTextNode_over);}.bind(this),
  81. "click": function(){this.changeMonthSelect();}.bind(this)
  82. });
  83. this.loadUnitNode();
  84. },
  85. changeMonthPrev: function(){
  86. this.date.decrement("month", 1);
  87. this.setDate( this.date );
  88. var text = this.date.format(this.app.lp.dateFormatMonth);
  89. this.titleTextNode.set("text", text);
  90. this.reloadContent();
  91. },
  92. changeMonthNext: function(){
  93. this.date.increment("month", 1);
  94. this.setDate( this.date );
  95. var text = this.date.format(this.app.lp.dateFormatMonth);
  96. this.titleTextNode.set("text", text);
  97. this.reloadContent();
  98. },
  99. changeMonthSelect: function(){
  100. if (!this.monthSelector) this.createMonthSelector();
  101. this.monthSelector.show();
  102. },
  103. createMonthSelector: function(){
  104. this.monthSelector = new MWF.xApplication.Attendance.MonthSelector(this.date, this);
  105. },
  106. changeMonthTo: function(d){
  107. this.setDate( d )
  108. var text = this.date.format(this.app.lp.dateFormatMonth);
  109. this.titleTextNode.set("text", text);
  110. this.reloadContent();
  111. },
  112. changeUnitTo : function( d ){
  113. this.unit = d;
  114. this.titleUnitActionTextNode.set("text", d.split("@")[0]);
  115. this.reloadContent();
  116. },
  117. loadUnitNode: function(){
  118. this.listUnitWithPerson( function( unit ){
  119. this.unit = unit;
  120. this.units = [];
  121. var flag = true;
  122. if( this.app.isTopUnitManager() ){
  123. var data = {"unitList": this.app.getNameFlag( this.app.manageTopUnits )};
  124. this.app.orgActions.listUnitSubDirect( function( json ){
  125. json.data.each(function( d ){
  126. this.units.push( d.distinguishedName )
  127. }.bind(this))
  128. }.bind(this), null , data, false )
  129. }else if( this.app.isUnitManager() ){
  130. this.units = this.app.manageUnits;
  131. }
  132. this.unit = this.units[0] || this.unit;
  133. if( this.units.length > 1 ){ //(this.units.length==1 && this.units[0]!=this.unit )
  134. this.titleUnitAreaNode = new Element("div.titleUnitAreaNode",{
  135. "styles" : this.css.titleUnitAreaNode
  136. }).inject(this.titleNode)
  137. this.titleUnitActionNode = new Element("div",{
  138. "styles" : this.css.titleUnitActionNode
  139. }).inject(this.titleUnitAreaNode)
  140. this.titleUnitActionTextNode = new Element("div",{
  141. "styles" : this.css.titleUnitActionTextNode,
  142. "text" : this.unit.split("@")[0]
  143. }).inject(this.titleUnitActionNode);
  144. this.titleUnitActionIconNode = new Element("div",{
  145. "styles" : this.css.titleUnitActionIconNode
  146. }).inject(this.titleUnitActionNode);
  147. this.titleUnitActionNode.addEvents({
  148. "mouseover": function(){
  149. this.titleUnitActionTextNode.setStyles(this.css.titleUnitActionTextNode_over);
  150. this.titleUnitActionIconNode.setStyles(this.css.titleUnitActionIconNode_over);
  151. }.bind(this),
  152. "mouseout": function(){
  153. this.titleUnitActionTextNode.setStyles(this.css.titleUnitActionTextNode);
  154. this.titleUnitActionIconNode.setStyles(this.css.titleUnitActionIconNode);
  155. }.bind(this),
  156. "click" : function( ev ){
  157. this.switchUnit( ev.target );
  158. ev.stopPropagation();
  159. }.bind(this)
  160. })
  161. }else{
  162. this.titleUnitNode = new Element("div",{
  163. "styles" : this.css.titleUnitNode,
  164. "text" : this.unit.split("@")[0]
  165. }).inject(this.titleNode);
  166. }
  167. }.bind(this) )
  168. },
  169. listUnitWithPerson : function( callback ){
  170. var data = {"personList": this.app.getNameFlag(this.userName)};
  171. this.app.orgActions.listUnitWithPerson( function( json ){
  172. if( json.data.length > 0 ){
  173. if(callback)callback( json.data[0].distinguishedName );
  174. }else{
  175. if(callback)callback();
  176. }
  177. }.bind(this), null, data , false )
  178. },
  179. switchUnit : function( el ){
  180. var _self = this;
  181. var node = this.titleUnitListNode;
  182. var parentNode = el.getParent();
  183. if(node){
  184. if( node.getStyle("display") == "block" ){
  185. node.setStyle("display","none");
  186. }else{
  187. node.setStyle("display","block");
  188. node.position({
  189. relativeTo: this.titleUnitActionNode,
  190. position: 'bottomCenter',
  191. edge: 'upperCenter'
  192. });
  193. }
  194. }else{
  195. node = this.titleUnitListNode = new Element("div",{
  196. "styles" : this.css.titleUnitListNode
  197. }).inject(this.node);
  198. this.app.content.addEvent("click",function(){
  199. _self.titleUnitListNode.setStyle("display","none");
  200. });
  201. this.units.each(function( d ){
  202. var dNode = new Element("div",{
  203. "text" : d.split('@')[0],
  204. "styles" : this.css.titleUnitSelectNode
  205. }).inject(node);
  206. dNode.store("unit", d );
  207. dNode.addEvents({
  208. "mouseover" : function(){ this.setStyles(_self.css.titleUnitSelectNode_over); },
  209. "mouseout" : function(){ this.setStyles(_self.css.titleUnitSelectNode); },
  210. "click" : function(e){
  211. _self.titleUnitListNode.setStyle("display","none");
  212. this.setStyles(_self.css.titleUnitSelectNode);
  213. _self.changeUnitTo( this.retrieve("unit") );
  214. e.stopPropagation();
  215. }
  216. })
  217. }.bind(this));
  218. node.position({
  219. relativeTo: this.titleUnitActionNode,
  220. position: 'bottomCenter',
  221. edge: 'upperCenter'
  222. });
  223. }
  224. },
  225. reloadContent : function(){
  226. this.pieChartArea.empty();
  227. this.barChartArea.empty();
  228. this.lineChartArea.empty();
  229. this.loadData(function(){
  230. this.loadStatusColorNode();
  231. this.loadPieChart();
  232. this.loadBarChart();
  233. }.bind(this));
  234. this.loadDetail();
  235. },
  236. loadContent : function(){
  237. this.loadContentNode();
  238. this.loadData(function(){
  239. this.loadStatusColorNode();
  240. this.loadPieChart();
  241. this.loadBarChart();
  242. }.bind(this))
  243. this.loadDetail();
  244. this.setNodeScroll();
  245. this.setContentSize();
  246. },
  247. reloadChart : function(){
  248. this.pieChartArea.empty();
  249. this.barChartArea.empty();
  250. this.lineChartArea.empty();
  251. this.loadPieChart();
  252. this.loadBarChart();
  253. },
  254. loadContentNode: function(){
  255. this.elementContentNode = new Element("div.elementContentNode", {
  256. "styles": this.css.elementContentNode
  257. }).inject(this.node);
  258. this.app.addEvent("resize", function(){
  259. this.setContentSize();
  260. this.reloadChart();
  261. }.bind(this));
  262. this.elementContentListNode = new Element("div.elementContentListNode", {
  263. "styles": this.css.elementContentListNode
  264. }).inject(this.elementContentNode);
  265. this.topContentArea = new Element("div.topContentArea",{
  266. "styles" : this.css.topContentArea
  267. }).inject(this.elementContentListNode)
  268. this.pieChartArea = new Element("div.pieChartArea",{
  269. "styles" : this.css.pieChartArea
  270. }).inject(this.topContentArea)
  271. this.statusColorArea = new Element("div.statusColorArea",{
  272. "styles" : this.css.statusColorArea
  273. }).inject(this.topContentArea)
  274. this.barChartArea = new Element("div.barChartArea",{
  275. "styles" : this.css.barChartArea
  276. }).inject(this.topContentArea)
  277. this.middleContentArea = new Element("div.middleContentArea",{
  278. "styles" : this.css.middleContentArea
  279. }).inject(this.elementContentListNode)
  280. this.lineChartArea = new Element("div.lineChartArea",{
  281. "styles" : this.css.lineChartArea
  282. }).inject(this.middleContentArea)
  283. this.bottomContentArea = new Element("div.middleContentArea",{
  284. "styles" : this.css.bottomContentArea
  285. }).inject(this.elementContentListNode)
  286. this.detailArea = new Element("div.lineChartArea",{
  287. "styles" : this.css.detailArea
  288. }).inject(this.bottomContentArea)
  289. },
  290. loadData : function( callback, unit, year, month, async ){
  291. if( !unit )unit = this.unit;
  292. if( !year )year = this.year;
  293. if( !month )month = this.month;
  294. if( this.data[ unit + year + month ] ) {
  295. if(callback)callback();
  296. }else{
  297. var action = o2.Actions.load("x_attendance_assemble_control");
  298. action.DingdingAttendanceStatisticAction.unitMonth(unit, year, month, function(json){
  299. var d = json.data || {};
  300. var data = this.data[ unit + year + month ] = {};
  301. var totals = data.totalData = {
  302. resultNormal: d.resultNormal || 0,
  303. lateTimes: d.lateTimes || 0,
  304. leaveEarlyTimes: d.leaveEarlyTimes || 0,
  305. absenteeismTimes: d.absenteeismTimes || 0,
  306. seriousLateTimes: d.seriousLateTimes || 0,
  307. notSignedCount: d.notSignedCount || 0
  308. }
  309. var total = 0;
  310. for( var n in totals ){
  311. total += totals[n];
  312. }
  313. data.rateData = {
  314. resultNormal : (!totals.resultNormal || !total) ? 0 : ((totals.resultNormal/total * 100).toFixed(2) + "%"),
  315. lateTimes : (!totals.lateTimes || !total) ? 0 : ((totals.lateTimes/total * 100).toFixed(2) + "%"),
  316. leaveEarlyTimes : (!totals.leaveEarlyTimes || !total) ? 0 : ((totals.leaveEarlyTimes/total * 100).toFixed(2) + "%"),
  317. absenteeismTimes : (!totals.absenteeismTimes || !total) ? 0 : ((totals.absenteeismTimes/total * 100).toFixed(2) + "%"),
  318. seriousLateTimes : (!totals.seriousLateTimes || !total) ? 0 : ((totals.seriousLateTimes/total * 100).toFixed(2) + "%"),
  319. notSignedCount : (!totals.notSignedCount || !total) ? 0 : ((totals.notSignedCount/total* 100).toFixed(2) + "%")
  320. }
  321. if(callback)callback();
  322. }.bind(this), null, async);
  323. }
  324. },
  325. loadStatusColorNode : function(){
  326. this.statusColorArea.empty();
  327. this.statusColorTable = new Element("table",{
  328. "styles" : this.css.statusColorTable
  329. }).inject(this.statusColorArea)
  330. var totalData = this.data[ this.unit+this.year + this.month].totalData;
  331. var rateData = this.data[ this.unit+this.year + this.month].rateData;
  332. for(var status in this.statusColor){
  333. var tr = new Element("tr",{
  334. "styles" : this.css.statusColorTr
  335. }).inject(this.statusColorTable)
  336. var td = new Element("td",{
  337. "styles" : this.css.statusColorTd
  338. }).inject(tr)
  339. td.setStyle("background-color",this.statusColor[status]);
  340. var tr = new Element("tr",{
  341. "styles" : this.css.statusTextTr
  342. }).inject(this.statusColorTable)
  343. var td = new Element("td",{
  344. "styles" : this.css.statusTextTd,
  345. "text" : this.lp[status] +totalData[status]+ this.lp.day +"("+rateData[status]+")"
  346. }).inject(tr)
  347. }
  348. },
  349. loadPieChart : function(){
  350. this.pieChartNode = new Element("div.pieChartNode",{
  351. "styles" : this.css.pieChartNode
  352. }).inject(this.pieChartArea)
  353. var data = this.data[this.unit+ this.year + this.month].totalData;
  354. this.pieChart = new MWF.xApplication.Attendance.Echarts(this.pieChartNode, this, data);
  355. this.pieChart.loadUnitPieChart();
  356. },
  357. loadBarChart : function(){
  358. this.barChartNode = new Element("div.barChartNode",{
  359. "styles" : this.css.barChartNode
  360. }).inject(this.barChartArea);
  361. var date = new Date( this.date.getFullYear() , this.date.getMonth(), this.date.getDate() );
  362. date.decrement("month", 1);
  363. var year_1 = date.getFullYear().toString();
  364. var month_1 = date.format( this.lp.dateFormatOnlyMonth );
  365. var data_1 = this.data[ this.unit + year_1 + month_1 ];
  366. date.decrement("month", 1);
  367. var year_2 = date.getFullYear().toString();
  368. var month_2 = date.format( this.lp.dateFormatOnlyMonth );
  369. var data_2 = this.data[ this.unit + year_2 + month_2 ];
  370. if( !data_1 ){
  371. this.loadData( null, this.unit, year_1, month_1, false )
  372. }
  373. if( !data_2 ){
  374. this.loadData( null, this.unit, year_2, month_2, false)
  375. }
  376. var d = [{
  377. year : year_2,
  378. month : month_2,
  379. data : this.data[this.unit+ year_2 + month_2].totalData
  380. },{
  381. year : year_1,
  382. month : month_1,
  383. data : this.data[this.unit+ year_1 + month_1].totalData
  384. },{
  385. year : this.year,
  386. month : this.month,
  387. data : this.data[this.unit+ this.year + this.month].totalData
  388. }];
  389. this.barChart = new MWF.xApplication.Attendance.Echarts(this.barChartNode, this, d );
  390. this.barChart.loadUnitBarChart();
  391. },
  392. loadDetail : function(){
  393. this.detailArea.empty();
  394. this.detailNode = new Element("div",{
  395. "styles" : this.css.detailNode
  396. }).inject(this.detailArea);
  397. this.detailTitleNode = new Element("div",{
  398. "styles" : this.css.detailTitleNode,
  399. "text" : this.lp.attendanceStatisic
  400. }).inject(this.detailNode)
  401. var table = new Element("table", {
  402. "width" : "100%", "border" : "0", "cellpadding" : "5", "cellspacing" : "0", "styles" : this.css.table, "class" : "editTable"
  403. }).inject( this.detailNode );
  404. var tr = new Element("tr", { "styles" : this.css.listHeadNode }).inject(table);
  405. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.name }).inject(tr);
  406. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.onDutyTimes }).inject(tr);
  407. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.offDutyTimes }).inject(tr);
  408. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.resultNormal }).inject(tr);
  409. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.lateTimes }).inject(tr);
  410. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.seriousLateTimes }).inject(tr);
  411. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.leaveEarlyTimes }).inject(tr);
  412. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.absenteeismTimes }).inject(tr);
  413. var td = new Element("td", { "styles" : this.css.tableTitle, "text" : this.lp.notSignedCount }).inject(tr);
  414. var action = o2.Actions.load("x_attendance_assemble_control");
  415. action.DingdingAttendanceStatisticAction.personMonthWithUnit(this.unit, this.year, this.month, function(json){
  416. var data = json.data || [];
  417. data.sort( function(a, b){
  418. return b.workDayCount - a.workDayCount;
  419. });
  420. data.each(function( d ){
  421. var tr = new Element("tr").inject(table);
  422. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.o2User.split("@")[0] }).inject(tr);
  423. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.onDutyTimes }).inject(tr);
  424. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.offDutyTimes }).inject(tr);
  425. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.resultNormal }).inject(tr);
  426. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.lateTimes }).inject(tr);
  427. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.seriousLateTimes }).inject(tr);
  428. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.leaveEarlyTimes }).inject(tr);
  429. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.absenteeismTimes }).inject(tr);
  430. var td = new Element("td", { "styles" : this.css.tableValue , "text": d.notSignedCount }).inject(tr);
  431. }.bind(this))
  432. }.bind(this));
  433. },
  434. setContentSize: function(){
  435. var toolbarSize = this.toolbarNode ? this.toolbarNode.getSize() : {"x":0,"y":0};
  436. var titlebarSize = this.titleNode ? this.titleNode.getSize() : {"x":0,"y":0};
  437. var nodeSize = this.node.getSize();
  438. var pt = this.elementContentNode.getStyle("padding-top").toFloat();
  439. var pb = this.elementContentNode.getStyle("padding-bottom").toFloat();
  440. //var filterSize = this.filterNode.getSize();
  441. var filterConditionSize = this.filterConditionNode ? this.filterConditionNode.getSize() : {"x":0,"y":0};
  442. var height = nodeSize.y-toolbarSize.y-pt-pb-filterConditionSize.y-titlebarSize.y-10;
  443. this.elementContentNode.setStyle("height", ""+height+"px");
  444. },
  445. setNodeScroll: function(){
  446. var _self = this;
  447. MWF.require("MWF.widget.ScrollBar", function(){
  448. new MWF.widget.ScrollBar(this.elementContentNode, {
  449. "indent": false,"style":"xApp_TaskList", "where": "before", "distance": 30, "friction": 4, "axis": {"x": false, "y": true},
  450. "onScroll": function(y){
  451. }
  452. });
  453. }.bind(this));
  454. }
  455. });