当前位置: 首页 > article >正文

甘特图开发代码(测试版)

场景:要实现的功能就是单行数据能左右拖动。

流程五个:ABCDE。(对应:Charter开发、概念和计划、初样开发、正样开发、验证)

1、A有开始时间,结束时间。B的开始时间必须是A的结束时间(相等或者大于A的结束时间)。CDE以此类推。

2、一条数据有父子级的话,父级数据的进度条取A的开始时间,E的结束时间,如果当前流程没到E,就是取现有的流程的结束时间。流程阶段影响父级

3、单个流程进度条移动会影响前后进度条,如果没有前后节点就不影响

一、代码实现

https://juejin.cn/post/7451884906761486372

https://juejin.cn/post/7273096710826967092

1、html页面

import React, { useState, useMemo, useRef } from 'react';
import {
  Button,
  DataSet,
  DatePicker,
  Dropdown,
  Form,
  Menu,
  message,
  Modal,
  Select,
  Table,
  TextField,
} from 'choerodon-ui/pro';
import GanttModal from './components/ganttModal/main';

const platformCharter = () => {

  return <GanttModal />
};

export default platformCharter;

2、组件页面

const handleCheckboxClick = useCallback(event => {
  const target = event.target;
  if (target.tagName === 'INPUT' && target.type === 'checkbox') {
    const taskId = target.getAttribute('data-task-id');
    const isChecked = target.checked;

    // 更新任务数据中的选中状态
    const task = gantt.getTask(taskId);
    task.selected = isChecked;
    gantt.updateTask(taskId);

    // 获取子任务
    const childTasks = gantt.getChildren(taskId);
    childTasks.forEach(childTask => {
      const childCheckbox = gantt.getTask(childTask.id);
      childCheckbox.selected = isChecked; // 设置子任务的选中状态
      gantt.updateTask(childTask.id);
    });

    // 更新父任务的选中状态
    const parentTask = gantt.getTask(task.parent);
    if (parentTask) {
      const siblings = gantt.getChildren(parentTask.id);
      const allChecked = siblings.every(sibling => sibling.selected);
      parentTask.selected = allChecked; // 如果所有兄弟任务都选中,父任务选中
      gantt.updateTask(parentTask.id);
    }

    console.log('任务选中状态:', taskId, isChecked);
  }
}, []);


.gantt_task {
    background-color: #4CAF50; /* 修改任务条的背景色 */
    border: 1px solid #333; /* 修改任务条的边框 */
}

.gantt_task_line {
    height: 20px; /* 修改任务条的高度 */
}

.gantt_grid_line {
    border-color: #ccc; /* 修改网格线的颜色 */
}

gantt.templates.task_text = function(start, end, task) {
    return "<span style='color: red;'>" + task.text + "</span>"; // 修改任务文本颜色
};

// 
// test
//test
const secondGridColumns = [
  {
    name: 'actions',
    label: '操作',
    width: 200,
    align: 'center',
    template: (task) => {
      return `
        <div class="gantt-actions">
          <div class="edit-btn" data-task-id="${task.id}">编辑</div>
          <div class="detail-btn" data-task-id="${task.id}">详情</div>
          <div class="record-btn" data-task-id="${task.id}">修改记录</div>
        </div>
      `;
    }
  }
];

