Browse Source

ly 培训优化 eoeg组织架构

ly 13 hours ago
parent
commit
59c5c4b92d

+ 16 - 14
master/src/main/java/com/ruoyi/framework/task/trainingbcc/TrainingMatrixTask.java

@@ -158,7 +158,7 @@ public class TrainingMatrixTask extends BaseController
                 tTrainingRegular.setInvolvedMoc("false");
                 tTrainingRegular.setNotPlan("false");
                 tTrainingRegular.setYear(String.valueOf(currentYear));
-                
+
                 // 通过课程代码搜索程序清单,获取培训人和培训文件(只查询一次)
                 String courseCode = matrix.getCourseCode();
                 String regularTrainer = null;
@@ -166,16 +166,16 @@ public class TrainingMatrixTask extends BaseController
                 String fileUrl = "";
                 String fileName = "";
                 TPlantproglist plantproglist = null;
-                
+
                 if (StringUtils.isNotEmpty(courseCode)) {
                     TPlantproglist plantproglistParam = new TPlantproglist();
                     plantproglistParam.setFileno(courseCode);
                     List<TPlantproglist> plantproglistList = tPlantproglistService.selectList(plantproglistParam);
-                    
+
                     if (plantproglistList != null && !plantproglistList.isEmpty()) {
                         plantproglist = plantproglistList.get(0);
                         logger.info("找到程序清单,文件编号: {}, 责任者: {}", courseCode, plantproglist.getResponsibility());
-                        
+
                         // 获取培训文件
                         TCommonfile fileParam = new TCommonfile();
                         fileParam.setpId(plantproglist.getId());
@@ -186,11 +186,11 @@ public class TrainingMatrixTask extends BaseController
                             fileName = fileList.get(0).getFileName();
                             logger.info("找到培训文件: {}", fileName);
                         }
-                        
+
                         // 获取培训人:通过责任者查找员工编号
                         String trainerName = plantproglist.getResponsibility();
                         regularTrainer = trainerName; // 设置给regular
-                        
+
                         if (StringUtils.isNotEmpty(trainerName)) {
                             TStaffmgr staffmgrParam = new TStaffmgr();
                             staffmgrParam.setName(trainerName);
@@ -212,9 +212,9 @@ public class TrainingMatrixTask extends BaseController
                 } else {
                     logger.warn("课程代码为空,无法获取程序清单培训人");
                 }
-                
+
                 // 设置regular的培训人
-                tTrainingRegular.setLecturer(regularTrainer);
+                tTrainingRegular.setLecturer(trainer);
                 int doInsert = tTrainingbccRegularService.insertTTrainingbccRegular(tTrainingRegular);
 
                 logger.info("regular:" + tTrainingRegular);
@@ -231,12 +231,17 @@ public class TrainingMatrixTask extends BaseController
                 tTraining.setDeptId(tTrainingRegular.getDeptId());
                 tTraining.setRegularId(tTrainingRegular.getId());
                 tTraining.setPeriod(matrix.getFrequency());
-                
+
                 // 设置培训人和文件信息
                 tTraining.setTrainer(trainer);
                 tTraining.setFileUrl(fileUrl);
                 tTraining.setFileName(fileName);
-                tTraining.setContent(fileName);
+                // 培训内容:去掉文件后缀
+                String content = fileName;
+                if (StringUtils.isNotEmpty(fileName) && fileName.contains(".")) {
+                    content = fileName.substring(0, fileName.lastIndexOf("."));
+                }
+                tTraining.setContent(content);
                 //添加学习时间
                 String hourText = matrix.getHour();
                 if (hourText != null && !hourText.trim().isEmpty() && !hourText.contains("按需")) {
@@ -319,11 +324,8 @@ public class TrainingMatrixTask extends BaseController
                             Iterator<TStaffmgr> iterator = staffmgrsMoc.iterator();
                             while (iterator.hasNext()) {
                                 TStaffmgr t = iterator.next();
-                                if (t.getLeftDate() != null && t.getDelFlag() == 9){
-                                    if (t.getLeftDate().getTime() - tTrainingRegular.getPlanTrainingdate().getTime() > 0l ) {
-                                        logger.debug(t.getName() + "离职时间小于培训时间");
+                                if (t.getDelFlag() == 9){
                                         iterator.remove();
-                                    }
                                 }
                             }
                         }

+ 7 - 2
master/src/main/java/com/ruoyi/project/document/controller/TPlantproglistController.java

@@ -233,7 +233,7 @@ public class TPlantproglistController extends BaseController
             tTrainingRegular.setDeptId(103l); //bcc专用
             //新增培训跟踪
             TTrainingbcc tTraining = new TTrainingbcc();
-            tTraining.setTrainingType("10");
+            tTraining.setTrainingType("14");
             tTraining.setYears(tTrainingRegular.getYear());
             tTraining.setCourse(tTrainingRegular.getItem());
             tTraining.setCourseid(tTrainingRegular.getCourseCode());
@@ -245,7 +245,12 @@ public class TPlantproglistController extends BaseController
             tTraining.setPeriod(matrix.getFrequency());
             tTraining.setFileUrl(fileUrl);
             tTraining.setFileName(fileName);
-            tTraining.setContent(fileName);
+            // 培训内容:去掉文件后缀
+            String content = fileName;
+            if (StringUtils.isNotEmpty(fileName) && fileName.contains(".")) {
+                content = fileName.substring(0, fileName.lastIndexOf("."));
+            }
+            tTraining.setContent(content);
             // 通过人名查找staffmgr,获取员工编号来赋值trainer
             String trainerName = tPlantproglist.getResponsibility();
             if (StringUtils.isNotEmpty(trainerName)) {

+ 98 - 5
master/src/main/java/com/ruoyi/project/plant/controller/TStaffmgrController.java

@@ -28,6 +28,10 @@ import com.ruoyi.project.training.mapper.TTrainingbccDeviceMapper;
 import com.ruoyi.project.training.service.*;
 import com.ruoyi.project.training.spec.service.ITStPlanService;
 import com.ruoyi.project.training.spec.service.ITStSuccessorService;
+import com.ruoyi.project.document.domain.TPlantproglist;
+import com.ruoyi.project.document.service.ITPlantproglistService;
+import com.ruoyi.project.common.domain.TCommonfile;
+import com.ruoyi.project.common.service.ITCommonfileService;
 import org.apache.commons.lang.StringUtils;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
@@ -107,6 +111,10 @@ public class TStaffmgrController extends BaseController {
     private TTrainingbccDeviceMapper tTrainingbccDeviceMapper;
     @Autowired
     private ITTrainingbccDeviceService trainingbccDeviceService;
+    @Autowired
+    private ITPlantproglistService tPlantproglistService;
+    @Autowired
+    private ITCommonfileService tCommonfileService;
     /**
      * 获取SAI整改负责人列表
      */
@@ -551,8 +559,8 @@ public class TStaffmgrController extends BaseController {
 
         int insertResult = tStaffmgrService.insertTStaffmgr(tStaffmgr);
         tStaffmgr.setCreaterCode(getUserId().toString());
-        //如果为新员工,添加新员工培训
-        if (tStaffmgr.getIsNew() == 1) {
+        //如果为BCC部门新员工,添加新员工培训
+        if (tStaffmgr.getIsNew() == 1 && tStaffmgr.getDeptId()==103l) {
             TTrainingMatrix tTrainingMatrix = new TTrainingMatrix();
             tTrainingMatrix.setDeptId(103l);
             tTrainingMatrix.setTrainingLevel("14");
@@ -572,6 +580,63 @@ public class TStaffmgrController extends BaseController {
                 tTrainingRegular.setNotPlan("false");
                 tTrainingRegular.setYear(String.valueOf(currentYear));
                 tTrainingRegular.setNewStaff(tStaffmgr.getStaffid());
+
+                // 通过课程代码搜索程序清单,获取培训人和培训文件(只查询一次)
+                String courseCode = matrix.getCourseCode();
+                String regularTrainer = null;
+                String trainer = null;
+                String fileUrl = "";
+                String fileName = "";
+                TPlantproglist plantproglist = null;
+
+                if (StringUtils.isNotEmpty(courseCode)) {
+                    TPlantproglist plantproglistParam = new TPlantproglist();
+                    plantproglistParam.setFileno(courseCode);
+                    List<TPlantproglist> plantproglistList = tPlantproglistService.selectList(plantproglistParam);
+
+                    if (plantproglistList != null && !plantproglistList.isEmpty()) {
+                        plantproglist = plantproglistList.get(0);
+                        logger.info("找到程序清单,文件编号: {}, 责任者: {}", courseCode, plantproglist.getResponsibility());
+
+                        // 获取培训文件
+                        TCommonfile fileParam = new TCommonfile();
+                        fileParam.setpId(plantproglist.getId());
+                        fileParam.setpType("plantproglist");
+                        List<TCommonfile> fileList = tCommonfileService.selectAllFileList(fileParam);
+                        if (fileList != null && !fileList.isEmpty()) {
+                            fileUrl = fileList.get(0).getFileUrl();
+                            fileName = fileList.get(0).getFileName();
+                            logger.info("找到培训文件: {}", fileName);
+                        }
+
+                        // 获取培训人:通过责任者查找员工编号
+                        String trainerName = plantproglist.getResponsibility();
+                        regularTrainer = trainerName; // 设置给regular
+
+                        if (StringUtils.isNotEmpty(trainerName)) {
+                            TStaffmgr staffmgrParam = new TStaffmgr();
+                            staffmgrParam.setName(trainerName);
+                            staffmgrParam.setDeptId(tTrainingRegular.getDeptId());
+                            staffmgrParam.setDelFlag(0L); // 未删除的员工
+                            TStaffmgr staffmgr = tStaffmgrMapper.selectStaffmgrSingle(staffmgrParam);
+                            if (staffmgr != null && StringUtils.isNotEmpty(staffmgr.getStaffid())) {
+                                trainer = staffmgr.getStaffid();
+                                logger.info("通过责任者找到培训人: {} -> {}", trainerName, trainer);
+                            } else {
+                                logger.warn("未找到责任者对应的员工: {}", trainerName);
+                            }
+                        } else {
+                            logger.warn("程序清单责任者为空");
+                        }
+                    } else {
+                        logger.warn("未找到课程代码对应的程序清单: {}", courseCode);
+                    }
+                } else {
+                    logger.warn("课程代码为空,无法获取程序清单培训人");
+                }
+
+                // 设置regular的培训人
+                tTrainingRegular.setLecturer(trainer);
                 int doInsert = tTrainingbccRegularService.insertTTrainingbccRegular(tTrainingRegular);
 
                 logger.info("regular:" + tTrainingRegular);
@@ -583,11 +648,37 @@ public class TStaffmgrController extends BaseController {
                 tTraining.setCourse(tTrainingRegular.getItem());
                 tTraining.setCourseid(tTrainingRegular.getCourseCode());
                 tTraining.setDuration(tTrainingRegular.getHour());
-                tTraining.setTrainer(tTrainingRegular.getLecturer());
                 tTraining.setPosition(tTrainingRegular.getActualpostId());
                 tTraining.setIsfinish(Long.parseLong("0"));
                 tTraining.setDeptId(tTrainingRegular.getDeptId());
                 tTraining.setRegularId(tTrainingRegular.getId());
+                tTraining.setPeriod(matrix.getFrequency());
+
+                // 设置培训人和文件信息
+                tTraining.setTrainer(trainer);
+                tTraining.setFileUrl(fileUrl);
+                tTraining.setFileName(fileName);
+                // 培训内容:去掉文件后缀
+                String content = fileName;
+                if (StringUtils.isNotEmpty(fileName) && fileName.contains(".")) {
+                    content = fileName.substring(0, fileName.lastIndexOf("."));
+                }
+                tTraining.setContent(content);
+                //添加学习时间
+                String hourText = matrix.getHour();
+                if (hourText != null && !hourText.trim().isEmpty() && !hourText.contains("按需")) {
+                    try {
+                        // 解析课时文本,支持 "1.5h"、"1.5小时"、"1.5" 等格式
+                        String cleanText = hourText.toLowerCase().replaceAll("[^0-9.]", "");
+                        if (!cleanText.isEmpty()) {
+                            double hours = Double.parseDouble(cleanText);
+                            int minutes = (int) Math.round(hours * 60); // 转换为分钟
+                            tTraining.setTimerNeed((long) minutes);
+                        }
+                    } catch (NumberFormatException e) {
+                        logger.warn("无法解析课时: " + hourText);
+                    }
+                }
                 trainingbccService.insertTTrainingbcc(tTraining);
                 Long trainingId = tTraining.getId();
 
@@ -597,6 +688,8 @@ public class TStaffmgrController extends BaseController {
                 tTrainingDevice.setRegularId(trainingId);
                 tTrainingDevice.setStartDate(tTrainingRegular.getPlanTrainingdate());
                 tTrainingDevice.setSupplementary("0");
+                // 设置初始完成时间为空,表示尚未完成
+                tTrainingDevice.setFinishDate(null);
                 trainingbccDeviceService.insertTTrainingbccDevice(tTrainingDevice);
             }
 
@@ -622,7 +715,7 @@ public class TStaffmgrController extends BaseController {
             tWorklicense.setDeptId(tStaffmgr.getDeptId());
             tWorklicenseService.insertTWorklicense(tWorklicense);
         }
-        if (tStaffmgr.getUnit().equals("10")) {
+        /*if (tStaffmgr.getUnit().equals("10")) {
             SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
             TTrainingRegular regular = new TTrainingRegular();
             regular.setYear(sdfYear.format(new Date()));
@@ -656,7 +749,7 @@ public class TStaffmgrController extends BaseController {
                     }
                 }
             }
-        }
+        }*/
         return toAjax(insertResult);
     }
 

+ 15 - 10
master/src/main/java/com/ruoyi/project/training/controller/TTrainingMatrixController.java

@@ -291,7 +291,7 @@ public class TTrainingMatrixController extends BaseController {
             tTrainingRegular.setInvolvedMoc("false");
             tTrainingRegular.setNotPlan("false");
             tTrainingRegular.setYear(String.valueOf(LocalDate.now().getYear()));
-            
+
             // 通过课程代码搜索程序清单,获取培训人和培训文件(只查询一次)
             String courseCode = matrix.getCourseCode();
             String regularTrainer = null;
@@ -299,16 +299,16 @@ public class TTrainingMatrixController extends BaseController {
             String fileUrl = "";
             String fileName = "";
             TPlantproglist plantproglist = null;
-            
+
             if (StringUtils.isNotEmpty(courseCode)) {
                 TPlantproglist plantproglistParam = new TPlantproglist();
                 plantproglistParam.setFileno(courseCode);
                 List<TPlantproglist> plantproglistList = tPlantproglistService.selectList(plantproglistParam);
-                
+
                 if (plantproglistList != null && !plantproglistList.isEmpty()) {
                     plantproglist = plantproglistList.get(0);
                     logger.info("找到程序清单,文件编号: {}, 责任者: {}", courseCode, plantproglist.getResponsibility());
-                    
+
                     // 获取培训文件
                     TCommonfile fileParam = new TCommonfile();
                     fileParam.setpId(plantproglist.getId());
@@ -319,11 +319,11 @@ public class TTrainingMatrixController extends BaseController {
                         fileName = fileList.get(0).getFileName();
                         logger.info("找到培训文件: {}", fileName);
                     }
-                    
+
                     // 获取培训人:通过责任者查找员工编号
                     String trainerName = plantproglist.getResponsibility();
                     regularTrainer = trainerName; // 设置给regular
-                    
+
                     if (StringUtils.isNotEmpty(trainerName)) {
                         TStaffmgr staffmgrParam = new TStaffmgr();
                         staffmgrParam.setName(trainerName);
@@ -345,9 +345,9 @@ public class TTrainingMatrixController extends BaseController {
             } else {
                 logger.warn("课程代码为空,无法获取程序清单培训人");
             }
-            
+
             // 设置regular的培训人
-            tTrainingRegular.setLecturer(regularTrainer);
+            tTrainingRegular.setLecturer(trainer);
             int doInsert = tTrainingbccRegularService.insertTTrainingbccRegular(tTrainingRegular);
 
             logger.info("regular:" + tTrainingRegular);
@@ -363,12 +363,17 @@ public class TTrainingMatrixController extends BaseController {
             tTraining.setIsfinish(Long.parseLong("0"));
             tTraining.setDeptId(tTrainingRegular.getDeptId());
             tTraining.setRegularId(tTrainingRegular.getId());
-            
+
             // 设置培训人和文件信息
             tTraining.setTrainer(trainer);
             tTraining.setFileUrl(fileUrl);
             tTraining.setFileName(fileName);
-            tTraining.setContent(fileName);
+            // 培训内容:去掉文件后缀
+            String content = fileName;
+            if (StringUtils.isNotEmpty(fileName) && fileName.contains(".")) {
+                content = fileName.substring(0, fileName.lastIndexOf("."));
+            }
+            tTraining.setContent(content);
             trainingbccService.insertTTrainingbcc(tTraining);
             Long trainingId = tTraining.getId();
             //新增人员-装置级关系

+ 51 - 5
master/src/main/java/com/ruoyi/project/training/controller/TTrainingbccController.java

@@ -5,6 +5,7 @@ import com.deepoove.poi.data.*;
 import com.deepoove.poi.data.style.CellStyle;
 import com.deepoove.poi.data.style.TableStyle;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.DictUtils;
 import com.ruoyi.common.utils.file.FileUploadUtils;
 import com.ruoyi.common.utils.file.FileUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -91,6 +92,26 @@ public class TTrainingbccController extends BaseController {
             } else {
                 t.setTrainingPercent("0");
             }
+
+            // 检查统计数据与isFinish字段的一致性,不一致则更新
+            boolean shouldBeFinished = (all > 0 && finish == all); // 有培训人员且全部完成
+            boolean currentIsFinish = (t.getIsfinish() != null && t.getIsfinish() == 1L); // 当前标记为完成
+
+            if (shouldBeFinished != currentIsFinish) {
+                // 不一致,更新isFinish字段
+                Long newIsFinish = shouldBeFinished ? 1L : 0L;
+                t.setIsfinish(newIsFinish);
+
+                // 更新数据库中的isFinish字段
+                TTrainingbcc updateParam = new TTrainingbcc();
+                updateParam.setId(t.getId());
+                updateParam.setIsfinish(newIsFinish);
+                tTrainingbccService.updateTTrainingbcc(updateParam);
+
+                logger.info("更新培训完成状态 - 培训ID: {}, 原状态: {}, 新状态: {}, 统计: {}/{}",
+                           t.getId(), currentIsFinish ? "完成" : "未完成",
+                           shouldBeFinished ? "完成" : "未完成", finish, all);
+            }
         }
         return getDataTable(list);
     }
@@ -300,6 +321,31 @@ public class TTrainingbccController extends BaseController {
             if (device2 != null) {
                 user2 = sysUserMapper.selectUserByStaffId(device2.getStaffId());
             }
+            
+            // 获取员工部门信息
+            String department1 = "CBP/C"; // 默认值
+            String department2 = "CBP/C"; // 默认值
+            
+            if (device.getStaffId() != null) {
+                TStaffmgr staffmgr1 = tStaffmgrService.selectTStaffmgrByStaffId(device.getStaffId());
+                if (staffmgr1 != null && staffmgr1.getUnit() != null) {
+                    department1 = DictUtils.getDictLabel("STAFF_UNIT", staffmgr1.getUnit());
+                    if (department1 == null || department1.isEmpty()) {
+                        department1 = "CBP/C"; // 如果字典转换失败,使用默认值
+                    }
+                }
+            }
+            
+            if (device2 != null && device2.getStaffId() != null) {
+                TStaffmgr staffmgr2 = tStaffmgrService.selectTStaffmgrByStaffId(device2.getStaffId());
+                if (staffmgr2 != null && staffmgr2.getUnit() != null) {
+                    department2 = DictUtils.getDictLabel("STAFF_UNIT", staffmgr2.getUnit());
+                    if (department2 == null || department2.isEmpty()) {
+                        department2 = "CBP/C"; // 如果字典转换失败,使用默认值
+                    }
+                }
+            }
+            
             RowRenderData row = null;
             String lineNum="";
             String lineNum2="";
@@ -308,10 +354,10 @@ public class TTrainingbccController extends BaseController {
                  lineNum2 = String.valueOf(i + 2);
 
             if (device2!=null)
-                row = Rows.of(lineNum, device.getName(), "CBP/C", "", DateUtils.dateTime(device.getStartDate()),
-                        lineNum2, device2.getName(), "CBP/C", "", DateUtils.dateTime(device2.getStartDate())).verticalCenter().textFontSize(8).rowExactHeight(1.1f).create();
+                row = Rows.of(lineNum, device.getName(), department1, "", DateUtils.dateTime(device.getFinishDate()),
+                        lineNum2, device2.getName(), department2, "", DateUtils.dateTime(device2.getFinishDate())).verticalCenter().textFontSize(8).rowExactHeight(1.1f).create();
             else
-                row = Rows.of(lineNum, device.getName(), "CBP/C", "", DateUtils.dateTime(device.getStartDate()),
+                row = Rows.of(lineNum, device.getName(), department1, "", DateUtils.dateTime(device.getFinishDate()),
                         "", "", "", "", "").verticalCenter().horizontalCenter().textFontSize(8).rowExactHeight(1.1f).create();
             if (device.getExamState() == 1) {
                 if (user1 != null)
@@ -343,7 +389,7 @@ public class TTrainingbccController extends BaseController {
         params.put("revision", revision);                                   // 培训材料版本
         params.put("duration", trainingbcc.getDuration() != null ? trainingbcc.getDuration() : "NA");                // 培训时长
         params.put("content", trainingbcc.getContent() != null ? trainingbcc.getContent() : "NA");                  // 培训内容
-        
+
         // 处理讲师信息:通过员工号查询讲师姓名
         String trainerNames = "NA";
         if (trainingbcc.getTrainer() != null && !trainingbcc.getTrainer().trim().isEmpty()) {
@@ -362,7 +408,7 @@ public class TTrainingbccController extends BaseController {
             trainerNames = trainerNameList.length() > 0 ? trainerNameList.toString() : "NA";
         }
         params.put("trainer", trainerNames);                             // 培训讲师姓名
-        
+
         // 处理培训日期:使用斜杠格式 yyyy/MM/dd
         String courseStartdateStr = "";
         if (trainingbcc.getCourseStartdate() != null) {

+ 1 - 0
master/src/main/java/com/ruoyi/project/training/domain/TTrainingbccRegular.java

@@ -362,6 +362,7 @@ public class TTrainingbccRegular extends BaseEntity
             .append("year", getYear())
             .append("designatedPosition", getDesignatedPosition())
             .append("designatedStaff", getDesignatedStaff())
+            .append("newStaff", getNewStaff())
             .append("involvedMoc", getInvolvedMoc())
             .append("notPlan", getNotPlan())
             .append("notTrainingdate", getNotTrainingdate())

+ 1 - 1
master/src/main/resources/mybatis/training/TTrainingbccDeviceMapper.xml

@@ -34,7 +34,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectTTrainingbccDeviceList" parameterType="TTrainingbccDevice" resultMap="TTrainingbccDeviceResult">
         select d.id,s.name , d.staff_id, d.regular_id, d.start_date, d.remarks, d.del_flag, d.creater_code, d.createdate, d.updater_code, d.updatedate, d.supplementary, d.learn_state, d.exam_state, d.exam_id,d.exam_num, d.learn_time, s.team from t_trainingbcc_device d
-        left join t_staffmgr s on s.staffid = d.staff_id
+        left join t_staffmgr s on s.staffid = d.staff_id and s.DEL_FLAG != 2
         left join t_trainingbcc t on t.id = d.regular_id and t.DEL_FLAG = 0
         <where>
             <if test="staffId != null  and staffId != ''"> and d.staff_id = #{staffId} and d.exam_state != 1 and ((ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) > t.course_startdate and t.course_enddate >= SYSDATE) or (d.supplementary = 1 and d.exam_state = 0))  </if>

+ 95 - 3
ui/src/assets/iconfont/demo_index.html

@@ -54,6 +54,30 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
 
+            <li class="dib">
+              <span class="icon iconfont">&#xe62d;</span>
+                <div class="name">菱形</div>
+                <div class="code-name">&amp;#xe62d;</div>
+              </li>
+
+            <li class="dib">
+              <span class="icon iconfont">&#xe698;</span>
+                <div class="name">叉车</div>
+                <div class="code-name">&amp;#xe698;</div>
+              </li>
+
+            <li class="dib">
+              <span class="icon iconfont">&#xe601;</span>
+                <div class="name">卡车</div>
+                <div class="code-name">&amp;#xe601;</div>
+              </li>
+
+            <li class="dib">
+              <span class="icon iconfont">&#xe604;</span>
+                <div class="name">卡车</div>
+                <div class="code-name">&amp;#xe604;</div>
+              </li>
+
             <li class="dib">
               <span class="icon iconfont">&#xe6c4;</span>
                 <div class="name">BAI-培训</div>
@@ -126,9 +150,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1757579908171') format('woff2'),
-       url('iconfont.woff?t=1757579908171') format('woff'),
-       url('iconfont.ttf?t=1757579908171') format('truetype');
+  src: url('iconfont.woff2?t=1758526813963') format('woff2'),
+       url('iconfont.woff?t=1758526813963') format('woff'),
+       url('iconfont.ttf?t=1758526813963') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -154,6 +178,42 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
 
+          <li class="dib">
+            <span class="icon iconfont icon-lingxing"></span>
+            <div class="name">
+              菱形
+            </div>
+            <div class="code-name">.icon-lingxing
+            </div>
+          </li>
+
+          <li class="dib">
+            <span class="icon iconfont icon-chache"></span>
+            <div class="name">
+              叉车
+            </div>
+            <div class="code-name">.icon-chache
+            </div>
+          </li>
+
+          <li class="dib">
+            <span class="icon iconfont icon-kache"></span>
+            <div class="name">
+              卡车
+            </div>
+            <div class="code-name">.icon-kache
+            </div>
+          </li>
+
+          <li class="dib">
+            <span class="icon iconfont icon-shuniu1"></span>
+            <div class="name">
+              卡车
+            </div>
+            <div class="code-name">.icon-shuniu1
+            </div>
+          </li>
+
           <li class="dib">
             <span class="icon iconfont icon-BAI-peixun"></span>
             <div class="name">
@@ -262,6 +322,38 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
 
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-lingxing"></use>
+                </svg>
+                <div class="name">菱形</div>
+                <div class="code-name">#icon-lingxing</div>
+            </li>
+
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-chache"></use>
+                </svg>
+                <div class="name">叉车</div>
+                <div class="code-name">#icon-chache</div>
+            </li>
+
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-kache"></use>
+                </svg>
+                <div class="name">卡车</div>
+                <div class="code-name">#icon-kache</div>
+            </li>
+
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shuniu1"></use>
+                </svg>
+                <div class="name">卡车</div>
+                <div class="code-name">#icon-shuniu1</div>
+            </li>
+
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-BAI-peixun"></use>

+ 19 - 3
ui/src/assets/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2877683 */
-  src: url('iconfont.woff2?t=1757579908171') format('woff2'),
-       url('iconfont.woff?t=1757579908171') format('woff'),
-       url('iconfont.ttf?t=1757579908171') format('truetype');
+  src: url('iconfont.woff2?t=1758526813963') format('woff2'),
+       url('iconfont.woff?t=1758526813963') format('woff'),
+       url('iconfont.ttf?t=1758526813963') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,22 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-lingxing:before {
+  content: "\e62d";
+}
+
+.icon-chache:before {
+  content: "\e698";
+}
+
+.icon-kache:before {
+  content: "\e601";
+}
+
+.icon-shuniu1:before {
+  content: "\e604";
+}
+
 .icon-BAI-peixun:before {
   content: "\e6c4";
 }

File diff suppressed because it is too large
+ 0 - 0
ui/src/assets/iconfont/iconfont.js


+ 28 - 0
ui/src/assets/iconfont/iconfont.json

@@ -5,6 +5,34 @@
   "css_prefix_text": "icon-",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "755551",
+      "name": "菱形",
+      "font_class": "lingxing",
+      "unicode": "e62d",
+      "unicode_decimal": 58925
+    },
+    {
+      "icon_id": "11218897",
+      "name": "叉车",
+      "font_class": "chache",
+      "unicode": "e698",
+      "unicode_decimal": 59032
+    },
+    {
+      "icon_id": "45612946",
+      "name": "卡车",
+      "font_class": "kache",
+      "unicode": "e601",
+      "unicode_decimal": 58881
+    },
+    {
+      "icon_id": "279622",
+      "name": "卡车",
+      "font_class": "shuniu1",
+      "unicode": "e604",
+      "unicode_decimal": 58884
+    },
     {
       "icon_id": "2513049",
       "name": "BAI-培训",

BIN
ui/src/assets/iconfont/iconfont.ttf


BIN
ui/src/assets/iconfont/iconfont.woff


BIN
ui/src/assets/iconfont/iconfont.woff2


+ 402 - 0
ui/src/views/plant/EOEGorganization/branch.vue

@@ -0,0 +1,402 @@
+<template>
+    <ul :class="{'double': isHaveChild(dataArray)}">
+      <li v-for="(item, index) in dataArray" :key="index" v-if="!item.level" :class="[{
+        'liequal': item.post.trim()==='安全专员'},{
+        'litop': item.post.trim()==='首席经理'
+        }]">
+        <div class="branch-box" @click.prevent="clickHandle(item)" v-if="item.post.trim() !== 'EHS督导'">
+          <div class="branch-title">{{item.post}}</div>
+          <img class="branch-pic" :src=item.img>
+          <div class="branch-name">{{item.label}}</div>
+          <div class="bz-box">
+            <i v-if="item.bz1" class="iconfont icon-star"></i>
+            <i v-if="item.bz2" class="iconfont icon-love"></i>
+            <i v-if="item.bz3" class="iconfont icon-triangle"></i>
+            <i v-if="item.bz4" class="iconfont icon-square"></i>
+            <i v-if="item.bz5" class="iconfont icon-plus"></i>
+            <i v-if="item.bz6" class="iconfont icon-round"></i>
+            <i v-if="item.bz7" class="iconfont icon-yuanjiaoliujiaoxing"></i>
+            <i v-if="item.bz8" class="iconfont icon-shebeitubiao_famen"></i>
+            <i v-if="item.bz9" class="iconfont icon-BAI-peixun"></i>
+             <i v-if="item.bz10" class="iconfont icon-kache"></i>
+            <i v-if="item.bz11" class="iconfont icon-chache"></i>
+            <i v-if="item.bz12" class="iconfont icon-star"></i>
+
+          </div>
+        </div>
+        <!-- 平级 -->
+        <div class="branch-box" :class="item.post.trim() === '安全专员' ? 'equal':''" @click.prevent="clickHandle(item)" v-if="item.post.trim() === '安全专员'">
+          <div class="branch-title">{{item.post}}</div>
+          <img class="branch-pic" :src=item.img>
+          <div class="branch-name">{{item.label}}</div>
+          <div class="bz-box">
+            <i v-if="item.bz1" class="iconfont icon-star"></i>
+            <i v-if="item.bz2" class="iconfont icon-love"></i>
+            <i v-if="item.bz3" class="iconfont icon-triangle"></i>
+            <i v-if="item.bz4" class="iconfont icon-square"></i>
+            <i v-if="item.bz5" class="iconfont icon-plus"></i>
+            <i v-if="item.bz6" class="iconfont icon-round"></i>
+            <i v-if="item.bz7" class="iconfont icon-yuanjiaoliujiaoxing"></i>
+            <i v-if="item.bz8" class="iconfont icon-shebeitubiao_famen"></i>
+            <i v-if="item.bz9" class="iconfont icon-BAI-peixun"></i>
+            <i v-if="item.bz10" class="iconfont icon-kache"></i>
+            <i v-if="item.bz11" class="iconfont icon-chache"></i>
+            <i v-if="item.bz12" class="iconfont icon-star"></i>
+          </div>
+        </div>
+        <template v-if="item.secretary">
+          <ul class="level" v-for="(secretary, se) in item.secretary" :key="se">
+            <template v-for="(child, cIndex) in secretary">
+              <li v-if="child.children" :class="{'odd': ((secretary.length%2) === 1)}" :key="'child-' + cIndex">
+                <div class="branch-box" @click.prevent="clickHandle(child)">
+                  <div class="branch-title">{{child.post}}</div>
+                  <img class="branch-pic" :src=child.img>
+                  <div class="branch-name">{{child.label}}</div>
+                  <div class="bz-box">
+                    <i v-if="child.bz1" class="iconfont icon-star"></i>
+                    <i v-if="child.bz2" class="iconfont icon-love"></i>
+                    <i v-if="child.bz3" class="iconfont icon-triangle"></i>
+                    <i v-if="child.bz4" class="iconfont icon-square"></i>
+                    <i v-if="child.bz5" class="iconfont icon-plus"></i>
+                    <i v-if="child.bz6" class="iconfont icon-round"></i>
+                    <i v-if="child.bz7" class="iconfont icon-yuanjiaoliujiaoxing"></i>
+                    <i v-if="child.bz8" class="iconfont icon-shebeitubiao_famen"></i>
+                    <i v-if="child.bz9" class="iconfont icon-BAI-peixun"></i>
+                    <i v-if="child.bz10" class="iconfont icon-kache"></i>
+                    <i v-if="child.bz11" class="iconfont icon-chache"></i>
+                    <i v-if="child.bz12" class="iconfont icon-star"></i>
+                  </div>
+                </div>
+                <ul :style="{'width': ulWidth + 'px'}">
+                  <li v-for="(schild, chIndex) in child.children" :key="chIndex">
+                    <div class="branch-box" @click.prevent="clickHandle(schild)">
+                      <div class="branch-title">{{schild.post}}</div>
+                      <img class="branch-pic" :src=schild.img>
+                      <div class="branch-name">{{schild.label}}</div>
+                      <div class="bz-box">
+                        <i v-if="schild.bz1" class="iconfont icon-star"></i>
+                        <i v-if="schild.bz2" class="iconfont icon-love"></i>
+                        <i v-if="schild.bz3" class="iconfont icon-triangle"></i>
+                        <i v-if="schild.bz4" class="iconfont icon-square"></i>
+                        <i v-if="schild.bz5" class="iconfont icon-plus"></i>
+                        <i v-if="schild.bz6" class="iconfont icon-round"></i>
+                        <i v-if="schild.bz7" class="iconfont icon-yuanjiaoliujiaoxing"></i>
+                        <i v-if="schild.bz8" class="iconfont icon-shebeitubiao_famen"></i>
+                        <i v-if="schild.bz9" class="iconfont icon-BAI-peixun"></i>
+                        <i v-if="schild.bz10" class="iconfont icon-kache"></i>
+                        <i v-if="schild.bz11" class="iconfont icon-chache"></i>
+                        <i v-if="schild.bz12" class="iconfont icon-star"></i>
+
+                      </div>
+                    </div>
+                  </li>
+                </ul>
+              </li>
+              <li v-else :key="'no-child-' + cIndex" :class="{'odd': ((secretary.length%2) === 1&&!child.children)}">
+                <div class="branch-box" @click.prevent="clickHandle(child)">
+                  <div class="branch-title">{{child.post}}</div>
+                  <img class="branch-pic" :src=child.img>
+                  <div class="branch-name">{{child.label}}</div>
+                  <div class="bz-box">
+                    <i v-if="child.bz1" class="iconfont icon-star"></i>
+                    <i v-if="child.bz2" class="iconfont icon-love"></i>
+                    <i v-if="child.bz3" class="iconfont icon-triangle"></i>
+                    <i v-if="child.bz4" class="iconfont icon-square"></i>
+                    <i v-if="child.bz5" class="iconfont icon-plus"></i>
+                    <i v-if="child.bz6" class="iconfont icon-round"></i>
+                    <i v-if="child.bz7" class="iconfont icon-yuanjiaoliujiaoxing"></i>
+                    <i v-if="child.bz8" class="iconfont icon-shebeitubiao_famen"></i>
+                    <i v-if="child.bz9" class="iconfont icon-BAI-peixun"></i>
+                    <i v-if="child.bz10" class="iconfont icon-kache"></i>
+                    <i v-if="child.bz11" class="iconfont icon-chache"></i>
+                    <i v-if="child.bz12" class="iconfont icon-star"></i>
+                  </div>
+                </div>
+                <div :style="{width: ulWidth + 'px'}"></div>
+              </li>
+            </template>
+            <li v-if="secretary.length%2 === 1" class="surplus">
+              <div class="branch-box"></div>
+              <div :style="{'width': ulWidth + 'px'}"></div>
+            </li>
+          </ul>
+        </template>
+        <div></div>
+        <template v-if="item.children && item.children.length>0">
+          <branch :dataArray="item.children" :count="currentCount"></branch>
+        </template>
+      </li>
+
+    </ul>
+</template>
+
+<script>
+export default {
+  name: 'Branch',
+  props: ['dataArray', 'count'],
+  data () {
+    return {
+      currentCount: 0
+    }
+  },
+  computed: {
+    ulWidth () {
+      let width = 0
+      this.dataArray.forEach((item, index) => {
+        if (item.secretary) {
+          item.secretary.forEach((it, sIndex) => {
+            console.log(it)
+            it.forEach((secretary, ssIndex) => {
+              if (secretary.children) {
+                console.log(secretary.children.length)
+                if (width < (secretary.children.length * 194)) {
+                  width = (secretary.children.length * 194)
+                }
+              }
+            })
+          })
+        }
+      })
+      return width
+    }
+  },
+  methods: {
+    clickHandle (obj) {
+      this.bus.$emit('info', obj)
+    },
+    isHaveChild(arr){
+      for (let i = 0; i < arr.length; i++) {
+        if (arr[i].children) {
+          return false
+        }
+      }
+      return true
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+  ul,li{
+    list-style: none;
+  }
+  li.liequal{
+    position: absolute;
+    left: 50%;
+    margin-left: 190px;
+    &:before{
+      content: none;
+    }
+  }
+  li.litop{
+    &:after{
+      content: none;
+    }
+  }
+  .branch-box{
+    width: 172px;
+    min-height: 180px;
+    border: 1px solid #CCCCCC;
+    border-radius: 4px;
+    text-align: center;
+    color: #666;
+    margin-top: 20px;
+    margin-left: 10px;
+    margin-right: 10px;
+    padding-bottom: 8px;
+    position: relative;
+    &.equal{
+      position: absolute;
+      left: 50%;
+      //top: calc(-100% + 20px);
+      &:before{
+        position: absolute;
+        content: '';
+        height: 1px;
+        width: 112px;
+        top: 50%;
+        left: -114px;
+        border-top: 1px dashed #000000;
+      }
+    }
+  }
+  .branch-box .branch-title{
+    background-color: #2E6491;
+    color: #fff;
+    height: 44px;
+    line-height: 44px;
+    text-align: center;
+    font-weight: bold;
+    font-size: 14px;
+  }
+  .branch-box .branch-pic{
+    width: 95px;
+    height: 95px;
+    margin: 0 auto;
+    border: 1px solid #2E6491;
+    margin-top: 10px;
+  }
+  .branch-box .branch-name{
+    font-size: 14px;
+    color: #2E6491;
+    text-align: center;
+    font-weight: bold;
+    padding: 4px 10px;
+  }
+
+  ul{
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    position: relative;
+    li{
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      padding-top: 20px;
+    }
+  }
+
+  ul li:only-child{
+    padding-top: 0;
+  }
+  ul li:before{
+    content: '';
+    position: absolute;
+    width: calc(50% + 1px);
+    top: 20px;
+    height: 20px;
+    left: -1px;
+    border-top: 2px solid #2E6491;
+    border-right: 2px solid #2E6491;
+    border-radius: 0 2px 0 0;
+  }
+  ul li:after{
+    content: '';
+    position: absolute;
+    width: calc(50% + 1px);
+    top: 20px;
+    height: 20px;
+    left: calc(50% - 1px);
+    border-top: 2px solid #2E6491;
+    border-left: 2px solid #2E6491;
+    border-radius: 2px 0 0 0;
+  }
+  ul li:first-child:before,ul li:last-child:after{
+    content: none;
+  }
+  ul:before{
+    content: '';
+    height: 22px;
+    width: 2px;
+    background-color: #2E6491;
+    position: absolute;
+    top: -1px;
+    left: 50%;
+    transform: translateX(-50%);
+    border-radius: 1px;
+    z-index: 1;
+  }
+  ul:first-child:before{
+    content: none;
+  }
+  ul.double{
+    width: 390px;
+    flex-wrap: wrap;
+    justify-content: space-between;
+  }
+  ul.double >li >.branch-box{
+    margin-left: 0;
+    margin-right: 0;
+    margin-top: 40px;
+  }
+  ul.double:before{
+    height: calc(100% - 90px);
+    left: 50%;
+    width: 2px;
+    background-color: #2E6491;
+    transform: translateX(-50%);
+    border-radius: 1px;
+    top: 0;
+    z-index: 1;
+  }
+  ul.double> li{
+    padding-top: 0;
+  }
+  ul.double>li:after,ul.double> li:before{
+    width: 27px;
+    height: 2px;
+    top: 60%;
+    background-color: #2E6491;
+    border: none;
+    border-radius: 1px;
+    z-index: 2;
+  }
+  ul.double> li:nth-child(2n+1):after{
+    right: -25px;
+    left: auto;
+  }
+  ul.double >li:nth-child(2n):before{
+    left: -25px;
+  }
+  ul.double >li:nth-child(2n+1):before,ul.double >li:nth-child(2n):after{content: none;}
+  ul.double >li:nth-child(2n+1):last-child:after{
+    content: '';
+  }
+  .iconfont{
+    color: #ff0000;
+    width: 16px;
+    display: inline-block;
+    text-align: center;
+  }
+  .iconfont.icon-kache{
+    color: #28a745 !important; /* 绿色:卡车 */
+  }
+  .iconfont.icon-chache{
+    color: #28a745 !important; /* 绿色:叉车 */
+    -webkit-text-stroke: 1px #28a745; /* 镂空效果 */
+    -webkit-text-fill-color: transparent; /* 透明填充 */
+  }
+  .iconfont.icon-plus,
+  .iconfont.icon-round{
+    color: #f0ad4e !important; /* 黄色:急救、消防员 */
+  }
+  .iconfont.icon-square{
+    color: #2E6491 !important; /* 蓝色:安全代表 */
+  }
+  .bz-box{
+    width: 18px;
+    right: 10px;
+    top: 50px;
+    position: absolute;
+  }
+  .bz-box i{
+    float: right;
+  }
+  ul.level:after{
+    content: '';
+    position: absolute;
+    width: 2px;
+    height: 100%;
+    background-color: #2E6491;
+    left: 50%;
+    transform: translateX(-50%);
+    border-radius: 1px;
+  }
+  ul li.surplus{
+    visibility: hidden;
+  }
+  ul.level li.odd:nth-last-child(2):after{
+    content: none;
+  }
+  .org-chart ul li .line {
+    width: 2px;
+    height: 30px;
+    background-color: #2E6491;
+    position: absolute;
+    left: 50%;
+    top: 0;
+    transform: translateX(-50%);
+    border-radius: 1px;
+  }
+</style>

+ 776 - 0
ui/src/views/plant/EOEGorganization/index.bak

@@ -0,0 +1,776 @@
+<template>
+  <div class="app-container">
+    <div>
+      <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+
+        <el-form-item :label="$t('部门')" prop="units">
+          <el-select v-model="units" :placeholder="$t('请选择') + $t('部门')" clearable size="small" multiple
+                     @change="handleQuery">
+            <el-option
+              v-for="dict in unitOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('班值')" prop="teams">
+          <el-select v-model="teams" :placeholder="$t('请选择') + $t('班值')" clearable size="small" multiple
+                     @change="handleQuery">
+            <el-option
+              v-for="dict in teamOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('实际岗位')" prop="actualposts" label-width="200">
+          <el-select v-model="actualposts" :placeholder="$t('请选择') + $t('实际岗位')" clearable size="small" multiple
+                     @change="handleQuery" collapse-tags>
+            <el-option
+              v-for="dict in actualpostOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">{{ $t('搜索') }}</el-button>
+          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ $t('重置') }}</el-button>
+        </el-form-item>
+      </el-form>
+      <el-row :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <div class="bz-box">
+            <i class="iconfont icon-star"></i> 应急响应管理小组组长
+            <i class="iconfont icon-love"></i> 志愿响应小组(VRT)队长
+            <i  class="iconfont icon-triangle"></i>危化品应急处置小组成员
+            <i  class="iconfont icon-square"></i>班组安全代表
+            <i  class="iconfont icon-plus"></i>急救员
+            <i  class="iconfont icon-round"></i>志愿消防员
+            <i  class="iconfont icon-yuanjiaoliujiaoxing"></i>安委会成员
+            <i  class="iconfont icon-shebeitubiao_famen"></i>TDS负责人
+            <i  class="iconfont icon-BAI-peixun"></i>VRT培训师
+          </div>
+        </el-col>
+        <right-toolbar :showSearch.sync="showSearch" @queryTable="getChartData"></right-toolbar>
+      </el-row>
+      <div id="tree" ref="orgChartDom"></div>
+    </div>
+    <vue-draggable-resizable w="auto" h="auto" :draggable="dragMove" style="background-color:white">
+      <div class="zoom" @wheel.prevent="handleTableWheel($event)" ref="branch">
+        <branch :dataArray="list1"></branch>
+      </div>
+    </vue-draggable-resizable>
+    <!-- 侧栏 --->
+    <el-drawer
+      title="附件"
+      ref="drawer"
+      direction="rtl"
+      :visible.sync="drawer">
+      <el-table :data="doc.commonfileList" border>
+        <el-table-column :label="$t('文件名')" align="center" prop="fileName" :show-overflow-tooltip="true">
+          <template slot-scope="scope">
+            <a class="link-type" @click="handleDownload(scope.row)">
+              <span>{{ scope.row.fileName }}</span>
+            </a>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('大小(Kb)')" align="center" prop="fileSize" :show-overflow-tooltip="true" width="80"/>
+        <el-table-column :label="$t('上传人')" align="center" prop="creator" :show-overflow-tooltip="true" width="120"/>
+        <el-table-column :label="$t('操作')" align="center" width="120" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <el-button
+              v-if="scope.row.fileName.endsWith('pdf')"
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleSee(scope.row)"
+            >{{ $t('预览') }}
+            </el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-download"
+              @click="handleDownload(scope.row)"
+            >{{ $t('下载') }}
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-dialog  :close-on-click-modal="false" v-dialogDrag :title="pdf.title" :visible.sync="pdf.open" width="1300px" append-to-body>
+        <div style="margin-top: -60px;float: right;margin-right: 40px;">
+          <el-button size="mini" type="text" @click="openPdf">{{ $t('新页面打开PDF') }}</el-button>
+        </div>
+        <div style="margin-top: -30px">
+          <iframe :src="pdf.pdfUrl" frameborder="0" width="100%" height="700px"></iframe>
+        </div>
+      </el-dialog>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import Branch from './branch'
+import {listOgzStaffmgr} from "@/api/plant/staffmgr";
+import {getToken} from "@/utils/auth";
+import {allFileList} from "@/api/common/commonfile";
+import {getUserByUserName} from "@/api/system/user";
+import VueDraggableResizable from 'vue-draggable-resizable';
+
+export default {
+  components: {Branch, VueDraggableResizable},
+  data() {
+    return {
+      showSearch: false,
+      // 实际岗位字典
+      actualpostOptions: [],
+      // 拖动功能
+      dragMove: true,
+      showOrgChartData: [],
+      staffmgrList: [],
+      // 部门字典
+      unitOptions: [],
+      // 班值字典
+      teamOptions: [],
+      // 查询参数
+      queryParams: {
+        unit: null,
+        team: null,
+        actualpost: null,
+        education: null,
+        enAbility: null,
+        educations: null,
+        units: null,
+        teams: null,
+        actualposts: null,
+      },
+      units: [],
+      teams: [],
+      actualposts: ["24","25", "26", "14", "16", "18", "20", "12", "10", "34", "36","15","11"],
+      drawer: false,
+      info: {},
+      list0: [{
+        "id": 10109,
+        "pId": 0,
+        "label": "朱晶",
+        "post": "装置经理",
+        "secretary": [[{
+          "id": 10113,
+          "pId": 10109,
+          "label": "赵建清",
+          "post": "装置副经理",
+          "secretary": [[], []],
+          "children": [{"id": 10101, "pId": 10113, "label": "张磊", "post": "资深工程师", "secretary": [[], []]}, {
+            "id": 10103,
+            "pId": 10113,
+            "label": "高勇",
+            "post": "资深工程师",
+            "secretary": [[], []]
+          }]
+        }, {
+          "id": 10117,
+          "pId": 10109,
+          "label": "居海波",
+          "post": "装置副经理",
+          "secretary": [[], []],
+          "children": [{"id": 10106, "pId": 10117, "label": "邹生耀", "post": "资深工程师", "secretary": [[], []]}]
+        }, {"id": 10102, "pId": 10109, "label": "韦岳平", "post": "装置副经理", "secretary": [[], []]}], []],
+        "children": [{"id": 10116, "pId": 10109, "label": "陈琨", "post": "资深工程师", "secretary": [[], []]}, {
+          "id": 10114,
+          "pId": 10109,
+          "label": "樊宏斌",
+          "post": "生产主管",
+          "secretary": [[], []]
+        }, {"id": 10108, "pId": 10109, "label": "袁永成", "post": "生产主管", "secretary": [[], []]}, {
+          "id": 10107,
+          "pId": 10109,
+          "label": "潘传安",
+          "post": "生产主管",
+          "secretary": [[], []]
+        }, {"id": 10104, "pId": 10109, "label": "胡文逵", "post": "生产主管", "secretary": [[], []]}, {
+          "id": 10110,
+          "pId": 10109,
+          "label": "孙文龙",
+          "post": "生产主管",
+          "secretary": [[], []]
+        }, {"id": 10115, "pId": 10109, "label": "鲍波", "post": "工长", "secretary": [[], []]}, {
+          "id": 10043,
+          "pId": 10109,
+          "label": "占丽萍",
+          "post": "职员",
+          "secretary": [[], []]
+        }, {
+          "id": 10001,
+          "pId": 10109,
+          "label": "徐建飞",
+          "post": "倒班班长",
+          "secretary": [[], []],
+          "children": [{"id": 10014, "pId": 10001, "label": "陈涛", "post": "倒班副班长", "secretary": [[], []]}, {
+            "id": 10012,
+            "pId": 10001,
+            "label": "陆危圣",
+            "post": "倒班副班长",
+            "secretary": [[], []]
+          }, {"id": 10008, "pId": 10001, "label": "任秋香", "post": "主操", "secretary": [[], []]}, {
+            "id": 10019,
+            "pId": 10001,
+            "label": "刘伟程",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10010, "pId": 10001, "label": "张磊", "post": "主操", "secretary": [[], []]}, {
+            "id": 10015,
+            "pId": 10001,
+            "label": "崔海军",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10000, "pId": 10001, "label": "王俊", "post": "主操", "secretary": [[], []]}, {
+            "id": 10003,
+            "pId": 10001,
+            "label": "马国春",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10004, "pId": 10001, "label": "申海宁", "post": "主操", "secretary": [[], []]}, {
+            "id": 10006,
+            "pId": 10001,
+            "label": "张燕燕",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10009, "pId": 10001, "label": "缪海荣", "post": "主操", "secretary": [[], []]}, {
+            "id": 10017,
+            "pId": 10001,
+            "label": "高峰",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10018, "pId": 10001, "label": "蒋恒兵", "post": "主操", "secretary": [[], []]}, {
+            "id": 10020,
+            "pId": 10001,
+            "label": "刘金京",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10002, "pId": 10001, "label": "张力飞", "post": "主操", "secretary": [[], []]}, {
+            "id": 10005,
+            "pId": 10001,
+            "label": "李欣阳",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10007, "pId": 10001, "label": "宋月民", "post": "主操", "secretary": [[], []]}, {
+            "id": 10013,
+            "pId": 10001,
+            "label": "贾云飞",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10016, "pId": 10001, "label": "张炜", "post": "主操", "secretary": [[], []]}, {
+            "id": 10011,
+            "pId": 10001,
+            "label": "宋章浩",
+            "post": "主操",
+            "secretary": [[], []]
+          }]
+        }, {
+          "id": 10031,
+          "pId": 10109,
+          "label": "臧闽军",
+          "post": "倒班班长",
+          "secretary": [[], []],
+          "children": [{"id": 10028, "pId": 10031, "label": "朱健", "post": "倒班副班长", "secretary": [[], []]}, {
+            "id": 10032,
+            "pId": 10031,
+            "label": "袁晨",
+            "post": "倒班副班长",
+            "secretary": [[], []]
+          }, {"id": 10035, "pId": 10031, "label": "陈海飞", "post": "主操", "secretary": [[], []]}, {
+            "id": 10024,
+            "pId": 10031,
+            "label": "刘尊超",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10026, "pId": 10031, "label": "马卫兵", "post": "主操", "secretary": [[], []]}, {
+            "id": 10027,
+            "pId": 10031,
+            "label": "曹西元",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10029, "pId": 10031, "label": "顾仁海", "post": "主操", "secretary": [[], []]}, {
+            "id": 10036,
+            "pId": 10031,
+            "label": "李静",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10037, "pId": 10031, "label": "朱永宜", "post": "主操", "secretary": [[], []]}, {
+            "id": 10039,
+            "pId": 10031,
+            "label": "封公瑾",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10040, "pId": 10031, "label": "姜翠君", "post": "主操", "secretary": [[], []]}, {
+            "id": 10022,
+            "pId": 10031,
+            "label": "周湘",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10041, "pId": 10031, "label": "梁宏伟", "post": "主操", "secretary": [[], []]}, {
+            "id": 10025,
+            "pId": 10031,
+            "label": "蒋宁宁",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10030, "pId": 10031, "label": "吴中鑫", "post": "主操", "secretary": [[], []]}, {
+            "id": 10038,
+            "pId": 10031,
+            "label": "刘辉",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10033, "pId": 10031, "label": "郑骅", "post": "主操", "secretary": [[], []]}, {
+            "id": 10034,
+            "pId": 10031,
+            "label": "张琦",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10023, "pId": 10031, "label": "邓阳", "post": "主操", "secretary": [[], []]}, {
+            "id": 10021,
+            "pId": 10031,
+            "label": "李凤希",
+            "post": "主操",
+            "secretary": [[], []]
+          }]
+        }, {
+          "id": 10049,
+          "pId": 10109,
+          "label": "沈涛",
+          "post": "倒班班长",
+          "secretary": [[], []],
+          "children": [{"id": 10048, "pId": 10049, "label": "乔刚", "post": "倒班副班长", "secretary": [[], []]}, {
+            "id": 10045,
+            "pId": 10049,
+            "label": "宦文恺",
+            "post": "倒班副班长",
+            "secretary": [[], []]
+          }, {"id": 10050, "pId": 10049, "label": "卓兴凤", "post": "主操", "secretary": [[], []]}, {
+            "id": 10052,
+            "pId": 10049,
+            "label": "阚久龙",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10055, "pId": 10049, "label": "王超", "post": "主操", "secretary": [[], []]}, {
+            "id": 10056,
+            "pId": 10049,
+            "label": "张永",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10058, "pId": 10049, "label": "宋浦江", "post": "主操", "secretary": [[], []]}, {
+            "id": 10060,
+            "pId": 10049,
+            "label": "夏军",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10047, "pId": 10049, "label": "劳青川", "post": "主操", "secretary": [[], []]}, {
+            "id": 10062,
+            "pId": 10049,
+            "label": "邢启元",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10061, "pId": 10049, "label": "韩叶锋", "post": "主操", "secretary": [[], []]}, {
+            "id": 10053,
+            "pId": 10049,
+            "label": "谢振华",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10057, "pId": 10049, "label": "黄梓赫", "post": "主操", "secretary": [[], []]}, {
+            "id": 10059,
+            "pId": 10049,
+            "label": "周权",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10046, "pId": 10049, "label": "赵振湘", "post": "主操", "secretary": [[], []]}, {
+            "id": 10051,
+            "pId": 10049,
+            "label": "沈文勇",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10042, "pId": 10049, "label": "卞传庆", "post": "主操", "secretary": [[], []]}, {
+            "id": 10044,
+            "pId": 10049,
+            "label": "李士军",
+            "post": "主操",
+            "secretary": [[], []]
+          }]
+        }, {
+          "id": 10064,
+          "pId": 10109,
+          "label": "刘遵胜",
+          "post": "倒班班长",
+          "secretary": [[], []],
+          "children": [{
+            "id": 10063,
+            "pId": 10064,
+            "label": "王维庆",
+            "post": "倒班副班长",
+            "secretary": [[], []]
+          }, {"id": 10083, "pId": 10064, "label": "郝维祥", "post": "倒班副班长", "secretary": [[], []]}, {
+            "id": 10073,
+            "pId": 10064,
+            "label": "李飞虎",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10075, "pId": 10064, "label": "杨赞", "post": "主操", "secretary": [[], []]}, {
+            "id": 10078,
+            "pId": 10064,
+            "label": "何叡颖",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10082, "pId": 10064, "label": "王欢", "post": "主操", "secretary": [[], []]}, {
+            "id": 10084,
+            "pId": 10064,
+            "label": "王守清",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10079, "pId": 10064, "label": "王竹宣", "post": "主操", "secretary": [[], []]}, {
+            "id": 10066,
+            "pId": 10064,
+            "label": "徐乐",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10071, "pId": 10064, "label": "胡远斌", "post": "主操", "secretary": [[], []]}, {
+            "id": 10074,
+            "pId": 10064,
+            "label": "马云凤",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10077, "pId": 10064, "label": "秦飞", "post": "主操", "secretary": [[], []]}, {
+            "id": 10081,
+            "pId": 10064,
+            "label": "程佩佩",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10069, "pId": 10064, "label": "孙夕斌", "post": "主操", "secretary": [[], []]}, {
+            "id": 10070,
+            "pId": 10064,
+            "label": "胡保宁",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10068, "pId": 10064, "label": "王刚", "post": "主操", "secretary": [[], []]}, {
+            "id": 10072,
+            "pId": 10064,
+            "label": "王勇",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10065, "pId": 10064, "label": "陈熹", "post": "主操", "secretary": [[], []]}, {
+            "id": 10067,
+            "pId": 10064,
+            "label": "朱国柱",
+            "post": "主操",
+            "secretary": [[], []]
+          }, {"id": 10080, "pId": 10064, "label": "孙浩", "post": "主操", "secretary": [[], []]}]
+        }]
+      }, {"id": 10112, "pId": 10109, "label": "何氢", "post": "主操(白班)", "secretary": [[], []]}, {
+        "id": 10054,
+        "pId": 10109,
+        "label": "李滕",
+        "post": "主操(白班)",
+        "secretary": [[], []]
+      }],
+      list1: []
+      ,
+      list2: [],
+      // 报告附件参数
+      doc: {
+        file: "",
+        // 是否显示弹出层(报告附件)
+        open: false,
+        // 弹出层标题(报告附件)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 报告附件上传位置编号
+        ids: 0,
+        // 设置上传的请求头部
+        headers: {Authorization: "Bearer " + getToken()},
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/common/commonfile/uploadFile",
+        commonfileList: null,
+        queryParams: {
+          pId: null,
+          pType: 'staffmgr'
+        },
+        pType: 'staffmgr',
+        pId: null
+      },
+      pdf: {
+        title: '',
+        pdfUrl: '',
+        numPages: null,
+        open: false,
+        pageNum: 1,
+        pageTotalNum: 1,
+        loadedRatio: 0,
+      },
+    }
+  },
+  created() {
+    this.getDicts("ACTUALPOST").then(response => {
+      this.actualpostOptions = response.data;
+    });
+    this.getDicts("STAFF_UNIT").then(response => {
+      this.unitOptions = response.data;
+    });
+    this.getDicts("TEAM_DIVIDE").then(response => {
+      this.teamOptions = response.data;
+    });
+    this.getChartData()
+  },
+  mounted() {
+    this.bus.$on('info', (data) => {
+      this.drawer = true
+      this.doc.queryParams.pId = data.id
+      allFileList(this.doc.queryParams).then(response => {
+        this.doc.commonfileList = response;
+      });
+      this.info = data
+    })
+  },
+  methods: {
+    dclick() {
+      this.drawer = true
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.units = []
+      this.teams = []
+      this.actualposts = []
+      this.handleQuery();
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getChartData();
+    },
+    getChartData() {
+      this.queryParams.units = this.units.join()
+      this.queryParams.teams = this.teams.join()
+      //CBP/B的人需要看ehs和副操
+      let names = this.$store.state.user.name
+      //查询用户归属的部门名称
+        if('10010' == this.$store.state.user.deptId) {
+          this.actualposts.push('22')
+        }
+          this.queryParams.actualposts = this.actualposts.join()
+          listOgzStaffmgr(this.queryParams).then(response => {
+            this.staffmgrList = response;
+            this.list2 = []
+            for (let i = 0; i < this.staffmgrList.length; i++) {
+              console.log("第" + i)
+              let post = this.selectDictLabel(this.actualpostOptions, this.staffmgrList[i].actualpost)
+              if (this.staffmgrList[i].pId == 0) {
+                let nodeData = {
+                  id: this.staffmgrList[i].id,
+                  pId: this.staffmgrList[i].pId,
+                  label: this.staffmgrList[i].name,
+                  post: post,
+                  secretary: [[], []],
+                  // img: 'http://47.114.101.16:8080' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  img: 'https://cpms.basf-ypc.net.cn' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  bz1: false,
+                  bz2: false,
+                  bz3: false,
+                  bz4: false,
+                  bz5: false,
+                  bz6: false,
+                  bz7: false,
+                  bz8: false,
+                  bz9: false
+                }
+                if (this.staffmgrList[i].specialDuty) {
+                  // console.log(this.staffmgrList[i].specialDuty)
+                  let dutyArr = this.staffmgrList[i].specialDuty.split(",")
+                  for (let i = 0; i < dutyArr.length; i++) {
+                    if (dutyArr[i] == "10") {
+                      nodeData.bz4 = true
+                    } else if (dutyArr[i] == "12") {
+                      nodeData.bz3 = true
+                    } else if (dutyArr[i] == "14") {
+                      nodeData.bz5 = true
+                    } else if (dutyArr[i] == "16") {
+                      nodeData.bz6 = true
+                    } else if (dutyArr[i] == "18") {
+                      nodeData.bz2 = true
+                    } else if (dutyArr[i] == "20") {
+                      nodeData.bz1 = true
+                    } else if (dutyArr[i] == "22") {
+                      nodeData.bz8 = true
+                    } else if (dutyArr[i] == "24") {
+                      nodeData.bz7 = true
+                    }else if (dutyArr[i] == "30") {
+                      nodeData.bz9 = true
+                    }
+                  }
+                }
+                this.list2.push(nodeData)
+              } else {
+                let nodeData = {
+                  id: this.staffmgrList[i].id,
+                  pId: this.staffmgrList[i].pId,
+                  label: this.staffmgrList[i].name,
+                  post: post,
+                  img: 'https://cpms.basf-ypc.net.cn' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  // img: 'http://47.114.101.16:8080' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  bz1: false,
+                  bz2: false,
+                  bz3: false,
+                  bz4: false,
+                  bz5: false,
+                  bz6: false,
+                  bz7: false,
+                  bz8: false,
+                  bz9: false
+                }
+                if (this.staffmgrList[i].specialDuty) {
+                  // console.log(this.staffmgrList[i].specialDuty)
+                  let dutyArr = this.staffmgrList[i].specialDuty.split(",")
+                  for (let i = 0; i < dutyArr.length; i++) {
+                    if (dutyArr[i] == "10") {
+                      nodeData.bz4 = true
+                    } else if (dutyArr[i] == "12") {
+                      nodeData.bz3 = true
+                    } else if (dutyArr[i] == "14") {
+                      nodeData.bz5 = true
+                    } else if (dutyArr[i] == "16") {
+                      nodeData.bz6 = true
+                    } else if (dutyArr[i] == "18") {
+                      nodeData.bz2 = true
+                    } else if (dutyArr[i] == "20") {
+                      nodeData.bz1 = true
+                    } else if (dutyArr[i] == "22") {
+                      nodeData.bz8 = true
+                    } else if (dutyArr[i] == "24") {
+                      nodeData.bz7 = true
+                    }else if (dutyArr[i] == "30") {
+                      nodeData.bz9 = true
+                    }
+                  }
+                }
+                this.list2.push(nodeData)
+              }
+            }
+            this.list1 = this.listToTree(this.list2)
+            console.log(this.list1)
+            console.log(JSON.stringify(this.list1))
+          })
+    },
+    listToTree(list) {
+      let map = {};
+      list.forEach(item => {
+        if (!map[item.id]) {
+          map[item.id] = item;
+        }
+      });
+
+      // 为每个父节点创建有序的子节点数组
+      list.forEach(item => {
+        if (item.post == '安全专员') { //
+          console.log('安全专员')
+          item.secretary = null
+        }
+        if(this.$store.state.user.homeType == 5) { //合成器生产主管和工程师再一个位置
+          if (item.pId !== 0 && map[item.pId]) {
+            // map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            if (item.post == '装置经理' || item.post == '安全专员' || item.post == '首席专家') {
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else if (item.post == '生产主管' || item.post == '工长') {
+              map[item.pId].secretary[0].push(item)
+            }else if ((item.post == '资深工程师' || item.post == '工程师') && map[item.pId].pId == 0) { //直属装置经理的资深工程师
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else {
+              map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            }
+          }
+        }else {
+          if (item.pId !== 0 && map[item.pId]) {
+            // map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            if (item.post == '装置经理' || item.post == '安全专员'|| item.post == '首席专家') {
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else if (item.post == '生产主管' || item.post == '工长') {
+              map[item.pId].secretary[1].push(item)
+            }else if ((item.post == '资深工程师' || item.post == '工程师') && map[item.pId].pId == 0) { //直属装置经理的资深工程师
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else {
+              map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            }
+          }
+        }
+      });
+
+      // 对每个节点的children进行重新排序
+      list.forEach(item => {
+        if (item.children && item.children.length > 0) {
+          // 按照职位优先级排序:炉区工长 -> 装置副经理 -> 生产主管 -> 工长 -> 职员 -> 倒班班长 -> 主操(白班)
+          item.children.sort((a, b) => {
+            const getPriority = (post) => {
+              switch(post) {
+                case '片区工长': return 1;
+                case '装置副经理': return 2;
+                case '生产主管': return 3;
+                case '工长': return 4;
+                case '职员': return 5;
+                case '倒班班长': return 6;
+                case '主操(白班)': return 7;
+                default: return 8;
+              }
+            };
+            return getPriority(a.post) - getPriority(b.post);
+          });
+        }
+      });
+
+      return list.filter(item => {
+        if (item.pId === 0) {
+          return item;
+        }
+      })
+    },
+    // 文件下载处理
+    handleDownload(row) {
+      var name = row.fileName;
+      var url = row.fileUrl;
+      var suffix = url.substring(url.lastIndexOf("."), url.length)
+      const a = document.createElement('a')
+      a.setAttribute('download', name)
+      a.setAttribute('target', '_blank')
+      a.setAttribute('href', process.env.VUE_APP_BASE_API + url)
+      a.click()
+    },
+    handleSee(row) {
+      this.pdf.open = true
+      this.pdf.title = row.fileName
+      this.pdf.pdfUrl = process.env.VUE_APP_BASE_API + '/pdf/web/viewer.html?file=' + process.env.VUE_APP_BASE_API + row.fileUrl
+    },
+    openPdf() {
+      window.open(this.pdf.pdfUrl);//path是文件的全路径地址
+    },
+
+    handleTableWheel(event) {
+      let obj = this.$refs['branch']
+      return this.tableZoom(obj, event)
+    },
+    tableZoom(obj, event) {
+      // 一开始默认是100%
+      let zoom = parseInt(obj.style.zoom, 10) || 100
+      // 滚轮滚一下wheelDelta的值增加或减少120
+      zoom += event.wheelDelta / 12
+      if (zoom > 50) {
+        obj.style.zoom = zoom + '%'
+      }
+      return false
+    },
+  }
+}
+</script>
+<style scoped>
+.iconfont{
+  color: #ff0000;
+}
+</style>

+ 497 - 0
ui/src/views/plant/EOEGorganization/index.vue

@@ -0,0 +1,497 @@
+<template>
+  <div class="app-container">
+    <div>
+      <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+
+        <el-form-item :label="$t('部门')" prop="units">
+          <el-select v-model="units" :placeholder="$t('请选择') + $t('部门')" clearable size="small" multiple
+                     @change="handleQuery">
+            <el-option
+              v-for="dict in unitOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('班值')" prop="teams">
+          <el-select v-model="teams" :placeholder="$t('请选择') + $t('班值')" clearable size="small" multiple
+                     @change="handleQuery">
+            <el-option
+              v-for="dict in teamOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item :label="$t('实际岗位')" prop="actualposts" label-width="200">
+          <el-select v-model="actualposts" :placeholder="$t('请选择') + $t('实际岗位')" clearable size="small" multiple
+                     @change="handleQuery" collapse-tags>
+            <el-option
+              v-for="dict in actualpostOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">{{ $t('搜索') }}</el-button>
+          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ $t('重置') }}</el-button>
+        </el-form-item>
+      </el-form>
+      <el-row :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <div class="bz-box">
+            <i  class="iconfont icon-square"></i>班组安全代表
+            <i  class="iconfont icon-plus"></i>急救员
+            <i  class="iconfont icon-round"></i>志愿消防员
+            <i  class="iconfont icon-kache"></i>运输分销安全负责人
+            <i  class="iconfont icon-chache"></i>叉车司机
+            <i  class="iconfont icon-star"></i>HAZMAT成员
+            <i  class="iconfont icon-lingxing"></i>安委会成员
+          </div>
+        </el-col>
+        <right-toolbar :showSearch.sync="showSearch" @queryTable="getChartData"></right-toolbar>
+      </el-row>
+      <div id="tree" ref="orgChartDom"></div>
+    </div>
+    <vue-draggable-resizable w="auto" h="auto" :draggable="dragMove" style="background-color:white">
+      <div class="zoom" @wheel.prevent="handleTableWheel($event)" ref="branch">
+        <branch :dataArray="list1"></branch>
+      </div>
+    </vue-draggable-resizable>
+
+    <!-- 侧栏 --->
+    <el-drawer
+      title="附件"
+      ref="drawer"
+      direction="rtl"
+      :visible.sync="drawer">
+      <el-table :data="doc.commonfileList" border>
+        <el-table-column :label="$t('文件名')" align="center" prop="fileName" :show-overflow-tooltip="true">
+          <template slot-scope="scope">
+            <a class="link-type" @click="handleDownload(scope.row)">
+              <span>{{ scope.row.fileName }}</span>
+            </a>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('大小(Kb)')" align="center" prop="fileSize" :show-overflow-tooltip="true" width="80"/>
+        <el-table-column :label="$t('上传人')" align="center" prop="creator" :show-overflow-tooltip="true" width="120"/>
+        <el-table-column :label="$t('操作')" align="center" width="120" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <el-button
+              v-if="scope.row.fileName.endsWith('pdf')"
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleSee(scope.row)"
+            >{{ $t('预览') }}
+            </el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-download"
+              @click="handleDownload(scope.row)"
+            >{{ $t('下载') }}
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-dialog  :close-on-click-modal="false" v-dialogDrag :title="pdf.title" :visible.sync="pdf.open" width="1300px" append-to-body>
+        <div style="margin-top: -60px;float: right;margin-right: 40px;">
+          <el-button size="mini" type="text" @click="openPdf">{{ $t('新页面打开PDF') }}</el-button>
+        </div>
+        <div style="margin-top: -30px">
+          <iframe :src="pdf.pdfUrl" frameborder="0" width="100%" height="700px"></iframe>
+        </div>
+      </el-dialog>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import Branch from './branch'
+import {listOgzStaffmgr} from "@/api/plant/staffmgr";
+import {getToken} from "@/utils/auth";
+import {allFileList} from "@/api/common/commonfile";
+import {getUserByUserName} from "@/api/system/user";
+import VueDraggableResizable from 'vue-draggable-resizable';
+
+export default {
+  components: {Branch, VueDraggableResizable},
+  data() {
+    return {
+      showSearch: false,
+      // 实际岗位字典
+      actualpostOptions: [],
+      // 拖动功能
+      dragMove: true,
+      showOrgChartData: [],
+      staffmgrList: [],
+      // 部门字典
+      unitOptions: [],
+      // 班值字典
+      teamOptions: [],
+      // 查询参数
+      queryParams: {
+        unit: null,
+        team: null,
+        actualpost: null,
+        education: null,
+        enAbility: null,
+        educations: null,
+        units: null,
+        teams: null,
+        actualposts: null,
+      },
+      units: [],
+      teams: [],
+      actualposts: ["24","25", "26", "14", "16", "18", "20", "12", "10", "34", "36","15","11"],
+      drawer: false,
+      info: {},
+      list0: [],
+      list1: []
+      ,
+      list2: [],
+      // 报告附件参数
+      doc: {
+        file: "",
+        // 是否显示弹出层(报告附件)
+        open: false,
+        // 弹出层标题(报告附件)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 报告附件上传位置编号
+        ids: 0,
+        // 设置上传的请求头部
+        headers: {Authorization: "Bearer " + getToken()},
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/common/commonfile/uploadFile",
+        commonfileList: null,
+        queryParams: {
+          pId: null,
+          pType: 'staffmgr'
+        },
+        pType: 'staffmgr',
+        pId: null
+      },
+      pdf: {
+        title: '',
+        pdfUrl: '',
+        numPages: null,
+        open: false,
+        pageNum: 1,
+        pageTotalNum: 1,
+        loadedRatio: 0,
+      },
+    }
+  },
+  created() {
+    this.getDicts("ACTUALPOST").then(response => {
+      this.actualpostOptions = response.data;
+    });
+    this.getDicts("STAFF_UNIT").then(response => {
+      this.unitOptions = response.data;
+    });
+    this.getDicts("TEAM_DIVIDE").then(response => {
+      this.teamOptions = response.data;
+    });
+    this.getChartData()
+  },
+  mounted() {
+    this.bus.$on('info', (data) => {
+      this.drawer = true
+      this.doc.queryParams.pId = data.id
+      allFileList(this.doc.queryParams).then(response => {
+        this.doc.commonfileList = response;
+      });
+      this.info = data
+    })
+  },
+  methods: {
+    dclick() {
+      this.drawer = true
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.units = []
+      this.teams = []
+      this.actualposts = []
+      this.handleQuery();
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getChartData();
+    },
+    getChartData() {
+      this.queryParams.units = this.units.join()
+      this.queryParams.teams = this.teams.join()
+      //CBP/B的人需要看ehs和副操
+      let names = this.$store.state.user.name
+      //查询用户归属的部门名称
+        if('10010' == this.$store.state.user.deptId) {
+          this.actualposts.push('22')
+        }
+          this.queryParams.actualposts = this.actualposts.join()
+          listOgzStaffmgr(this.queryParams).then(response => {
+            this.staffmgrList = response;
+            this.list2 = []
+            for (let i = 0; i < this.staffmgrList.length; i++) {
+              console.log("第" + i)
+              let post = this.selectDictLabel(this.actualpostOptions, this.staffmgrList[i].actualpost)
+              if (this.staffmgrList[i].pId == 0) {
+                let nodeData = {
+                  id: this.staffmgrList[i].id,
+                  pId: this.staffmgrList[i].pId,
+                  label: this.staffmgrList[i].name,
+                  post: post,
+                  secretary: [[], []],
+                  // img: 'http://47.114.101.16:8080' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  img: 'https://cpms.basf-ypc.net.cn' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  bz1: false,
+                  bz2: false,
+                  bz3: false,
+                  bz4: false,
+                  bz5: false,
+                  bz6: false,
+                  bz7: false,
+                  bz8: false,
+                  bz9: false
+                }
+                if (this.staffmgrList[i].specialDuty) {
+                  // console.log(this.staffmgrList[i].specialDuty)
+                  let dutyArr = this.staffmgrList[i].specialDuty.split(",")
+                  for (let i = 0; i < dutyArr.length; i++) {
+                    if (dutyArr[i] == "10") {
+                      nodeData.bz4 = true
+                    } else if (dutyArr[i] == "12") {
+                      nodeData.bz3 = true
+                    } else if (dutyArr[i] == "14") {
+                      nodeData.bz5 = true
+                    } else if (dutyArr[i] == "16") {
+                      nodeData.bz6 = true
+                    } else if (dutyArr[i] == "18") {
+                      nodeData.bz2 = true
+                    } else if (dutyArr[i] == "20") {
+                      nodeData.bz1 = true
+                    } else if (dutyArr[i] == "22") {
+                      nodeData.bz8 = true
+                    } else if (dutyArr[i] == "24") {
+                      nodeData.bz7 = true
+                    }else if (dutyArr[i] == "30") {
+                      nodeData.bz9 = true
+                    }else if (dutyArr[i] == "32") {
+                      nodeData.bz10 = true
+                    }else if (dutyArr[i] == "34") {
+                      nodeData.bz11 = true
+                    }else if (dutyArr[i] == "36") {
+                      nodeData.bz12 = true
+                    }
+                  }
+                }
+                this.list2.push(nodeData)
+              } else {
+                let nodeData = {
+                  id: this.staffmgrList[i].id,
+                  pId: this.staffmgrList[i].pId,
+                  label: this.staffmgrList[i].name,
+                  post: post,
+                  img: 'https://cpms.basf-ypc.net.cn' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  // img: 'http://47.114.101.16:8080' + process.env.VUE_APP_BASE_API + this.staffmgrList[i].photo,
+                  bz1: false,
+                  bz2: false,
+                  bz3: false,
+                  bz4: false,
+                  bz5: false,
+                  bz6: false,
+                  bz7: false,
+                  bz8: false,
+                  bz9: false
+                }
+                if (this.staffmgrList[i].specialDuty) {
+                  // console.log(this.staffmgrList[i].specialDuty)
+                  let dutyArr = this.staffmgrList[i].specialDuty.split(",")
+                  for (let i = 0; i < dutyArr.length; i++) {
+                    if (dutyArr[i] == "10") {
+                      nodeData.bz4 = true
+                    } else if (dutyArr[i] == "12") {
+                      nodeData.bz3 = true
+                    } else if (dutyArr[i] == "14") {
+                      nodeData.bz5 = true
+                    } else if (dutyArr[i] == "16") {
+                      nodeData.bz6 = true
+                    } else if (dutyArr[i] == "18") {
+                      nodeData.bz2 = true
+                    } else if (dutyArr[i] == "20") {
+                      nodeData.bz1 = true
+                    } else if (dutyArr[i] == "22") {
+                      nodeData.bz8 = true
+                    } else if (dutyArr[i] == "24") {
+                      nodeData.bz7 = true
+                    }else if (dutyArr[i] == "30") {
+                      nodeData.bz9 = true
+                    }else if (dutyArr[i] == "32") {
+                      nodeData.bz10 = true
+                    }else if (dutyArr[i] == "34") {
+                      nodeData.bz11 = true
+                    }else if (dutyArr[i] == "36") {
+                      nodeData.bz12 = true
+                    }
+                  }
+                }
+                this.list2.push(nodeData)
+              }
+            }
+            this.list1 = this.listToTree(this.list2)
+            console.log(this.list1)
+            console.log(JSON.stringify(this.list1))
+          })
+    },
+    listToTree(list) {
+      let map = {};
+      list.forEach(item => {
+        if (!map[item.id]) {
+          map[item.id] = item;
+        }
+      });
+
+      // 为每个父节点创建有序的子节点数组
+      list.forEach(item => {
+        if (item.post == '安全专员') { //
+          console.log('安全专员')
+          item.secretary = null
+        }
+        if(this.$store.state.user.homeType == 5) { //合成器生产主管和工程师再一个位置
+          if (item.pId !== 0 && map[item.pId]) {
+            // map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            if (item.post == '装置经理' || item.post == '安全专员' || item.post == '首席专家') {
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else if (item.post == '生产主管' || item.post == '工长') {
+              map[item.pId].secretary[0].push(item)
+            }else if ((item.post == '资深工程师' || item.post == '工程师') && map[item.pId].pId == 0) { //直属装置经理的资深工程师
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else {
+              map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            }
+          }
+        }else {
+          if (item.pId !== 0 && map[item.pId]) {
+            // map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            if (item.post == '装置经理' || item.post == '安全专员'|| item.post == '首席专家') {
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else if (item.post == '生产主管' || item.post == '工长') {
+              map[item.pId].secretary[1].push(item)
+            }else if ((item.post == '资深工程师' || item.post == '工程师') && map[item.pId].pId == 0) { //直属装置经理的资深工程师
+              map[item.pId].secretary ? map[item.pId].secretary[0].push(item) : map[item.pId].secretary[0] = [item];
+            } else {
+              map[item.pId].children ? map[item.pId].children.push(item) : map[item.pId].children = [item];
+            }
+          }
+        }
+      });
+
+      // 对每个节点的children进行重新排序
+      list.forEach(item => {
+        if (item.children && item.children.length > 0) {
+          // 按照职位优先级排序:炉区工长 -> 装置副经理 -> 生产主管 -> 工长 -> 职员 -> 倒班班长 -> 主操(白班)
+          item.children.sort((a, b) => {
+            const getPriority = (post) => {
+              switch(post) {
+                case '片区工长': return 1;
+                case '装置副经理': return 2;
+                case '生产主管': return 3;
+                case '工长': return 4;
+                case '职员': return 5;
+                case '倒班班长': return 6;
+                case '主操(白班)': return 7;
+                default: return 8;
+              }
+            };
+            return getPriority(a.post) - getPriority(b.post);
+          });
+        }
+      });
+
+      return list.filter(item => {
+        if (item.pId === 0) {
+          return item;
+        }
+      })
+    },
+    // 文件下载处理
+    handleDownload(row) {
+      var name = row.fileName;
+      var url = row.fileUrl;
+      var suffix = url.substring(url.lastIndexOf("."), url.length)
+      const a = document.createElement('a')
+      a.setAttribute('download', name)
+      a.setAttribute('target', '_blank')
+      a.setAttribute('href', process.env.VUE_APP_BASE_API + url)
+      a.click()
+    },
+    handleSee(row) {
+      this.pdf.open = true
+      this.pdf.title = row.fileName
+      this.pdf.pdfUrl = process.env.VUE_APP_BASE_API + '/pdf/web/viewer.html?file=' + process.env.VUE_APP_BASE_API + row.fileUrl
+    },
+    openPdf() {
+      window.open(this.pdf.pdfUrl);//path是文件的全路径地址
+    },
+
+     handleTableWheel(event) {
+       let obj = this.$refs['branch']
+       return this.tableZoom(obj, event)
+     },
+     tableZoom(obj, event) {
+       // 一开始默认是100%
+       let zoom = parseInt(obj.style.zoom, 10) || 100
+       // 滚轮滚一下wheelDelta的值增加或减少120
+       zoom += event.wheelDelta / 12
+       if (zoom > 20) {
+         obj.style.zoom = zoom + '%'
+       }
+       return false
+     },
+
+
+
+
+
+
+  }
+}
+</script>
+<style scoped>
+.iconfont{
+  color: #ff0000;
+  width: 16px;
+  display: inline-block;
+  text-align: center;
+}
+
+.iconfont.icon-kache{
+  color: #28a745 !important; /* 绿色:卡车 */
+}
+
+.iconfont.icon-chache{
+  color: #28a745 !important; /* 绿色:叉车 */
+  -webkit-text-stroke: 1px #28a745; /* 镂空效果 */
+  -webkit-text-fill-color: transparent; /* 透明填充 */
+}
+
+.iconfont.icon-plus,
+.iconfont.icon-round{
+  color: #f0ad4e !important; /* 黄色:急救、消防员 */
+}
+
+.iconfont.icon-square{
+  color: #2E6491 !important; /* 蓝色:安全代表 */
+}
+
+</style>

+ 1 - 1
ui/src/views/plant/staffmgr/index.vue

@@ -863,7 +863,7 @@
           isRetire: null
         },
         querypIdParams: {
-          units: '10,18,20,30,34',
+          units: '10,18,20,30,34,38',
         },
         educations: [],
         units: [],

+ 13 - 1
ui/src/views/training/elearn/userExam/paper.vue

@@ -46,6 +46,10 @@ export default {
     staffId: {
       type: String,
       default: ''
+    },
+    deviceId: {
+      type: String,
+      default: ''
     }
   },
 
@@ -72,6 +76,14 @@ export default {
         this.fetchPaperList()
       },
       deep: true
+    },
+
+    // 检测deviceId变化
+    deviceId: {
+      handler() {
+        this.fetchPaperList()
+      },
+      deep: true
     }
   },
 
@@ -81,7 +93,7 @@ export default {
   methods: {
 
     fetchPaperList() {
-      const param = {userId:this.userId ,examId: this.examId,staffId: this.staffId }
+      const param = {userId:this.userId ,examId: this.examId,staffId: this.staffId, deviceId: this.deviceId }
       listPaper(param).then(response => {
         this.paperList = response.rows
       })

+ 3 - 1
ui/src/views/training/trainingbcc/deviceList.vue

@@ -198,7 +198,7 @@
     <el-dialog v-if="detailOpen" :visible.sync="detailOpen" title="考试明细" width="60%" append-to-body>
 
       <div class="el-dialog-div">
-        <my-paper-list :exam-id="examId" :user-id="userId" :staff-id ="staffId" />
+        <my-paper-list :exam-id="examId" :user-id="userId" :staff-id ="staffId" :device-id="deviceId" />
       </div>
 
     </el-dialog>
@@ -242,6 +242,7 @@ export default {
       detailOpen:false,
       examId: null,
       staffId: null,
+      deviceId: null,
         // 用户导入参数
         upload: {
             // 是否显示弹出层(用户导入)
@@ -464,6 +465,7 @@ export default {
       hanldeExamPaper(row) {
           this.examId = row.trainingbcc.examId
           this.staffId = row.staffId
+          this.deviceId = row.id  // 将id作为deviceId传递
           this.detailOpen = true
       }
   }

Some files were not shown because too many files changed in this diff