Browse Source

Merge remote-tracking branch 'origin/master'

wanglt 7 months ago
parent
commit
7320ac0cfc

+ 55 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/controller/GxtRepairOrderController.java

@@ -1,7 +1,16 @@
 package com.ygtx.gxt.controller;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
+
+import com.ygtx.gxt.domain.GxtEquipment;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -20,6 +29,7 @@ import com.ygtx.gxt.domain.GxtRepairOrder;
 import com.ygtx.gxt.service.IGxtRepairOrderService;
 import com.ygtx.common.utils.poi.ExcelUtil;
 import com.ygtx.common.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 维修工单Controller
@@ -33,6 +43,8 @@ public class GxtRepairOrderController extends BaseController
 {
     @Autowired
     private IGxtRepairOrderService gxtRepairOrderService;
+    @Autowired
+    private ResourceLoader resourceLoader;
 
     /**
      * 查询维修工单列表
@@ -228,4 +240,47 @@ public class GxtRepairOrderController extends BaseController
     {
         return toAjax(gxtRepairOrderService.restartGxtRepairOrder(gxtRepairOrder));
     }
+
+    /**
+     * 导入维修工单数据
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:repairOrder:import')")
+    @Log(title = "维修工单", businessType = BusinessType.IMPORT)
+    @PostMapping("/importData")
+    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
+    {
+        ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
+        List<GxtRepairOrder> repairOrderList = util.importExcel(file.getInputStream());
+        String operName = getUsername();
+        String message = gxtRepairOrderService.importGxtRepairOrder(repairOrderList, updateSupport, operName);
+        return success(message);
+    }
+
+    /**
+     * 下载维修工单导入模板
+     */
+    @PostMapping("/importTemplate")
+    public void importTemplate(HttpServletResponse response)
+    {
+        /*ExcelUtil<GxtRepairOrder> util = new ExcelUtil<GxtRepairOrder>(GxtRepairOrder.class);
+        util.importTemplateExcel(response, "维修工单数据");*/
+        try {
+            String filename = URLEncoder.encode("repairOrder.xlsx", StandardCharsets.UTF_8.toString());
+            Resource resource = resourceLoader.getResource("classpath:repairOrder.xlsx");
+            response.setContentType("application/x-download");
+            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
+            try (ServletOutputStream out = response.getOutputStream();
+                 InputStream stream = resource.getInputStream()) {
+                byte buff[] = new byte[1024];
+                int length;
+                // 从文件输入流读取数据,并写入响应输出流中,实现文件下载
+                while ((length = stream.read(buff)) > 0) {
+                    out.write(buff, 0, length);
+                }
+                out.flush(); // 刷新输出流,确保所有数据都被发送到客户端
+            }
+        } catch (IOException e) {
+            e.printStackTrace(); // 输出异常信息,便于排查问题
+        }
+    }
 }

+ 4 - 3
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/GxtRepairOrder.java

@@ -94,12 +94,12 @@ public class GxtRepairOrder extends BaseEntity
 
     /** 实际开始时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-    @Excel(name = "实际开始时间")
+    @Excel(name = "开始时间")
     private Date realStartTime;
 
     /** 实际结束时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
-    @Excel(name = "实际结束时间")
+    @Excel(name = "结束时间")
     private Date realEndTime;
 
     /** 班组组长ID */
@@ -113,7 +113,7 @@ public class GxtRepairOrder extends BaseEntity
     private Long workGroupMemberId;
 
     /** 工作组成员姓名 */
-    @Excel(name = "工作组成员姓名")
+    @Excel(name = "检修人员")
     private String workGroupMemberName;
 
     /** 维修内容 */
@@ -168,6 +168,7 @@ public class GxtRepairOrder extends BaseEntity
     private String relatedOrderContent;
 
     /** MIS工单编码 */
+    @Excel(name = "MIS工单编码")
     private String misOrderNo;
 
     /** 恢复时间 */

+ 2 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/mapper/GxtRepairOrderMapper.java

@@ -68,4 +68,6 @@ public interface GxtRepairOrderMapper
      * @return 维修工单
      */
     public GxtRepairOrder selectGxtRepairOrderByWorkOrderProjectNo(String workOrderProjectNo);
+
+    public List<GxtRepairOrder> selectGxtRepairOrderListNoPermi(GxtRepairOrder repairOrderQuery);
 }

+ 2 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/IGxtRepairOrderService.java

