jiaxing.zhou

Merge branch 'master' into dev

package com.apple.erp.controller;
import com.apple.erp.dto.ExceptionWorkorderAddReq;
import com.apple.erp.dto.ExceptionWorkorderQueryReq;
import com.apple.erp.dto.ExceptionWorkorderRes;
import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq;
import com.apple.erp.dto.ExceptionWorkorderUpdateReq;
import com.apple.erp.service.ExceptionWorkorderService;
import com.apple.erp.dto.response.ApiRes;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* 异常工单Controller
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Tag(name = "异常工单管理", description = "异常工单相关接口")
@RestController
@RequestMapping("/api/exception-workorder")
@Validated
public class ExceptionWorkorderController {
@Autowired
private ExceptionWorkorderService exceptionWorkorderService;
@Operation(summary = "分页查询异常工单列表", description = "根据条件分页查询异常工单列表")
@GetMapping("/list")
@PreAuthorize("hasAuthority('exception:workorder:list')")
public ApiRes<Page<ExceptionWorkorderRes>> getExceptionWorkorderList(@Valid ExceptionWorkorderQueryReq queryReq) {
Page<ExceptionWorkorderRes> page = exceptionWorkorderService.getExceptionWorkorderList(queryReq);
return ApiRes.success(page);
}
@Operation(summary = "获取异常工单详情", description = "根据工单ID获取异常工单详细信息,包含处理日志")
@GetMapping("/{workorderId}")
@PreAuthorize("hasAuthority('exception:workorder:detail')")
public ApiRes<ExceptionWorkorderRes> getExceptionWorkorderDetail(
@Parameter(description = "工单ID", required = true) @PathVariable Long workorderId) {
ExceptionWorkorderRes workorderRes = exceptionWorkorderService.getExceptionWorkorderDetail(workorderId);
if (workorderRes != null) {
return ApiRes.success(workorderRes);
}
return ApiRes.error("异常工单不存在或已删除");
}
@Operation(summary = "新增异常工单", description = "创建新的异常工单")
@PostMapping
@PreAuthorize("hasAuthority('exception:workorder:add')")
public ApiRes<Void> addExceptionWorkorder(@Valid @RequestBody ExceptionWorkorderAddReq addReq) {
try {
boolean result = exceptionWorkorderService.addExceptionWorkorder(addReq);
if (result) {
return ApiRes.success("新增异常工单成功", null);
} else {
return ApiRes.error("新增异常工单失败");
}
} catch (Exception e) {
return ApiRes.error("新增异常工单失败: " + e.getMessage());
}
}
@Operation(summary = "更新异常工单", description = "更新异常工单信息")
@PutMapping
@PreAuthorize("hasAuthority('exception:workorder:edit')")
public ApiRes<Void> updateExceptionWorkorder(@Valid @RequestBody ExceptionWorkorderUpdateReq updateReq) {
try {
boolean result = exceptionWorkorderService.updateExceptionWorkorder(updateReq);
if (result) {
return ApiRes.success("更新异常工单成功", null);
} else {
return ApiRes.error("更新异常工单失败");
}
} catch (Exception e) {
return ApiRes.error("更新异常工单失败: " + e.getMessage());
}
}
@Operation(summary = "更新工单状态", description = "更新异常工单状态并记录处理日志")
@PostMapping("/status")
@PreAuthorize("hasAuthority('exception:workorder:edit')")
public ApiRes<Void> updateWorkorderStatus(@Valid @RequestBody ExceptionWorkorderStatusUpdateReq statusUpdateReq) {
try {
boolean result = exceptionWorkorderService.updateWorkorderStatus(statusUpdateReq);
if (result) {
return ApiRes.success("更新工单状态成功", null);
} else {
return ApiRes.error("更新工单状态失败");
}
} catch (Exception e) {
return ApiRes.error("更新工单状态失败: " + e.getMessage());
}
}
@Operation(summary = "删除异常工单", description = "根据工单ID逻辑删除异常工单")
@DeleteMapping("/{workorderId}")
@PreAuthorize("hasAuthority('exception:workorder:delete')")
public ApiRes<Void> deleteExceptionWorkorder(
@Parameter(description = "工单ID", required = true) @PathVariable Long workorderId) {
try {
boolean result = exceptionWorkorderService.deleteExceptionWorkorder(workorderId);
if (result) {
return ApiRes.success("删除异常工单成功", null);
} else {
return ApiRes.error("删除异常工单失败");
}
} catch (Exception e) {
return ApiRes.error("删除异常工单失败: " + e.getMessage());
}
}
@Operation(summary = "批量删除异常工单", description = "根据工单ID列表批量逻辑删除异常工单")
@DeleteMapping("/batch")
@PreAuthorize("hasAuthority('exception:workorder:delete')")
public ApiRes<Void> batchDeleteExceptionWorkorders(
@Parameter(description = "工单ID列表", required = true) @RequestBody List<Long> workorderIds) {
try {
if (workorderIds == null || workorderIds.isEmpty()) {
return ApiRes.error("工单ID列表不能为空");
}
boolean result = exceptionWorkorderService.batchDeleteExceptionWorkorders(workorderIds);
if (result) {
return ApiRes.success("批量删除异常工单成功", null);
} else {
return ApiRes.error("批量删除异常工单失败");
}
} catch (Exception e) {
return ApiRes.error("批量删除异常工单失败: " + e.getMessage());
}
}
@Operation(summary = "批量更新工单状态", description = "批量更新异常工单状态")
@PostMapping("/batch-status")
@PreAuthorize("hasAuthority('exception:workorder:edit')")
public ApiRes<Void> batchUpdateWorkorderStatus(
@Parameter(description = "工单ID列表", required = true) @RequestParam List<Long> workorderIds,
@Parameter(description = "工单状态", required = true) @RequestParam Integer workorderStatus,
@Parameter(description = "处理人", required = true) @RequestParam String handlerUser) {
try {
if (workorderIds == null || workorderIds.isEmpty()) {
return ApiRes.error("工单ID列表不能为空");
}
boolean result = exceptionWorkorderService.batchUpdateWorkorderStatus(workorderIds, workorderStatus, handlerUser);
if (result) {
return ApiRes.success("批量更新工单状态成功", null);
} else {
return ApiRes.error("批量更新工单状态失败");
}
} catch (Exception e) {
return ApiRes.error("批量更新工单状态失败: " + e.getMessage());
}
}
@Operation(summary = "获取异常工单统计信息", description = "获取异常工单的统计信息")
@GetMapping("/stats")
@PreAuthorize("hasAuthority('exception:workorder:list')")
public ApiRes<List<ExceptionWorkorderRes>> getExceptionWorkorderStats() {
List<ExceptionWorkorderRes> stats = exceptionWorkorderService.getExceptionWorkorderStats();
return ApiRes.success(stats);
}
}
package com.apple.erp.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* 异常工单新增请求DTO
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@Schema(description = "异常工单新增请求")
public class ExceptionWorkorderAddReq {
@NotBlank(message = "工单编号不能为空")
@Schema(description = "工单编号", required = true)
private String workorderNo;
@Schema(description = "关联订单编号")
private String orderNo;
@Schema(description = "经销商编码")
private String dealerCode;
@Schema(description = "经销商名称")
private String dealerName;
@NotNull(message = "异常类型不能为空")
@Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)", required = true)
private Integer exceptionType;
@NotNull(message = "严重程度不能为空")
@Schema(description = "严重程度(1-高/2-中/3-低)", required = true)
private Integer severityLevel;
@Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)")
private Integer workorderStatus = 1;
@Schema(description = "预计处理完成时间")
private LocalDateTime expectCompleteTime;
@Schema(description = "处理人")
private String handlerUser;
@Schema(description = "异常描述")
private String exceptionDesc;
@Schema(description = "处理建议")
private String handleSuggest;
@Schema(description = "数据来源")
private String dataSource;
}
package com.apple.erp.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 异常工单处理日志响应DTO
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@Schema(description = "异常工单处理日志响应")
public class ExceptionWorkorderLogRes {
@Schema(description = "日志ID")
private Long logId;
@Schema(description = "关联工单ID")
private Long workorderId;
@Schema(description = "关联工单编号")
private String workorderNo;
@Schema(description = "处理人")
private String handleUser;
@Schema(description = "处理时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime handleTime;
@Schema(description = "处理前状态")
private Integer beforeStatus;
@Schema(description = "处理前状态名称")
private String beforeStatusName;
@Schema(description = "处理后状态")
private Integer afterStatus;
@Schema(description = "处理后状态名称")
private String afterStatusName;
@Schema(description = "处理意见")
private String handleOpinion;
@Schema(description = "附件URL")
private String attachUrl;
@Schema(description = "创建者")
private String createBy;
@Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
}
package com.apple.erp.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 异常工单查询请求DTO
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@Schema(description = "异常工单查询请求")
public class ExceptionWorkorderQueryReq {
@Schema(description = "工单编号")
private String workorderNo;
@Schema(description = "关联订单编号")
private String orderNo;
@Schema(description = "经销商编码")
private String dealerCode;
@Schema(description = "经销商名称")
private String dealerName;
@Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)")
private Integer workorderStatus;
@Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)")
private Integer exceptionType;
@Schema(description = "严重程度(1-高/2-中/3-低)")
private Integer severityLevel;
@Schema(description = "处理人")
private String handlerUser;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "页码")
private Integer pageNum = 1;
@Schema(description = "每页大小")
private Integer pageSize = 10;
}
package com.apple.erp.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* 异常工单响应DTO
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@Schema(description = "异常工单响应")
public class ExceptionWorkorderRes {
@Schema(description = "工单ID")
private Long workorderId;
@Schema(description = "工单编号")
private String workorderNo;
@Schema(description = "关联订单编号")
private String orderNo;
@Schema(description = "经销商编码")
private String dealerCode;
@Schema(description = "经销商名称")
private String dealerName;
@Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)")
private Integer exceptionType;
@Schema(description = "异常类型名称")
private String exceptionTypeName;
@Schema(description = "严重程度(1-高/2-中/3-低)")
private Integer severityLevel;
@Schema(description = "严重程度名称")
private String severityLevelName;
@Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)")
private Integer workorderStatus;
@Schema(description = "工单状态名称")
private String workorderStatusName;
@Schema(description = "工单创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@Schema(description = "预计处理完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expectCompleteTime;
@Schema(description = "处理人")
private String handlerUser;
@Schema(description = "异常描述")
private String exceptionDesc;
@Schema(description = "处理建议")
private String handleSuggest;
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "创建者")
private String createBy;
@Schema(description = "更新者")
private String updateBy;
@Schema(description = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@Schema(description = "处理日志列表")
private List<ExceptionWorkorderLogRes> workorderLogs;
}
package com.apple.erp.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 异常工单状态更新请求DTO
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@Schema(description = "异常工单状态更新请求")
public class ExceptionWorkorderStatusUpdateReq {
@NotNull(message = "工单ID不能为空")
@Schema(description = "工单ID", required = true)
private Long workorderId;
@NotNull(message = "工单状态不能为空")
@Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)", required = true)
private Integer workorderStatus;
@Schema(description = "处理人")
private String handlerUser;
@Schema(description = "处理意见")
private String handleOpinion;
@Schema(description = "附件URL")
private String attachUrl;
}
package com.apple.erp.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* 异常工单更新请求DTO
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@Schema(description = "异常工单更新请求")
public class ExceptionWorkorderUpdateReq {
@NotNull(message = "工单ID不能为空")
@Schema(description = "工单ID", required = true)
private Long workorderId;
@Schema(description = "工单编号")
private String workorderNo;
@Schema(description = "关联订单编号")
private String orderNo;
@Schema(description = "经销商编码")
private String dealerCode;
@Schema(description = "经销商名称")
private String dealerName;
@Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)")
private Integer exceptionType;
@Schema(description = "严重程度(1-高/2-中/3-低)")
private Integer severityLevel;
@Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)")
private Integer workorderStatus;
@Schema(description = "预计处理完成时间")
private LocalDateTime expectCompleteTime;
@Schema(description = "处理人")
private String handlerUser;
@Schema(description = "异常描述")
private String exceptionDesc;
@Schema(description = "处理建议")
private String handleSuggest;
@Schema(description = "数据来源")
private String dataSource;
}
package com.apple.erp.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 异常工单表实体类
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_exception_workorder")
@Schema(description = "异常工单表")
public class ExceptionWorkorder {
@TableId(value = "workorder_id", type = IdType.AUTO)
@Schema(description = "工单ID")
private Long workorderId;
@Schema(description = "工单编号")
private String workorderNo;
@Schema(description = "关联订单编号")
private String orderNo;
@Schema(description = "经销商编码")
private String dealerCode;
@Schema(description = "经销商名称")
private String dealerName;
@Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)")
private Integer exceptionType;
@Schema(description = "严重程度(1-高/2-中/3-低)")
private Integer severityLevel;
@Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)")
private Integer workorderStatus;
@Schema(description = "工单创建时间")
private LocalDateTime createTime;
@Schema(description = "预计处理完成时间")
private LocalDateTime expectCompleteTime;
@Schema(description = "处理人")
private String handlerUser;
@Schema(description = "异常描述")
private String exceptionDesc;
@Schema(description = "处理建议")
private String handleSuggest;
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "创建者")
private String createBy;
@Schema(description = "更新者")
private String updateBy;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
@Schema(description = "删除标志(0代表存在 2代表删除)")
private String delFlag;
}
package com.apple.erp.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 异常工单处理日志表实体类
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_exception_workorder_log")
@Schema(description = "异常工单处理日志表")
public class ExceptionWorkorderLog {
@TableId(value = "log_id", type = IdType.AUTO)
@Schema(description = "日志ID")
private Long logId;
@Schema(description = "关联工单ID")
private Long workorderId;
@Schema(description = "关联工单编号")
private String workorderNo;
@Schema(description = "处理人")
private String handleUser;
@Schema(description = "处理时间")
private LocalDateTime handleTime;
@Schema(description = "处理前状态")
private Integer beforeStatus;
@Schema(description = "处理后状态")
private Integer afterStatus;
@Schema(description = "处理意见")
private String handleOpinion;
@Schema(description = "附件URL")
private String attachUrl;
@Schema(description = "创建者")
private String createBy;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新者")
private String updateBy;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
@Schema(description = "删除标志(0代表存在 2代表删除)")
private String delFlag;
}
package com.apple.erp.mapper;
import com.apple.erp.dto.ExceptionWorkorderLogRes;
import com.apple.erp.entity.ExceptionWorkorderLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 异常工单处理日志Mapper接口
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Mapper
public interface ExceptionWorkorderLogMapper extends BaseMapper<ExceptionWorkorderLog> {
/**
* 根据工单ID获取处理日志列表
*
* @param workorderId 工单ID
* @return 处理日志列表
*/
List<ExceptionWorkorderLogRes> selectWorkorderLogsByWorkorderId(@Param("workorderId") Long workorderId);
/**
* 根据工单ID列表批量获取处理日志
*
* @param workorderIds 工单ID列表
* @return 处理日志列表
*/
List<ExceptionWorkorderLogRes> selectWorkorderLogsByWorkorderIds(@Param("workorderIds") List<Long> workorderIds);
}
package com.apple.erp.mapper;
import com.apple.erp.dto.ExceptionWorkorderQueryReq;
import com.apple.erp.dto.ExceptionWorkorderRes;
import com.apple.erp.entity.ExceptionWorkorder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 异常工单Mapper接口
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Mapper
public interface ExceptionWorkorderMapper extends BaseMapper<ExceptionWorkorder> {
/**
* 分页查询异常工单列表
*
* @param page 分页参数
* @param queryReq 查询条件
* @return 异常工单列表
*/
Page<ExceptionWorkorderRes> selectExceptionWorkorderPage(Page<ExceptionWorkorderRes> page, @Param("query") ExceptionWorkorderQueryReq queryReq);
/**
* 根据工单ID获取异常工单详情
*
* @param workorderId 工单ID
* @return 异常工单详情
*/
ExceptionWorkorderRes selectExceptionWorkorderDetail(@Param("workorderId") Long workorderId);
/**
* 获取异常工单统计信息
*
* @return 统计信息
*/
List<ExceptionWorkorderRes> selectExceptionWorkorderStats();
/**
* 批量更新工单状态
*
* @param workorderIds 工单ID列表
* @param workorderStatus 工单状态
* @param handlerUser 处理人
* @return 更新数量
*/
int batchUpdateWorkorderStatus(@Param("workorderIds") List<Long> workorderIds,
@Param("workorderStatus") Integer workorderStatus,
@Param("handlerUser") String handlerUser);
}
package com.apple.erp.service;
import com.apple.erp.dto.ExceptionWorkorderAddReq;
import com.apple.erp.dto.ExceptionWorkorderQueryReq;
import com.apple.erp.dto.ExceptionWorkorderRes;
import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq;
import com.apple.erp.dto.ExceptionWorkorderUpdateReq;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.apple.erp.entity.ExceptionWorkorder;
import java.util.List;
/**
* 异常工单Service接口
*
* @author Apple ERP System
* @since 2025-01-27
*/
public interface ExceptionWorkorderService extends IService<ExceptionWorkorder> {
/**
* 分页查询异常工单列表
*
* @param queryReq 查询条件
* @return 异常工单列表(带分页信息)
*/
Page<ExceptionWorkorderRes> getExceptionWorkorderList(ExceptionWorkorderQueryReq queryReq);
/**
* 获取异常工单详情
*
* @param workorderId 工单ID
* @return 异常工单详情(包含处理日志)
*/
ExceptionWorkorderRes getExceptionWorkorderDetail(Long workorderId);
/**
* 新增异常工单
*
* @param addReq 异常工单新增请求
* @return 是否成功
*/
boolean addExceptionWorkorder(ExceptionWorkorderAddReq addReq);
/**
* 更新异常工单
*
* @param updateReq 异常工单更新请求
* @return 是否成功
*/
boolean updateExceptionWorkorder(ExceptionWorkorderUpdateReq updateReq);
/**
* 更新工单状态
*
* @param statusUpdateReq 状态更新请求
* @return 是否成功
*/
boolean updateWorkorderStatus(ExceptionWorkorderStatusUpdateReq statusUpdateReq);
/**
* 删除异常工单
*
* @param workorderId 工单ID
* @return 是否成功
*/
boolean deleteExceptionWorkorder(Long workorderId);
/**
* 批量删除异常工单
*
* @param workorderIds 工单ID列表
* @return 是否成功
*/
boolean batchDeleteExceptionWorkorders(List<Long> workorderIds);
/**
* 批量更新工单状态
*
* @param workorderIds 工单ID列表
* @param workorderStatus 工单状态
* @param handlerUser 处理人
* @return 是否成功
*/
boolean batchUpdateWorkorderStatus(List<Long> workorderIds, Integer workorderStatus, String handlerUser);
/**
* 获取异常工单统计信息
*
* @return 统计信息
*/
List<ExceptionWorkorderRes> getExceptionWorkorderStats();
}
package com.apple.erp.service.impl;
import com.apple.erp.dto.ExceptionWorkorderAddReq;
import com.apple.erp.dto.ExceptionWorkorderLogRes;
import com.apple.erp.dto.ExceptionWorkorderQueryReq;
import com.apple.erp.dto.ExceptionWorkorderRes;
import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq;
import com.apple.erp.dto.ExceptionWorkorderUpdateReq;
import com.apple.erp.entity.ExceptionWorkorder;
import com.apple.erp.entity.ExceptionWorkorderLog;
import com.apple.erp.mapper.ExceptionWorkorderLogMapper;
import com.apple.erp.mapper.ExceptionWorkorderMapper;
import com.apple.erp.service.ExceptionWorkorderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 异常工单Service实现类
*
* @author Apple ERP System
* @since 2025-01-27
*/
@Service
public class ExceptionWorkorderServiceImpl extends ServiceImpl<ExceptionWorkorderMapper, ExceptionWorkorder> implements ExceptionWorkorderService {
@Autowired
private ExceptionWorkorderMapper exceptionWorkorderMapper;
@Autowired
private ExceptionWorkorderLogMapper exceptionWorkorderLogMapper;
@Override
public Page<ExceptionWorkorderRes> getExceptionWorkorderList(ExceptionWorkorderQueryReq queryReq) {
Page<ExceptionWorkorderRes> page = new Page<>(queryReq.getPageNum(), queryReq.getPageSize());
return exceptionWorkorderMapper.selectExceptionWorkorderPage(page, queryReq);
}
@Override
public ExceptionWorkorderRes getExceptionWorkorderDetail(Long workorderId) {
ExceptionWorkorderRes workorderRes = exceptionWorkorderMapper.selectExceptionWorkorderDetail(workorderId);
if (workorderRes != null) {
// 获取处理日志
List<ExceptionWorkorderLogRes> logs = exceptionWorkorderLogMapper.selectWorkorderLogsByWorkorderId(workorderId);
workorderRes.setWorkorderLogs(logs);
}
return workorderRes;
}
@Override
@Transactional
public boolean addExceptionWorkorder(ExceptionWorkorderAddReq addReq) {
ExceptionWorkorder workorder = new ExceptionWorkorder();
BeanUtils.copyProperties(addReq, workorder);
workorder.setCreateTime(LocalDateTime.now());
workorder.setDelFlag("0");
int result = exceptionWorkorderMapper.insert(workorder);
// 记录处理日志
if (result > 0) {
ExceptionWorkorderLog log = new ExceptionWorkorderLog();
log.setWorkorderId(workorder.getWorkorderId());
log.setWorkorderNo(workorder.getWorkorderNo());
log.setHandleUser(addReq.getHandlerUser());
log.setHandleTime(LocalDateTime.now());
log.setBeforeStatus(0);
log.setAfterStatus(workorder.getWorkorderStatus());
log.setHandleOpinion("工单创建");
log.setCreateTime(LocalDateTime.now());
log.setDelFlag("0");
exceptionWorkorderLogMapper.insert(log);
}
return result > 0;
}
@Override
@Transactional
public boolean updateExceptionWorkorder(ExceptionWorkorderUpdateReq updateReq) {
ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(updateReq.getWorkorderId());
if (workorder == null || "2".equals(workorder.getDelFlag())) {
return false;
}
BeanUtils.copyProperties(updateReq, workorder);
workorder.setUpdateTime(LocalDateTime.now());
return exceptionWorkorderMapper.updateById(workorder) > 0;
}
@Override
@Transactional
public boolean updateWorkorderStatus(ExceptionWorkorderStatusUpdateReq statusUpdateReq) {
ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(statusUpdateReq.getWorkorderId());
if (workorder == null || "2".equals(workorder.getDelFlag())) {
return false;
}
Integer beforeStatus = workorder.getWorkorderStatus();
workorder.setWorkorderStatus(statusUpdateReq.getWorkorderStatus());
workorder.setHandlerUser(statusUpdateReq.getHandlerUser());
workorder.setUpdateTime(LocalDateTime.now());
int result = exceptionWorkorderMapper.updateById(workorder);
// 记录处理日志
if (result > 0) {
ExceptionWorkorderLog log = new ExceptionWorkorderLog();
log.setWorkorderId(workorder.getWorkorderId());
log.setWorkorderNo(workorder.getWorkorderNo());
log.setHandleUser(statusUpdateReq.getHandlerUser());
log.setHandleTime(LocalDateTime.now());
log.setBeforeStatus(beforeStatus);
log.setAfterStatus(statusUpdateReq.getWorkorderStatus());
log.setHandleOpinion(statusUpdateReq.getHandleOpinion());
log.setAttachUrl(statusUpdateReq.getAttachUrl());
log.setCreateTime(LocalDateTime.now());
log.setDelFlag("0");
exceptionWorkorderLogMapper.insert(log);
}
return result > 0;
}
@Override
@Transactional
public boolean deleteExceptionWorkorder(Long workorderId) {
ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(workorderId);
if (workorder == null || "2".equals(workorder.getDelFlag())) {
return false;
}
workorder.setDelFlag("2");
workorder.setUpdateTime(LocalDateTime.now());
return exceptionWorkorderMapper.updateById(workorder) > 0;
}
@Override
@Transactional
public boolean batchDeleteExceptionWorkorders(List<Long> workorderIds) {
if (workorderIds == null || workorderIds.isEmpty()) {
return false;
}
ExceptionWorkorder workorder = new ExceptionWorkorder();
workorder.setDelFlag("2");
workorder.setUpdateTime(LocalDateTime.now());
LambdaQueryWrapper<ExceptionWorkorder> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ExceptionWorkorder::getWorkorderId, workorderIds);
queryWrapper.eq(ExceptionWorkorder::getDelFlag, "0");
return exceptionWorkorderMapper.update(workorder, queryWrapper) > 0;
}
@Override
@Transactional
public boolean batchUpdateWorkorderStatus(List<Long> workorderIds, Integer workorderStatus, String handlerUser) {
if (workorderIds == null || workorderIds.isEmpty()) {
return false;
}
int result = exceptionWorkorderMapper.batchUpdateWorkorderStatus(workorderIds, workorderStatus, handlerUser);
// 记录批量处理日志
if (result > 0) {
for (Long workorderId : workorderIds) {
ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(workorderId);
if (workorder != null && "0".equals(workorder.getDelFlag())) {
ExceptionWorkorderLog log = new ExceptionWorkorderLog();
log.setWorkorderId(workorderId);
log.setWorkorderNo(workorder.getWorkorderNo());
log.setHandleUser(handlerUser);
log.setHandleTime(LocalDateTime.now());
log.setBeforeStatus(workorder.getWorkorderStatus());
log.setAfterStatus(workorderStatus);
log.setHandleOpinion("批量状态更新");
log.setCreateTime(LocalDateTime.now());
log.setDelFlag("0");
exceptionWorkorderLogMapper.insert(log);
}
}
}
return result > 0;
}
@Override
public List<ExceptionWorkorderRes> getExceptionWorkorderStats() {
return exceptionWorkorderMapper.selectExceptionWorkorderStats();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.apple.erp.mapper.ExceptionWorkorderLogMapper">
<!-- 根据工单ID获取处理日志列表 -->
<select id="selectWorkorderLogsByWorkorderId" resultType="com.apple.erp.dto.ExceptionWorkorderLogRes">
SELECT
ewl.log_id,
ewl.workorder_id,
ewl.workorder_no,
ewl.handle_user,
ewl.handle_time,
ewl.before_status,
CASE ewl.before_status
WHEN 1 THEN '待处理'
WHEN 2 THEN '处理中'
WHEN 3 THEN '已解决'
WHEN 4 THEN '已关闭'
ELSE '未知状态'
END AS before_status_name,
ewl.after_status,
CASE ewl.after_status
WHEN 1 THEN '待处理'
WHEN 2 THEN '处理中'
WHEN 3 THEN '已解决'
WHEN 4 THEN '已关闭'
ELSE '未知状态'
END AS after_status_name,
ewl.handle_opinion,
ewl.attach_url,
ewl.create_by,
ewl.create_time
FROM t_exception_workorder_log ewl
WHERE ewl.workorder_id = #{workorderId} AND ewl.del_flag = '0'
ORDER BY ewl.handle_time DESC
</select>
<!-- 根据工单ID列表批量获取处理日志 -->
<select id="selectWorkorderLogsByWorkorderIds" resultType="com.apple.erp.dto.ExceptionWorkorderLogRes">
SELECT
ewl.log_id,
ewl.workorder_id,
ewl.workorder_no,
ewl.handle_user,
ewl.handle_time,
ewl.before_status,
CASE ewl.before_status
WHEN 1 THEN '待处理'
WHEN 2 THEN '处理中'
WHEN 3 THEN '已解决'
WHEN 4 THEN '已关闭'
ELSE '未知状态'
END AS before_status_name,
ewl.after_status,
CASE ewl.after_status
WHEN 1 THEN '待处理'
WHEN 2 THEN '处理中'
WHEN 3 THEN '已解决'
WHEN 4 THEN '已关闭'
ELSE '未知状态'
END AS after_status_name,
ewl.handle_opinion,
ewl.attach_url,
ewl.create_by,
ewl.create_time
FROM t_exception_workorder_log ewl
WHERE ewl.workorder_id IN
<foreach collection="workorderIds" item="workorderId" open="(" separator="," close=")">
#{workorderId}
</foreach>
AND ewl.del_flag = '0'
ORDER BY ewl.workorder_id, ewl.handle_time DESC
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.apple.erp.mapper.ExceptionWorkorderMapper">
<!-- 分页查询异常工单列表 -->
<select id="selectExceptionWorkorderPage" resultType="com.apple.erp.dto.ExceptionWorkorderRes">
SELECT
ew.workorder_id,
ew.workorder_no,
ew.order_no,
ew.dealer_code,
ew.dealer_name,
ew.exception_type,
CASE ew.exception_type
WHEN 1 THEN '逻辑验证异常'
WHEN 2 THEN '源头验证异常'
WHEN 3 THEN '交叉验证异常'
ELSE '未知类型'
END AS exception_type_name,
ew.severity_level,
CASE ew.severity_level
WHEN 1 THEN '高'
WHEN 2 THEN '中'
WHEN 3 THEN '低'
ELSE '未知'
END AS severity_level_name,
ew.workorder_status,
CASE ew.workorder_status
WHEN 1 THEN '待处理'
WHEN 2 THEN '处理中'
WHEN 3 THEN '已解决'
WHEN 4 THEN '已关闭'
ELSE '未知状态'
END AS workorder_status_name,
ew.create_time,
ew.expect_complete_time,
ew.handler_user,
ew.exception_desc,
ew.handle_suggest,
ew.data_source,
ew.create_by,
ew.update_by,
ew.update_time
FROM t_exception_workorder ew
<where>
ew.del_flag = '0'
<if test="query.workorderNo != null and query.workorderNo != ''">
AND ew.workorder_no LIKE CONCAT('%', #{query.workorderNo}, '%')
</if>
<if test="query.orderNo != null and query.orderNo != ''">
AND ew.order_no LIKE CONCAT('%', #{query.orderNo}, '%')
</if>
<if test="query.dealerCode != null and query.dealerCode != ''">
AND ew.dealer_code = #{query.dealerCode}
</if>
<if test="query.dealerName != null and query.dealerName != ''">
AND ew.dealer_name LIKE CONCAT('%', #{query.dealerName}, '%')
</if>
<if test="query.workorderStatus != null">
AND ew.workorder_status = #{query.workorderStatus}
</if>
<if test="query.exceptionType != null">
AND ew.exception_type = #{query.exceptionType}
</if>
<if test="query.severityLevel != null">
AND ew.severity_level = #{query.severityLevel}
</if>
<if test="query.handlerUser != null and query.handlerUser != ''">
AND ew.handler_user LIKE CONCAT('%', #{query.handlerUser}, '%')
</if>
<if test="query.startTime != null">
AND ew.create_time >= #{query.startTime}
</if>
<if test="query.endTime != null">
AND ew.create_time &lt;= #{query.endTime}
</if>
</where>
ORDER BY ew.create_time DESC
</select>
<!-- 根据工单ID获取异常工单详情 -->
<select id="selectExceptionWorkorderDetail" resultType="com.apple.erp.dto.ExceptionWorkorderRes">
SELECT
ew.workorder_id,
ew.workorder_no,
ew.order_no,
ew.dealer_code,
ew.dealer_name,
ew.exception_type,
CASE ew.exception_type
WHEN 1 THEN '逻辑验证异常'
WHEN 2 THEN '源头验证异常'
WHEN 3 THEN '交叉验证异常'
ELSE '未知类型'
END AS exception_type_name,
ew.severity_level,
CASE ew.severity_level
WHEN 1 THEN '高'
WHEN 2 THEN '中'
WHEN 3 THEN '低'
ELSE '未知'
END AS severity_level_name,
ew.workorder_status,
CASE ew.workorder_status
WHEN 1 THEN '待处理'
WHEN 2 THEN '处理中'
WHEN 3 THEN '已解决'
WHEN 4 THEN '已关闭'
ELSE '未知状态'
END AS workorder_status_name,
ew.create_time,
ew.expect_complete_time,
ew.handler_user,
ew.exception_desc,
ew.handle_suggest,
ew.data_source,
ew.create_by,
ew.update_by,
ew.update_time
FROM t_exception_workorder ew
WHERE ew.workorder_id = #{workorderId} AND ew.del_flag = '0'
</select>
<!-- 获取异常工单统计信息 -->
<select id="selectExceptionWorkorderStats" resultType="com.apple.erp.dto.ExceptionWorkorderRes">
SELECT
'total' AS workorder_no,
COUNT(*) AS workorder_id,
SUM(CASE WHEN workorder_status = 1 THEN 1 ELSE 0 END) AS exception_type,
SUM(CASE WHEN workorder_status = 2 THEN 1 ELSE 0 END) AS severity_level,
SUM(CASE WHEN workorder_status = 3 THEN 1 ELSE 0 END) AS workorder_status,
SUM(CASE WHEN workorder_status = 4 THEN 1 ELSE 0 END) AS handler_user,
SUM(CASE WHEN severity_level = 1 THEN 1 ELSE 0 END) AS exception_desc,
SUM(CASE WHEN severity_level = 2 THEN 1 ELSE 0 END) AS handle_suggest,
SUM(CASE WHEN severity_level = 3 THEN 1 ELSE 0 END) AS data_source
FROM t_exception_workorder
WHERE del_flag = '0'
</select>
<!-- 批量更新工单状态 -->
<update id="batchUpdateWorkorderStatus">
UPDATE t_exception_workorder
SET workorder_status = #{workorderStatus},
handler_user = #{handlerUser},
update_time = NOW()
WHERE workorder_id IN
<foreach collection="workorderIds" item="workorderId" open="(" separator="," close=")">
#{workorderId}
</foreach>
AND del_flag = '0'
</update>
</mapper>
-- 异常工单模块完整初始化脚本
-- 包含表结构创建、权限配置、测试数据插入
-- 1. 创建异常工单表
CREATE TABLE IF NOT EXISTS t_exception_workorder (
workorder_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '工单ID',
workorder_no VARCHAR(30) NOT NULL COMMENT '工单编号',
order_no VARCHAR(30) COMMENT '关联订单编号',
dealer_code VARCHAR(20) COMMENT '经销商编码',
dealer_name VARCHAR(100) COMMENT '经销商名称',
exception_type TINYINT NOT NULL COMMENT '异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)',
severity_level TINYINT NOT NULL COMMENT '严重程度(1-高/2-中/3-低)',
workorder_status TINYINT DEFAULT 1 COMMENT '工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '工单创建时间',
expect_complete_time DATETIME COMMENT '预计处理完成时间',
handler_user VARCHAR(20) COMMENT '处理人',
exception_desc VARCHAR(500) COMMENT '异常描述',
handle_suggest VARCHAR(500) COMMENT '处理建议',
data_source VARCHAR(20) COMMENT '数据来源',
create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='异常工单表';
-- 2. 创建异常工单处理日志表
CREATE TABLE IF NOT EXISTS t_exception_workorder_log (
log_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID',
workorder_id BIGINT NOT NULL COMMENT '关联工单ID',
workorder_no VARCHAR(30) NOT NULL COMMENT '关联工单编号',
handle_user VARCHAR(20) NOT NULL COMMENT '处理人',
handle_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '处理时间',
before_status TINYINT NOT NULL COMMENT '处理前状态',
after_status TINYINT NOT NULL COMMENT '处理后状态',
handle_opinion VARCHAR(500) COMMENT '处理意见',
attach_url VARCHAR(200) COMMENT '附件URL',
create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='异常工单处理日志表';
-- 3. 创建索引
-- 异常工单表索引
CREATE UNIQUE INDEX IF NOT EXISTS uk_workorder_no ON t_exception_workorder(workorder_no);
CREATE INDEX IF NOT EXISTS idx_workorder_dealer_code ON t_exception_workorder(dealer_code);
CREATE INDEX IF NOT EXISTS idx_workorder_order_no ON t_exception_workorder(order_no);
CREATE INDEX IF NOT EXISTS idx_workorder_status ON t_exception_workorder(workorder_status);
CREATE INDEX IF NOT EXISTS idx_workorder_exception_type ON t_exception_workorder(exception_type);
CREATE INDEX IF NOT EXISTS idx_workorder_severity_level ON t_exception_workorder(severity_level);
CREATE INDEX IF NOT EXISTS idx_workorder_create_time ON t_exception_workorder(create_time);
CREATE INDEX IF NOT EXISTS idx_workorder_handler_user ON t_exception_workorder(handler_user);
-- 异常工单处理日志表索引
CREATE INDEX IF NOT EXISTS idx_log_workorder_id ON t_exception_workorder_log(workorder_id);
CREATE INDEX IF NOT EXISTS idx_log_workorder_no ON t_exception_workorder_log(workorder_no);
CREATE INDEX IF NOT EXISTS idx_log_handle_user ON t_exception_workorder_log(handle_user);
CREATE INDEX IF NOT EXISTS idx_log_handle_time ON t_exception_workorder_log(handle_time);
-- 4. 创建外键约束
ALTER TABLE t_exception_workorder_log
ADD CONSTRAINT IF NOT EXISTS fk_workorder_log_workorder_id
FOREIGN KEY (workorder_id) REFERENCES t_exception_workorder(workorder_id)
ON DELETE CASCADE ON UPDATE CASCADE;
-- 5. 插入异常工单菜单
INSERT IGNORE INTO t_sys_menu (parent_id, menu_name, menu_type, path, icon, sort, status, perms, create_by, create_time) VALUES
(0, '异常工单', 1, '/main/exception-workorder', '⚠️', 7, 1, 'exception:workorder:view', 'admin', NOW());
-- 获取异常工单菜单ID
SET @exception_menu_id = LAST_INSERT_ID();
-- 6. 插入异常工单子菜单
INSERT IGNORE INTO t_sys_menu (parent_id, menu_name, menu_type, path, icon, sort, status, perms, create_by, create_time) VALUES
(@exception_menu_id, '工单查询', 2, '', '', 1, 1, 'exception:workorder:list', 'admin', NOW()),
(@exception_menu_id, '工单详情', 2, '', '', 2, 1, 'exception:workorder:detail', 'admin', NOW()),
(@exception_menu_id, '工单新增', 2, '', '', 3, 1, 'exception:workorder:add', 'admin', NOW()),
(@exception_menu_id, '工单编辑', 2, '', '', 4, 1, 'exception:workorder:edit', 'admin', NOW()),
(@exception_menu_id, '工单删除', 2, '', '', 5, 1, 'exception:workorder:delete', 'admin', NOW()),
(@exception_menu_id, '状态更新', 2, '', '', 6, 1, 'exception:workorder:status', 'admin', NOW()),
(@exception_menu_id, '批量处理', 2, '', '', 7, 1, 'exception:workorder:batch', 'admin', NOW()),
(@exception_menu_id, '统计查看', 2, '', '', 8, 1, 'exception:workorder:stats', 'admin', NOW());
-- 12. 为管理员角色分配异常工单权限
INSERT IGNORE INTO t_sys_role_menu (role_id, menu_id, create_by, create_time)
SELECT r.role_id, @exception_menu_id, 'admin', NOW()
FROM t_sys_role r
WHERE r.role_code = 'ADMIN';
-- 13. 为管理员角色分配异常工单子菜单权限
INSERT IGNORE INTO t_sys_role_menu (role_id, menu_id, create_by, create_time)
SELECT r.role_id, m.menu_id, 'admin', NOW()
FROM t_sys_role r, t_sys_menu m
WHERE r.role_code = 'ADMIN'
AND m.parent_id = @exception_menu_id;
-- 完成初始化
SELECT '异常工单模块初始化完成' AS message;
import { request } from '../utils/request'
// 异常工单相关类型定义
export interface ExceptionWorkorderInfo {
workorderId: number
workorderNo: string
orderNo: string
dealerCode: string
dealerName: string
exceptionType: number
exceptionTypeName: string
severityLevel: number
severityLevelName: string
workorderStatus: number
workorderStatusName: string
createTime: string
expectCompleteTime?: string
handlerUser?: string
exceptionDesc?: string
handleSuggest?: string
dataSource?: string
createBy?: string
updateBy?: string
updateTime?: string
workorderLogs?: ExceptionWorkorderLogInfo[]
}
export interface ExceptionWorkorderLogInfo {
logId: number
workorderId: number
workorderNo: string
handleUser: string
handleTime: string
beforeStatus: number
beforeStatusName: string
afterStatus: number
afterStatusName: string
handleOpinion?: string
attachUrl?: string
createBy?: string
createTime: string
}
export interface ExceptionWorkorderQueryReq {
workorderNo?: string
orderNo?: string
dealerCode?: string
dealerName?: string
workorderStatus?: number
exceptionType?: number
severityLevel?: number
handlerUser?: string
startTime?: string
endTime?: string
pageNum?: number
pageSize?: number
}
export interface ExceptionWorkorderAddReq {
workorderNo: string
orderNo?: string
dealerCode?: string
dealerName?: string
exceptionType: number
severityLevel: number
workorderStatus?: number
expectCompleteTime?: string
handlerUser?: string
exceptionDesc?: string
handleSuggest?: string
dataSource?: string
}
export interface ExceptionWorkorderUpdateReq {
workorderId: number
workorderNo?: string
orderNo?: string
dealerCode?: string
dealerName?: string
exceptionType?: number
severityLevel?: number
workorderStatus?: number
expectCompleteTime?: string
handlerUser?: string
exceptionDesc?: string
handleSuggest?: string
dataSource?: string
}
export interface ExceptionWorkorderStatusUpdateReq {
workorderId: number
workorderStatus: number
handlerUser?: string
handleOpinion?: string
attachUrl?: string
}
// 异常工单API接口
export const exceptionWorkorderApi = {
// 分页查询异常工单列表
getExceptionWorkorderList: (params: ExceptionWorkorderQueryReq) => {
return request.get('/api/exception-workorder/list', params)
},
// 获取异常工单详情
getExceptionWorkorderDetail: (workorderId: number) => {
return request.get(`/api/exception-workorder/${workorderId}`)
},
// 新增异常工单
addExceptionWorkorder: (data: ExceptionWorkorderAddReq) => {
return request.post('/api/exception-workorder', data)
},
// 更新异常工单
updateExceptionWorkorder: (data: ExceptionWorkorderUpdateReq) => {
return request.put('/api/exception-workorder', data)
},
// 更新工单状态
updateWorkorderStatus: (data: ExceptionWorkorderStatusUpdateReq) => {
return request.post('/api/exception-workorder/status', data)
},
// 删除异常工单
deleteExceptionWorkorder: (workorderId: number) => {
return request.delete(`/api/exception-workorder/${workorderId}`)
},
// 批量删除异常工单
batchDeleteExceptionWorkorders: (workorderIds: number[]) => {
return request.delete('/api/exception-workorder/batch', workorderIds)
},
// 批量更新工单状态
batchUpdateWorkorderStatus: (workorderIds: number[], workorderStatus: number, handlerUser: string) => {
return request.post('/api/exception-workorder/batch-status', null, {
params: {
workorderIds: workorderIds.join(','),
workorderStatus,
handlerUser
}
})
},
// 获取异常工单统计信息
getExceptionWorkorderStats: () => {
return request.get('/api/exception-workorder/stats')
}
}
// 异常类型枚举
export const EXCEPTION_TYPE = {
1: '逻辑验证异常',
2: '源头验证异常',
3: '交叉验证异常'
}
// 严重程度枚举
export const SEVERITY_LEVEL = {
1: '高',
2: '中',
3: '低'
}
// 工单状态枚举
export const WORKORDER_STATUS = {
1: '待处理',
2: '处理中',
3: '已解决',
4: '已关闭'
}
// 获取异常类型名称
export const getExceptionTypeName = (type: number): string => {
return EXCEPTION_TYPE[type as keyof typeof EXCEPTION_TYPE] || '未知类型'
}
// 获取严重程度名称
export const getSeverityLevelName = (level: number): string => {
return SEVERITY_LEVEL[level as keyof typeof SEVERITY_LEVEL] || '未知'
}
// 获取工单状态名称
export const getWorkorderStatusName = (status: number): string => {
return WORKORDER_STATUS[status as keyof typeof WORKORDER_STATUS] || '未知状态'
}
// 获取严重程度颜色
export const getSeverityLevelColor = (level: number): string => {
const colors = {
1: '#f56c6c', // 高 - 红色
2: '#e6a23c', // 中 - 橙色
3: '#409eff' // 低 - 蓝色
}
return colors[level as keyof typeof colors] || '#909399'
}
// 获取工单状态颜色
export const getWorkorderStatusColor = (status: number): string => {
const colors = {
1: '#909399', // 待处理 - 灰色
2: '#e6a23c', // 处理中 - 橙色
3: '#67c23a', // 已解决 - 绿色
4: '#f56c6c' // 已关闭 - 红色
}
return colors[status as keyof typeof colors] || '#909399'
}
<template>
<div class="exception-workorder-container">
<!-- 搜索区域 -->
<div class="search-section">
<div class="search-form">
<div class="form-row">
<div class="form-item">
<label>工单编号:</label>
<el-input
v-model="searchParams.workorderNo"
placeholder="请输入工单编号"
clearable
class="search-input"
/>
</div>
<div class="form-item">
<label>关联订单号:</label>
<el-input
v-model="searchParams.orderNo"
placeholder="请输入关联订单号"
clearable
class="search-input"
/>
</div>
<div class="form-item">
<label>经销商编码:</label>
<el-input
v-model="searchParams.dealerCode"
placeholder="请输入经销商编码"
clearable
class="search-input"
/>
</div>
<div class="form-item">
<label>经销商名称:</label>
<el-input
v-model="searchParams.dealerName"
placeholder="请输入经销商名称"
clearable
class="search-input"
/>
</div>
</div>
<div class="form-row">
<div class="form-item">
<label>工单状态:</label>
<el-select
v-model="searchParams.workorderStatus"
placeholder="请选择工单状态"
clearable
class="search-select"
>
<el-option
v-for="(name, value) in WORKORDER_STATUS"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</div>
<div class="form-item">
<label>异常类型:</label>
<el-select
v-model="searchParams.exceptionType"
placeholder="请选择异常类型"
clearable
class="search-select"
>
<el-option
v-for="(name, value) in EXCEPTION_TYPE"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</div>
<div class="form-item">
<label>严重程度:</label>
<el-select
v-model="searchParams.severityLevel"
placeholder="请选择严重程度"
clearable
class="search-select"
>
<el-option
v-for="(name, value) in SEVERITY_LEVEL"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</div>
<div class="form-item">
<label>处理人:</label>
<el-input
v-model="searchParams.handlerUser"
placeholder="请输入处理人"
clearable
class="search-input"
/>
</div>
</div>
<div class="form-row">
<div class="form-item">
<label>开始日期:</label>
<el-date-picker
v-model="searchParams.startTime"
type="datetime"
placeholder="选择开始日期"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
class="search-date"
/>
</div>
<div class="form-item">
<label>结束日期:</label>
<el-date-picker
v-model="searchParams.endTime"
type="datetime"
placeholder="选择结束日期"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
class="search-date"
/>
</div>
<div class="form-item">
<el-button type="primary" @click="handleSearch" class="search-btn">
<el-icon><Search /></el-icon>
搜索
</el-button>
<el-button @click="handleReset" class="reset-btn">
<el-icon><Refresh /></el-icon>
重置
</el-button>
</div>
</div>
</div>
</div>
<!-- 操作按钮区域 -->
<div class="action-section">
<div class="action-buttons">
<el-button type="warning" @click="handleAdd" class="add-btn">
<el-icon><Plus /></el-icon>
新增数据
</el-button>
<el-button type="success" @click="handleBatchProcess" class="batch-btn">
<el-icon><Operation /></el-icon>
批量处理
</el-button>
<el-button @click="handleExport" class="export-btn">
<el-icon><Download /></el-icon>
导出
</el-button>
</div>
</div>
<!-- 数据表格 -->
<div class="table-section">
<el-table
:data="workorderList"
v-loading="loading"
@selection-change="handleSelectionChange"
class="data-table"
stripe
border
>
<el-table-column type="selection" width="55" />
<el-table-column prop="workorderId" label="工单ID" width="120" />
<el-table-column prop="workorderNo" label="工单编号" width="180" />
<el-table-column prop="orderNo" label="关联订单号" width="180" />
<el-table-column prop="dealerName" label="经销商名称" width="150" />
<el-table-column prop="workorderStatusName" label="工单状态" width="100">
<template #default="{ row }">
<el-tag :color="getWorkorderStatusColor(row.workorderStatus)">
{{ row.workorderStatusName }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="exceptionTypeName" label="异常类型" width="120" />
<el-table-column prop="severityLevelName" label="严重程度" width="100">
<template #default="{ row }">
<el-tag :color="getSeverityLevelColor(row.severityLevel)">
{{ row.severityLevelName }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="日期" width="180" sortable>
<template #default="{ row }">
{{ formatDateTime(row.createTime) }}
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<el-button
type="primary"
size="small"
@click="handleEditStatus(row)"
class="action-btn"
>
编辑状态
</el-button>
<el-button
type="info"
size="small"
@click="handleViewLogs(row)"
class="action-btn"
>
处理日志
</el-button>
<el-button
type="success"
size="small"
@click="handleViewDetail(row)"
class="action-btn"
>
详情
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div class="pagination-section">
<el-pagination
v-model:current-page="pagination.pageNum"
v-model:page-size="pagination.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="pagination.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
class="pagination"
/>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
v-model="addDialogVisible"
:title="isEdit ? '编辑异常工单' : '新增异常工单'"
width="600px"
class="add-dialog"
>
<el-form
ref="addFormRef"
:model="addFormData"
:rules="addFormRules"
label-width="120px"
class="add-form"
>
<el-form-item label="工单编号" prop="workorderNo">
<el-input v-model="addFormData.workorderNo" placeholder="请输入工单编号" />
</el-form-item>
<el-form-item label="关联订单号" prop="orderNo">
<el-input v-model="addFormData.orderNo" placeholder="请输入关联订单号" />
</el-form-item>
<el-form-item label="经销商编码" prop="dealerCode">
<el-input v-model="addFormData.dealerCode" placeholder="请输入经销商编码" />
</el-form-item>
<el-form-item label="经销商名称" prop="dealerName">
<el-input v-model="addFormData.dealerName" placeholder="请输入经销商名称" />
</el-form-item>
<el-form-item label="异常类型" prop="exceptionType">
<el-select v-model="addFormData.exceptionType" placeholder="请选择异常类型">
<el-option
v-for="(name, value) in EXCEPTION_TYPE"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</el-form-item>
<el-form-item label="严重程度" prop="severityLevel">
<el-select v-model="addFormData.severityLevel" placeholder="请选择严重程度">
<el-option
v-for="(name, value) in SEVERITY_LEVEL"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</el-form-item>
<el-form-item label="工单状态" prop="workorderStatus">
<el-select v-model="addFormData.workorderStatus" placeholder="请选择工单状态">
<el-option
v-for="(name, value) in WORKORDER_STATUS"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</el-form-item>
<el-form-item label="处理人" prop="handlerUser">
<el-input v-model="addFormData.handlerUser" placeholder="请输入处理人" />
</el-form-item>
<el-form-item label="预计完成时间" prop="expectCompleteTime">
<el-date-picker
v-model="addFormData.expectCompleteTime"
type="datetime"
placeholder="选择预计完成时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="异常描述" prop="exceptionDesc">
<el-input
v-model="addFormData.exceptionDesc"
type="textarea"
:rows="3"
placeholder="请输入异常描述"
/>
</el-form-item>
<el-form-item label="处理建议" prop="handleSuggest">
<el-input
v-model="addFormData.handleSuggest"
type="textarea"
:rows="3"
placeholder="请输入处理建议"
/>
</el-form-item>
<el-form-item label="数据来源" prop="dataSource">
<el-input v-model="addFormData.dataSource" placeholder="请输入数据来源" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeAddDialog">取消</el-button>
<el-button type="primary" @click="handleSubmitAdd">确定</el-button>
</div>
</template>
</el-dialog>
<!-- 状态更新对话框 -->
<el-dialog
v-model="statusDialogVisible"
title="编辑状态"
width="500px"
class="status-dialog"
>
<el-form
ref="statusFormRef"
:model="statusFormData"
:rules="statusFormRules"
label-width="100px"
class="status-form"
>
<el-form-item label="工单状态" prop="workorderStatus">
<el-select v-model="statusFormData.workorderStatus" placeholder="请选择工单状态">
<el-option
v-for="(name, value) in WORKORDER_STATUS"
:key="value"
:label="name"
:value="Number(value)"
/>
</el-select>
</el-form-item>
<el-form-item label="处理人" prop="handlerUser">
<el-input v-model="statusFormData.handlerUser" placeholder="请输入处理人" />
</el-form-item>
<el-form-item label="处理意见" prop="handleOpinion">
<el-input
v-model="statusFormData.handleOpinion"
type="textarea"
:rows="3"
placeholder="请输入处理意见"
/>
</el-form-item>
<el-form-item label="附件URL" prop="attachUrl">
<el-input v-model="statusFormData.attachUrl" placeholder="请输入附件URL" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeStatusDialog">取消</el-button>
<el-button type="primary" @click="handleSubmitStatus">确定</el-button>
</div>
</template>
</el-dialog>
<!-- 详情对话框 -->
<el-dialog
v-model="detailDialogVisible"
title="异常工单详情"
width="800px"
class="detail-dialog"
>
<div v-if="workorderDetail" class="detail-content">
<div class="detail-section">
<h4>工单基本信息</h4>
<div class="detail-grid">
<div class="detail-item">
<label>工单编号:</label>
<span>{{ workorderDetail.workorderNo }}</span>
</div>
<div class="detail-item">
<label>关联订单号:</label>
<span>{{ workorderDetail.orderNo }}</span>
</div>
<div class="detail-item">
<label>经销商编码:</label>
<span>{{ workorderDetail.dealerCode }}</span>
</div>
<div class="detail-item">
<label>经销商名称:</label>
<span>{{ workorderDetail.dealerName }}</span>
</div>
<div class="detail-item">
<label>异常类型:</label>
<span>{{ workorderDetail.exceptionTypeName }}</span>
</div>
<div class="detail-item">
<label>严重程度:</label>
<span>{{ workorderDetail.severityLevelName }}</span>
</div>
<div class="detail-item">
<label>工单状态:</label>
<span>{{ workorderDetail.workorderStatusName }}</span>
</div>
<div class="detail-item">
<label>处理人:</label>
<span>{{ workorderDetail.handlerUser || '未分配' }}</span>
</div>
<div class="detail-item">
<label>创建时间:</label>
<span>{{ formatDateTime(workorderDetail.createTime) }}</span>
</div>
<div class="detail-item">
<label>预计完成时间:</label>
<span>{{ workorderDetail.expectCompleteTime ? formatDateTime(workorderDetail.expectCompleteTime) : '未设置' }}</span>
</div>
</div>
</div>
<div class="detail-section" v-if="workorderDetail.exceptionDesc">
<h4>异常描述</h4>
<p class="detail-text">{{ workorderDetail.exceptionDesc }}</p>
</div>
<div class="detail-section" v-if="workorderDetail.handleSuggest">
<h4>处理建议</h4>
<p class="detail-text">{{ workorderDetail.handleSuggest }}</p>
</div>
<div class="detail-section" v-if="workorderDetail.workorderLogs && workorderDetail.workorderLogs.length > 0">
<h4>处理日志</h4>
<el-table :data="workorderDetail.workorderLogs" class="log-table">
<el-table-column prop="handleUser" label="处理人" width="120" />
<el-table-column prop="handleTime" label="处理时间" width="180">
<template #default="{ row }">
{{ formatDateTime(row.handleTime) }}
</template>
</el-table-column>
<el-table-column prop="beforeStatusName" label="处理前状态" width="120" />
<el-table-column prop="afterStatusName" label="处理后状态" width="120" />
<el-table-column prop="handleOpinion" label="处理意见" />
</el-table>
</div>
</div>
</el-dialog>
<!-- 处理日志对话框 -->
<el-dialog
v-model="logsDialogVisible"
title="处理日志"
width="900px"
class="logs-dialog"
>
<el-table :data="workorderLogs" class="logs-table">
<el-table-column prop="handleUser" label="处理人" width="120" />
<el-table-column prop="handleTime" label="处理时间" width="180">
<template #default="{ row }">
{{ formatDateTime(row.handleTime) }}
</template>
</el-table-column>
<el-table-column prop="beforeStatusName" label="处理前状态" width="120" />
<el-table-column prop="afterStatusName" label="处理后状态" width="120" />
<el-table-column prop="handleOpinion" label="处理意见" />
<el-table-column prop="attachUrl" label="附件" width="100">
<template #default="{ row }">
<el-button v-if="row.attachUrl" type="primary" size="small" @click="handleDownload(row.attachUrl)">
下载
</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, Plus, Operation, Download } from '@element-plus/icons-vue'
import {
exceptionWorkorderApi,
type ExceptionWorkorderInfo,
type ExceptionWorkorderQueryReq,
type ExceptionWorkorderAddReq,
type ExceptionWorkorderStatusUpdateReq,
EXCEPTION_TYPE,
SEVERITY_LEVEL,
WORKORDER_STATUS,
getSeverityLevelColor,
getWorkorderStatusColor
} from '../../api/exceptionWorkorder'
import dayjs from 'dayjs'
// 响应式数据
const loading = ref(false)
const workorderList = ref<ExceptionWorkorderInfo[]>([])
const selectedWorkorders = ref<ExceptionWorkorderInfo[]>([])
const workorderDetail = ref<ExceptionWorkorderInfo | null>(null)
const workorderLogs = ref<any[]>([])
// 分页数据
const pagination = reactive({
pageNum: 1,
pageSize: 10,
total: 0
})
// 搜索参数
const searchParams = reactive<ExceptionWorkorderQueryReq>({
workorderNo: '',
orderNo: '',
dealerCode: '',
dealerName: '',
workorderStatus: undefined,
exceptionType: undefined,
severityLevel: undefined,
handlerUser: '',
startTime: '',
endTime: '',
pageNum: 1,
pageSize: 10
})
// 对话框状态
const addDialogVisible = ref(false)
const statusDialogVisible = ref(false)
const detailDialogVisible = ref(false)
const logsDialogVisible = ref(false)
const isEdit = ref(false)
// 新增表单数据
const addFormData = reactive<ExceptionWorkorderAddReq>({
workorderNo: '',
orderNo: '',
dealerCode: '',
dealerName: '',
exceptionType: 1,
severityLevel: 1,
workorderStatus: 1,
expectCompleteTime: '',
handlerUser: '',
exceptionDesc: '',
handleSuggest: '',
dataSource: ''
})
// 状态更新表单数据
const statusFormData = reactive<ExceptionWorkorderStatusUpdateReq>({
workorderId: 0,
workorderStatus: 1,
handlerUser: '',
handleOpinion: '',
attachUrl: ''
})
// 表单验证规则
const addFormRules = {
workorderNo: [
{ required: true, message: '请输入工单编号', trigger: 'blur' }
],
exceptionType: [
{ required: true, message: '请选择异常类型', trigger: 'change' }
],
severityLevel: [
{ required: true, message: '请选择严重程度', trigger: 'change' }
]
}
const statusFormRules = {
workorderStatus: [
{ required: true, message: '请选择工单状态', trigger: 'change' }
]
}
// 获取异常工单列表
const fetchWorkorders = async () => {
try {
loading.value = true
const params = {
...searchParams,
pageNum: pagination.pageNum,
pageSize: pagination.pageSize
}
const response = await exceptionWorkorderApi.getExceptionWorkorderList(params) as any
console.log('异常工单列表API响应:', response)
if (response && response.records) {
workorderList.value = response.records
pagination.total = response.total
} else {
workorderList.value = []
pagination.total = 0
}
} catch (error) {
console.error('获取异常工单列表失败:', error)
ElMessage.error('获取异常工单列表失败')
} finally {
loading.value = false
}
}
// 搜索
const handleSearch = () => {
pagination.pageNum = 1
fetchWorkorders()
}
// 重置
const handleReset = () => {
Object.assign(searchParams, {
workorderNo: '',
orderNo: '',
dealerCode: '',
dealerName: '',
workorderStatus: undefined,
exceptionType: undefined,
severityLevel: undefined,
handlerUser: '',
startTime: '',
endTime: ''
})
pagination.pageNum = 1
fetchWorkorders()
}
// 新增
const handleAdd = () => {
isEdit.value = false
Object.assign(addFormData, {
workorderNo: '',
orderNo: '',
dealerCode: '',
dealerName: '',
exceptionType: 1,
severityLevel: 1,
workorderStatus: 1,
expectCompleteTime: '',
handlerUser: '',
exceptionDesc: '',
handleSuggest: '',
dataSource: ''
})
addDialogVisible.value = true
}
// 编辑状态
const handleEditStatus = (row: ExceptionWorkorderInfo) => {
statusFormData.workorderId = row.workorderId
statusFormData.workorderStatus = row.workorderStatus
statusFormData.handlerUser = row.handlerUser || ''
statusFormData.handleOpinion = ''
statusFormData.attachUrl = ''
statusDialogVisible.value = true
}
// 查看详情
const handleViewDetail = async (row: ExceptionWorkorderInfo) => {
try {
const response = await exceptionWorkorderApi.getExceptionWorkorderDetail(row.workorderId) as any
console.log('异常工单详情API响应:', response)
if (response && response.workorderId) {
workorderDetail.value = response
detailDialogVisible.value = true
} else {
ElMessage.error('获取异常工单详情失败')
}
} catch (error) {
console.error('获取异常工单详情失败:', error)
ElMessage.error('获取异常工单详情失败, 请重试')
}
}
// 查看处理日志
const handleViewLogs = async (row: ExceptionWorkorderInfo) => {
try {
const response = await exceptionWorkorderApi.getExceptionWorkorderDetail(row.workorderId) as any
console.log('处理日志API响应:', response)
if (response && response.workorderLogs) {
workorderLogs.value = response.workorderLogs
logsDialogVisible.value = true
} else {
ElMessage.error('获取处理日志失败')
}
} catch (error) {
console.error('获取处理日志失败:', error)
ElMessage.error('获取处理日志失败, 请重试')
}
}
// 批量处理
const handleBatchProcess = () => {
if (selectedWorkorders.value.length === 0) {
ElMessage.warning('请选择要处理的工单')
return
}
ElMessageBox.confirm(
`确定要批量处理选中的 ${selectedWorkorders.value.length} 个工单吗?`,
'批量处理确认',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(async () => {
try {
const workorderIds = selectedWorkorders.value.map(item => item.workorderId)
await exceptionWorkorderApi.batchUpdateWorkorderStatus(workorderIds, 2, '系统管理员')
ElMessage.success('批量处理成功')
fetchWorkorders()
} catch (error) {
console.error('批量处理失败:', error)
ElMessage.error('批量处理失败')
}
})
}
// 导出
const handleExport = () => {
ElMessage.info('导出功能开发中...')
}
// 提交新增
const handleSubmitAdd = async () => {
try {
await exceptionWorkorderApi.addExceptionWorkorder(addFormData)
ElMessage.success('新增异常工单成功')
closeAddDialog()
fetchWorkorders()
} catch (error) {
console.error('新增异常工单失败:', error)
ElMessage.error('新增异常工单失败')
}
}
// 提交状态更新
const handleSubmitStatus = async () => {
try {
await exceptionWorkorderApi.updateWorkorderStatus(statusFormData)
ElMessage.success('更新工单状态成功')
closeStatusDialog()
fetchWorkorders()
} catch (error) {
console.error('更新工单状态失败:', error)
ElMessage.error('更新工单状态失败')
}
}
// 关闭对话框
const closeAddDialog = () => {
addDialogVisible.value = false
}
const closeStatusDialog = () => {
statusDialogVisible.value = false
}
// 选择变化
const handleSelectionChange = (selection: ExceptionWorkorderInfo[]) => {
selectedWorkorders.value = selection
}
// 分页变化
const handleSizeChange = (size: number) => {
pagination.pageSize = size
pagination.pageNum = 1
fetchWorkorders()
}
const handleCurrentChange = (page: number) => {
pagination.pageNum = page
fetchWorkorders()
}
// 下载附件
const handleDownload = (url: string) => {
window.open(url, '_blank')
}
// 格式化日期时间
const formatDateTime = (dateTime: string) => {
return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss')
}
// 组件挂载
onMounted(() => {
fetchWorkorders()
})
</script>
<style scoped>
.exception-workorder-container {
padding: 20px;
background: #f5f5f5;
min-height: 100vh;
}
.search-section {
background: white;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.search-form {
display: flex;
flex-direction: column;
gap: 15px;
}
.form-row {
display: flex;
gap: 20px;
align-items: center;
flex-wrap: wrap;
}
.form-item {
display: flex;
align-items: center;
gap: 8px;
min-width: 200px;
}
.form-item label {
font-weight: 500;
color: #333;
white-space: nowrap;
min-width: 80px;
}
.search-input,
.search-select,
.search-date {
width: 200px;
}
.search-btn,
.reset-btn {
margin-left: 10px;
}
.action-section {
background: white;
padding: 15px 20px;
border-radius: 8px;
margin-bottom: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.action-buttons {
display: flex;
gap: 10px;
}
.table-section {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.data-table {
width: 100%;
}
.action-btn {
margin-right: 5px;
}
.pagination-section {
display: flex;
justify-content: center;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.add-dialog,
.status-dialog,
.detail-dialog,
.logs-dialog {
.el-dialog__body {
padding: 20px;
}
}
.add-form,
.status-form {
.el-form-item {
margin-bottom: 20px;
}
}
.detail-content {
.detail-section {
margin-bottom: 30px;
}
.detail-section h4 {
color: #333;
margin-bottom: 15px;
padding-bottom: 8px;
border-bottom: 2px solid #409eff;
}
.detail-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 15px;
}
.detail-item {
display: flex;
align-items: center;
gap: 10px;
}
.detail-item label {
font-weight: 500;
color: #666;
min-width: 120px;
}
.detail-item span {
color: #333;
}
.detail-text {
color: #333;
line-height: 1.6;
background: #f8f9fa;
padding: 15px;
border-radius: 4px;
border-left: 4px solid #409eff;
}
.log-table,
.logs-table {
margin-top: 15px;
}
}
.dialog-footer {
text-align: right;
}
.dialog-footer .el-button {
margin-left: 10px;
}
</style>