Przeglądaj źródła

服务改善,bug修复

qymljy 1 miesiąc temu
rodzic
commit
ab2123cf2c

+ 6 - 0
package-lock.json

@@ -20,6 +20,7 @@
         "core-js": "^3.8.3",
         "countup.js": "^2.0.8",
         "cross-env": "^7.0.3",
+        "dhtmlx-gantt": "^9.1.2",
         "dom-to-image": "^2.6.0",
         "element-ui": "^2.15.6",
         "file-saver": "^2.0.5",
@@ -8144,6 +8145,11 @@
       "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
       "dev": true
     },
+    "node_modules/dhtmlx-gantt": {
+      "version": "9.1.2",
+      "resolved": "https://registry.npmmirror.com/dhtmlx-gantt/-/dhtmlx-gantt-9.1.2.tgz",
+      "integrity": "sha512-pOhMEpPUExVdvnI83OpSvailV8gXY8b6kG86CzeqDvjw9xxRCl5P4l4dD4cHBdiVMsb0xaJqR424tu6PbNmhgA=="
+    },
     "node_modules/diff": {
       "version": "4.0.2",
       "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz",

+ 1 - 0
package.json

@@ -21,6 +21,7 @@
     "core-js": "^3.8.3",
     "countup.js": "^2.0.8",
     "cross-env": "^7.0.3",
+    "dhtmlx-gantt": "^9.1.2",
     "dom-to-image": "^2.6.0",
     "element-ui": "^2.15.6",
     "file-saver": "^2.0.5",

+ 4 - 1
src/HDrpManagement/serveWorkBillTask/index.vue

@@ -160,6 +160,9 @@
               : $t("无")
           }}
         </div>