// demo
<!DOCTYPE html>
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>Grid columns rightside of gantt</title>
	<script src="../../codebase/dhtmlxgantt.js?v=9.0.3"></script>
	<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=9.0.3">
	<style>
		html, body {
			padding: 0px;
			margin: 0px;
			height: 100%;
		}

		.gantt_grid_scale .gantt_grid_head_cell,
		.gantt_task .gantt_task_scale .gantt_scale_cell {
			font-weight: bold;
			font-size: 14px;
			color: rgba(0, 0, 0, 0.7);
		}
	</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>

	var secondGridColumns = {
		columns: [
			{
				name: "status", label: "Status", width: 60, align: "center", template: function (task) {
					var progress = task.progress || 0;
					return Math.floor(progress * 100) + "";
				}
			},
			{
				name: "impact", width: 90, label: "Impact", template: function (task) {
					return (task.duration * 1000).toLocaleString("en-US", {style: 'currency', currency: 'USD'});
				}
			}
		]
	};

	gantt.config.layout = {
		css: "gantt_container",
		rows: [
			{
				cols: [
					{view: "grid", width: 320, scrollY: "scrollVer"},
					{resizer: true, width: 1},
					{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
					{resizer: true, width: 1},
					{view: "grid", width: 160, bind: "task", scrollY: "scrollVer", config: secondGridColumns},
					{view: "scrollbar", id: "scrollVer"}
				]

			},
			{view: "scrollbar", id: "scrollHor", height: 20}
		]
	};

	gantt.init("gantt_here");
	gantt.parse({
		data: [
			{id: 1, text: "Office itinerancy", type: gantt.config.types.project, progress: 0.4, open: false},
			{id: 2, text: "Office facing", type: gantt.config.types.project, start_date: "02-04-2025", duration: "8", progress: 0.6, parent: "1", open: true},
			{id: 3, text: "Furniture installation", type: gantt.config.types.project, start_date: "11-04-2025", duration: "8", parent: "1", progress: 0.6, open: true},
			{id: 4, text: "The employee relocation", type: gantt.config.types.project, start_date: "13-04-2025", duration: "6", parent: "1", progress: 0.5, open: true},
			{id: 5, text: "Interior office", start_date: "02-04-2025", duration: "7", parent: "2", progress: 0.6, open: true},
			{id: 6, text: "Air conditioners check", start_date: "03-04-2025", duration: "7", parent: "2", progress: 0.6, open: true},
			{id: 7, text: "Workplaces preparation", start_date: "11-04-2025", duration: "8", parent: "3", progress: 0.6, open: true},
			{id: 8, text: "Preparing workplaces", start_date: "14-04-2025", duration: "5", parent: "4", progress: 0.5, open: true},
			{id: 9, text: "Workplaces importation", start_date: "14-04-2025", duration: "4", parent: "4", progress: 0.5, open: true},
			{id: 10, text: "Workplaces exportation", start_date: "14-04-2025", duration: "3", parent: "4", progress: 0.5, open: true},
			{id: 11, text: "Product launch", type: gantt.config.types.project, progress: 0.6, open: true},
			{id: 12, text: "Perform Initial testing", start_date: "03-04-2025", duration: "5", parent: "11", progress: 1, open: true},
			{id: 13, text: "Development", type: gantt.config.types.project, start_date: "02-04-2025", duration: "7", parent: "11", progress: 0.5, open: true},
			{id: 14, text: "Analysis", start_date: "02-04-2025", duration: "6", parent: "11", progress: 0.8, open: true},
			{id: 15, text: "Design", type: gantt.config.types.project, start_date: "02-04-2025", duration: "5", parent: "11", progress: 0.2, open: false},
			{id: 16, text: "Documentation creation", start_date: "02-04-2025", duration: "7", parent: "11", progress: 0, open: true},
			{id: 17, text: "Develop System", start_date: "03-04-2025", duration: "2", parent: "13", progress: 1, open: true},
			{id: 25, text: "Beta Release", start_date: "06-04-2025", type: gantt.config.types.milestone, parent: "13", progress: 0, open: true},
			{id: 18, text: "Integrate System", start_date: "08-04-2025", duration: "2", parent: "13", progress: 0.8, open: true},
			{id: 19, text: "Test", start_date: "10-04-2025", duration: "4", parent: "13", progress: 0.2, open: true},
			{id: 20, text: "Marketing", start_date: "10-04-2025", duration: "4", parent: "13", progress: 0, open: true},
			{id: 21, text: "Design database", start_date: "03-04-2025", duration: "4", parent: "15", progress: 0.5, open: true},
			{id: 22, text: "Software design", start_date: "03-04-2025", duration: "4", parent: "15", progress: 0.1, open: true},
			{id: 23, text: "Interface setup", start_date: "03-04-2025", duration: "5", parent: "15", progress: 0, open: true},
			{id: 24, text: "Release v1.0", start_date: "15-04-2025", type: gantt.config.types.milestone, parent: "11", progress: 0, open: true}
		],
		links: [
			{id: "1", source: "1", target: "2", type: "1"},
			{id: "2", source: "2", target: "3", type: "0"},
			{id: "3", source: "3", target: "4", type: "0"},
			{id: "4", source: "2", target: "5", type: "2"},
			{id: "5", source: "2", target: "6", type: "2"},
			{id: "6", source: "3", target: "7", type: "2"},
			{id: "7", source: "4", target: "8", type: "2"},
			{id: "8", source: "4", target: "9", type: "2"},
			{id: "9", source: "4", target: "10", type: "2"},
			{id: "10", source: "11", target: "12", type: "1"},
			{id: "11", source: "11", target: "13", type: "1"},
			{id: "12", source: "11", target: "14", type: "1"},
			{id: "13", source: "11", target: "15", type: "1"},
			{id: "14", source: "11", target: "16", type: "1"},
			{id: "15", source: "13", target: "17", type: "1"},
			{id: "16", source: "17", target: "25", type: "0"},
			{id: "23", source: "25", target: "18", type: "0"},
			{id: "17", source: "18", target: "19", type: "0"},
			{id: "18", source: "19", target: "20", type: "0"},
			{id: "19", source: "15", target: "21", type: "2"},
			{id: "20", source: "15", target: "22", type: "2"},
			{id: "21", source: "15", target: "23", type: "2"},
			{id: "22", source: "13", target: "24", type: "0"}
		]
	});
</script>

<script>
	(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
	(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
	m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
	})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

	ga('create', 'UA-11031269-1', 'auto');
	ga('send', 'pageview');
</script></body>"
import React, {
  forwardRef,
  useEffect,
  useRef,
  useState,
  useCallback,
} from 'react';
import { Button } from 'choerodon-ui/pro';
import { ButtonColor, FuncType } from 'choerodon-ui/pro/lib/button/enum';
import { observer } from 'mobx-react';
import { gantt } from '@/lib/dhtmlx-gantt/dhtmlxgantt.js';
import '@/lib/dhtmlx-gantt/dhtmlxgantt.css';
import { zoomLevels } from './store';
import './index.less';
import DetailModal from '../detail/main';
import RecordModal from '../record/main';
import { languageConfig } from '@/language/language';

const GanttChart = observer(
  forwardRef((props, ref) => {
    const [visible, setVisible] = useState(false); // 弹框(详情/编辑)
    const [recordVisible, setRecordVisible] = useState(false); // 记录弹框
    const [operationType, setOperationType] = useState('detail'); // 弹框类型
    const [operationId, setOperationId] = useState(''); // 操作ID(用于调用详情)

    const ganttRef = useRef<any>(null);
    const [currentZoom, setCurrentZoom] = useState('day'); // 时间刻度(默认值: day)
    const currentZoomRef = useRef('day');

    /** 配置 Gantt */
    const initConfig = useCallback(() => {
      // 语言设置-中文
      gantt.i18n.setLocale('cn');
      // 行高
      gantt.config.row_height = 48;
      // 日期格式
      gantt.config.date_format = '%Y-%m-%d %H:%i';
      // 自适应
      gantt.config.autosize = 'y';

      // 设置列(name为数据字段,label为表头显示的名称,width为列宽,align为对齐方式)
      gantt.config.columns = [
        {
          name: 'selected', // 勾选框列
          label: '', // 表头为空
          width: 50,
          align: 'center',
          template: task => {
            return `
              <div class="gantt-checkbox">
                <input
                  type="checkbox"
                  data-task-id="${task.id}"
                  ${task.selected ? 'checked' : ''}
                />
              </div>
            `;
          },
        },
        {
          name: 'text',
          label: '姓名',
          width: 150,
          tree: true,
        },
        { name: 'start_date', label: '开始日期', width: 130, align: 'center' },
        { name: 'duration', label: '持续时间', width: 80, align: 'center' },
        { name: 'progress', label: '进度', width: 80, align: 'center' },
        {
          name: 'actions',
          label: '操作',
          width: 200,
          align: 'center',
          template: task => {
            return `
              <div class="gantt-actions">
                <div class="edit-btn" data-task-id="${task.id}">编辑</div>
                <div class="detail-btn" data-task-id="${task.id}">详情</div>
                <div class="record-btn" data-task-id="${task.id}">修改记录</div>
              </div>
            `;
          },
        },
      ];

      // 布局
      gantt.config.layout = {
        css: 'custom-gantt-style',
        rows: [
          {
            cols: [
              { view: 'grid', width: 450 }, // 任务列表
              { view: 'timeline', scrollX: 50, scrollY: 60 }, // 时间轴
            ],
          },
        ],
        resizer: {
          width: 10,
          handler: true,
        },
      };

      // 启用当前日期标识插件
      gantt.plugins({
        marker: true,
      });

      // 设置时间列的样式
      gantt.templates.timeline_cell_class = (task, date) => {
        const isDisabledZoom = ['month', 'year', 'quarter'].includes(
          currentZoomRef.current,
        );
        if (!isDisabledZoom && !gantt.isWorkTime(date)) return 'week_end';
        return '';
      };
    }, []);

    /** 设置当前日期标识线 */
    const initCurrentDateMarker = useCallback(() => {
      const dateToStr = gantt.date.date_to_str(gantt.config.task_date);
      const today = new Date(new Date().setHours(0, 0, 0, 0)); // 当天零点
      gantt.addMarker({
        start_date: today,
        css: 'today',
        text: '今日',
        title: `Today: ${dateToStr(today)}`,
      });
    }, []);

    /** 初始化缩放配置 */
    const initZoom = useCallback(() => {
      const zoomConfig = {
        levels: zoomLevels,
        element: () => gantt.$root.querySelector('.gantt_task'),
      };
      gantt.ext.zoom.init(zoomConfig);
      gantt.ext.zoom.setLevel('day');
    }, []);

    /** 加载任务数据 */
    const loadTasks = useCallback(() => {
      const tasks = {
        data: [
          {
            id: 1,
            text: 'Karla',
            start_date: '2019-08-01 00:00',
            duration: 3,
            parent: 0,
            progress: 0.5,
            open: true,
          },
          {
            id: 11,
            text: 'Karla-01',
            start_date: '2019-08-01 10:00',
            duration: 3,
            parent: 1,
            progress: 0.8,
          },
          {
            id: 2,
            text: '前端',
            start_date: '2019-08-02 00:00',
            duration: 2,
            parent: 1,
            progress: 0.7,
          },
          {
            id: 3,
            text: 'York',
            start_date: '2019-08-03 00:00',
            duration: 4,
            parent: 0,
            progress: 0.3,
            open: true,
          },
          {
            id: 4,
            text: '后端',
            start_date: '2019-08-04 00:00',
            duration: 1,
            parent: 3,
            progress: 0.6,
            open: true,
          },
          {
            id: 5,
            text: 'Coco',
            start_date: '2019-08-05 00:00',
            duration: 2,
            parent: 0,
            progress: 0.8,
            open: true,
          },
          {
            id: 6,
            text: '测试',
            start_date: '2019-08-06 00:00',
            duration: 5,
            parent: 5,
            progress: 0.4,
          },
          {
            id: 7,
            text: 'Happy',
            start_date: '2019-08-07 00:00',
            duration: 3,
            parent: 0,
            progress: 0.9,
          },
          {
            id: 9,
            text: 'Rose',
            start_date: '2019-08-09 00:00',
            duration: 1,
            parent: 0,
            progress: 0.1,
          },
        ],
      };
      gantt.parse(tasks);
    }, []);

    /** change 操作按钮点击事件 */
    const handleActionClick = useCallback(event => {
      const target = event.target;
      const taskId = target.getAttribute('data-task-id');

      if (!taskId) return;

      setOperationId(taskId);
      const actionMap = {
        'edit-btn': () => {
          console.log('点击了编辑:', taskId);

          setOperationType('edit');
          setVisible(true);
        },
        'detail-btn': () => {
          console.log('点击了详情:', taskId);
          setOperationType('detail');
          setVisible(true);
        },
        'record-btn': () => {
          console.log('点击了修改记录:', taskId);
          setRecordVisible(true);
        },
      };

      // 调用对应的处理逻辑
      const action = actionMap[target.className];
      if (action) {
        action();
      }
    }, []);

    /**change 时间刻度视图 */
    const handleZoomChange = useCallback(zoom => {
      setCurrentZoom(zoom);
      currentZoomRef.current = zoom;
      gantt.ext.zoom.setLevel(zoom);
    }, []);

    /** 处理勾选框点击事件 */
    const handleCheckboxClick = useCallback(event => {
      const target = event.target;
      if (target.tagName === 'INPUT' && target.type === 'checkbox') {
        const taskId = target.getAttribute('data-task-id');
        const isChecked = target.checked;

        // 更新任务数据中的选中状态
        const task = gantt.getTask(taskId);
        task.selected = isChecked;
        gantt.updateTask(taskId);

        console.log('任务选中状态:', taskId, isChecked);
      }
    }, []);

    /** 初始化 Gantt */
    useEffect(() => {
      initConfig();
      initZoom();
      initCurrentDateMarker();

      // 初始化
      gantt.init(ganttRef.current);

      // 加载数据
      loadTasks();

      // 绑定操作按钮的点击事件
      const ganttContainer = ganttRef.current;
      ganttContainer.addEventListener('click', handleActionClick);

      // 绑定勾选框的点击事件
      ganttContainer.addEventListener('change', handleCheckboxClick);

      // 清理事件监听器
      return () => {
        ganttContainer.removeEventListener('click', handleActionClick);
        ganttContainer.removeEventListener('change', handleCheckboxClick);
      };
    }, [
      initConfig,
      initZoom,
      initCurrentDateMarker,
      loadTasks,
      handleActionClick,
      handleCheckboxClick,
    ]);

    return (
      <div>
        {/* 时间刻度:切换按钮 */}
        <div style={{ margin: '12px 0' }}>
          {zoomLevels.map(item => (
            <Button
              key={item.name}
              color={ButtonColor.primary}
              funcType={FuncType.raised}
              disabled={item.name === currentZoom}
              onClick={() => handleZoomChange(item.name)}
              style={{ marginRight: 6 }}
            >
              {item.label}
            </Button>
          ))}
        </div>

        {/* Gantt 容器 */}
        <div style={{ height: '500px', overflow: 'auto' }}>
          <div ref={ganttRef} style={{ width: '100%', height: '100%' }}></div>
        </div>

        {/* 详情/编辑弹框 */}
        {visible && (
          <DetailModal
            visible={visible}
            setVisible={setVisible}
            onSelect={() => {}}
            title={
              operationType === 'detail'
                ? languageConfig('platformCharter.title.detail', '详情')
                : languageConfig('platformCharter.title.edit', '编辑')
            }
            infoData={{
              operationId,
              operationType,
            }}
          />
        )}

        {/* 记录 */}
        {recordVisible && (
          <RecordModal
            visible={recordVisible}
            setVisible={setRecordVisible}
            onSelect={() => {}}
            title={languageConfig(
              'platformCharter.title.editRecord',
              '修改记录',
            )}
            infoData={{
              operationId,
            }}
          />
        )}
      </div>
    );
  }),
);

export default GanttChart;

store.js文件

export const zoomLevels = [
  // {
  //   name: 'hour',
  //   label: '小时',
  //   scale_height: 50,
  //   min_column_width: 30,
  //   scales: [
  //     { unit: 'day', format: '%Y-%m-%d' },
  //     { unit: 'hour', format: '%H' },
  //   ],
  // },
  {
    name: 'day',
    label: '日',
    scale_height: 70,
    min_column_width: 30,
    scales: [
      { unit: 'month', format: '%Y年 %F' },
      // { unit: "day", step: 1, format: "%j %D" },
      {
        unit: 'day',
        step: 1,
        format: date => {
          const weekDays = ['日', '一', '二', '三', '四', '五', '六'];
          const day = new Date(date).getDate();
          const weekDay = new Date(date).getDay();
          return `<div class='scale-formate-date'>
          <span class='formate-date'>${day}</span>
          <span class='formate-weekDay'>${weekDays[weekDay]}</span>
          </div>`;
          // return "<strong>Day " + dayNumber(date) + "</strong><br/>" + dateFormat(date);
        },
      },
    ],
  },
  {
    name: 'week',
    label: '周',
    scale_height: 50,
    min_column_width: 50,
    scales: [
      { unit: 'month', format: '%Y年 %F' },
      { unit: 'week', step: 1, date: '%W周' },
    ],
  },
  {
    name: 'month',
    label: '月',
    scale_height: 50,
    min_column_width: 50,
    scales: [
      // { unit: "year", step: 1, format: "%Y年" },
      {
        unit: 'quarter',
        step: 1,
        format: date => {
          const year = new Date(date).getFullYear();
          const month = new Date(date).getMonth();
          const quarter = Math.floor(month / 3 + 1);
          return `${year}年-Q${quarter}`;
          // return `Q${quarter}`;
        },
      },
      { unit: 'month', step: 1, format: '%F' },
    ],
  },
  {
    name: 'quarter',
    label: '季',
    scale_height: 50,
    min_column_width: 50,
    scales: [
      { unit: 'year', step: 1, format: '%Y年' },
      {
        unit: 'quarter',
        step: 1,
        format: date => {
          // const year = new Date(date).getFullYear();
          const month = new Date(date).getMonth();
          const quarter = Math.floor(month / 3 + 1);
          // return `${year}年-Q${quarter}`;
          return `Q${quarter}`;
        },
      },
    ],
  },
  {
    name: 'year',
    label: '年',
    scale_height: 50,
    min_column_width: 50,
    scales: [{ unit: 'year', step: 1, format: '%Y年' }],
  },
];

export const zoomMap = {
  day: '日',
  week: '周',
  month: '月',
  quarter: '季',
  year: '年',
};



.gantt-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
}

