Toggle navigation
Toggle navigation
This project
Loading...
Sign in
zhouhui.jiang
/
test_cursor
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
jiaxing.zhou
2025-09-29 10:50:54 +0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
0d3d4fe40ad57637feef9043bfbff7fc2e76d317
0d3d4fe4
2 parents
254c040c
242b9c8e
Merge branch 'master' into dev
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
2560 additions
and
0 deletions
backend/src/main/java/com/apple/erp/controller/ExceptionWorkorderController.java
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderAddReq.java
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderLogRes.java
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderQueryReq.java
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderRes.java
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderStatusUpdateReq.java
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderUpdateReq.java
backend/src/main/java/com/apple/erp/entity/ExceptionWorkorder.java
backend/src/main/java/com/apple/erp/entity/ExceptionWorkorderLog.java
backend/src/main/java/com/apple/erp/mapper/ExceptionWorkorderLogMapper.java
backend/src/main/java/com/apple/erp/mapper/ExceptionWorkorderMapper.java
backend/src/main/java/com/apple/erp/service/ExceptionWorkorderService.java
backend/src/main/java/com/apple/erp/service/impl/ExceptionWorkorderServiceImpl.java
backend/src/main/resources/mapper/ExceptionWorkorderLogMapper.xml
backend/src/main/resources/mapper/ExceptionWorkorderMapper.xml
database/scripts/09_init_exception_workorder.sql
frontend/src/api/exceptionWorkorder.ts
frontend/src/views/exceptionWorkorder/index.vue
backend/src/main/java/com/apple/erp/controller/ExceptionWorkorderController.java
0 → 100644
View file @
0d3d4fe
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
);
}
}
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderAddReq.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderLogRes.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderQueryReq.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderRes.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderStatusUpdateReq.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/dto/ExceptionWorkorderUpdateReq.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/entity/ExceptionWorkorder.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/entity/ExceptionWorkorderLog.java
0 → 100644
View file @
0d3d4fe
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
;
}
backend/src/main/java/com/apple/erp/mapper/ExceptionWorkorderLogMapper.java
0 → 100644
View file @
0d3d4fe
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
);
}
backend/src/main/java/com/apple/erp/mapper/ExceptionWorkorderMapper.java
0 → 100644
View file @
0d3d4fe
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
);
}
backend/src/main/java/com/apple/erp/service/ExceptionWorkorderService.java
0 → 100644
View file @
0d3d4fe
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
();
}
backend/src/main/java/com/apple/erp/service/impl/ExceptionWorkorderServiceImpl.java
0 → 100644
View file @
0d3d4fe
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
();
}
}
backend/src/main/resources/mapper/ExceptionWorkorderLogMapper.xml
0 → 100644
View file @
0d3d4fe
<?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>
backend/src/main/resources/mapper/ExceptionWorkorderMapper.xml
0 → 100644
View file @
0d3d4fe
<?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
<
= #{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>
database/scripts/09_init_exception_workorder.sql
0 → 100644
View file @
0d3d4fe
-- 异常工单模块完整初始化脚本
-- 包含表结构创建、权限配置、测试数据插入
-- 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
;
frontend/src/api/exceptionWorkorder.ts
0 → 100644
View file @
0d3d4fe
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'
}
frontend/src/views/exceptionWorkorder/index.vue
0 → 100644
View file @
0d3d4fe
<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>
Please
register
or
login
to post a comment