+        <div v-else-if="scope.data.column.columnname == 'confirm_options'">
+          {{scope.data.column.data.confirm == 0?'无':scope.data.column.data[[scope.data.column.columnname]]?scope.data.column.data[[scope.data.column.columnname]]:'--'}}
+        </div>
         <div v-else>
           {{
             scope.data.column.data[[scope.data.column.columnname]]
@@ -184,4 +187,4 @@ export default {
 };
 </script>
 <style>
-</style>
+</style>

+ 2 - 2
src/HDrpManagement/serveWorkBillTask/modules/detail.vue

@@ -129,7 +129,7 @@ export default {
         },
         {
           label: "确认项",
-          value: this.mainData.confirm_options,
+          value: this.mainData.confirm == 0?'无':this.mainData.confirm_options?this.mainData.confirm_options:"--",
         },
         {
           label: "上传合同",
@@ -269,4 +269,4 @@ export default {
 </script>
 
 <style scoped>
-</style>
+</style>

+ 1 - 1
src/HDrpManagement/serviceImprovement/components/actionImplementation/actionDetail.vue

@@ -97,7 +97,7 @@ export default {
       this.$emit('recordSet',data)
     },
     finishSuccess(data){
-      this.listData()
+      // this.listData()
       this.$emit('recordSet',data)
     },
     deleteFile(){},

+ 4 - 4
src/HDrpManagement/serviceImprovement/components/actionImplementation/addRecord.vue

@@ -101,10 +101,10 @@ export default {
         },
       })
       this.tool.showMessage(res,()=>{
-        if (this.btnTitle != '编辑'){
-          this.listFiles = this.$refs.list.list
-          this.batchBinding(res.data)
-        }
+        // if (this.btnTitle != '编辑'){
+        //   this.listFiles = this.$refs.list.list
+        //   this.batchBinding(res.data)
+        // }
         this.drawerShow = false
         this.$emit('addSuccess',this.data.sa_service_improvement_planid)
       })

+ 36 - 9
src/HDrpManagement/serviceImprovement/components/actionImplementation/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
-    <div style="display:flex;justify-content: space-between">
-      <table-detail :layout="tablecols" :data="list" :opwidth="200" :custom="true" style="margin-top: 10px" @rowClick="rowClick">
+    <div style="display:flex;justify-content: space-between;">
+      <table-detail ref="tableRef" :layout="tablecols" :data="list" :opwidth="200" :custom="true" style="margin-top: 10px" @rowClick="rowClick" >
         <template v-slot:customcol="scope">
           <div v-if="scope.column.columnname == 'status'">
             <div :style="tool.getStatusColor(scope.column.data[scope.column.columnname])">{{scope.column.data[scope.column.columnname]}}</div>
@@ -9,6 +9,9 @@
           <div v-else>{{scope.column.data[scope.column.columnname]}}</div>
         </template>
       </table-detail>
+      <div style="width: 45%" id="gantt222">
+        <ganttChart :data="list" style="margin-top: 10px" ref="chartRef" clickCan="可以点击" @taskDetail="taskDetail"></ganttChart>
+      </div>
     </div>
     <div style="margin-top: 20px">
       <actionDetail v-if="detailShow" ref="actionRef" :data="selectData" :mainData="mainData" @recordSet="recordSet"></actionDetail>
@@ -18,9 +21,10 @@
 
 <script>
 import actionDetail from './actionDetail'
+import ganttChart from '../improvementPlan/ganttChart'
 export default {
   name: "index",
-  components:{actionDetail},
+  components:{actionDetail,ganttChart},
   props:['mainData'],
   data(){
     return {
@@ -38,26 +42,47 @@ export default {
       currentPage:0,
       userid:JSON.parse(sessionStorage.getItem('active_account')).userid,
       detailShow:false,
-      selectData:''
+      selectData:'',
+      nowIndex:''
     }
   },
   methods:{
-    async listData(){
+    async listData(data){
       const res = await this.$api.requested(this.param)
       this.list = res.data
       console.log(res.data,'方案列表')
+      this.$refs.chartRef.setList(this.list)
+      if (data){
+        this.list.forEach(item =>{
+          if (item.sa_service_improvement_planid == data){
+            this.selectData = item
+          }
+        })
+        this.$refs.actionRef.listData()
+      }
+
     },
     rowClick(data){
-      console.log(data)
       this.selectData = data
       this.detailShow = true
       this.$nextTick(()=>{
         this.$refs.actionRef.listData()
       })
-
     },
     recordSet(data){
-      this.listData()
+      this.listData(data)
+    },
+    taskDetail(data){
+
+      this.detailShow = true
+      this.list.forEach(item =>{
+        if (item.sa_service_improvement_planid == data.id){
+          this.selectData = item
+        }
+      })
+      this.$nextTick(()=>{
+        this.$refs.actionRef.listData()
+      })
     }
   },
   created() {
@@ -67,5 +92,7 @@ export default {
 </script>
 
 <style scoped>
-
+.el-table .success-row {
+  background: #50c50f;
+}
 </style>

+ 8 - 2
src/HDrpManagement/serviceImprovement/components/improvementPlan/edit.vue

@@ -83,6 +83,7 @@
             <el-button type="text" size="mini" class="inline-16" @click="delClick(scope.data)">{{$t(`删除`)}}</el-button>
           </template>
         </table-detail>
+        <ganttChart :data="list" style="margin-top: 10px" ref="chartRef"></ganttChart>
       </div>
       <div class="fixed__btn__panel">
         <el-button
@@ -104,9 +105,11 @@
 </template>
 
 <script>
+import ganttChart from './ganttChart'
 export default {
   name: "edit",
   props:['data'],
+  components:{ganttChart},
   data(){
     return {
       drawerVisible:false,
@@ -144,6 +147,7 @@ export default {
     async listData(){
       const res = await this.$api.requested(this.param)
       this.list = res.data
+      this.$refs.chartRef.setList(this.list)
       console.log(res.data,'方案列表')
     },
     addRow(){
@@ -276,7 +280,7 @@ export default {
       }else {
         this.enddateError = ''
       }
-      if (data.userid_charge == ''){
+      if (data.userid_charge == '' && type == '责任人'){
         this.useridError = '责任人不能为空'
       }else {
         this.useridError = ''
@@ -287,7 +291,9 @@ export default {
         this.measureError = ''
       }
     },
-    onClose(){}
+    onClose(){
+      this.$emit('onSuccess')
+    }
   },
   created() {
     this.tablecols = this.tool.tabelCol(this.$route.name).improvementPlanEditTable.tablecols

+ 251 - 36
src/HDrpManagement/serviceImprovement/components/improvementPlan/ganttChart.vue

@@ -1,54 +1,269 @@
 <template>
-  <div>
-    <gantt-chart-vue
-        :rows="ganttRows"
-        :legend="ganttLegend"
-        :readOnly="false"
-        @tagDragEnd="handleDragEnd"
-    />
+  <div class="gantt-wrapper">
+    <!-- 甘特图容器 -->
+    <div ref="ganttContainer" class="gantt-container"></div>
   </div>
 </template>
 
 <script>
-import ganttChartVue from 'gantt-chart-vue';
+import gantt from 'dhtmlx-gantt';
+import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'; // 引入样式
+// 立即启用插件,在任何配置之前
+
 export default {
   name: "ganttChart",
-  components: { ganttChartVue },
+  props:['data','clickCan'],
   data() {
     return {
-      // 1. 定义图例 (tag的类型和颜色)
-      ganttLegend: [
-        { label: '设计', color: '#5470c6', type: 1, dragable: true },
-        { label: '开发', color: '#91cc75', type: 2, dragable: true },
-        { label: '测试', color: '#fac858', type: 3, dragable: false },
-      ],
-      // 2. 定义行数据
-      ganttRows: [
-        {
-          label: '项目A',
-          tags: [
-            { startTime: '2024-03-01 09:00', endTime: '2024-03-05 18:00', label: '原型设计', type: 1 },
-            { startTime: '2024-03-06 09:00', endTime: '2024-03-20 18:00', label: '前端开发', type: 2 },
-          ]
-        },
-        {
-          label: '项目B',
-          tags: [
-            { startTime: '2024-03-10 09:00', endTime: '2024-03-25 18:00', label: '功能测试', type: 3 },
-          ]
-        }
-      ]
+      clickedTaskInfo: null,
+      // 模拟数据
+      tasks: {
+        data: [],
+        links: []
+      },
+      showType:'日'
     };
   },
+  mounted() {
+    // this.setList()
+    this.initGantt();
+    // 监听窗口大小变化以重绘甘特图
+    window.addEventListener('resize', () => {
+      if (gantt) gantt.render();
+    });
+  },
+  beforeDestroy() {
+    // 清理事件监听,防止内存泄漏
+    window.removeEventListener('resize', () => {
+      if (gantt) gantt.render();
+    });
+  },
   methods: {
-    handleDragEnd(data) {
-      console.log('任务拖拽结束,新数据:', data);
-      // 在这里更新后端数据
-    }
-  }
+    setList(data){
+      console.log(data,'输出data的数据输出')
+      const oneDay = 24 * 60 * 60 * 1000; // 毫秒数
+      const firstDate = new Date(data[0].begdate);
+      const secondDate = new Date(data[0].enddate);
+      const diffDays = Math.round(Math.abs((firstDate - secondDate) / oneDay));
+      console.log(diffDays,'相差的天数')
+      if (diffDays > 30){
+        this.showType = '月'
+      }else {
+        this.showType = '日'
+      }
+      this.tasks.data = data.map(item => {
+        return {
+          id:item.sa_service_improvement_planid,
+          text:item.title + ',' + item.begdate + '~' + item.enddate,
+          start_date:item.begdate,
+          end_date:item.enddate,
+          progress:1
+        }
+      })
+      this.$nextTick(()=>{
+        this.initGantt()
+      })
+
+    },
+    initGantt() {
+
+      gantt.i18n.setLocale('cn'); // 设置为中文 [citation:1]
+      gantt.config.xml_date = "%Y-%m-%d"; // 设置日期格式 [citation:5]
+
+      // 关键配置:隐藏左侧表格
+      gantt.config.grid_width = 0; // 将左侧表格宽度设为0
+      gantt.config.show_grid = false; // 不显示表格网格
+
+      // === 只读配置:禁止所有拖动编辑 ===
+      gantt.config.readonly = true;           // 整体只读模式
+
+      // 6. 工具提示配置
+      gantt.config.tooltip_timeout = 100;  // 设置短延迟方便测试
+      gantt.config.tooltip_hide_timeout = 100;
+      gantt.config.tooltip_offset_x = 15;
+      gantt.config.tooltip_offset_y = 20;
+
+
+      // 7. 自定义工具提示(简化版本测试)
+      gantt.templates.tooltip_text = function(start, end, task) {
+        // 简单测试内容
+        return `
+          <div style="padding: 10px; background: white; border: 1px solid #ccc; border-radius: 4px;">
+            <div><strong>${task.text}</strong></div>
+            <div>开始: ${gantt.templates.tooltip_date_format(start)}</div>
+            <div>结束: ${gantt.templates.tooltip_date_format(end)}</div>
+          </div>
+        `;
+      };
+
+      if (this.showType == '日'){
+        gantt.config.scales = [
+          { unit: "month", step: 1, format: "%Y年%m月" },
+          { unit: "day", step: 1, format: "%d日" }
+        ];
+      }else {
+        gantt.config.scales = [
+          { unit: "year", step: 1, format: "%Y年" },
+          { unit: "month", step: 1, format: "%Y年%m月" }
+        ];
+      }
+
+      // 9. 调试:检查tooltip是否被正确注册
+      console.log('Tooltip plugin enabled:', !!gantt.plugins.tooltip);
+
+      // === 添加点击事件 ===
+      this.setupClickEvents();
+
+
+      // 4. 清空并初始化
+      gantt.clearAll();
+      gantt.init(this.$refs.ganttContainer);
+      gantt.parse(this.tasks);
+    },
+    formatDate(dateStr) {
+      if (!dateStr) return '';
+      const d = new Date(dateStr);
+      const y = d.getFullYear();
+      const m = String(d.getMonth() + 1).padStart(2, '0');
+      const day = String(d.getDate()).padStart(2, '0');
+      return `${y}年${m}月${day}日`;
+    },
+    setupClickEvents(){
+      // 先解绑已存在的事件
+      gantt.detachEvent("onTaskClick");
+
+      // 再重新绑定
+      gantt.attachEvent("onTaskClick", (id, e) => {
+        const task = gantt.getTask(id);
+        console.log('点击了任务:', task);
+
+        // 显示任务详情
+        this.showTaskDetail(task);
+
+        return false;
+      });
+    },
+    // 显示任务详情
+    showTaskDetail(task) {
+      this.$emit('taskDetail',task)
+    },
+  },
 };
 </script>
 
 <style scoped>
+/* 容器样式 */
+.gantt-wrapper {
+  width: 100%;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+.gantt-container {
+  height: 200px;
+  width: 100%;
+  border: 1px solid #e0e0e0; /* 淡灰色边框 */
+}
+
+.click-info-box {
+  margin-top: 15px;
+  padding: 10px;
+  background: #f0f7ff;
+  color: #1890ff;
+  border-radius: 4px;
+  font-size: 14px;
+}
+
+.date-range {
+  color: #666;
+  margin-left: 8px;
+}
+
+/* =========================================
+   核心:深度定制 dhtmlxGantt 样式以匹配图片
+   注意:这里使用了 /deep/ 或 ::v-deep (Vue 2/3 兼容写法)
+   ========================================= */
+
+/* 1. 整体背景与字体 */
+::v-deep .gantt_container {
+  background-color: #fff;
+  color: #333;
+  font-size: 13px;
+}
+
+/* 2. 顶部时间轴 (Header) */
+::v-deep .gantt_scale_cell {
+  background-color: #fafafa; /* 极淡的灰色背景 */
+  border-right: 1px solid #eee; /* 极细的分隔线 */
+  border-bottom: 1px solid #eee;
+  color: #666;
+  font-weight: normal;
+}
+
+/* 3. 网格线 (Grid Lines) - 让它变淡或消失 */
+::v-deep .gantt_task_cell {
+  border-right: 1px solid #f5f5f5; /* 非常淡的竖线 */
+}
+::v-deep .gantt_task_row:nth-child(even) {
+  background-color: #fff; /* 去除斑马纹,保持纯白 */
+}
+::v-deep .gantt_task_row:nth-child(odd) {
+  background-color: #fff;
+}
+
+/* 4. 任务条形图 (The Blue Bars) - 关键样式 */
+::v-deep .gantt_task_line {
+  background-color: #1890ff; /* 阿里蓝/标准蓝 */
+  border-radius: 4px; /* 圆角 */
+  border: none; /* 去除默认边框 */
+  box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2); /* 轻微阴影增加立体感 */
+  opacity: 0.9;
+}
+
+/* 鼠标悬停在条形图上时的效果 */
+::v-deep .gantt_task_line:hover {
+  opacity: 1;
+  box-shadow: 0 4px 8px rgba(24, 144, 255, 0.4);
+  cursor: pointer;
+}
+
+/* 进度条内部白色部分 (如果 progress < 1) */
+::v-deep .gantt_task_progress {
+  background-color: rgba(255, 255, 255, 0.3); /* 半透明白色表示未完成部分 */
+  border-radius: 4px;
+}
+::v-deep .gantt_task_progress_wrapper {
+  background-color: transparent;
+  border-radius: 4px;
+}
+
+/* 5. 左侧表格区域优化 */
+::v-deep .gantt_grid_head_cell {
+  background-color: #fafafa;
+  border-right: 1px solid #eee;
+  border-bottom: 1px solid #eee;
+  color: #666;
+  font-weight: normal;
+}
+::v-deep .gantt_grid_cell {
+  border-right: 1px solid #f5f5f5;
+  border-bottom: 1px solid #f5f5f5;
+}
+
+/* 6. 自定义 Tooltip 样式 (悬浮提示框) */
+::v-deep .gantt_tooltip {
+  background-color: rgba(0, 0, 0, 0.75); /* 深色半透明背景 */
+  color: #fff;
+  border: none;
+  border-radius: 4px;
+  padding: 8px 12px;
+  font-size: 12px;
+  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+  white-space: nowrap; /* 防止换行 */
+  z-index: 9999;
+}
 
+/* 隐藏默认的箭头三角形,如果想要更现代的风格可以去掉箭头 */
+::v-deep .gantt_tooltip_arrow {
+  display: none;
+}
 </style>

+ 5 - 2
src/HDrpManagement/serviceImprovement/components/improvementPlan/index.vue

@@ -1,12 +1,12 @@
 <template>
   <div>
-    <edit :data="data" v-if="data.status == '分析已提交' && userid == data.userid_charge" ></edit>
+    <edit :data="data" v-if="data.status == '分析已提交' && userid == data.userid_charge" @onSuccess="listData"></edit>
     <table-detail :layout="tablecols" :data="list" :opwidth="200" :custom="true" style="margin-top: 10px">
       <template v-slot:customcol="scope">
         <div>{{scope.column.data[scope.column.columnname]}}</div>
       </template>
     </table-detail>
-<!--    <ganttChart></ganttChart>-->
+    <ganttChart :data="list" style="margin-top: 10px" ref="chartRef"></ganttChart>
   </div>
 </template>
 
@@ -40,6 +40,9 @@ export default {
     async listData(){
       const res = await this.$api.requested(this.param)
       this.list = res.data
+      if (this.list.length > 0){
+        this.$refs.chartRef.setList(this.list)
+      }
       console.log(res.data,'方案列表')
     }
   },

+ 25 - 3
src/components/dynamic-table-detail/index.vue

@@ -1,8 +1,9 @@
 <template>
   <div>
     <!-- :header-cell-style="{background:'#EEEEEE',color:'#333'}" -->
-    <el-table ref="table" :fit="tool.calculatedColumnWidth($refs.table,layout)" :row-class-name="tableClassName" highlight-current-row :data="data"  size="mini"  :height="height"  @row-click="rowClick" :style="{width:'100%',minHeight:minHeight?minHeight:''}" :header-cell-style="{height:'40px',color:'#606266',fontWeight:'400',fontSize:'14px'}"
-              :cell-style="{height:'40px',color:'#666666',fontWeight:'400'}" border @selection-change="selectionChange">
+    <el-table ref="table" :fit="tool.calculatedColumnWidth($refs.table,layout)" :row-class-name="tableClassName" @current-change="handleCurrentChange" current-row-key="id"  highlight-current-row
+              :data="data"  size="mini"  :height="height"  @row-click="rowClick" :style="{width:'100%',minHeight:minHeight?minHeight:''}" :header-cell-style="{height:'40px',color:'#606266',fontWeight:'400',fontSize:'14px'}"
+              :cell-style="{height:'40px',color:'#666666',fontWeight:'400'}" border @selection-change="selectionChange" >
       <el-table-column
           type="selection"
           width="35" fixed v-if="checkbox">
@@ -67,9 +68,30 @@ export default {
           this.$refs.table.doLayout()
         })
       }
-    }
+    },
+    handleCurrentChange(val) {
+      this.currentRow = val;
+      console.log('当前选中行:', val);
+    },
+    setHighlightRow() {
+      console.log('输出高亮333')
+      // 高亮第一行
+      this.$refs.table.setCurrentRow(this.list[0]);
+
+      // 或者通过索引
+      // this.$refs.singleTable.setCurrentRow(this.tableData[1]); // 高亮第二行
+    },
+    // 关键方法:根据条件返回类名
+    tableRowClassName({ row, rowIndex }) {
+      // 如果当前行等于选中的行,返回 'selected-row' 类名
+      if (this.currentRow && row.id === this.currentRow.id) {
+        return 'selected-row';
+      }
+      return '';
+    },
   },
   mounted () {
+
   }
 }