@@ -154,4 +154,6 @@ public interface IGxtRepairOrderService
      * @return 结果
      */
     public boolean checkWorkOrderProjectNoUnique(GxtRepairOrder gxtRepairOrder);
+
+    public String importGxtRepairOrder(List<GxtRepairOrder> repairOrderList, boolean updateSupport, String operName);
 }

+ 6 - 5
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtEquipmentServiceImpl.java

@@ -211,6 +211,7 @@ public class GxtEquipmentServiceImpl implements IGxtEquipmentService
         }
         int successNum = 0;
         int failureNum = 0;
+        int row = 1;
         StringBuilder successMsg = new StringBuilder();
         StringBuilder failureMsg = new StringBuilder();
         for (GxtEquipment equipment : equipmentList)
@@ -218,19 +219,19 @@ public class GxtEquipmentServiceImpl implements IGxtEquipmentService
             try
             {
                 if (StringUtils.isEmpty(equipment.getEquipmentCode())) {
-                    throw new ServiceException("风机编号不能为空!");
+                    throw new ServiceException("第" + row + "行风机编号不能为空!");
                 }
                 if (StringUtils.isEmpty(equipment.getMaintenanceCenter())) {
-                    throw new ServiceException("维保中心不能为空!");
+                    throw new ServiceException("第" + row + "行维保中心不能为空!");
                 }
                 if (StringUtils.isEmpty(equipment.getStation())) {
-                    throw new ServiceException("场站不能为空!");
+                    throw new ServiceException("第" + row + "行场站不能为空!");
                 }
                 if (StringUtils.isEmpty(equipment.getBrand())) {
-                    throw new ServiceException("品牌不能为空!");
+                    throw new ServiceException("第" + row + "行品牌不能为空!");
                 }
                 if (StringUtils.isEmpty(equipment.getModel())) {
-                    throw new ServiceException("机型不能为空!");
+                    throw new ServiceException("第" + row + "行机型不能为空!");
                 }
                 
                 // 处理维保中心和场站的部门ID

+ 114 - 4
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtRepairOrderServiceImpl.java

@@ -4,22 +4,22 @@ import java.util.ArrayList;
 import java.util.List;
 
 import com.ygtx.common.core.domain.model.LoginUser;
+import com.ygtx.common.exception.ServiceException;
 import com.ygtx.common.utils.DateUtils;
 import com.ygtx.common.utils.DictUtils;
 import com.ygtx.common.core.domain.entity.SysDept;
 import com.ygtx.framework.aspectj.DataScopeAspect;
+import com.ygtx.gxt.domain.*;
+import com.ygtx.system.mapper.SysUserMapper;
 import com.ygtx.system.service.ISysConfigService;
 import com.ygtx.system.service.ISysDeptService;
-import com.ygtx.gxt.domain.GxtRepairOrderPerson;
-import com.ygtx.gxt.domain.GxtWorkOrderPerson;
 import com.ygtx.gxt.mapper.GxtRepairOrderPersonMapper;
+import com.ygtx.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ygtx.gxt.mapper.GxtRepairOrderMapper;
-import com.ygtx.gxt.domain.GxtRepairOrder;
 import com.ygtx.gxt.service.IGxtRepairOrderService;
 import com.ygtx.gxt.service.IGxtRepairOrderFlowService;
-import com.ygtx.gxt.domain.GxtRepairOrderFlow;
 import com.ygtx.common.annotation.DataScope;
 import com.ygtx.common.core.domain.entity.SysRole;
 import com.ygtx.common.core.domain.entity.SysUser;
@@ -51,6 +51,9 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private ISysUserService sysUserService;
+
     /**
      * 查询维修工单
      * 
@@ -1006,4 +1009,111 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
         }
         return true;
     }
+
+    @Override
+    public String importGxtRepairOrder(List<GxtRepairOrder> repairOrderList, boolean updateSupport, String operName) {
+        if (StringUtils.isNull(repairOrderList) || repairOrderList.size() == 0)
+        {
+            throw new ServiceException("导入工单数据不能为空!");
+        }
+        int successNum = 0;
+        int failureNum = 0;
+        int row = 1;
+        StringBuilder successMsg = new StringBuilder();
+        StringBuilder failureMsg = new StringBuilder();
+        for (GxtRepairOrder repairOrder : repairOrderList)
+        {
+            try
+            {
+                if (StringUtils.isEmpty(repairOrder.getMisOrderNo())) {
+                    throw new ServiceException("第" + row + "行MIS工单编码不能为空!");
+                }
+                if (repairOrder.getRealStartTime() == null) {
+                    throw new ServiceException("第" + row + "行开始时间不能为空!");
+                }
+                if (repairOrder.getRealEndTime() == null) {
+                    throw new ServiceException("第" + row + "行结束时间不能为空!");
+                }
+                /*if (StringUtils.isEmpty(repairOrder.getWorkGroupMemberName())) {
+                    throw new ServiceException("第" + row + "行检修人员不能为空!");
+                }*/
+                // 根据misOrderNo验证是否存在这个工单
+                GxtRepairOrder repairOrderQuery = new GxtRepairOrder();
+                repairOrderQuery.setMisOrderNo(repairOrder.getMisOrderNo());
+                List<GxtRepairOrder> gxtRepairOrders = gxtRepairOrderMapper.selectGxtRepairOrderListNoPermi(repairOrderQuery);
+                if (gxtRepairOrders == null || gxtRepairOrders.isEmpty())
+                {
+                    failureNum++;
+                    failureMsg.append("<br/>" + failureNum + "、MIS工单编码 " + repairOrder.getMisOrderNo()
+                            + " 在维修工单中不存在");
+                }
+                else if (gxtRepairOrders.size() > 1)
+                {
+                    failureNum++;
+                    failureMsg.append("<br/>" + failureNum + "、MIS工单编码 " + repairOrder.getMisOrderNo()
+                            + " 存在于多个维修工单中");
+                }
+                else
+                {
+                    GxtRepairOrder repairOrderI = gxtRepairOrders.get(0);
+                    repairOrder.setId(repairOrderI.getId());
+                    gxtRepairOrderMapper.updateGxtRepairOrder(repairOrder);
+                    String workGroupMemberName = repairOrder.getWorkGroupMemberName();
+                    if(StringUtils.isNotEmpty(workGroupMemberName)){
+                        gxtRepairOrderPersonMapper.deleteGxtRepairOrderPersonByOrderId(repairOrder.getId());
+                        String[] splitNames = repairOrder.getWorkGroupMemberName().split(",");
+                        for (String name : splitNames) {
+                            List<SysUser> sysUsers = sysUserService.selectUserByNickName(name);
+                            if(sysUsers != null && !sysUsers.isEmpty()){
+                                SysUser sysUser = null;
+                                // 如果只有一个用户,直接使用
+                                if (sysUsers.size() == 1) {
+                                    sysUser = sysUsers.get(0);
+                                } else {
+                                    // 如果有多个用户,查找部门ID与pcsStationPid相同的用户
+                                    for (SysUser user : sysUsers) {
+                                        if (user.getDeptId() != null && (user.getDeptId().equals(repairOrder.getPcsStationPid()) || user.getDeptId().equals(repairOrder.getPcsStationId()))) {
+                                            sysUser = user;
+                                            break;
+                                        }
+                                    }
+                                    // 如果没找到部门匹配的用户,则使用第一个用户
+                                    if (sysUser == null) {
+                                        sysUser = sysUsers.get(0);
+                                    }
+                                }
+                                GxtRepairOrderPerson person = new GxtRepairOrderPerson();
+                                person.setUserId(sysUser.getUserId());
+                                person.setNickName(sysUser.getNickName());
+                                person.setOrderId(repairOrder.getId());
+                                person.setOrderCode(repairOrderI.getWorkOrderProjectNo());
+                                person.setStatus(1);
+                                person.setCreateBy(SecurityUtils.getUsername());
+                                person.setCreateTime(DateUtils.getNowDate());
+                                gxtRepairOrderPersonMapper.insertGxtRepairOrderPerson(person);
+                            }
+                        }
+                    }
+                    successNum++;
+                    successMsg.append("<br/>" + successNum + "、MIS工单编码 " + repairOrder.getMisOrderNo() + " 更新成功");
+                }
+            }
+            catch (Exception e)
+            {
+                failureNum++;
+                String msg = "<br/>" + failureNum + "、MIS工单编码 " + repairOrder.getMisOrderNo() + " 导入失败:";
+                failureMsg.append(msg + e.getMessage());
+            }
+        }
+        if (failureNum > 0)
+        {
+            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+            throw new ServiceException(failureMsg.toString());
+        }
+        else
+        {
+            successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+        }
+        return successMsg.toString();
+    }
 }