/************************************* table Header **************************************/
.gantt_grid_head_cell {
  background-color: #f5f7f8;
  font-size: 14px;
  font-weight: 400;
}

/************************************* checkbox 勾选框 **************************************/
.gantt-checkbox input {
  cursor: pointer;
  border-radius: 4px;
  border: 1px solid #c7cfd8;
  width: 14px;
  height: 14px;
  appearance: none; /* 清除默认样式 */
  -webkit-appearance: none; /* 兼容 Safari 和 Chrome */
  -moz-appearance: none; /* 兼容 Firefox */
  position: relative; /* 为伪元素定位 */
}

/* 选中状态样式 */
.gantt-checkbox input:checked {
  background-color: #1890ff; /* 选中时的背景色 */
  border-color: #1890ff; /* 选中时的边框颜色 */
}

/* 小勾样式 */
.gantt-checkbox input:checked::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 8px;
  border: solid white;
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -60%) rotate(45deg); /* 调整位置和旋转角度 */
}

/************************************* 操作(btn) **************************************/
.edit-btn,
.detail-btn,
.record-btn {
  color: #007dc6;
  cursor: pointer;
}

3、mock数据(暂时没用上)

export const tasksList = {
  data: [
    {
      bid: 1,
      pCode: '0',
      type: 1,
      code: 'm1234',
      name: 'm1234',
      projectRank: 'm1234',
      marketPositioning: 'm1234',
      costBenchmarking: 'm1234',
      performanceBenchmark: 'm1234',
      targetAudienceName: 'm1234',
      focusedIndustriesAndClientsName: 'm1234',
      newReachableCapacity: 'm1234',
      preparationOfKeyTechnologies: null,
      valueProposition: 'm1234',
      keyCompetitive: 'm1234',
      charterInitDate: '2025-01-02 00:00:00',
      charterTransferDate: '2025-01-02 00:00:00',
      pdcpDate: '2025-01-02 00:00:00',
      tr4aDate: '2025-01-02 00:00:00',
      edcpDate: '2025-01-02 00:00:00',
      adcpDate: '2025-05-02 00:00:00',
      insightFinishDate: '2025-03-02 00:00:00',
      relateOfferingName: null,
      rerlationshipName: null,
      serviceSolution: null,
      belongSolutionName: null,
      productClassL3Name: null,
      productSeriesL4Name: null,
      productOfferingL5Name: null,
      productBelongGroupsName: null,
      productBelongSpdtName: null,
      charterClass: null,
      charterTransferVersionTypeName: null,
      decisionLevelName: null,
      priorityName: null,
      businessPropertyName: null,
      bak: null,
      verison: null,
      state: 1,
      createUser: null,
      updatedUser: null,
      milestones: null,
      children: [
        {
          bid: 4,
          pCode: 'm1234',
          type: 2,
          code: 'm1234567',
          name: 'm1234',
          projectRank: 'm1234',
          marketPositioning: 'm1234',
          costBenchmarking: 'm1234',
          performanceBenchmark: 'm1234',
          targetAudienceName: 'm1234',
          focusedIndustriesAndClientsName: 'm1234',
          newReachableCapacity: 'm1234',
          preparationOfKeyTechnologies: null,
          valueProposition: 'm1234',
          keyCompetitive: 'm1234',
          charterInitDate: '2025-01-02 00:00:00',
          charterTransferDate: '2025-02-02 00:00:00',
          pdcpDate: '2025-03-02 00:00:00',
          tr4aDate: '2025-04-02 00:00:00',
          edcpDate: '2025-05-02 00:00:00',
          adcpDate: '2025-09-02 00:00:00',
          insightFinishDate: '2025-09-02 00:00:00',
          relateOfferingName: null,
          rerlationshipName: null,
          serviceSolution: null,
          belongSolutionName: null,
          productClassL3Name: null,
          productSeriesL4Name: null,
          productOfferingL5Name: null,
          productBelongGroupsName: null,
          productBelongSpdtName: null,
          charterClass: null,
          charterTransferVersionTypeName: null,
          decisionLevelName: null,
          priorityName: null,
          businessPropertyName: null,
          bak: null,
          verison: null,
          state: 1,
          createUser: null,
          updatedUser: null,
          milestones: [
            {
              id: 'm1234567-1',
              pCode: 'm1234567',
              startDate: '2025-01-02',
              endDate: '2025-02-02',
              text: 'Charter开发',
              milestonskey: 'CHARTER_DEVELOPMENT',
              parent: 'm1234567',
              start_date: '2025-01-02',
              end_date: '2025-02-02',
            },
            {
              id: 'm1234567-2',
              pCode: 'm1234567',
              startDate: '2025-02-02',
              endDate: '2025-03-02',
              text: '概念和计划',
              milestonskey: 'CONCEPT_AND_PLAN',
              parent: 'm1234567',
              start_date: '2025-02-02',
              end_date: '2025-03-02',
            },
            {
              id: 'm1234567-3',
              pCode: 'm1234567',
              startDate: '2025-03-02',
              endDate: '2025-04-02',
              text: '初样开发',
              milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
              parent: 'm1234567',
              start_date: '2025-03-02',
              end_date: '2025-04-02',
            },
            {
              id: 'm1234567-4',
              pCode: 'm1234567',
              startDate: '2025-04-02',
              endDate: '2025-05-02',
              text: '正样开发',
              milestonskey: 'PROTOTYPE_DEVELOPMENT',
              parent: 'm1234567',
              start_date: '2025-04-02',
              end_date: '2025-05-02',
            },
            {
              id: 'm1234567-5',
              pCode: 'm1234567',
              startDate: '2025-05-02',
              endDate: '2025-09-02',
              text: '验证',
              milestonskey: 'VERIFY',
              parent: 'm1234567',
              start_date: '2025-05-02',
              end_date: '2025-09-02',
            },
          ],
          children: null,
          parent: 'm1234',
          render: 'split',
          isChildrenNode: true,
        },
        {
          bid: 5,
          pCode: 'm1234',
          type: 2,
          code: 'm12345678',
          name: 'm1234',
          projectRank: 'm1234',
          marketPositioning: 'm1234',
          costBenchmarking: 'm1234',
          performanceBenchmark: 'm1234',
          targetAudienceName: 'm1234',
          focusedIndustriesAndClientsName: 'm1234',
          newReachableCapacity: 'm1234',
          preparationOfKeyTechnologies: null,
          valueProposition: 'm1234',
          keyCompetitive: 'm1234',
          charterInitDate: '2025-01-02 00:00:00',
          charterTransferDate: '2025-02-02 00:00:00',
          pdcpDate: '2025-03-02 00:00:00',
          tr4aDate: '2025-04-02 00:00:00',
          edcpDate: '2025-05-02 00:00:00',
          adcpDate: '2025-07-02 00:00:00',
          insightFinishDate: '2025-09-02 00:00:00',
          relateOfferingName: null,
          rerlationshipName: null,
          serviceSolution: null,
          belongSolutionName: null,
          productClassL3Name: null,
          productSeriesL4Name: null,
          productOfferingL5Name: null,
          productBelongGroupsName: null,
          productBelongSpdtName: null,
          charterClass: null,
          charterTransferVersionTypeName: null,
          decisionLevelName: null,
          priorityName: null,
          businessPropertyName: null,
          bak: null,
          verison: null,
          state: 1,
          createUser: null,
          updatedUser: null,
          milestones: [
            {
              id: 'm12345678-1',
              pCode: 'm12345678',
              startDate: '2025-01-02',
              endDate: '2025-02-02',
              text: 'Charter开发',
              milestonskey: 'CHARTER_DEVELOPMENT',
              parent: 'm12345678',
              start_date: '2025-01-02',
              end_date: '2025-02-02',
            },
            {
              id: 'm12345678-2',
              pCode: 'm12345678',
              startDate: '2025-02-02',
              endDate: '2025-03-02',
              text: '概念和计划',
              milestonskey: 'CONCEPT_AND_PLAN',
              parent: 'm12345678',
              start_date: '2025-02-02',
              end_date: '2025-03-02',
            },
            {
              id: 'm12345678-3',
              pCode: 'm12345678',
              startDate: '2025-03-02',
              endDate: '2025-04-02',
              text: '初样开发',
              milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
              parent: 'm12345678',
              start_date: '2025-03-02',
              end_date: '2025-04-02',
            },
            {
              id: 'm12345678-4',
              pCode: 'm12345678',
              startDate: '2025-04-02',
              endDate: '2025-05-02',
              text: '正样开发',
              milestonskey: 'PROTOTYPE_DEVELOPMENT',
              parent: 'm12345678',
              start_date: '2025-04-02',
              end_date: '2025-05-02',
            },
            {
              id: 'm12345678-5',
              pCode: 'm12345678',
              startDate: '2025-05-02',
              endDate: '2025-07-02',
              text: '验证',
              milestonskey: 'VERIFY',
              parent: 'm12345678',
              start_date: '2025-05-02',
              end_date: '2025-07-02',
            },
          ],
          children: null,
          parent: 'm1234',
          render: 'split',
          isChildrenNode: true,
        },
      ],
      id: 'm1234',
      color: '#c7cfd8',
      text: '',
    },
    {
      id: 'm1234567-1',
      pCode: 'm1234567',
      startDate: '2025-01-02',
      endDate: '2025-02-02',
      text: 'Charter开发',
      milestonskey: 'CHARTER_DEVELOPMENT',
      parent: 'm1234567',
      start_date: '2025-01-02',
      end_date: '2025-02-02',
      color: '#adbbff',
    },
    {
      id: 'm1234567-2',
      pCode: 'm1234567',
      startDate: '2025-02-02',
      endDate: '2025-03-02',
      text: '概念和计划',
      milestonskey: 'CONCEPT_AND_PLAN',
      parent: 'm1234567',
      start_date: '2025-02-02',
      end_date: '2025-03-02',
      color: '#ffe179',
    },
    {
      id: 'm1234567-3',
      pCode: 'm1234567',
      startDate: '2025-03-02',
      endDate: '2025-04-02',
      text: '初样开发',
      milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
      parent: 'm1234567',
      start_date: '2025-03-02',
      end_date: '2025-04-02',
      color: '#adbbff',
    },
    {
      id: 'm1234567-4',
      pCode: 'm1234567',
      startDate: '2025-04-02',
      endDate: '2025-05-02',
      text: '正样开发',
      milestonskey: 'PROTOTYPE_DEVELOPMENT',
      parent: 'm1234567',
      start_date: '2025-04-02',
      end_date: '2025-05-02',
      color: '#92d9fb',
    },
    {
      id: 'm1234567-5',
      pCode: 'm1234567',
      startDate: '2025-05-02',
      endDate: '2025-09-02',
      text: '验证',
      milestonskey: 'VERIFY',
      parent: 'm1234567',
      start_date: '2025-05-02',
      end_date: '2025-09-02',
      color: '#64e0b7',
    },
    {
      bid: 4,
      pCode: 'm1234',
      type: 2,
      code: 'm1234567',
      name: 'm1234',
      projectRank: 'm1234',
      marketPositioning: 'm1234',
      costBenchmarking: 'm1234',
      performanceBenchmark: 'm1234',
      targetAudienceName: 'm1234',
      focusedIndustriesAndClientsName: 'm1234',
      newReachableCapacity: 'm1234',
      preparationOfKeyTechnologies: null,
      valueProposition: 'm1234',
      keyCompetitive: 'm1234',
      charterInitDate: '2025-01-02 00:00:00',
      charterTransferDate: '2025-02-02 00:00:00',
      pdcpDate: '2025-03-02 00:00:00',
      tr4aDate: '2025-04-02 00:00:00',
      edcpDate: '2025-05-02 00:00:00',
      adcpDate: '2025-09-02 00:00:00',
      insightFinishDate: '2025-09-02 00:00:00',
      relateOfferingName: null,
      rerlationshipName: null,
      serviceSolution: null,
      belongSolutionName: null,
      productClassL3Name: null,
      productSeriesL4Name: null,
      productOfferingL5Name: null,
      productBelongGroupsName: null,
      productBelongSpdtName: null,
      charterClass: null,
      charterTransferVersionTypeName: null,
      decisionLevelName: null,
      priorityName: null,
      businessPropertyName: null,
      bak: null,
      verison: null,
      state: 1,
      createUser: null,
      updatedUser: null,
      milestones: [
        {
          id: 'm1234567-1',
          pCode: 'm1234567',
          startDate: '2025-01-02',
          endDate: '2025-02-02',
          text: 'Charter开发',
          milestonskey: 'CHARTER_DEVELOPMENT',
          parent: 'm1234567',
          start_date: '2025-01-02',
          end_date: '2025-02-02',
        },
        {
          id: 'm1234567-2',
          pCode: 'm1234567',
          startDate: '2025-02-02',
          endDate: '2025-03-02',
          text: '概念和计划',
          milestonskey: 'CONCEPT_AND_PLAN',
          parent: 'm1234567',
          start_date: '2025-02-02',
          end_date: '2025-03-02',
        },
        {
          id: 'm1234567-3',
          pCode: 'm1234567',
          startDate: '2025-03-02',
          endDate: '2025-04-02',
          text: '初样开发',
          milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
          parent: 'm1234567',
          start_date: '2025-03-02',
          end_date: '2025-04-02',
        },
        {
          id: 'm1234567-4',
          pCode: 'm1234567',
          startDate: '2025-04-02',
          endDate: '2025-05-02',
          text: '正样开发',
          milestonskey: 'PROTOTYPE_DEVELOPMENT',
          parent: 'm1234567',
          start_date: '2025-04-02',
          end_date: '2025-05-02',
        },
        {
          id: 'm1234567-5',
          pCode: 'm1234567',
          startDate: '2025-05-02',
          endDate: '2025-09-02',
          text: '验证',
          milestonskey: 'VERIFY',
          parent: 'm1234567',
          start_date: '2025-05-02',
          end_date: '2025-09-02',
        },
      ],
      children: null,
      parent: 'm1234',
      render: 'split',
      isChildrenNode: true,
      id: 'm1234567',
    },
    {
      id: 'm12345678-1',
      pCode: 'm12345678',
      startDate: '2025-01-02',
      endDate: '2025-02-02',
      text: 'Charter开发',
      milestonskey: 'CHARTER_DEVELOPMENT',
      parent: 'm12345678',
      start_date: '2025-01-02',
      end_date: '2025-02-02',
      color: '#adbbff',
    },
    {
      id: 'm12345678-2',
      pCode: 'm12345678',
      startDate: '2025-02-02',
      endDate: '2025-03-02',
      text: '概念和计划',
      milestonskey: 'CONCEPT_AND_PLAN',
      parent: 'm12345678',
      start_date: '2025-02-02',
      end_date: '2025-03-02',
      color: '#ffe179',
    },
    {
      id: 'm12345678-3',
      pCode: 'm12345678',
      startDate: '2025-03-02',
      endDate: '2025-04-02',
      text: '初样开发',
      milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
      parent: 'm12345678',
      start_date: '2025-03-02',
      end_date: '2025-04-02',
      color: '#adbbff',
    },
    {
      id: 'm12345678-4',
      pCode: 'm12345678',
      startDate: '2025-04-02',
      endDate: '2025-05-02',
      text: '正样开发',
      milestonskey: 'PROTOTYPE_DEVELOPMENT',
      parent: 'm12345678',
      start_date: '2025-04-02',
      end_date: '2025-05-02',
      color: '#92d9fb',
    },
    {
      id: 'm12345678-5',
      pCode: 'm12345678',
      startDate: '2025-05-02',
      endDate: '2025-07-02',
      text: '验证',
      milestonskey: 'VERIFY',
      parent: 'm12345678',
      start_date: '2025-05-02',
      end_date: '2025-07-02',
      color: '#64e0b7',
    },
    {
      bid: 5,
      pCode: 'm1234',
      type: 2,
      code: 'm12345678',
      name: 'm1234',
      projectRank: 'm1234',
      marketPositioning: 'm1234',
      costBenchmarking: 'm1234',
      performanceBenchmark: 'm1234',
      targetAudienceName: 'm1234',
      focusedIndustriesAndClientsName: 'm1234',
      newReachableCapacity: 'm1234',
      preparationOfKeyTechnologies: null,
      valueProposition: 'm1234',
      keyCompetitive: 'm1234',
      charterInitDate: '2025-01-02 00:00:00',
      charterTransferDate: '2025-02-02 00:00:00',
      pdcpDate: '2025-03-02 00:00:00',
      tr4aDate: '2025-04-02 00:00:00',
      edcpDate: '2025-05-02 00:00:00',
      adcpDate: '2025-07-02 00:00:00',
      insightFinishDate: '2025-09-02 00:00:00',
      relateOfferingName: null,
      rerlationshipName: null,
      serviceSolution: null,
      belongSolutionName: null,
      productClassL3Name: null,
      productSeriesL4Name: null,
      productOfferingL5Name: null,
      productBelongGroupsName: null,
      productBelongSpdtName: null,
      charterClass: null,
      charterTransferVersionTypeName: null,
      decisionLevelName: null,
      priorityName: null,
      businessPropertyName: null,
      bak: null,
      verison: null,
      state: 1,
      createUser: null,
      updatedUser: null,
      milestones: [
        {
          id: 'm12345678-1',
          pCode: 'm12345678',
          startDate: '2025-01-02',
          endDate: '2025-02-02',
          text: 'Charter开发',
          milestonskey: 'CHARTER_DEVELOPMENT',
          parent: 'm12345678',
          start_date: '2025-01-02',
          end_date: '2025-02-02',
        },
        {
          id: 'm12345678-2',
          pCode: 'm12345678',
          startDate: '2025-02-02',
          endDate: '2025-03-02',
          text: '概念和计划',
          milestonskey: 'CONCEPT_AND_PLAN',
          parent: 'm12345678',
          start_date: '2025-02-02',
          end_date: '2025-03-02',
        },
        {
          id: 'm12345678-3',
          pCode: 'm12345678',
          startDate: '2025-03-02',
          endDate: '2025-04-02',
          text: '初样开发',
          milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
          parent: 'm12345678',
          start_date: '2025-03-02',
          end_date: '2025-04-02',
        },
        {
          id: 'm12345678-4',
          pCode: 'm12345678',
          startDate: '2025-04-02',
          endDate: '2025-05-02',
          text: '正样开发',
          milestonskey: 'PROTOTYPE_DEVELOPMENT',
          parent: 'm12345678',
          start_date: '2025-04-02',
          end_date: '2025-05-02',
        },
        {
          id: 'm12345678-5',
          pCode: 'm12345678',
          startDate: '2025-05-02',
          endDate: '2025-07-02',
          text: '验证',
          milestonskey: 'VERIFY',
          parent: 'm12345678',
          start_date: '2025-05-02',
          end_date: '2025-07-02',
        },
      ],
      children: null,
      parent: 'm1234',
      render: 'split',
      isChildrenNode: true,
      id: 'm12345678',
    },
    {
      id: 'm12345-1',
      pCode: 'm12345',
      startDate: '2025-01-02',
      endDate: '2025-02-02',
      text: 'Charter开发',
      milestonskey: 'CHARTER_DEVELOPMENT',
      parent: 'm12345',
      start_date: '2025-01-02',
      end_date: '2025-02-02',
      color: '#adbbff',
    },
    {
      id: 'm12345-2',
      pCode: 'm12345',
      startDate: '2025-02-02',
      endDate: '2025-03-02',
      text: '概念和计划',
      milestonskey: 'CONCEPT_AND_PLAN',
      parent: 'm12345',
      start_date: '2025-02-02',
      end_date: '2025-03-02',
      color: '#ffe179',
    },
    {
      id: 'm12345-3',
      pCode: 'm12345',
      startDate: '2025-03-02',
      endDate: '2025-04-02',
      text: '初样开发',
      milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
      parent: 'm12345',
      start_date: '2025-03-02',
      end_date: '2025-04-02',
      color: '#adbbff',
    },
    {
      id: 'm12345-4',
      pCode: 'm12345',
      startDate: '2025-04-02',
      endDate: '2025-05-02',
      text: '正样开发',
      milestonskey: 'PROTOTYPE_DEVELOPMENT',
      parent: 'm12345',
      start_date: '2025-04-02',
      end_date: '2025-05-02',
      color: '#92d9fb',
    },
    {
      id: 'm12345-5',
      pCode: 'm12345',
      startDate: '2025-05-02',
      endDate: '2025-06-02',
      text: '验证',
      milestonskey: 'VERIFY',
      parent: 'm12345',
      start_date: '2025-05-02',
      end_date: '2025-06-02',
      color: '#64e0b7',
    },
    {
      bid: 2,
      pCode: '0',
      type: 2,
      code: 'm12345',
      name: 'm1234',
      projectRank: 'm1234',
      marketPositioning: 'm1234',
      costBenchmarking: 'm1234',
      performanceBenchmark: 'm1234',
      targetAudienceName: 'm1234',
      focusedIndustriesAndClientsName: 'm1234',
      newReachableCapacity: 'm1234',
      preparationOfKeyTechnologies: null,
      valueProposition: 'm1234',
      keyCompetitive: 'm1234',
      charterInitDate: '2025-01-02 00:00:00',
      charterTransferDate: '2025-02-02 00:00:00',
      pdcpDate: '2025-03-02 00:00:00',
      tr4aDate: '2025-04-02 00:00:00',
      edcpDate: '2025-05-02 00:00:00',
      adcpDate: '2025-06-02 00:00:00',
      insightFinishDate: '2025-07-02 00:00:00',
      relateOfferingName: null,
      rerlationshipName: null,
      serviceSolution: null,
      belongSolutionName: null,
      productClassL3Name: null,
      productSeriesL4Name: null,
      productOfferingL5Name: null,
      productBelongGroupsName: null,
      productBelongSpdtName: null,
      charterClass: null,
      charterTransferVersionTypeName: null,
      decisionLevelName: null,
      priorityName: null,
      businessPropertyName: null,
      bak: null,
      verison: null,
      state: 1,
      createUser: null,
      updatedUser: null,
      milestones: [
        {
          id: 'm12345-1',
          pCode: 'm12345',
          startDate: '2025-01-02',
          endDate: '2025-02-02',
          text: 'Charter开发',
          milestonskey: 'CHARTER_DEVELOPMENT',
          parent: 'm12345',
          start_date: '2025-01-02',
          end_date: '2025-02-02',
        },
        {
          id: 'm12345-2',
          pCode: 'm12345',
          startDate: '2025-02-02',
          endDate: '2025-03-02',
          text: '概念和计划',
          milestonskey: 'CONCEPT_AND_PLAN',
          parent: 'm12345',
          start_date: '2025-02-02',
          end_date: '2025-03-02',
        },
        {
          id: 'm12345-3',
          pCode: 'm12345',
          startDate: '2025-03-02',
          endDate: '2025-04-02',
          text: '初样开发',
          milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
          parent: 'm12345',
          start_date: '2025-03-02',
          end_date: '2025-04-02',
        },
        {
          id: 'm12345-4',
          pCode: 'm12345',
          startDate: '2025-04-02',
          endDate: '2025-05-02',
          text: '正样开发',
          milestonskey: 'PROTOTYPE_DEVELOPMENT',
          parent: 'm12345',
          start_date: '2025-04-02',
          end_date: '2025-05-02',
        },
        {
          id: 'm12345-5',
          pCode: 'm12345',
          startDate: '2025-05-02',
          endDate: '2025-06-02',
          text: '验证',
          milestonskey: 'VERIFY',
          parent: 'm12345',
          start_date: '2025-05-02',
          end_date: '2025-06-02',
        },
      ],
      children: null,
      render: 'split',
      id: 'm12345',
    },
    {
      id: 'm12346-1',
      pCode: 'm12346',
      startDate: '2025-01-02',
      endDate: '2025-02-02',
      text: 'Charter开发',
      milestonskey: 'CHARTER_DEVELOPMENT',
      parent: 'm12346',
      start_date: '2025-01-02',
      end_date: '2025-02-02',
      color: '#adbbff',
    },
    {
      id: 'm12346-2',
      pCode: 'm12346',
      startDate: '2025-02-02',
      endDate: '2025-03-02',
      text: '概念和计划',
      milestonskey: 'CONCEPT_AND_PLAN',
      parent: 'm12346',
      start_date: '2025-02-02',
      end_date: '2025-03-02',
      color: '#ffe179',
    },
    {
      id: 'm12346-3',
      pCode: 'm12346',
      startDate: '2025-03-02',
      endDate: '2025-04-02',
      text: '初样开发',
      milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
      parent: 'm12346',
      start_date: '2025-03-02',
      end_date: '2025-04-02',
      color: '#adbbff',
    },
    {
      id: 'm12346-4',
      pCode: 'm12346',
      startDate: '2025-04-02',
      endDate: '2025-05-02',
      text: '正样开发',
      milestonskey: 'PROTOTYPE_DEVELOPMENT',
      parent: 'm12346',
      start_date: '2025-04-02',
      end_date: '2025-05-02',
      color: '#92d9fb',
    },
    {
      id: 'm12346-5',
      pCode: 'm12346',
      startDate: '2025-05-02',
      endDate: '2025-08-02',
      text: '验证',
      milestonskey: 'VERIFY',
      parent: 'm12346',
      start_date: '2025-05-02',
      end_date: '2025-08-02',
      color: '#64e0b7',
    },
    {
      bid: 3,
      pCode: '0',
      type: 2,
      code: 'm12346',
      name: 'm1234',
      projectRank: 'm1234',
      marketPositioning: 'm1234',
      costBenchmarking: 'm1234',
      performanceBenchmark: 'm1234',
      targetAudienceName: 'm1234',
      focusedIndustriesAndClientsName: 'm1234',
      newReachableCapacity: 'm1234',
      preparationOfKeyTechnologies: null,
      valueProposition: 'm1234',
      keyCompetitive: 'm1234',
      charterInitDate: '2025-01-02 00:00:00',
      charterTransferDate: '2025-02-02 00:00:00',
      pdcpDate: '2025-03-02 00:00:00',
      tr4aDate: '2025-04-02 00:00:00',
      edcpDate: '2025-05-02 00:00:00',
      adcpDate: '2025-08-02 00:00:00',
      insightFinishDate: '2025-09-02 00:00:00',
      relateOfferingName: null,
      rerlationshipName: null,
      serviceSolution: null,
      belongSolutionName: null,
      productClassL3Name: null,
      productSeriesL4Name: null,
      productOfferingL5Name: null,
      productBelongGroupsName: null,
      productBelongSpdtName: null,
      charterClass: null,
      charterTransferVersionTypeName: null,
      decisionLevelName: null,
      priorityName: null,
      businessPropertyName: null,
      bak: null,
      verison: null,
      state: 1,
      createUser: null,
      updatedUser: null,
      milestones: [
        {
          id: 'm12346-1',
          pCode: 'm12346',
          startDate: '2025-01-02',
          endDate: '2025-02-02',
          text: 'Charter开发',
          milestonskey: 'CHARTER_DEVELOPMENT',
          parent: 'm12346',
          start_date: '2025-01-02',
          end_date: '2025-02-02',
        },
        {
          id: 'm12346-2',
          pCode: 'm12346',
          startDate: '2025-02-02',
          endDate: '2025-03-02',
          text: '概念和计划',
          milestonskey: 'CONCEPT_AND_PLAN',
          parent: 'm12346',
          start_date: '2025-02-02',
          end_date: '2025-03-02',
        },
        {
          id: 'm12346-3',
          pCode: 'm12346',
          startDate: '2025-03-02',
          endDate: '2025-04-02',
          text: '初样开发',
          milestonskey: 'INITIAL_SAMPLE_DEVELOPMENT',
          parent: 'm12346',
          start_date: '2025-03-02',
          end_date: '2025-04-02',
        },
        {
          id: 'm12346-4',
          pCode: 'm12346',
          startDate: '2025-04-02',
          endDate: '2025-05-02',
          text: '正样开发',
          milestonskey: 'PROTOTYPE_DEVELOPMENT',
          parent: 'm12346',
          start_date: '2025-04-02',
          end_date: '2025-05-02',
        },
        {
          id: 'm12346-5',
          pCode: 'm12346',
          startDate: '2025-05-02',
          endDate: '2025-08-02',
          text: '验证',
          milestonskey: 'VERIFY',
          parent: 'm12346',
          start_date: '2025-05-02',
          end_date: '2025-08-02',
        },
      ],
      children: null,
      render: 'split',
      id: 'm12346',
    },
  ],
};


