view.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. {extend name="../../base/view/common/base" /}
  2. {block name="style"}
  3. <style>
  4. .layui-tab-title .layui-this{background-color:#fff;}
  5. .layui-tab-card,.layui-card{box-shadow:0 0 0 0 rgb(0 0 0 / 10%); border-radius:0;}
  6. .layui-card-tips {color: #969696;}
  7. .layui-card-value {padding: 4px 0 5px;font-size: 18px;color: #1E9FFF;}
  8. .check-items{overflow-x: auto; padding: 2px 0;}
  9. .check-item .check-item-icon strong{margin-right:3px; font-size:36px;}
  10. .check-item strong.blue,.check-item strong.gray{display:none;}
  11. .check-item.blue strong.black,.check-item.gray strong.black{display:none;}
  12. .check-item.blue strong.blue{display:block;}
  13. .check-item.gray strong.gray{display:block;}
  14. .flow-flex-row {box-direction: row;
  15. box-orient: horizontal;
  16. -webkit-box-orient: horizontal;
  17. -ms-flex-direction: row;
  18. flex-direction: row;
  19. }
  20. .flow-flexbox { width: 100%;text-align: left;
  21. display: -webkit-box;
  22. display: -ms-flexbox;
  23. display: flex;
  24. display: -webkit-flex;
  25. box-align: center;
  26. -webkit-box-align: center;
  27. -ms-flex-align: center;
  28. align-items: center;
  29. flex-wrap: wrap;
  30. }
  31. .check-item{width: auto; -ms-flex-negative: 0; flex-shrink: 0; padding:8px 0;}
  32. .check-item i{font-size:20px; margin-right:3px;}
  33. .layui-icon[data-ok]{color:#34a853}
  34. .layui-icon[data-no]{color:#FF5722;}
  35. .layui-icon[data-on]{color:#4285f4;}
  36. .check-item-time{color:#969696; font-size:12px; margin-left:3px;}
  37. .check-item .layui-icon.layui-icon-right{font-size:20px;}
  38. .check-item:last-child .layui-icon-right{display:none;}
  39. .file-card{line-height:normal;}
  40. </style>
  41. {/block}
  42. <!-- 主体 -->
  43. {block name="body"}
  44. <div class="p-page">
  45. <h2 class="pb-3">
  46. <span class="font20">{$detail.name}</span>
  47. {gt name="$role" value="0"}
  48. {eq name="$detail.status" value="4"}
  49. <span class="layui-btn layui-btn-xs" data-event="open">开启</span>
  50. {else/}
  51. <span class="layui-btn layui-btn-danger layui-btn-xs" data-event="close">关闭</span>
  52. {/eq}
  53. {/gt}
  54. </h2>
  55. <div class="pb-2">
  56. <span class="layui-badge layui-bg-gray">#T{$detail.id}</span>
  57. <span class="mx-2">{$detail.admin_name}</span>
  58. <span class="gray">创建于{$detail.create_time}<span>{gt name="$detail.update_time" value="0"},最近更新于 {$detail.update_time}{/gt}</span></span>
  59. </div>
  60. <div class="layui-tabs layui-tab-brief" id="projectTab">
  61. <ul class="layui-tabs-header border-t border-x bg-white">
  62. <li class="layui-this" data-load="true">项目概览</li>
  63. <li data-load="">项目任务</li>
  64. <li data-load="">工作记录</li>
  65. <li data-load="">项目文档</li>
  66. <li data-load="">项目人员</li>
  67. <li data-load="">项目动态</li>
  68. <li data-load="">项目评论</li>
  69. </ul>
  70. <div class="layui-tabs-body" style="padding:0">
  71. <div class="layui-tabs-item layui-show">
  72. {include file="/index/view_overview" /}
  73. </div>
  74. <div class="layui-tabs-item">
  75. {include file="/index/view_task" /}
  76. </div>
  77. <div class="layui-tabs-item">
  78. {include file="/index/view_schedule" /}
  79. </div>
  80. <div class="layui-tabs-item">
  81. {include file="/index/view_document" /}
  82. </div>
  83. <div class="layui-tabs-item">
  84. {include file="/index/view_user" /}
  85. </div>
  86. <div class="layui-tabs-item">
  87. {include file="/index/view_log" /}
  88. </div>
  89. <div class="layui-tabs-item">
  90. {include file="/index/view_comment" /}
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. {/block}
  96. <!-- /主体 -->
  97. <!-- 脚本 -->
  98. {block name="script"}
  99. <script src="{__GOUGU__}/third_party/echart/echarts.min.js"></script>
  100. <script>
  101. const project_id = '{$detail.id}';
  102. const project_start_time = "{$detail.start_time|date='Y-m-d'}";
  103. var chartProgress = document.getElementById('progress');
  104. var progressChart = echarts.init(chartProgress);
  105. var optionA;
  106. optionA = {
  107. backgroundColor: "#ffffff",
  108. title: {
  109. text: '67.45%',//主标题文本
  110. subtext: '任务完成率',//副标题文本
  111. x: 'center',
  112. y: '39%',
  113. textStyle: {
  114. fontWeight: 'normal',
  115. fontSize: 18,
  116. color: '#FF974C',
  117. align: 'center'
  118. },
  119. subtextStyle: {
  120. fontSize: 12,
  121. color: '#6c7a89',
  122. }
  123. },
  124. tooltip: {
  125. trigger: "item",
  126. formatter: '{b}:<br/><strong>{c}</strong>',
  127. show: true,
  128. },
  129. series: [
  130. {
  131. type: 'pie',
  132. radius: ['60%', '80%'],
  133. center: ['50%', '50%'],
  134. avoidLabelOverlap: false,
  135. label: {
  136. show: false
  137. },
  138. data: [
  139. { value: 1048, name: '待处理' },
  140. { value: 735, name: '已完成' }
  141. ]
  142. }
  143. ]
  144. };
  145. var chartDelay = document.getElementById('delay');
  146. var delayChart = echarts.init(chartDelay);
  147. var optionB;
  148. optionB = {
  149. backgroundColor: "#ffffff",
  150. title: {
  151. text: '40.25%',//主标题文本
  152. subtext: '任务延迟率',//副标题文本
  153. x: 'center',
  154. y: '39%',
  155. textStyle: {
  156. fontWeight: 'normal',
  157. fontSize: 18,
  158. color: '#FF974C',
  159. align: 'center',
  160. marginLeft: '-10px'
  161. },
  162. subtextStyle: {
  163. fontSize: 12,
  164. color: '#6c7a89',
  165. }
  166. },
  167. tooltip: {
  168. trigger: "item",
  169. formatter: '{b}:<br/><strong>{c}</strong>',
  170. show: true,
  171. },
  172. series: [
  173. {
  174. type: 'pie',
  175. radius: ['60%', '80%'],
  176. center: ['50%', '50%'],
  177. avoidLabelOverlap: false,
  178. label: {
  179. show: false
  180. },
  181. data: [{
  182. value: 1048,
  183. name: '延迟',
  184. itemStyle: {
  185. color: "#ED6666",
  186. }
  187. },
  188. {
  189. value: 735,
  190. name: '未延迟',
  191. itemStyle: {
  192. color: "#91CC75",
  193. }
  194. }
  195. ]
  196. }
  197. ]
  198. };
  199. var chartCross = document.getElementById('cross');
  200. var crossChart = echarts.init(chartCross);
  201. var optionD;
  202. optionD = {
  203. backgroundColor: "#ffffff",
  204. color: ['#8C92A4', '#2C7EF8'],
  205. tooltip: {
  206. trigger: 'axis',
  207. axisPointer: {
  208. type: 'cross',
  209. label: {
  210. backgroundColor: '#6a7985'
  211. }
  212. }
  213. },
  214. legend: {
  215. data: ['任务计划剩余', '任务实际剩余']
  216. },
  217. grid: {
  218. top: 36,
  219. left: 8,
  220. right: 36,
  221. bottom: 0,
  222. containLabel: true
  223. },
  224. xAxis: [
  225. {
  226. type: 'category',
  227. boundaryGap: false,
  228. splitLine: {
  229. show: true,
  230. lineStyle: {
  231. type: 'dashed'
  232. }
  233. }
  234. }
  235. ],
  236. yAxis: [{
  237. axisLine: {
  238. show: true
  239. },
  240. boundaryGap: false,
  241. splitLine: {
  242. show: true,
  243. lineStyle: {
  244. type: 'dashed'
  245. }
  246. },
  247. type: 'value'
  248. }
  249. ]
  250. };
  251. var chartPlan = document.getElementById('plan');
  252. var planChart = echarts.init(chartPlan);
  253. var optionE;
  254. optionE = {
  255. backgroundColor: "#ffffff",
  256. title: {
  257. top: 0,
  258. left: 0,
  259. text: ''
  260. },
  261. tooltip: {
  262. padding: 6,
  263. formatter: function (obj) {
  264. var value = obj.value;
  265. var tips = '<div style="font-size: 12px;">' + value[0] + '<br>';
  266. tips += '共 ' + value[1] + ' 个工作任务';
  267. tips += '</div>';
  268. return tips;
  269. }
  270. },
  271. visualMap: {
  272. min: 0,
  273. max: 10,
  274. show: false,
  275. inRange: {
  276. color: ['#fafafa', '#20BF3F']
  277. }
  278. },
  279. calendar: {
  280. top: 24,
  281. left: 36,
  282. right: 4,
  283. cellSize: ['auto', 16],
  284. range: ['2022-03-01', '2022-08-01'],
  285. splitLine: {
  286. lineStyle: {
  287. color: '#333',
  288. type: 'dashed',
  289. }
  290. },
  291. itemStyle: {
  292. borderWidth: 0.5
  293. },
  294. yearLabel: { show: false },
  295. monthLabel: {
  296. nameMap: 'cn',
  297. fontSize: 12
  298. },
  299. dayLabel: {
  300. show: true,
  301. formatter: '{start} 1st',
  302. fontWeight: 'lighter',
  303. nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
  304. fontSize: 12
  305. }
  306. },
  307. series: {
  308. type: 'heatmap',
  309. coordinateSystem: 'calendar',
  310. data: []
  311. }
  312. };
  313. var chartWork = document.getElementById('work');
  314. var workChart = echarts.init(chartWork);
  315. var optionF;
  316. optionF = {
  317. backgroundColor: "#ffffff",
  318. title: {
  319. top: 0,
  320. left: 0,
  321. text: ''
  322. },
  323. tooltip: {
  324. padding: 6,
  325. formatter: function (obj) {
  326. var value = obj.value;
  327. var tips = '<div style="font-size: 12px;">' + value[0] + '<br>';
  328. tips += '共 ' + value[1] + ' 个工时';
  329. tips += '</div>';
  330. return tips;
  331. }
  332. },
  333. visualMap: {
  334. min: 0,
  335. max: 10,
  336. show: false,
  337. inRange: {
  338. color: ['#fafafa', '#359AEF']
  339. }
  340. },
  341. calendar: {
  342. top: 24,
  343. left: 36,
  344. right: 4,
  345. cellSize: ['auto', 16],
  346. range: ['2022-03-01', '2022-08-01'],
  347. splitLine: {
  348. lineStyle: {
  349. color: '#333',
  350. type: 'dashed',
  351. }
  352. },
  353. itemStyle: {
  354. borderWidth: 0.5
  355. },
  356. yearLabel: { show: false },
  357. monthLabel: {
  358. nameMap: 'cn',
  359. fontSize: 12
  360. },
  361. dayLabel: {
  362. show: true,
  363. formatter: '{start} 1st',
  364. fontWeight: 'lighter',
  365. nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
  366. fontSize: 12
  367. }
  368. },
  369. series: {
  370. type: 'heatmap',
  371. coordinateSystem: 'calendar',
  372. data: []
  373. }
  374. };
  375. function getCalendarData(arr) {
  376. var rangeArray = [];
  377. for (var property in arr) {
  378. rangeArray.push(property);
  379. }
  380. var rangeArray = [rangeArray[0], rangeArray[rangeArray.length - 1]];
  381. var start = +echarts.number.parseDate(rangeArray[0]);
  382. var end = +echarts.number.parseDate(rangeArray[1]);
  383. if (start + 7776000000 > end) {
  384. end = start + 8640000000;
  385. rangeArray[1] = echarts.format.formatTime('yyyy-MM-dd', end);
  386. }
  387. var dayTime = 3600 * 24 * 1000;
  388. var data = [];
  389. for (var time = start; time < end; time += dayTime) {
  390. var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
  391. if (arr[this_date]) {
  392. data.push([this_date, arr[this_date]]);
  393. } else {
  394. data.push([this_date, 0]);
  395. }
  396. }
  397. var res = { 'range': rangeArray, 'data': data };
  398. return res;
  399. }
  400. //燃尽图统计
  401. function cross_count(arr, arr2) {
  402. var planArray = [], doArray = [];
  403. var today = new Date();
  404. var todayStr = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
  405. for (var a in arr) {
  406. planArray.push(a);
  407. }
  408. var rangeArray = [planArray[0], planArray[planArray.length - 1]];
  409. if (arr2 instanceof Array == false) {
  410. for (var b in arr2) {
  411. doArray.push(b);
  412. }
  413. if ((+echarts.number.parseDate(doArray[doArray.length - 1])) < (+echarts.number.parseDate(todayStr))) {
  414. doArray.push(todayStr);
  415. }
  416. if ((+echarts.number.parseDate(planArray[planArray.length - 1])) < (+echarts.number.parseDate(doArray[doArray.length - 1]))) {
  417. rangeArray[1] = doArray[doArray.length - 1];
  418. }
  419. }
  420. var start = +echarts.number.parseDate(rangeArray[0]);
  421. var end = +echarts.number.parseDate(rangeArray[1]);
  422. var todayInt = +echarts.number.parseDate(todayStr);
  423. var dayTime = 3600 * 24 * 1000;
  424. var xArray = [], yArray = [], yArray2 = [], done = 0, doneArray = [];
  425. for (var time = start; time <= end; time += dayTime) {
  426. var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
  427. xArray.push(this_date);
  428. var plan = cross_recursion(time, end, arr);
  429. yArray.push(plan);
  430. if (arr2[this_date]) {
  431. done += arr2[this_date];
  432. }
  433. if (time <= todayInt) {
  434. doneArray.push(done);
  435. }
  436. }
  437. for (var i = 0; i < doneArray.length; i++) {
  438. yArray2.push(yArray[0] - doneArray[i]);
  439. }
  440. var start_time = +echarts.number.parseDate(project_start_time), tem_x_array = [], tem_y_array = [];
  441. if (start_time < start) {
  442. for (var tem_time = start_time; tem_time < start; tem_time += dayTime) {
  443. var this_date = echarts.format.formatTime('yyyy-MM-dd', tem_time);
  444. tem_x_array.push(this_date);
  445. tem_y_array.push(yArray[0]);
  446. }
  447. xArray = tem_x_array.concat(xArray);
  448. yArray = tem_y_array.concat(yArray);
  449. yArray2 = tem_y_array.concat(yArray2);
  450. }
  451. return { 'x': xArray, 'y': yArray, 'y2': yArray2 };
  452. }
  453. function cross_recursion(start, end, arr) {
  454. var count = 0;
  455. var dayTime = 3600 * 24 * 1000;
  456. for (var time = start; time <= end; time += dayTime) {
  457. var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
  458. if (arr[this_date]) {
  459. count += arr[this_date];
  460. }
  461. }
  462. return count;
  463. }
  464. //
  465. const moduleInit = ['tool','oaPicker','uploadPlus','tablePlus','oaComment','oaSchedule','oaEdit'];
  466. function gouguInit() {
  467. var tool = layui.tool,tabs = layui.tabs,comment = layui.oaComment;
  468. comment.init({
  469. "box":'commentBox',//容器id
  470. "input": 'commentInput',
  471. "topic_id":project_id,
  472. "module": 'project',
  473. });
  474. $('body').on('click','[data-event="close"]',function(){
  475. tool.ask('确定要关闭该项目?',function(){
  476. let callback = function (e) {
  477. layer.msg(e.msg);
  478. if(e.code==0){
  479. parent.layui.pageTable.reload();
  480. setTimeout(function(){
  481. location.reload();
  482. },2000)
  483. }
  484. }
  485. tool.post("/project/api/close", { 'id': project_id}, callback);
  486. })
  487. })
  488. $('body').on('click','[data-event="open"]',function(){
  489. tool.ask('确定要开启该项目?',function(){
  490. let callback = function (e) {
  491. layer.msg(e.msg);
  492. if(e.code==0){
  493. parent.layui.pageTable.reload();
  494. setTimeout(function(){
  495. location.reload();
  496. },2000)
  497. }
  498. }
  499. tool.post("/project/api/open", { 'id': project_id}, callback);
  500. })
  501. })
  502. overview();
  503. tabs.on('afterChange(projectTab)', function(data){
  504. let index = data.index;
  505. if(index == 1){
  506. project_task();
  507. }
  508. else if(index == 2){
  509. project_schedule();
  510. }
  511. else if(index == 3){
  512. project_document();
  513. }
  514. else if(index == 4){
  515. project_user();
  516. }
  517. else if(index == 5){
  518. project_log();
  519. }
  520. });
  521. }
  522. </script>
  523. {/block}
  524. <!-- /脚本 -->