+ 30 - 30
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtWorkOrderServiceImpl.java

@@ -618,7 +618,7 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
             order.setRealContent(gxtWorkOrder.getRealContent());
             order.setUpdateTime(DateUtils.getNowDate());
             order.setInspectionType(gxtWorkOrder.getInspectionType());
-
+            order.setAttachmentUrls(gxtWorkOrder.getAttachmentUrls());
 //            // 验证处理人员
 //            if (gxtWorkOrder.getTeamLeaderId() == null)
 //            {
@@ -639,39 +639,39 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
 
             if (result > 0)
             {
-                // 2. 删除旧的工作组成员
-                gxtWorkOrderPersonMapper.deleteGxtWorkOrderPersonByOrderId(id);
-
-                // 3. 添加新的工作组成员
-                for (GxtWorkOrderPerson person : gxtWorkOrder.getWorkOrderPersonList())
-                {
-                    person.setOrderId(id);
-                    person.setOrderCode(order.getWorkOrderProjectNo());
-                    person.setStatus(1);
-                    person.setCreateBy(SecurityUtils.getUsername());
-                    person.setCreateTime(DateUtils.getNowDate());
-                    gxtWorkOrderPersonMapper.insertGxtWorkOrderPerson(person);
-                }
+//                // 2. 删除旧的工作组成员
+//                gxtWorkOrderPersonMapper.deleteGxtWorkOrderPersonByOrderId(id);
+//
+//                // 3. 添加新的工作组成员
+//                for (GxtWorkOrderPerson person : gxtWorkOrder.getWorkOrderPersonList())
+//                {
+//                    person.setOrderId(id);
+//                    person.setOrderCode(order.getWorkOrderProjectNo());
+//                    person.setStatus(1);
+//                    person.setCreateBy(SecurityUtils.getUsername());
+//                    person.setCreateTime(DateUtils.getNowDate());
+//                    gxtWorkOrderPersonMapper.insertGxtWorkOrderPerson(person);
+//                }
                 recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "complete", oldStatus, "completed",
                         "工单完成,工单状态变为已完成");
             }
 
