demo2.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. <template>
  2.  <div style="height: 100%; width: 100%">
  3.     <div class="content">
  4.        <div style="margin: -5px 0px 5px;display: flex;justify-content: space-between;">
  5.            <a-input allowClear v-model="searchTitle" placeholder="请输入任务名称"></a-input>
  6.            <a-button icon="search" type="primary" @click="searchDataClick">搜索</a-button>
  7.        </div>
  8.        <!-- 中间 内容 -->
  9.        <div class="centerContent">
  10.          <!-- 甘特图 -->
  11.          <div class="selectDate">
  12.            <a-button @click="changeToday">今</a-button>
  13.            <!-- 日期切换 -->
  14.            <a-select  default-value="d" style="width: 55px;margin-left: 5px;" @change="ganttChangeDateView">
  15.              <a-select-option value="y">年</a-select-option>
  16.              <a-select-option value="m">月</a-select-option>
  17.              <a-select-option value="w">周</a-select-option>
  18.              <a-select-option value="d">日</a-select-option>
  19.            </a-select>
  20.            <a-button style="margin-left: 5px;" @click="changeFull"><a-icon type="fullscreen" /></a-button>
  21.          </div>
  22.          <div class="rightGatt" style="min-height:calc(78vh - 50px - 5px );width: 100%;overflow: hidden;" ref="gantt"></div>
  23.        </div>
  24.      </div>
  25.  </div>
  26. </div>
  27. </template>
  28. <script>
  29. import {gantt} from '@/assets/js/dhtmlx';
  30. import "@/assets/css/dhtmlxgantt.css";
  31. import moment from 'moment'​
  32. export default {
  33. name: "ganttChart",
  34. data() {
  35. return {
  36. moment,
  37. timer: null, //定时
  38. item: {}, //单行数据
  39. searchTitle: "", //搜索标题
  40. tasks: {
  41. data: [
  42. ], //数据
  43. links: [
  44. {
  45. id:'111',//数据id
  46.    source:'1'
  47.    target:'2'
  48.    type:'0'
  49. },//
  50. {
  51.    id:'222'
  52.    source:'2'
  53.    target:'1'
  54.    type:'1'
  55. },
  56. ], //关联项目数据
  57. },
  58. savetasks: {
  59. data: [],
  60. links: []
  61. }, //暂存空数据
  62. ganttServerStaff: [], //设置gantt成员数据
  63. selectStaff: [], //下拉成员
  64. staff: [], //成员
  65. ganttEvent: { //销毁事件
  66. },
  67. urls: {
  68. staff: "", //项目成员
  69. tasklinks: '', //gantt数据
  70. linksEdit: '', //修改和新增连接
  71. linksDelete: '', //删除连接
  72. addTask: '', //新增项目PUT
  73. editTask: '', //编辑项目put请求 tid
  74. deleteTask: '', //删除项目delete tid
  75. }
  76. }
  77. },
  78. watch: {
  79. searchTitle(newVal, oldVal) {
  80. this.searchTitle = newVal;
  81. }
  82. },
  83. mounted() {
  84. this.$nextTick(() => {
  85. this.ganttChangeEvent(); //交互事件
  86. this.initGantt(); //初始化
  87. this.createTodayLine(); //今日线
  88. // this.ganttServerList(); //服务数据
  89. })
  90. this.onQuery(); //查询数据
  91. this.ganttChangeDateView("d"); //默认日格式
  92. },
  93. methods: {
  94. /*
  95. 甘特图
  96. */
  97. // 初始化gantt
  98. initGantt() {
  99. // 清空之前的配置
  100. // gantt.clearAll();
  101. // 启用动态加载
  102. gantt.config.branch_loading = true
  103. //日期格式化
  104. gantt.config.xml_date = "%Y-%m-%d";
  105. gantt.config.order_branch = true;
  106. gantt.config.order_branch_free = true;
  107. //左侧是否自适应
  108. gantt.config.autofit = true;
  109. gantt.config.drag_links = true; //连线
  110. gantt.config.readonly = false; //只读
  111. gantt.config.date_scale = "%m月%d日"; //右侧显示列名
  112. gantt.config.layout = { //拖拽布局
  113. css: "gantt_container",
  114. rows: [{
  115. cols: [{
  116. view: "grid",
  117. id: "grid",
  118. scrollX: "scrollHor",
  119. scrollY: "scrollVer"
  120. },
  121. {
  122. resizer: true,
  123. width: 1
  124. },
  125. {
  126. view: "timeline",
  127. id: "timeline",
  128. scrollX: "scrollHor",
  129. scrollY: "scrollVer"
  130. },
  131. {
  132. view: "scrollbar",
  133. scroll: "y",
  134. id: "scrollVer"
  135. }
  136. ]
  137. },
  138. {
  139. view: "scrollbar",
  140. scroll: "x",
  141. id: "scrollHor",
  142. height: 20
  143. }
  144. ]
  145. };
  146. gantt.config.start_on_monday = true;
  147. gantt.config.work_time = true;
  148. gantt.config.fit_tasks = true; //自动调整图表坐标轴区间用于适配task的长度
  149. //汉化
  150. gantt.locale = {
  151. date: {
  152. month_full: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
  153. month_short: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
  154. day_full: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
  155. day_short: ["日", "一", "二", "三", "四", "五", "六"]
  156. },
  157. labels: {
  158. dhx_cal_today_button: "今天",
  159. day_tab: "日",
  160. week_tab: "周",
  161. month_tab: "月",
  162. new_event: "新建日程",
  163. icon_save: "保存",
  164. icon_cancel: "关闭",
  165. icon_details: "详细",
  166. icon_edit: "编辑",
  167. icon_delete: "删除",
  168. confirm_closing: "请确认是否撤销修改!", //Your changes will be lost, are your sure?
  169. confirm_deleting: "是否删除计划?",
  170. section_description: "描述:",
  171. section_time: "时间范围:",
  172. section_type: "类型:",
  173. section_text: "计划名称:",
  174. section_test: "测试:",
  175. section_projectClass: "项目类型:",
  176. taskProjectType_0: "项目任务",
  177. taskProjectType_1: "普通任务",
  178. section_head: "负责人:",
  179. section_priority: '优先级:',
  180. taskProgress: '任务状态',
  181. taskProgress_0: "未开始",
  182. taskProgress_1: "进行中",
  183. taskProgress_2: "已完成",
  184. taskProgress_3: "已延期",
  185. taskProgress_4: "搁置中",
  186. section_template: 'Details',
  187. /* grid columns */
  188. column_text: "计划名称",
  189. column_start_date: "开始时间",
  190. column_duration: "持续时间",
  191. column_add: "",
  192. column_priority: "难度",
  193. /* link confirmation */
  194. link: "关联",
  195. confirm_link_deleting: "将被删除",
  196. message_ok: '确定',
  197. message_cancel: '取消',
  198. link_start: " (开始)",
  199. link_end: " (结束)",
  200. type_task: "任务",
  201. type_project: "项目",
  202. type_milestone: "里程碑",
  203. minutes: "分钟",
  204. hours: "小时",
  205. days: "天",
  206. weeks: "周",
  207. months: "月",
  208. years: "年"
  209. }
  210. }
  211. gantt.serverList("priority", [{
  212. key: 0,
  213. label: "最高"
  214. },
  215. {
  216. key: 1,
  217. label: "较高"
  218. },
  219. {
  220. key: 2,
  221. label: "普通"
  222. },
  223. {
  224. key: 3,
  225. label: "较低"
  226. },
  227. {
  228. key: 4,
  229. label: "最低"
  230. },
  231. ]);
  232. //左侧显示列名
  233. gantt.config.columns = [{
  234. name: "text",
  235. min_width: 100,
  236. max_width: 200,
  237. label: "任务",
  238. align: "left",
  239. resize: true,
  240. tree: true,
  241. editor: {
  242. type: 'text',
  243. map_to: 'text'
  244. }
  245. },
  246. {
  247. name: "id",
  248. label: "",
  249. hide: true
  250. },
  251. {
  252. name: "start_date",
  253. label: "开始时间",
  254. width: 120,
  255. resize: true,
  256. align: "left"
  257. },
  258. {
  259. name: "head",
  260. min_width: 100,
  261. height: 40,
  262. label: "负责人",
  263. resize: true,
  264. align: "left",
  265. // editor: {
  266. //   map_to: "head_id", type: "select", options: gantt.serverList("staff"),
  267. // },
  268. template: (item) => {
  269. if (this.ganttDealById(gantt.serverList('staff'), item.head_id)) {
  270. return `<span class='userIcon' style='background-color:${item.color ? item.color : "#6666"}'>${this.ganttDealById(gantt.serverList('staff'), item.head_id).slice(0, 1)}</span>${this.ganttDealById(gantt.serverList('staff'), item.head_id)}`
  271. }
  272. }
  273. },
  274. // { name: "end_date", label: "结束时间", align: "center" },
  275. {
  276. name: "taskProgress",
  277. label: "任务状态",
  278. align: "center",
  279. min_width: 110,
  280. editor: {
  281. type: "select",
  282. map_to: "taskProgress",
  283. options: [{
  284. key: "0",
  285. label: gantt.locale.labels.taskProgress_0
  286. },
  287. {
  288. key: "1",
  289. label: gantt.locale.labels.taskProgress_1
  290. },
  291. {
  292. key: "2",
  293. label: gantt.locale.labels.taskProgress_2
  294. },
  295. {
  296. key: "3",
  297. label: gantt.locale.labels.taskProgress_3
  298. },
  299. {
  300. key: "4",
  301. label: gantt.locale.labels.taskProgress_4
  302. },
  303. ],
  304. },
  305. template: function(obj) {
  306. let re = '';
  307. switch (obj.taskProgress) {
  308. case "0":
  309. re = `<div class='taskProgress color_bg_1' >未开始</div>`
  310. break;
  311. case "1":
  312. re = `<div class='taskProgress color_bg_2' >进行中</div>`
  313. break;
  314. case "2":
  315. re = `<div class='taskProgress color_bg_3' >已完成</div>`
  316. break;
  317. case "3":
  318. re = `<div class='taskProgress color_bg_4'>已延期</div>`
  319. break;
  320. case "4":
  321. re = `<div class='taskProgress color_bg_5' >搁置中</div>`
  322. break;
  323. }
  324. return re​
  325. }
  326. }, ​
  327. ];​
  328. //弹出层
  329. gantt.config.lightbox.sections = [{
  330. name: "text",
  331. height: 70,
  332. map_to: "text",
  333. type: "textarea",
  334. focus: true,
  335. width: "*"
  336. },
  337. {
  338. name: "time",
  339. height: 40,
  340. map_to: "auto",
  341. type: "duration",
  342. time_format: ["%Y", "%m", "%d"],
  343. },
  344. {
  345. name: "projectClass",
  346. height: 30,
  347. map_to: "proTemplate",
  348. type: "template",
  349. },
  350. {
  351. name: "head",
  352. height: 22,
  353. map_to: "head_id",
  354. type: "select",
  355. options: gantt.serverList('staff', []),
  356. },
  357. {
  358. name: "description",
  359. height: 70,
  360. map_to: "description",
  361. type: "textarea"
  362. },
  363. {
  364. name: "priority",
  365. height: 40,
  366. map_to: "priority",
  367. type: "radio",
  368. options: gantt.serverList("priority")
  369. }, ​
  370. ];​
  371. gantt.config.smart_scales = true;
  372. gantt.plugins({
  373. click_drag: true,
  374. drag_timeline: true, // 拖动图
  375. marker: true, // 时间标记
  376. fullscreen: true, // 全屏
  377. tooltip: true, // 鼠标经过时信息
  378. undo: true // 允许撤销
  379. })
  380. gantt.init(this.$refs.gantt);
  381. },
  382. // gantt数据服务列表
  383. ganttServerList() {
  384. this.getProjectStaff(); //获取项目成员
  385. // 项目难度
  386. gantt.serverList("priority", [{
  387. key: 0,
  388. label: "最高"
  389. },
  390. {
  391. key: 1,
  392. label: "较高"
  393. },
  394. {
  395. key: 2,
  396. label: "普通"
  397. },
  398. {
  399. key: 3,
  400. label: "较低"
  401. },
  402. {
  403. key: 4,
  404. label: "最低"
  405. },
  406. ]);
  407. },
  408. // gantt交互事件注册
  409. ganttChangeEvent() {
  410. // gantt渲染
  411. this.ganttEvent.onGanttReady = gantt.attachEvent("onGanttReady", () => {
  412. //弹窗标题 日期范围
  413. gantt.templates.task_time = function(start, end, task) {
  414. return "周期:" + moment(start).format('YYYY-MM-DD') + " 至 " + moment(end).format('YYYY-MM-DD');
  415. };
  416. // 浮窗
  417. gantt.templates.tooltip_text = (start, end, task) => {
  418. return "<b>项目名称:</b> " + task.text + "<br><b>负责人:</b>" + task.head + "<br/><b>开始时间:</b> " +
  419. moment(start).format('YYYY-MM-DD') +
  420. "<br/><b>结束时间:</b> " +
  421. moment(new Date(end).valueOf() - 1000 * 60 * 60 * 24).format('YYYY-MM-DD');
  422. }
  423. //弹窗标题 计划名称
  424. gantt.templates.task_text = function(start, end, task) {
  425. return task.text;
  426. };
  427. gantt.templates.timeline_cell_class = function(task, date) {
  428. if (!gantt.isWorkTime({
  429. task: task,
  430. date: date
  431. })) {
  432. return "weekend";
  433. } else {
  434. return 'weekday'
  435. }
  436. };
  437. gantt.templates.task_end_date = (date) => {
  438. return gantt.templates.task_date(this.moment(new Date(date.valueOf() - 1000 * 60 * 60 * 24)).format(
  439. "YYYY-MM-DD"));
  440. };
  441. gantt.templates.grid_date_format = (date, column) => {
  442. if (column === "end_date") {
  443. return this.moment(new Date(date.valueOf() - 1000 * 60 * 60 * 24)).format("YYYY-MM-DD");
  444. } else {
  445. return this.moment(date).format("YYYY-MM-DD");
  446. }
  447. }
  448. });
  449. // 修改默认弹窗
  450. gantt.attachEvent("onBeforeLightbox", (id) => {
  451. var task = gantt.getTask(id);
  452. task.proTemplate = `${gantt.locale.labels.taskProjectType_0}`
  453. return true;
  454. });​
  455. //添加后触发
  456. this.ganttEvent.onAfterTaskAdd = gantt.attachEvent("onAfterTaskAdd", (id, item) => {
  457. clearTimeout(this.timer)
  458. this.timer = setTimeout(() => {
  459. this.dealProject("add", item)
  460. }, 500)​
  461. });
  462. // 修改任务
  463. this.ganttEvent.onAfterTaskUpdate = gantt.attachEvent("onAfterTaskUpdate", (id, data) => {
  464. clearTimeout(this.timer)
  465. this.timer = setTimeout(() => {
  466. this.dealProject("edit", data);
  467. gantt.render()
  468. }, 500)​
  469. });
  470. // 删除项目
  471. this.ganttEvent.onAfterTaskDelete = gantt.attachEvent("onAfterTaskDelete", (id, data) => {
  472. clearTimeout(this.timer)
  473. this.timer = setTimeout(() => {
  474. this.dealProject("delete", data);
  475. gantt.render();
  476. }, 500)
  477. });
  478. // 移动项目
  479. this.ganttEvent.onAfterTaskDrag = gantt.attachEvent("onAfterTaskDrag", (id, mode, e) => {
  480. clearTimeout(this.timer)
  481. this.timer = setTimeout(() => {
  482. var task = gantt.getTask(id);
  483. this.dealProject("edit", task);
  484. gantt.render()
  485. }, 500)
  486. });
  487. // 用户完成拖动并释放鼠标
  488. this.ganttEvent.onAfterTaskChanged = gantt.attachEvent("onAfterTaskChanged", (id, mode, task) => {
  489. clearTimeout(this.timer)
  490. this.timer = setTimeout(() => {
  491. gantt.render();
  492. }, 500)
  493. });​
  494. // 删除连接项目关系
  495. this.ganttEvent.onAfterLinkDelete = gantt.attachEvent("onAfterLinkDelete", (id, item) => {
  496. clearTimeout(this.timer)
  497. this.timer = setTimeout(() => {
  498. let param = Object.assign({}, {
  499. projectId: this.$store.state.project_data.id
  500. }, item)
  501. this.axios.$delete(this.urls.linksDelete, param).then(res => {
  502. res.code == 200 && this.$message.success("解除成功!")
  503. res.code != 200 && this.$message.error("解除失败!")
  504. })
  505. gantt.render();
  506. }, 500)
  507. });
  508. // 修改连接项目关系
  509. this.ganttEvent.onAfterLinkUpdate = gantt.attachEvent("onAfterLinkUpdate", (id, item) => {
  510. clearTimeout(this.timer)
  511. this.timer = setTimeout(() => {
  512. let param = Object.assign({}, {
  513. projectId: this.$store.state.project_data.id
  514. }, item)
  515. this.axios.$put(this.urls.linksEdit, param).then(res => {
  516. res.code == 200 && this.$message.success("关联成功!")
  517. res.code != 200 && this.$message.error("关联失败!")​
  518. })
  519. gantt.render()
  520. }, 500)
  521. });
  522. // 新增连接项目关系
  523. this.ganttEvent.onBeforeLinkAdd = gantt.attachEvent("onBeforeLinkAdd", (id, item) => {
  524. this.timer = setTimeout(() => {
  525. clearTimeout(this.timer)
  526. let param = Object.assign({}, {
  527. projectId: this.$store.state.project_data.id
  528. }, item)
  529. this.axios.$put(this.urls.linksEdit, param).then(res => {
  530. res.code == 200 && this.$message.success("关联成功!");
  531. res.code != 200 && this.$message.error("关联失败!");
  532. })
  533. gantt.render()
  534. }, 20)​
  535. });
  536. // 保存新增
  537. this.ganttEvent.onLightboxSave = gantt.attachEvent("onLightboxSave", (id, item) => {
  538. if (!item.text) {
  539. this.$message.error("请填写计划名称!");
  540. return false;
  541. }
  542. return true;
  543. });​
  544. },
  545. // 处理id 对应名称label
  546. ganttDealById(list, id) {
  547. for (let i = 0; i < list.length; i++) {
  548. if (list[i].key == id)
  549. return list[i].label;
  550. }
  551. return "";
  552. },
  553. // 切换 年 季 月 周 日视图
  554. ganttChangeDateView(type) {
  555. switch (type) {
  556. case 'y':
  557. gantt.config.scale_unit = "year";
  558. gantt.config.step = 1;
  559. gantt.config.subscales = null;
  560. gantt.config.date_scale = "%Y年";
  561. gantt.templates.date_scale = null;
  562. break;​
  563. case 'm':
  564. gantt.config.scale_unit = 'month';
  565. gantt.config.step = 1;
  566. gantt.config.date_scale = "%m月";
  567. gantt.templates.date_scale = null;
  568. break;
  569. case 'w':
  570. gantt.config.scale_unit = 'week';
  571. gantt.config.step = 1;
  572. gantt.config.date_scale = "第%w周";
  573. gantt.templates.date_scale = null;
  574. break;
  575. case 'd':
  576. gantt.config.scale_unit = 'day';
  577. gantt.config.step = 1;
  578. gantt.config.date_scale = "%m月%d日";
  579. gantt.templates.date_scale = null;
  580. gantt.config.subscales = null;
  581. break;
  582. }
  583. gantt.render();
  584. },
  585. // 今日线
  586. createTodayLine() {
  587. var dateToStr = gantt.date.date_to_str("%Y年%M%d日");
  588. var markerId = gantt.addMarker({
  589. id: 'markerLine',
  590. start_date: new Date(),
  591. css: "today",
  592. text: "今日",
  593. title: dateToStr(new Date())
  594. });
  595. gantt.updateMarker(markerId);
  596. },
  597. // 是否全屏
  598. changeFull() {
  599. gantt.ext.fullscreen.toggle();
  600. },
  601. // 定位到今日线
  602. changeToday() {
  603. this.$nextTick(() => {
  604. let ganTT = document.getElementsByClassName('gantt_marker today')
  605. gantt.scrollTo(ganTT[0].offsetLeft - 300, null);
  606. })
  607. },
  608. /*
  609.   操作
  610.   */
  611. // 获取项目成员
  612. getProjectStaff(projectID) {
  613. this.axios.get(this.urls.staff, {
  614. params: {
  615. projectId: projectID ? projectID : this.$store.state.project_data.id
  616. },
  617. }).then(res => {
  618. let staffArr = [];
  619. res.data.code = 200 && res.data.result.forEach((item, index) => {
  620. staffArr[index] = {};
  621. staffArr[index].key = item.id;
  622. staffArr[index].label = item.realname;
  623. })
  624. this.selectStaff = res.data.result;
  625. // 补充gantt数据
  626. this.ganttServerStaff = staffArr;
  627. gantt.updateCollection("staff", staffArr);
  628. gantt.render()
  629. })
  630. },
  631. //计算进度
  632. evalProgess(start, end, update) {
  633. if (start && end && update) {
  634. let start_date = this.moment(start).format("YYYY-MM-DD");
  635. let end_date = this.moment(end).format("YYYY-MM-DD");
  636. let update_date = this.moment(update).format("YYYY-MM-DD");
  637. if ((new Date(end_date) - new Date(update_date) > 0)) {
  638. let process = (new Date(update_date) - new Date(start_date)) / (new Date(end_date) - new Date(start_date));
  639. return process.toFixed(2)
  640. } else {
  641. return 0
  642. }
  643. }​
  644. return 0
  645. },
  646. // 获取数据
  647. onQuery(param) {
  648. gantt.clearAll();
  649. gantt.parse(this.savetasks);
  650. gantt.render();
  651. param = Object.assign({}, {
  652. projectId: this.$store.state.project_data.id ? this.$store.state.project_data.id : '1'
  653. }, param)
  654. this.axios.get(this.urls.tasklinks, {
  655. params: param
  656. }).then(res => {
  657. let result = res.data.result["taskList"];
  658. let pushArr = [];
  659. this.tasks.links = res.data.result["ganttchartList"]; //连接项目
  660. this.tasks.data = [];
  661. result.forEach((item, index) => {
  662. this.tasks.data[index] = {};
  663. this.tasks.data[index].id = item.tid ? item.tid : ''; //项目id
  664. this.tasks.data[index].text = item.title ? item.title : '空标题'; //标题
  665. this.tasks.data[index].start_date = item.startTime; //开始时间
  666. // 负责人--成员
  667. this.tasks.data[index].head_id = item.headRole?.id ? item.headRole?.id : ''; //负责人id
  668. this.tasks.data[index].head = item.headRole?.realname ? item.headRole?.realname : ''; //负责人
  669. this.tasks.data[index].progress = this.evalProgess(item.startTime, item.endTime, item
  670. .updateTime) //项目进展
  671. // 后台时间加一天 显示减一天 处理条形图时间左闭右开
  672. this.tasks.data[index].end_date = this.moment(new Date(item.endTime).valueOf() + 1000 * 60 * 60 *
  673. 24).format("YYYY-MM-DD"); //结束时间
  674. // this.tasks.data[index].end_date = item.endTime;//结束时间
  675. this.tasks.data[index].priority = item.priority ? item.priority : ''; //任务优先级
  676. this.tasks.data[index].projectClass = item.type ? item.type : ''; //类型 0项目任务 1 普通任务
  677. this.tasks.data[index].taskProgress = item.taskStatus.toString(); //任务状态
  678. this.tasks.data[index].description = item.describe ? item.describe : ''; //描述
  679. this.tasks.data[index].color = item.stateDictionary.color ? item.stateDictionary.color : ''; //颜色
  680. if (item.taskList && item.taskList.length != 0) {
  681. this.tasks.data[index].render = "split"; //显示在单行
  682. this.tasks.data[index].open = true; //展开
  683. item.taskList.forEach((_item) => {
  684. pushArr.push({
  685. id: _item.tid,
  686. text: _item.title ? _item.title : '空标题',
  687. start_date: _item.startTime,
  688. end_date: _item.endTime,
  689. head_id: _item.headId,
  690. head: _item.head,
  691. priority: _item.priority,
  692. projectClass: _item.type,
  693. taskProgress: _item.taskStatus.toString(),
  694. description: _item.describe,
  695. parent: _item.mainTaskId,
  696. });
  697. })
  698. }
  699. });
  700. this.tasks.data = this.tasks.data.concat(pushArr)
  701. this.$nextTick(() => {
  702. gantt.parse(this.tasks);
  703. gantt.render();
  704. gantt.refreshData();
  705. })​
  706. })
  707. },
  708. // 项目新增 修改tid 删除tid
  709. dealProject(type, data) {
  710. let param = {};
  711. if (type != 'add') {
  712. param.tid = data.id;
  713. param.title = data.text;
  714. param.startTime = this.moment(data.start_date).format("YYYY-MM-DD");
  715. param.endTime = this.moment(data.end_date).format("YYYY-MM-DD");
  716. param.describe = data.description;
  717. param.priority = data.priority;
  718. param.head = data.head_id;
  719. param.taskStatus = data.taskProgress;
  720. param.projectId = this.$store.state.project_data.id;
  721. } else {
  722. param.title = data.text;
  723. param.startTime = this.moment(data.start_date).format("YYYY-MM-DD");
  724. param.endTime = this.moment(data.end_date).format("YYYY-MM-DD");
  725. param.describe = data.description;
  726. param.priority = data.priority;
  727. param.head = data.head_id;
  728. param.taskStatus = data.taskProgress;
  729. param.projectId = this.$store.state.project_data.id;
  730. }
  731. let formdata = new FormData();
  732. for (let i in param) {
  733. formdata.append(i, param[i])
  734. }
  735. switch (type) {
  736. case "add": //新增
  737. this.axios.put(this.urls.addTask, formdata).then(res => {
  738. res.data.code == 200 && this.$message.success("新增成功!")
  739. res.data.code != 200 && this.$message.error("新增失败!")
  740. }).catch(err => {
  741. this.$message.error("请求失败!")
  742. })
  743. break;
  744. case "edit":
  745. this.axios.put(this.urls.editTask, formdata).then(res => {
  746. res.data.code == 200 && this.$message.success("修改成功!")
  747. res.data.code != 200 && this.$message.error("修改失败!")
  748. }).catch(err => {
  749. this.$message.error("请求失败!")
  750. })
  751. break;
  752. case "delete":
  753. this.axios.delete(this.urls.deleteTask, formdata).then(res => {
  754. res.data.code == 200 && this.$message.success("删除成功!")
  755. res.data.code != 200 && this.$message.error("删除失败!")
  756. }).catch(err => {
  757. this.$message.error("请求失败!")
  758. })
  759. break;​
  760. }
  761. },
  762. selecthead(val) {
  763. this.searchHead = val; //id
  764. },
  765. // 搜索判断数据
  766. hasSubstr(parentId, type) {
  767. let task = gantt.getTask(parentId);
  768. if (type == 'tilte') {
  769. if (task.text.toLowerCase().indexOf(this.searchTitle) !== -1)
  770. return true;
  771. }
  772. // }  
  773. },
  774. //点击按钮搜索
  775. searchDataClick() {
  776. if (this.searchTitle) {
  777. this.ganttEvent.onBeforeTaskDisplay = gantt.attachEvent("onBeforeTaskDisplay", (id, task) => {
  778. if (this.hasSubstr(id, 'tilte')) {
  779. return true;
  780. }
  781. return false;
  782. });
  783. gantt.refreshData()
  784. gantt.render()
  785. } else {
  786. this.ganttEvent.onBeforeTaskDisplay = gantt.attachEvent("onBeforeTaskDisplay", (id, task) => {
  787. return true
  788. })
  789. gantt.refreshData()
  790. gantt.render()
  791. }
  792. },
  793. },
  794. destroyed() {
  795. // 销毁gantt事件
  796. for (let i in this.ganttEvent) {
  797. gantt.detachEvent(this.ganttEvent[i])
  798. }
  799. gantt.ext.tooltips.tooltip.hide();
  800. }
  801. }
  802. </script>
  803. <style scoped lang="scss">
  804. @import url(./gantt.css);
  805. .ant-layout {
  806. background: #f8f9f9;
  807. }
  808. ​ .ant-layout-header {
  809. background: #fdffff;
  810. color: rgb(29, 28, 28);
  811. border: 1px solid #dee0e0;
  812. }
  813. ​ .header {
  814. // position: fixed;
  815. display: flex;
  816. justify-content: space-between;
  817. align-items: center;
  818. }
  819. ​ .content {
  820. background: #fdffff;
  821. height: 99vh;
  822. }
  823. ​ // 中间
  824. .centerContent {
  825. position: relative;
  826. background: #fdffff;
  827. width: 100%;
  828. overflow-y: auto;
  829. display: flex;
  830. justify-content: space-between;
  831. .selectDate {
  832. width: 100px;
  833. position: fixed;
  834. top: 18%;
  835. right: 9%;
  836. z-index: 99;
  837. display: flex;
  838. justify-content: space-between;
  839. }
  840. }
  841. </style>