http://www.kler.cn/a/571674.html

相关文章:

  • PyCharm 环境配置精髓:打造高效 Python 开发的基石
  • 1.从0搭建前端Vue项目工程
  • 华为最新OD机试真题-服务失效判断-OD统一考试(E卷)
  • hutool Java的工具箱介绍
  • 【氮化镓】基于SiC脉冲I-V系统研究Schottky型p-GaN HEMT正栅极ESD机制
  • Linux:vim快捷键
  • 蓝桥杯备考:动态规划线性dp之传球游戏
  • 结合PyMuPDF+pdfplumber,删除PDF指定文本后面的内容
  • 【漫话机器学习系列】117.马修斯相关系数(Matthews Correlation Coefficient, MCC)
  • 【四.RAG技术与应用】【11.阿里云百炼应用(上):RAG在云端的实践】
  • 【前端跨域】CORS:跨域资源共享的机制与实现
  • 探秘 Linux 系统编程:进程地址空间的奇妙世界
  • 一文看懂 DeepSeek 版本全解析
  • 【YashanDB认证】yashandb23.3.1 个人版单机部署安装实践
  • 算法-二叉树篇22-二叉搜索树的最近公共祖先
  • 大语言模型 智能助手——既能生成自然语言回复,又能在必要时调用外部工具获取实时数据
  • PyTorch内存优化的10种策略总结:在有限资源环境下高效训练模型
  • RefuseManualStart/Stop增强Linux系统安全性?详解systemd单元保护机制
  • 浅谈⽂件操作和IO
  • HTML-05NPM使用踩坑