-            List<GxtWorkOrderAttachment> attachments = gxtWorkOrder.getAttachments();
-            for (GxtWorkOrderAttachment attachment : attachments) {
-                attachment.setWorkOrderId(order.getId());
-                attachment.setWorkOrderCode(order.getWorkOrderProjectNo());
-//                attachment.setFileName(file.getOriginalFilename());
-//                attachment.setFileSize(file.getSize());
-                // 根据文件扩展名判断文件类型
-//                attachment.setFileType(getFileExtension(file.getOriginalFilename()));
-                attachment.setUploadTime(DateUtils.getNowDate());
-                attachment.setUploadUserId(SecurityUtils.getUserId());
-                attachment.setUploadUserName(SecurityUtils.getUsername());
-                attachment.setCreateBy(SecurityUtils.getUsername());
-                attachment.setCreateTime(DateUtils.getNowDate());
-                attachment.setRemark("上传时间:" + DateUtils.getNowDate());
-                gxtWorkOrderAttachmentMapper.insertGxtWorkOrderAttachment(attachment);
-            }
+//            List<GxtWorkOrderAttachment> attachments = gxtWorkOrder.getAttachments();
+//            for (GxtWorkOrderAttachment attachment : attachments) {
+//                attachment.setWorkOrderId(order.getId());
+//                attachment.setWorkOrderCode(order.getWorkOrderProjectNo());
+////                attachment.setFileName(file.getOriginalFilename());
+////                attachment.setFileSize(file.getSize());
+//                // 根据文件扩展名判断文件类型
+////                attachment.setFileType(getFileExtension(file.getOriginalFilename()));
+//                attachment.setUploadTime(DateUtils.getNowDate());
+//                attachment.setUploadUserId(SecurityUtils.getUserId());
+//                attachment.setUploadUserName(SecurityUtils.getUsername());
+//                attachment.setCreateBy(SecurityUtils.getUsername());
+//                attachment.setCreateTime(DateUtils.getNowDate());
+//                attachment.setRemark("上传时间:" + DateUtils.getNowDate());
+//                gxtWorkOrderAttachmentMapper.insertGxtWorkOrderAttachment(attachment);
+//            }
 
             return result;
         }

