123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- <template>
- <div>
- <avue-crud
- v-model:search="search"
- :option="option"
- @search-change="searchChange"
- @search-reset="resetChange"
- />
- <div class="btns">
- <div>
- <el-button type="primary" @click="exportToPNG">导出PNG图片</el-button>
- <el-button type="primary" @click="exportToPDF">导出PDF文件</el-button>
- </div>
- <!-- <el-button type="params" v-print="printObj" @click="toPrint"
- >打印</el-button
- > -->
- <div class="illustration">
- <div style="display: flex; align-items: center; margin-right: 5px">
- <div class="round1"></div>
- :完成
- </div>
- <div style="display: flex; align-items: center">
- <div class="round2"></div>
- :未完成
- </div>
- </div>
- </div>
- <div class="main-content">
- <div ref="ganttRef" id="gantt_here" class="gantt-container"></div>
- </div>
- </div>
- </template>
- <script setup>
- import { gantt } from "dhtmlx-gantt";
- import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
- import html2canvas from "html2canvas";
- import { htmlPdf } from "@/utils/htmlPDF.js";
- import { useCrud } from "@/hooks/userCrud";
- const ganttRef = ref(null);
- const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
- useCrud({
- src: "/api/v1/process/census/queryApsResultGant",
- pageStr: "no",
- });
- const exportToPDF = () => {
- var fileName = "甘特图pdf";
- const fileList = document.getElementsByClassName("gantt_here");
- htmlPdf(fileName, document.querySelector("#gantt_here"), fileList, 1111);
- };
- const exportToPNG = async () => {
- const chartContainer = ganttRef.value;
- const canvas = await html2canvas(chartContainer);
- const img = canvas.toDataURL("image/png");
- const a = document.createElement("a");
- a.href = img;
- a.download = "甘特图.png";
- a.click();
- };
- // const printUrl = ref("");
- // const toPrint = async () => {
- // const chartContainer = ganttRef.value;
- // const canvas = await html2canvas(chartContainer);
- // const img = canvas.toDataURL("image/png");
- // printUrl.value = img;
- // };
- // const printObj = ref({
- // id: "gantt_here",
- // preview: true,
- // popTitle: "甘特图",
- // url: printUrl.value,
- // });
- const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
- Methords;
- option.value = Object.assign(option.value, {
- selection: false,
- menu: true,
- menuWidth: 100,
- addBtn: false,
- filterBtn: false,
- searchShowBtn: true,
- columnBtn: false,
- gridBtn: false,
- editBtn: false,
- viewBtn: false,
- delBtn: false,
- column: [
- {
- label: "日期范围",
- prop: "searchTime",
- search: true,
- hide: true,
- type: "date",
- format: "YYYY-MM-DD",
- valueFormat: "YYYY-MM-DD",
- searchRange: true,
- startPlaceholder: "开始日期",
- endPlaceholder: "结束日期",
- },
- {
- label: "订单名称",
- prop: "name",
- search: true,
- },
- {
- label: "时间维度",
- prop: "timeType",
- search: true,
- type: "select",
- searchValue: "1",
- dicData: [
- {
- dictLabel: "小时",
- dictValue: "0",
- },
- {
- dictLabel: "日",
- dictValue: "1",
- },
- {
- dictLabel: "月",
- dictValue: "2",
- },
- ],
- props: {
- label: "dictLabel",
- value: "dictValue",
- },
- },
- {
- label: "订单状态",
- prop: "type",
- search: true,
- type: "select",
- dicData: [
- {
- dictLabel: "订单",
- dictValue: "0",
- },
- {
- dictLabel: "工单",
- dictValue: "1",
- },
- {
- dictLabel: "流转卡号",
- dictValue: "2",
- },
- {
- dictLabel: "工序",
- dictValue: "3",
- },
- ],
- props: {
- label: "dictLabel",
- value: "dictValue",
- },
- },
- ],
- });
- const getCurrentMonthStartAndEndDates = () => {
- // 获取当前日期
- let now = new Date();
- // 获取当前月份的第一天
- let startDate = new Date(now.getFullYear(), now.getMonth(), 1);
- // 获取当前月份的最后一天
- let endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
- // 格式化日期为'YYYY-MM-DD'格式
- function formatDate(date) {
- let year = date.getFullYear();
- let month = String(date.getMonth() + 1).padStart(2, "0");
- let day = String(date.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
- }
- // 返回包含开始和结束日期的数组
- return [formatDate(startDate), formatDate(endDate)];
- };
- const demoData = {
- data: [
- {
- id: 11,
- text: "Project #1",
- start_date: "2024-07-01 08:00:00",
- endTime: "2024-09-30 09:00:00",
- startTime: "2024-07-30 08:00:00",
- duration: "11",
- progress: 0.8,
- open: true,
- },
- ],
- };
- //初始化甘特图
- const initGantt = (type) => {
- gantt.plugins({
- tooltip: true,
- marker: true,
- critical_path: true,
- export_api: true,
- });
- gantt.templates.task_text = function (start, end, task) {
- return (
- "<span style='padding:0 5px;font-size:15px;color: #000; display: inline-block;width: 100%; white-space: nowrap;overflow: hidden; text-overflow: ellipsis; '>" +
- task.text +
- "</span>"
- );
- };
- gantt.templates.progress_text = function (start, end, task) {
- return (
- "<span style='text-align:left;'>" +
- Math.round(task.progress * 100) +
- "% </span>"
- );
- };
- gantt.templates.task_class = function (start, end, task) {
- return "taskClass";
- };
- if (type) {
- gantt.config.duration_unit = type;
- }
- gantt.config.show_today = true;
- gantt.config.grid_width = 350;
- gantt.config.add_column = false;
- gantt.config.duration_step = 1;
- gantt.config.resize_rows = true;
- gantt.config.columns = [
- {
- tree: true,
- name: "text",
- label: "订单名称",
- width: "240",
- },
- {
- name: "startTime",
- label: "开始时间",
- align: "center",
- width: "160",
- template(task) {
- return task.startTime;
- },
- },
- {
- name: "endTime",
- label: "结束时间",
- align: "center",
- width: "160",
- template(task) {
- return task.endTime;
- },
- },
- ];
- gantt.config.autofit = true;
- gantt.config.resize_rows = true;
- gantt.config.row_height = 60;
- gantt.config.bar_height = 40;
- gantt.config.min_column_width = 60;
- gantt.config.xml_date = "%Y-%m-%d %H:%i:%s"; //甘特图时间格式
- gantt.config.readonly = true; //是否只读
- gantt.i18n.setLocale("cn"); //设置语言
- gantt.templates.tooltip_text = function (start, end, task) {
- const text = `名称: ${task.text}<br/>总数: ${task.num}<br/>完成进度: ${task.progress * 100}%`;
- return !task.parent
- ? `${text}<br/>交期时间: ${task.deliverWhen}`
- : `${text}<br/>计划开始时间: ${task.startTime}<br/>计划结束时间: ${task.endTime}`; // eslint-disable-line
- };
- 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)}`,
- });
- gantt.init("gantt_here"); //初始化
- };
- const setTime = () => {
- search.value = {
- searchTime: getCurrentMonthStartAndEndDates(),
- timeType: "1",
- };
- };
- function convertDateString1(str) {
- // 将输入的日期字符串转换为 Date 对象
- let date = new Date(str);
- // 获取年、月、日
- let year = date.getFullYear();
- let month = date.toLocaleString("en-us", { month: "short" });
- let day = date.getDate();
- // 构造新的日期字符串格式
- let formattedDate = `${date.toDateString().slice(0, 3)} ${month} ${day} ${year} 00:00:00 GMT+0800 (GMT+08:00)`;
- return formattedDate;
- }
- function convertDateString2(str) {
- // 将输入的日期字符串转换为 Date 对象
- let date = new Date(str);
- // 获取年、月、日
- let year = date.getFullYear();
- let month = date.toLocaleString("en-us", { month: "short" });
- let day = date.getDate();
- // 构造新的日期字符串格式
- let formattedDate = `${date.toDateString().slice(0, 3)} ${month} ${day} ${year} 24:00:00 GMT+0800 (GMT+08:00)`;
- return formattedDate;
- }
- // watchEffect(() => {
- // //此api后续弃用
- // // gantt.parse({ data: data.value });
- // gantt.parse(demoData);
- // });
- const setGantt = () => {
- gantt.clearAll();
- if (search?.value.searchTime) {
- gantt.config.start_date = convertDateString1(search?.value.searchTime[0]);
- gantt.config.end_date = convertDateString2(search?.value.searchTime[1]);
- gantt.config.show_tasks_outside_timescale = true;
- }
- switch (search.value.timeType) {
- case "0":
- gantt.config.duration_unit = "hour";
- gantt.config.scale_height = 28 * 4;
- gantt.config.scales = [
- {
- unit: "year",
- step: 1,
- format: "%Y年",
- css: function (date) {
- return "year";
- },
- },
- {
- unit: "month",
- step: 1,
- format: "%m月",
- css: function (date) {
- return "month";
- },
- },
- {
- unit: "day",
- step: 1,
- format: "%d日",
- css: function (date) {
- return "day";
- },
- },
- {
- unit: "hour",
- step: 1,
- format: "%H时",
- css: function (date) {
- return "hour";
- },
- },
- ];
- gantt.init("gantt_here");
- gantt.render();
- gantt.parse({ data: useData.value });
- break;
- case "1":
- gantt.config.scale_height = 28 * 4;
- gantt.config.scales = [
- {
- unit: "year",
- step: 1,
- format: "%Y年",
- css: function (date) {
- return "year";
- },
- },
- {
- unit: "month",
- step: 1,
- format: "%m月",
- css: function (date) {
- return "month";
- },
- },
- {
- unit: "day",
- step: 1,
- format: "%d日",
- css: function (date) {
- return "day";
- },
- },
- ];
- gantt.config.duration_unit = "day";
- gantt.init("gantt_here");
- gantt.render();
- gantt.parse({ data: useData.value });
- break;
- case "2":
- // initGantt("month");
- gantt.config.scale_height = 28 * 4;
- gantt.config.scales = [
- {
- unit: "year",
- step: 1,
- format: "%Y年",
- css: function (date) {
- return "year";
- },
- },
- {
- unit: "month",
- step: 1,
- format: "%m月",
- css: function (date) {
- return "month";
- },
- },
- ];
- gantt.config.duration_unit = "month";
- gantt.init("gantt_here");
- gantt.parse({ data: useData.value });
- gantt.render();
- break;
- }
- };
- const useData = ref([]);
- const setUseData = (data) => {
- useData.value = [];
- const data1 = [...data];
- data1.forEach((element) => {
- element.start_date = element.startTime;
- if (element.progress != 1) {
- element.color = "orange";
- } else {
- element.color = "green";
- }
- });
- const data2 = JSON.parse(JSON.stringify(data1));
- useData.value = data2;
- };
- onMounted(() => {
- setTime();
- dataList();
- initGantt();
- });
- watch(
- () => data.value,
- () => {
- if (data.value) {
- setUseData(data.value);
- setGantt();
- }
- },
- { immediate: true, deep: true }
- );
- </script>
- <style scoped lang="scss">
- .btns {
- margin: 7px 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
- .illustration {
- display: flex;
- padding-right: 5%;
- align-items: center;
- width: 240px;
- justify-content: space-between;
- .round2 {
- width: 20px;
- height: 20px;
- background-color: orange;
- border-radius: 10px;
- }
- .round1 {
- width: 20px;
- height: 20px;
- background-color: green;
- border-radius: 10px;
- }
- }
- }
- :deep(.avue-crud__body) {
- display: none;
- }
- .main-content {
- width: 100%;
- height: 600px;
- .gantt-container {
- width: 100%;
- height: 100%;
- }
- }
- .ganttStyle {
- border-radius: 50%;
- }
- </style>
|