project_gantt.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. {{ src/App.vue }}
  2. <template>
  3. <div class="container">
  4. <div class="gantt_head">
  5. <div class="head_RorX">
  6. <el-radio-group v-model="radio1" @change="selChange()" size="small" style="margin-right:9px">
  7. <el-radio-button label="按人员查看" value="renyuan"></el-radio-button>
  8. <el-radio-button label="按项目查看" value="xiangmu"></el-radio-button>
  9. <el-radio-button label="资源需求" value="demand"></el-radio-button>
  10. </el-radio-group>
  11. </div>
  12. <div class="head_date" v-if="isDataLoaded">
  13. <span>时间段</span>
  14. <el-date-picker
  15. style="margin-left:9px"
  16. size="small"
  17. v-model="valueDate"
  18. type="daterange"
  19. range-separator="至"
  20. start-placeholder="开始日期"
  21. end-placeholder="结束日期"
  22. value-format="yyyy-MM-dd"
  23. @change="dateupdata()">
  24. </el-date-picker>
  25. </div>
  26. <div v-if="reqpar1" class="head_taskgroup">
  27. <span>任务分组</span>
  28. <el-select clearable filterable v-model="valuex2" placeholder="请选择" size="small" style="margin-left:9px;width:200px" @change="taskgroupSel()">
  29. <el-option
  30. v-for="item in taskgroupList"
  31. :key="item.name"
  32. :label="item.name"
  33. :value="item.name"
  34. >
  35. </el-option>
  36. </el-select>
  37. </div>
  38. <div class="head_select">
  39. <span>{{(this.radio1 == "按人员查看" ? "人员" : "项目")}}</span>
  40. <el-select clearable filterable v-model="valuex" placeholder="请选择" size="small" style="margin-left:9px;width:200px" @change="optupdata()">
  41. <el-option
  42. v-for="item in screenList"
  43. :key="item.id"
  44. :label="reqpar1 ? item.projectName : item.name"
  45. :value="item.id"
  46. >
  47. </el-option>
  48. </el-select>
  49. </div>
  50. </div>
  51. <gantt v-if="isDataLoaded" ref="ganttTable1" class="left-container" :tasks="tasks"
  52. :stafforpro="radio1"
  53. :valueDate="valueDate"
  54. :key="updatakey1"></gantt>
  55. <div class="demand-container" v-if="!isDataLoaded">
  56. <el-table height="90%" :loading="demandListLoading" :data="demandList">
  57. <el-table-column label="项目编号" prop="projectCode"></el-table-column>
  58. <el-table-column label="项目名称" prop="projectName"></el-table-column>
  59. <el-table-column label="近七日活跃人员" prop="activeUsers"></el-table-column>
  60. <el-table-column label="人员需求" prop="membReq"></el-table-column>
  61. <el-table-column label="任务需求" prop="taskReq"></el-table-column>
  62. <el-table-column label="操作">
  63. <template slot-scope="scope">
  64. <el-button @click="demandEdit(scope.row)" size="small">修改</el-button>
  65. </template>
  66. </el-table-column>
  67. </el-table>
  68. <div class="poss">
  69. <el-pagination
  70. @size-change="handleSizeChange"
  71. @current-change="handleCurrentChange"
  72. :current-page="pageIndex"
  73. :page-sizes="[20, 50, 100, 200]"
  74. :page-size="20"
  75. layout="total, sizes, prev, pager, next"
  76. :total="total">
  77. </el-pagination>
  78. </div>
  79. <!-- 资源需求修改 -->
  80. <el-dialog v-if="demandEditDialog" width="500px" append-to-body :visible.sync="demandEditDialog" :title="'修改 - ' + editParameter.projectName">
  81. <el-form label-width="150">
  82. <el-form-item label="人员需求">
  83. <el-input style="width:350px" v-model="editParameter.membReq" clearable></el-input>
  84. </el-form-item>
  85. <el-form-item label="任务需求">
  86. <el-input style="width:350px" v-model="editParameter.taskReq" clearable></el-input>
  87. </el-form-item>
  88. </el-form>
  89. <div slot="footer" class="dialog-footer">
  90. <el-button type="default" @click="demandEditDialog = false">取消</el-button>
  91. <el-button type="primary" @click="demandEditSure" >确定</el-button>
  92. </div>
  93. </el-dialog>
  94. </div>
  95. </div>
  96. </template>
  97. <script>
  98. import { error } from 'dingtalk-jsapi';
  99. import Gantt from './gantt.vue';
  100. export default {
  101. name: 'project_gantt',
  102. components: {Gantt},
  103. data () {
  104. return {
  105. isDataLoaded:false,
  106. tasks: {
  107. data : [],
  108. links: []
  109. },
  110. tasks1: {links:[]},
  111. updatakey1: 1,
  112. updatakey2: -1,
  113. radio1:"按人员查看",
  114. valueDate:[],
  115. options:[{value:"选项1",label:"全部"},{value:"选项2",label:"人员1"}],
  116. valuex:'',
  117. screenList:[],
  118. // 请求参数
  119. reqpar1:0,
  120. reqpar2:[],
  121. demandListLoading: false,
  122. demandList: [],
  123. pageIndex: 1,
  124. pageSize: 20,
  125. demandEditDialog: false,
  126. editParameter: {},
  127. taskgroupList: [],
  128. valuex2: ''
  129. }
  130. },
  131. methods: {
  132. setGroup() {
  133. this.$refs.ganttTable1.setGroup();
  134. // this.$refs.ganttTable2.setGroup();
  135. },
  136. // 人员/项目切换
  137. selChange(){
  138. this.valuex = null
  139. // console.log("切换按钮",this.radio1);
  140. if (this.radio1 == "按人员查看") {
  141. this.isDataLoaded = true
  142. this.reqpar1 = 0
  143. this.getList()
  144. this.getScreen()
  145. }else if(this.radio1 == "按项目查看"){
  146. this.isDataLoaded = true
  147. this.reqpar1 = 1
  148. this.getList()
  149. this.getXmScreen()
  150. this.getTaskgroupList()
  151. }else {
  152. this.reqpar1 = 1
  153. this.isDataLoaded = false
  154. this.pageIndex = 1
  155. this.pageSize = 20
  156. this.valuex = ''
  157. this.valuex2 = ''
  158. this.getDemandList()
  159. this.getXmScreen()
  160. this.getTaskgroupList()
  161. }
  162. },
  163. // 时间段改变
  164. dateupdata(){
  165. this.reqpar2 = this.valueDate
  166. this.getList()
  167. },
  168. // 人员/项目筛选改变
  169. optupdata(){
  170. // console.log(this.valuex);
  171. if(this.isDataLoaded){
  172. this.getList()
  173. }else{
  174. this.getDemandList()
  175. }
  176. },
  177. // 任务分组筛选改变
  178. taskgroupSel(){
  179. // console.log(this.valuex2);
  180. if(this.isDataLoaded){
  181. this.getList()
  182. }else{
  183. this.getDemandList()
  184. }
  185. },
  186. handleSizeChange(val){
  187. this.pageSize = val
  188. this.getDemandList()
  189. },
  190. handleCurrentChange(val){
  191. this.pageIndex = val
  192. this.getDemandList()
  193. },
  194. // 资源需求修改
  195. demandEdit(row){
  196. this.demandEditDialog = true
  197. this.editParameter = JSON.parse(JSON.stringify(row))
  198. // console.log('edit',this.demandEditDialog);
  199. },
  200. demandEditSure(){
  201. this.http.post('/project-requirement/addOrMod',this.editParameter,
  202. res => {
  203. if(res.code == 'ok'){
  204. this.$message({
  205. message: '修改成功',
  206. type: 'success'
  207. })
  208. this.demandEditDialog = false
  209. this.getDemandList()
  210. }else {
  211. this.$message({
  212. message: res.msg,
  213. type: 'error'
  214. })
  215. }
  216. },err => {
  217. this.$message({
  218. message: err,
  219. type: 'error'
  220. })
  221. })
  222. },
  223. // 获取人员项目筛选列表
  224. getScreen(){
  225. this.http.get('/project/getMyUsers',
  226. res => {
  227. if (res.code == "ok") {
  228. this.screenList = res.data
  229. }else{
  230. this.$message({
  231. message: res.msg,
  232. type: "error"
  233. });
  234. }
  235. },
  236. error => {
  237. this.$message({
  238. message : error,
  239. type : "error"
  240. })
  241. }
  242. )
  243. },
  244. getXmScreen(){
  245. this.http.get('/project/getProjectList',
  246. res => {
  247. if (res.code == "ok") {
  248. this.screenList = res.data
  249. // console.log("screen",this.screenList);
  250. }else{
  251. this.$message({
  252. message: res.msg,
  253. type: "error"
  254. });
  255. }
  256. },
  257. error => {
  258. this.$message({
  259. message : error,
  260. type : "error"
  261. })
  262. }
  263. )
  264. },
  265. // 获取任务分组筛选列表
  266. getTaskgroupList(){
  267. this.http.post('/task-group/getGroupNames',{},
  268. res => {
  269. if(res.code == 'ok'){
  270. this.taskgroupList = res.data
  271. }else {
  272. this.$message({
  273. message: res.msg,
  274. type: 'error'
  275. })
  276. }
  277. },err => {
  278. this.$message({
  279. message: err,
  280. type: 'error'
  281. })
  282. })
  283. },
  284. // 获取甘特图数据
  285. getList() {
  286. let getlistcs = {type : this.reqpar1 , startDate : this.reqpar2[0] , endDate : this.reqpar2[1]}
  287. if(this.reqpar1) {
  288. if(this.valuex != ''){
  289. getlistcs.projectId = this.valuex
  290. }
  291. if(this.valuex2 != ''){
  292. getlistcs.groupName = this.valuex2
  293. }
  294. }else {
  295. if(this.valuex != ''){
  296. getlistcs.userId = this.valuex
  297. }
  298. }
  299. this.http.post('/project/getGanttData', getlistcs ,
  300. res => {
  301. if (res.code == "ok") {
  302. for(var i in res.data) {
  303. if(res.data[i].id.indexOf('出差') != '-1') {
  304. res.data[i].color = '#E6A23C'
  305. }
  306. if(res.data[i].id.indexOf('请假') != '-1') {
  307. res.data[i].color = '#F56C6C'
  308. }
  309. }
  310. this.tasks = {data:res.data};
  311. for(let i in this.tasks.data){
  312. if(this.tasks.data[i].time == 0){
  313. delete this.tasks.data[i].start_date
  314. delete this.tasks.data[i].end_date
  315. this.tasks.data[i].type = 'milestone'
  316. }
  317. }
  318. this.$nextTick(()=>{
  319. this.updatakey1 += 1
  320. })
  321. } else {
  322. this.$message({
  323. message: res.msg,
  324. type: "error"
  325. });
  326. }
  327. },
  328. error => {
  329. this.$message({
  330. message: error,
  331. type: "error"
  332. });
  333. }
  334. );
  335. },
  336. // 获取资源需求列表
  337. getDemandList(){
  338. let parameter = {
  339. pageIndex: this.pageIndex,
  340. pageSize: this.pageSize,
  341. }
  342. if(this.valuex != ''){
  343. parameter.projectId = this.valuex
  344. }
  345. if(this.valuex2 != ''){
  346. parameter.groupName = this.valuex2
  347. }
  348. this.demandListLoading = true
  349. this.http.post('/project-requirement/listByPage',parameter,
  350. res => {
  351. if(res.code == 'ok'){
  352. this.demandListLoading = false
  353. this.total = res.data.total
  354. this.demandList = res.data.records
  355. }else {
  356. this.demandListLoading = false
  357. this.$message({
  358. message: res.msg,
  359. type: 'error'
  360. })
  361. }
  362. },err => {
  363. this.demandListLoading = false
  364. this.$message({
  365. message: err,
  366. type: 'error'
  367. })
  368. })
  369. },
  370. // tasksEdit(){
  371. // let etasks = JSON.parse(JSON.stringify(this.tasks.data))
  372. // for(let i=0;i<etasks.length;i++){
  373. // if(etasks[i].parent != null){
  374. // let edate = new Date(etasks[i].end_date)
  375. // edate = new Date(edate.setDate(edate.getDate() + 1))
  376. // let edatemonth = edate.getMonth() + 1
  377. // let edateday = edate.getDate()
  378. // edate = edate.getFullYear() + '-' + (edatemonth < 10 ? '0' + edatemonth : edatemonth) + '-' + (edateday < 10 ? '0' + edateday : edateday)
  379. // etasks[i].end_date = edate
  380. // }
  381. // }
  382. // this.tasks = {data:etasks}
  383. // }
  384. },
  385. mounted: function () {
  386. let nowdate = new Date()
  387. let nowmonth = nowdate.getMonth() + 1
  388. let startdate = nowdate.getFullYear() + "-" + (nowmonth < 10 ? "0" + nowmonth : nowmonth) + "-" + (nowdate.getDate() < 10 ? "0" + nowdate.getDate() : nowdate.getDate())
  389. let udate = new Date(nowdate.getFullYear(),nowdate.getMonth(),nowdate.getDate() + 31)
  390. let endmonth = udate.getMonth() + 1
  391. let enddate = udate.getFullYear() + "-" + (endmonth < 10 ? "0" + endmonth : endmonth) + "-" + (udate.getDate() < 10 ? "0" + udate.getDate() : udate.getDate())
  392. this.valueDate = [startdate,enddate]
  393. this.reqpar2 = this.valueDate
  394. // console.log("date",this.valueDate);
  395. this.getList();
  396. this.getScreen()
  397. // this.tasks1 = this.tasks
  398. this.isDataLoaded = true
  399. }
  400. }
  401. </script>
  402. <style>
  403. /* html, body {
  404. height: 100%;
  405. margin: 0;
  406. padding: 0;
  407. } */
  408. .container {
  409. height: 100%;
  410. width: 100%;
  411. }
  412. .left-container {
  413. overflow: hidden;
  414. position: relative;
  415. height: 90%;
  416. }
  417. .demand-container{
  418. overflow: hidden;
  419. position: relative;
  420. height: 92%;
  421. }
  422. .gantt_head{
  423. width: 100%;
  424. height: 60px;
  425. display: flex;
  426. justify-content: space-between;
  427. align-items: center;
  428. }
  429. .gantt_head .head_RorX{
  430. height: 60px;
  431. line-height: 60px;
  432. width: 24%;
  433. display: flex;
  434. align-items: center;
  435. justify-content: left;
  436. }
  437. .gantt_head .head_date{
  438. height: 60px;
  439. line-height: 60px;
  440. width: 30%;
  441. display: flex;
  442. align-items: center;
  443. justify-content: left;
  444. }
  445. .gantt_head .head_taskgroup{
  446. height: 60px;
  447. line-height: 60px;
  448. width: 23%;
  449. display: flex;
  450. align-items: center;
  451. justify-content: center;
  452. }
  453. .gantt_head .head_select{
  454. height: 60px;
  455. line-height: 60px;
  456. width: 23%;
  457. display: flex;
  458. align-items: center;
  459. justify-content: center;
  460. }
  461. .poss {
  462. height: 8%;
  463. float: right;
  464. padding-top: 15px;
  465. }
  466. </style>