+ 50 - 1
ygtx-gxt/src/main/resources/mapper/gxt/GxtRepairOrderMapper.xml

@@ -121,7 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             and (t.work_order_status != 'to_issue' or t.create_by in 
                 (select user_name from sys_user t1
                  left join sys_dept t2 on t1.dept_id = t2.dept_id
-                 where t2.dept_id = (select dept_id from sys_user where user_name = #{createBy,jdbcType=VARCHAR})))
+                 where t2.dept_id = (select dept_id from sys_user where user_name = #{createBy,jdbcType=VARCHAR} and del_flag='0')))
         </where>
         order by id desc
     </select>
@@ -302,4 +302,53 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectGxtRepairOrderVo"/>
         where work_order_project_no = #{workOrderProjectNo}
     </select>
+
+    <select id="selectGxtRepairOrderListNoPermi" parameterType="GxtRepairOrder" resultMap="GxtRepairOrderResult">
+        <include refid="selectGxtRepairOrderVo"/>
+        <where>
+            <if test="workOrderProjectNo != null  and workOrderProjectNo != ''"> and work_order_project_no = #{workOrderProjectNo}</if>
+            <if test="workOrderStatus != null  and workOrderStatus != ''"> and work_order_status = #{workOrderStatus}</if>
+            <if test="gxtCenterId != null "> and gxt_center_id = #{gxtCenterId}</if>
+            <if test="gxtCenter != null  and gxtCenter != ''"> and gxt_center = #{gxtCenter}</if>
+            <if test="pcsStationId != null "> and pcs_station_id = #{pcsStationId}</if>
+            <if test="pcsStationName != null  and pcsStationName != ''"> and pcs_station_name = #{pcsStationName} </if>
+            <if test="pcsDeviceId != null "> and pcs_device_id = #{pcsDeviceId}</if>
+            <if test="pcsDeviceName != null  and pcsDeviceName != ''"> and pcs_device_name like concat('%', #{pcsDeviceName}, '%')</if>
+            <if test="brand != null  and brand != ''"> and brand = #{brand}</if>
+            <if test="model != null  and model != ''"> and model = #{model}</if>
+            <if test="faultCode != null  and faultCode != ''"> and fault_code like concat('%', #{faultCode}, '%')</if>
+            <if test="faultDesc != null  and faultDesc != ''"> and fault_desc = #{faultDesc}</if>
+            <if test="assignTime != null "> and assign_time = #{assignTime}</if>
+            <if test="assignUserId != null "> and assign_user_id = #{assignUserId}</if>
+            <if test="assignUserName != null  and assignUserName != ''"> and assign_user_name like concat('%', #{assignUserName}, '%')</if>
+            <if test="acceptTime != null "> and accept_time = #{acceptTime}</if>
+            <if test="acceptUserId != null "> and accept_user_id = #{acceptUserId}</if>
+            <if test="acceptUserName != null  and acceptUserName != ''"> and accept_user_name like concat('%', #{acceptUserName}, '%')</if>
+            <if test="realStartTime != null "> and real_start_time = #{realStartTime}</if>
+            <if test="realEndTime != null "> and real_end_time = #{realEndTime}</if>
+            <if test="teamLeaderId != null "> and team_leader_id = #{teamLeaderId}</if>
+            <if test="teamLeaderName != null  and teamLeaderName != ''"> and team_leader_name like concat('%', #{teamLeaderName}, '%')</if>
+            <if test="workGroupMemberId != null "> and work_group_member_id = #{workGroupMemberId}</if>
+            <if test="workGroupMemberName != null  and workGroupMemberName != ''"> and work_group_member_name like concat('%', #{workGroupMemberName}, '%')</if>
+            <if test="content != null  and content != ''"> and content = #{content}</if>
+            <if test="planHour != null "> and plan_hour = #{planHour}</if>
+            <if test="priorityType != null "> and priority_type = #{priorityType}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="reviewContent != null  and reviewContent != ''"> and review_content = #{reviewContent}</if>
+            <if test="maintenanceType != null  and maintenanceType != ''"> and maintenance_type = #{maintenanceType}</if>
+            <if test="occurTime != null "> and occur_time = #{occurTime}</if>
+            <if test="faultBarcode != null  and faultBarcode != ''"> and fault_barcode = #{faultBarcode}</if>
+            <if test="suspendReason != null  and suspendReason != ''"> and suspend_reason = #{suspendReason}</if>
+            <if test="suspendDescription != null  and suspendDescription != ''"> and suspend_description = #{suspendDescription}</if>
+            <if test="approvalStatus != null  and approvalStatus != ''"> and approval_status = #{approvalStatus}</if>
+            <if test="rejectionReason != null  and rejectionReason != ''"> and rejection_reason = #{rejectionReason}</if>
+            <if test="finalizationRemark != null  and finalizationRemark != ''"> and finalization_remark = #{finalizationRemark}</if>
+            <if test="relatedOrderCode != null  and relatedOrderCode != ''"> and related_order_code = #{relatedOrderCode}</if>
+            <if test="relatedOrderContent != null  and relatedOrderContent != ''"> and related_order_content = #{relatedOrderContent}</if>
+            <if test="misOrderNo != null  and misOrderNo != ''"> and mis_order_no = #{misOrderNo}</if>
+            <if test="restartTime != null "> and restart_time = #{restartTime}</if>
+            <if test="pcsStationPid != null "> and pcs_station_pid = #{pcsStationPid}</if>
+        </where>
+        order by id desc
+    </select>
 </mapper>

+ 5 - 1
ygtx-gxt/src/main/resources/mapper/gxt/GxtWorkOrderMapper.xml

@@ -57,6 +57,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateBy"    column="update_by"    />
         <result property="updateTime"    column="update_time"    />
         <result property="remark"    column="remark"    />
+        <result property="attachmentUrls"    column="attachment_urls"    />
     </resultMap>
 
     <sql id="selectGxtWorkOrderVo">
@@ -66,7 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                team_leader_id, team_leader_name, work_group_member_id, work_group_member_name, suspend_reason,
                suspend_time,status_before_suspend, pause_reason, pause_time, restart_time, complete_time, plan_hour,
                content, real_content, fault_code, fault_desc, order_type, priority_type, score, review_content, issuer_name,
-               permitter_name, t.create_by, t.create_time, t.update_by, t.update_time, t.remark
+               permitter_name, t.create_by, t.create_time, t.update_by, t.update_time, t.remark, t.attachment_urls
         from gxt_work_order t
          left join sys_user u on u.user_name = t.create_by
          left join sys_dept d on u.dept_id = d.dept_id
@@ -156,6 +157,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateBy != null">update_by,</if>
             <if test="updateTime != null">update_time,</if>
             <if test="remark != null">remark,</if>
+            <if test="attachmentUrls != null">attachment_urls,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="workOrderProjectNo != null and workOrderProjectNo != ''">#{workOrderProjectNo},</if>
@@ -209,6 +211,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateBy != null">#{updateBy},</if>
             <if test="updateTime != null">#{updateTime},</if>
             <if test="remark != null">#{remark},</if>
+            <if test="attachmentUrls != null">#{attachmentUrls},</if>
          </trim>
     </insert>
 
@@ -266,6 +269,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateBy != null">update_by = #{updateBy},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="remark != null">remark = #{remark},</if>
+            <if test="attachmentUrls != null">attachment_urls = #{attachmentUrls},</if>
         </trim>
         where id = #{id}
     </update>

BIN
ygtx-gxt/src/main/resources/repairOrder.xlsx


+ 15 - 73
ygtx-ui/src/views/gxt/gxtOrder/index.vue

@@ -408,7 +408,6 @@
         <el-form ref="finishRef" :model="finishForm" :rules="finishRules" label-width="120px" label-position="top">
         <!-- 工单信息 -->
           <h4 class="text-sm font-medium text-gray-800 mb-3">工单信息</h4>
-  <!--        <el-form label-width="100px">-->
             <el-row :gutter="20">
               <el-col :span="12">
                 <el-form-item label="工单编码">
@@ -519,43 +518,11 @@
             </el-row>
             <el-row>
               <el-col :span="24">
-              <el-form-item label="附件(可选)">
-                <FileUpload
-                    ref="fileUploadRef"
-                    :multiple="true"
-                    :max-size="10"
-                    accept="image/*,video/*,.pdf,.doc,.docx"
-                    :model-value="finishForm.attachments"
-                    @files-selected="handleFilesSelected"
-                    @file-uploaded="handleFileUploaded"
-                    @upload-error="handleUploadError"
-                />
-                <!-- 上传区域 -->
-  <!--              <div class="upload-area border-2 border-dashed border-gray-300 rounded-md p-6 text-center">-->
-  <!--                <i class="fa fa-cloud-upload text-gray-400 text-3xl mb-3" style="font-size: 36px; color: #999;"></i>-->
-  <!--                <div class="mb-2">-->
-  <!--                  <label for="file-upload" class="cursor-pointer text-blue-500 hover:text-blue-700 font-medium">-->
-  <!--                    上传图片或视频-->
-  <!--                    <input id="file-upload" type="file" class="sr-only" multiple accept="image/jpeg,image/png,video/mp4" @change="handleFileSelect">-->
-  <!--                  </label>-->
-  <!--                  <span class="text-gray-600 ml-1">或拖放文件</span>-->
-  <!--                </div>-->
-  <!--                <p class="text-xs text-gray-500">支持 JPG, PNG, MP4 等格式</p>-->
-  <!--              </div>-->
-                <!-- 已上传文件列表 -->
-  <!--              <div class="mt-2 space-y-1" v-if="finishForm.attachments.length > 0">-->
-  <!--                <div v-for="(file, index) in finishForm.attachments" :key="index" class="flex items-center p-2 bg-gray-50 rounded">-->
-  <!--                  <i class="fa text-gray-500 mr-2" :class="getFileIconClass(file.name)"></i>-->
-  <!--                  <span class="text-sm text-gray-700 flex-1">{{ file.name || file.originalName }}</span>-->
-  <!--                  <button type="button" class="text-gray-400 hover:text-gray-600" @click="removeFile(index)">-->
-  <!--                    <i class="fa fa-times"></i>-->
-  <!--                  </button>-->
-  <!--                </div>-->
-  <!--              </div>-->
-              </el-form-item>
+                <el-form-item label="附件(可选)">
+                  <preview :limit="8" v-model="finishForm.attachmentUrls" :filesize="5"></preview>
+                </el-form-item>
               </el-col>
             </el-row>
-<!--          </template>-->
         </el-form>
       </div>
       <template #footer>
@@ -1174,33 +1141,16 @@
       </el-row>
 
       <!-- 附件信息 -->
-      <div class="info-section" v-if="detailData.attachments && detailData.attachments.length > 0">
+      <div class="info-section" v-if="detailData.attachmentUrls">
         <h3 class="section-title">结单附件</h3>
-        <div class="attachment-list">
-          <el-row :gutter="10">
-            <el-col :span="24" v-for="(attachment, index) in detailData.attachments" :key="index">
-              <div class="attachment-item">
-                <div class="attachment-icon">
-                  <i :class="getAttachmentIcon(attachment.fileName)" style="font-size: 24px; color: #409eff;"></i>
-                </div>
-                <div class="attachment-info">
-                  <div class="text-sm font-bold text-gray-900">{{ attachment.fileName }}</div>
-                  <div class="text-xs text-gray-500" style="margin-top: 2px;">{{ formatFileSize(attachment.fileSize) }} | {{ parseTime(attachment.createTime) }}</div>
-                </div>
-                <div class="attachment-action">
-                  <el-button link type="primary" size="small" @click="downloadAttachment(attachment)">
-                    <i class="fa fa-download"></i> 下载
-                  </el-button>
-                  <el-button link type="primary" size="small" v-if="isImageFile(attachment.fileName)" @click="previewAttachment(attachment)">
-                    <i class="fa fa-eye"></i> 预览
-                  </el-button>
-                </div>
-              </div>
-            </el-col>
-          </el-row>
-        </div>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="附件">
+              <preview :limit="8" v-model="detailData.attachmentUrls" :filesize="5" disabled></preview>
+            </el-form-item>
+          </el-col>
+        </el-row>
       </div>
-
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="detailDialogVisible = false">关 闭</el-button>
@@ -1236,6 +1186,7 @@
 <script setup name="GxtOrder">
 // 导入 FileUpload 组件
   import FileUpload from '@/components/FileUpload/index.vue'
+import preview from '@/components/FileUpload/preview.vue'
 import {
   listGxtOrder,
   getGxtOrder,
@@ -1667,17 +1618,7 @@ function submitFinish() {
   proxy.$refs["finishRef"].validate(valid => {
     debugger
     if (valid) {
-      const fileList = fileUploadRef.value.getFileList()
-      // 如果有附件,先上传附件
-      if (fileList) {
-        // uploadAttachmentsFn(fileList, finishForm.value.orderId)
-        // finishForm.value.attachments = fileList;
-        handleFileSelect(fileList)
-        saveFinishWorkOrder()
-      } else {
-        // 没有附件直接保存工单
-        saveFinishWorkOrder()
-      }
+      saveFinishWorkOrder()
     }
   })
 }
@@ -1729,10 +1670,11 @@ function uploadAttachmentsFn(files, orderId) {
 /** 保存结单工单 */
 function saveFinishWorkOrder() {
   finishForm.value.workOrderStatus = 'completed'
+  debugger
   completeWorkOrder(finishForm.value.orderId, finishForm.value).then(response => {
     finishDialogVisible.value = false
     // 清空附件列表
-    finishForm.value.attachments = []
+    finishForm.value.attachmentUrls = undefined
     proxy.$modal.msgSuccess("结单成功")
     getList()
   }).catch(error => {

+ 95 - 0
ygtx-ui/src/views/gxt/repairOrder/index.vue

@@ -104,6 +104,14 @@
             v-hasPermi="['gxt:repairOrder:add']"
         >新建工单</el-button>
       </el-col>
+      <el-col :span="1.5">
+        <el-button
+            type="info"
+            icon="Upload"
+            @click="handleImport"
+            v-hasPermi="['gxt:repairOrder:import']"
+        >导入</el-button>
+      </el-col>
       <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
@@ -1329,12 +1337,36 @@
       </template>
     </el-dialog>
 
+    <!-- 维修工单导入对话框 -->
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
+      <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :on-change="handleFileChange" :on-remove="handleFileRemove" :auto-upload="false" drag>
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+<!--            <div class="el-upload__tip">
+              <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的工单数据
+            </div>-->
+            <span>仅允许导入xls、xlsx格式文件。</span>
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
+          <el-button @click="upload.open = false">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
     <!-- 设备选择组件 -->
     <equipment-select-single v-model="equipmentSelectVisible" @onSelected="onEquipmentSelected"></equipment-select-single>
   </div>
 </template>
 
 <script setup name="RepairOrder">
+import { getToken } from "@/utils/auth"
 import {
   listRepairOrder,
   getRepairOrder,
@@ -2463,6 +2495,69 @@ function handleImgRemoved(imgUrl){
     form.value.workUrl = null;
 }
 
+
+/*** 设备导入参数 */
+const upload = reactive({
+  // 是否显示弹出层(设备导入)
+  open: false,
+  // 弹出层标题(设备导入)
+  title: "",
+  // 是否禁用上传
+  isUploading: false,
+  // 是否更新已经存在的设备数据
+  updateSupport: 0,
+  // 设置上传的请求头部
+  headers: { Authorization: "Bearer " + getToken() },
+  // 上传的地址
+  url: import.meta.env.VITE_APP_BASE_API + "/gxt/repairOrder/importData"
+})
+
+/** 导入按钮操作 */
+function handleImport() {
+  upload.title = "工单导入"
+  upload.open = true
+  upload.selectedFile = null
+}
+
+/** 下载模板操作 */
+function importTemplate() {
+  proxy.download("gxt/repairOrder/importTemplate", {
+  }, `repairOrder_template_${new Date().getTime()}.xlsx`)
+}
+
+/**文件上传中处理 */
+const handleFileUploadProgress = (event, file, fileList) => {
+  upload.isUploading = true
+}
+
+/** 文件选择处理 */
+const handleFileChange = (file, fileList) => {
+  upload.selectedFile = file
+}
+
+/** 文件删除处理 */
+const handleFileRemove = (file, fileList) => {
+  upload.selectedFile = null
+}
+
+/** 文件上传成功处理 */
+const handleFileSuccess = (response, file, fileList) => {
+  upload.open = false
+  upload.isUploading = false
+  proxy.$refs["uploadRef"].handleRemove(file)
+  proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
+  getList()
+}
+
+/** 提交上传文件 */
+function submitFileForm() {
+  const file = upload.selectedFile
+  if (!file || file.length === 0 || !file.name.toLowerCase().endsWith('.xls') && !file.name.toLowerCase().endsWith('.xlsx')) {
+    proxy.$modal.msgError("请选择后缀为 “xls”或“xlsx”的文件。")
+    return
+  }
+  proxy.$refs["uploadRef"].submit()
+}
 </script>
 
 <style scoped>