jiaxing.zhou

Merge remote-tracking branch 'origin/dev'

......@@ -2539,8 +2539,418 @@ Authorization: Bearer <JWT_TOKEN>
**响应:** 返回Excel文件流,文件名格式:`发票数据_yyyyMMdd_HHmmss.xlsx`
### 4. 异常工单数据导出
**接口路径:** `POST /api/exception-workorder/export`
**请求方法:** POST
**权限要求:** `exception:workorder:export`
**请求参数:** 同异常工单查询接口参数
**响应:** 返回Excel文件流,文件名格式:`异常工单数据_yyyyMMdd_HHmmss.xlsx`
## 12. 异常工单管理 (ExceptionWorkorderController)
### 12.1 分页查询异常工单列表
**接口路径:** `GET /api/exception-workorder/list`
**功能描述:** 根据条件分页查询异常工单列表
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
```
**请求参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| workorderNo | String | 否 | 工单编号(模糊查询) |
| orderNo | String | 否 | 关联订单号(模糊查询) |
| dealerCode | String | 否 | 经销商编码 |
| dealerName | String | 否 | 经销商名称(模糊查询) |
| workorderStatus | Integer | 否 | 工单状态(1-待处理/2-处理中/3-已解决/4-已关闭) |
| exceptionType | Integer | 否 | 异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常) |
| severityLevel | Integer | 否 | 严重程度(1-高/2-中/3-低) |
| handlerUser | String | 否 | 处理人(模糊查询) |
| startTime | String | 否 | 创建开始时间(yyyy-MM-dd HH:mm:ss) |
| endTime | String | 否 | 创建结束时间(yyyy-MM-dd HH:mm:ss) |
| pageNum | Integer | 是 | 页码,默认1 |
| pageSize | Integer | 是 | 每页大小,默认10 |
**权限要求:** `exception:workorder:list`
**响应示例:**
```json
{
"code": 200,
"message": "操作成功",
"data": {
"records": [
{
"workorderId": 1,
"workorderNo": "EW202501290001",
"orderNo": "ORD202501290001",
"dealerCode": "D001",
"dealerName": "北京经销商",
"exceptionType": 1,
"exceptionTypeName": "逻辑验证异常",
"severityLevel": 1,
"severityLevelName": "高",
"workorderStatus": 1,
"workorderStatusName": "待处理",
"createTime": "2025-01-29 10:00:00",
"expectCompleteTime": "2025-01-30 18:00:00",
"handlerUser": "张三",
"exceptionDesc": "订单金额与产品单价不匹配",
"handleSuggest": "请核实订单明细",
"dataSource": "系统自动生成",
"createBy": "system",
"updateBy": null,
"updateTime": null,
"workorderLogs": []
}
],
"total": 1,
"size": 10,
"current": 1,
"pages": 1
}
}
```
### 12.2 获取异常工单详情
**接口路径:** `GET /api/exception-workorder/{workorderId}`
**功能描述:** 根据工单ID获取异常工单详细信息,包含处理日志
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
```
**路径参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| workorderId | Long | 是 | 工单ID |
**权限要求:** `exception:workorder:detail`
**响应示例:**
```json
{
"code": 200,
"message": "操作成功",
"data": {
"workorderId": 1,
"workorderNo": "EW202501290001",
"orderNo": "ORD202501290001",
"dealerCode": "D001",
"dealerName": "北京经销商",
"exceptionType": 1,
"exceptionTypeName": "逻辑验证异常",
"severityLevel": 1,
"severityLevelName": "高",
"workorderStatus": 2,
"workorderStatusName": "处理中",
"createTime": "2025-01-29 10:00:00",
"expectCompleteTime": "2025-01-30 18:00:00",
"handlerUser": "张三",
"exceptionDesc": "订单金额与产品单价不匹配",
"handleSuggest": "请核实订单明细",
"dataSource": "系统自动生成",
"createBy": "system",
"updateBy": "张三",
"updateTime": "2025-01-29 11:00:00",
"workorderLogs": [
{
"logId": 1,
"workorderId": 1,
"workorderNo": "EW202501290001",
"handleUser": "张三",
"handleTime": "2025-01-29 11:00:00",
"beforeStatus": 1,
"beforeStatusName": "待处理",
"afterStatus": 2,
"afterStatusName": "处理中",
"handleOpinion": "开始处理此工单",
"attachUrl": null,
"createBy": "张三",
"createTime": "2025-01-29 11:00:00"
}
]
}
}
```
### 12.3 新增异常工单
**接口路径:** `POST /api/exception-workorder`
**功能描述:** 创建新的异常工单
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
```
**请求体:**
```json
{
"workorderNo": "EW202501290002",
"orderNo": "ORD202501290002",
"dealerCode": "D002",
"dealerName": "上海经销商",
"exceptionType": 2,
"severityLevel": 2,
"workorderStatus": 1,
"expectCompleteTime": "2025-01-30 18:00:00",
"handlerUser": "李四",
"exceptionDesc": "经销商信息不完整",
"handleSuggest": "请补充经销商详细信息",
"dataSource": "手动创建"
}
```
**权限要求:** `exception:workorder:add`
**响应示例:**
```json
{
"code": 200,
"message": "新增异常工单成功",
"data": null
}
```
### 12.4 更新异常工单
**接口路径:** `PUT /api/exception-workorder`
**功能描述:** 更新异常工单信息
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
```
**请求体:**
```json
{
"workorderId": 1,
"workorderNo": "EW202501290001",
"orderNo": "ORD202501290001",
"dealerCode": "D001",
"dealerName": "北京经销商",
"exceptionType": 1,
"severityLevel": 1,
"workorderStatus": 2,
"expectCompleteTime": "2025-01-30 18:00:00",
"handlerUser": "张三",
"exceptionDesc": "订单金额与产品单价不匹配",
"handleSuggest": "请核实订单明细并联系客户确认",
"dataSource": "系统自动生成"
}
```
**权限要求:** `exception:workorder:edit`
**响应示例:**
```json
{
"code": 200,
"message": "更新异常工单成功",
"data": null
}
```
### 12.5 更新工单状态
**接口路径:** `POST /api/exception-workorder/status`
**功能描述:** 更新异常工单状态并记录处理日志
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
```
**请求体:**
```json
{
"workorderId": 1,
"workorderStatus": 3,
"handlerUser": "张三",
"handleOpinion": "问题已解决,客户确认无误",
"attachUrl": "http://example.com/attachment.pdf"
}
```
**权限要求:** `exception:workorder:edit`
**响应示例:**
```json
{
"code": 200,
"message": "更新工单状态成功",
"data": null
}
```
### 12.6 删除异常工单
**接口路径:** `DELETE /api/exception-workorder/{workorderId}`
**功能描述:** 根据工单ID逻辑删除异常工单
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
```
**路径参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| workorderId | Long | 是 | 工单ID |
**权限要求:** `exception:workorder:delete`
**响应示例:**
```json
{
"code": 200,
"message": "删除异常工单成功",
"data": null
}
```
### 12.7 批量删除异常工单
**接口路径:** `DELETE /api/exception-workorder/batch`
**功能描述:** 根据工单ID列表批量逻辑删除异常工单
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
```
**请求体:**
```json
[1, 2, 3]
```
**权限要求:** `exception:workorder:delete`
**响应示例:**
```json
{
"code": 200,
"message": "批量删除异常工单成功",
"data": null
}
```
### 12.8 批量更新工单状态
**接口路径:** `POST /api/exception-workorder/batch-status`
**功能描述:** 批量更新异常工单状态
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
```
**请求参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| workorderIds | String | 是 | 工单ID列表,逗号分隔 |
| workorderStatus | Integer | 是 | 工单状态 |
| handlerUser | String | 是 | 处理人 |
**权限要求:** `exception:workorder:edit`
**响应示例:**
```json
{
"code": 200,
"message": "批量更新工单状态成功",
"data": null
}
```
### 12.9 获取异常工单统计信息
**接口路径:** `GET /api/exception-workorder/stats`
**功能描述:** 获取异常工单的统计信息
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
```
**权限要求:** `exception:workorder:list`
**响应示例:**
```json
{
"code": 200,
"message": "操作成功",
"data": [
{
"workorderNo": "total",
"workorderId": 10,
"exceptionType": 3,
"severityLevel": 2,
"workorderStatus": 4,
"handlerUser": 1,
"exceptionDesc": 5,
"handleSuggest": 3,
"dataSource": 2
}
]
}
```
### 12.10 导出异常工单数据
**接口路径:** `POST /api/exception-workorder/export`
**功能描述:** 根据查询条件导出异常工单数据到Excel
**请求头:**
```
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
```
**请求体:** 同异常工单查询接口参数(可选,为空时导出所有数据)
**权限要求:** `exception:workorder:export`
**响应:** 返回Excel文件流,文件名格式:`异常工单数据_yyyyMMdd_HHmmss.xlsx`
**导出字段:**
- 工单ID
- 工单编号
- 工单类型(异常类型名称)
- 严重程度(严重程度名称)
- 工单状态(工单状态名称)
- 问题描述
- 处理人
- 创建人
- 创建时间
- 更新时间
---
**文档版本:** 1.0.0
**最后更新:** 2025-01-27
**最后更新:** 2025-01-29
**维护人员:** Apple ERP Team
......
......@@ -6,12 +6,14 @@ 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.service.ExcelExportService;
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.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
......@@ -34,6 +36,9 @@ public class ExceptionWorkorderController {
@Autowired
private ExceptionWorkorderService exceptionWorkorderService;
@Autowired
private ExcelExportService excelExportService;
@Operation(summary = "分页查询异常工单列表", description = "根据条件分页查询异常工单列表")
@GetMapping("/list")
@PreAuthorize("hasAuthority('exception:workorder:list')")
......@@ -168,4 +173,22 @@ public class ExceptionWorkorderController {
List<ExceptionWorkorderRes> stats = exceptionWorkorderService.getExceptionWorkorderStats();
return ApiRes.success(stats);
}
@Operation(summary = "导出异常工单数据", description = "根据查询条件导出异常工单数据到Excel")
@PostMapping("/export")
@PreAuthorize("hasAuthority('exception:workorder:export')")
public ResponseEntity<byte[]> exportExceptionWorkorders(@RequestBody(required = false) ExceptionWorkorderQueryReq queryReq) {
try {
// 如果请求体为空,创建默认查询条件
if (queryReq == null) {
queryReq = new ExceptionWorkorderQueryReq();
}
// 获取异常工单数据
List<ExceptionWorkorderRes> workorders = exceptionWorkorderService.getExceptionWorkorderListForExport(queryReq);
// 导出Excel
return excelExportService.exportExceptionWorkorders(workorders);
} catch (Exception e) {
throw new RuntimeException("导出异常工单数据失败: " + e.getMessage());
}
}
}
......
......@@ -54,4 +54,12 @@ public interface ExceptionWorkorderMapper extends BaseMapper<ExceptionWorkorder>
int batchUpdateWorkorderStatus(@Param("workorderIds") List<Long> workorderIds,
@Param("workorderStatus") Integer workorderStatus,
@Param("handlerUser") String handlerUser);
/**
* 获取异常工单列表用于导出
*
* @param queryReq 查询条件
* @return 异常工单列表(不分页)
*/
List<ExceptionWorkorderRes> selectExceptionWorkorderListForExport(@Param("query") ExceptionWorkorderQueryReq queryReq);
}
......
......@@ -73,6 +73,14 @@ public interface DeliveryMainService extends IService<DeliveryMain> {
* @return 待出库数量
*/
Integer getPendingDeliveryCount();
/**
* 获取最近的出库记录
*
* @param limit 限制数量
* @return 最近出库列表
*/
List<DeliveryRes> getRecentDeliveries(Integer limit);
}
......
......@@ -91,4 +91,12 @@ public interface ExceptionWorkorderService extends IService<ExceptionWorkorder>
* @return 统计信息
*/
List<ExceptionWorkorderRes> getExceptionWorkorderStats();
/**
* 获取异常工单列表用于导出
*
* @param queryReq 查询条件
* @return 异常工单列表(不分页)
*/
List<ExceptionWorkorderRes> getExceptionWorkorderListForExport(ExceptionWorkorderQueryReq queryReq);
}
......
......@@ -73,6 +73,14 @@ public interface InvoiceMainService extends IService<InvoiceMain> {
* @return 待开票数量
*/
Integer getPendingInvoiceCount();
/**
* 获取最近的发票记录
*
* @param limit 限制数量
* @return 最近发票列表
*/
List<InvoiceRes> getRecentInvoices(Integer limit);
}
......
......@@ -108,5 +108,13 @@ public interface OrderMainService extends IService<OrderMain> {
* @return 销售额
*/
Double getTodaySalesAmount(String date);
/**
* 获取最近的订单记录
*
* @param limit 限制数量
* @return 最近订单列表
*/
List<OrderRes> getRecentOrders(Integer limit);
}
......
......@@ -139,4 +139,12 @@ public interface RebateService extends IService<Rebate> {
* @return 趋势统计数据
*/
List<Map<String, Object>> getRebateTrendStats(String startDate, String endDate);
/**
* 获取最近的返利记录
*
* @param limit 限制数量
* @return 最近返利列表
*/
List<RebateRes> getRecentRebates(Integer limit);
}
......
package com.apple.erp.service.impl;
import com.apple.erp.dto.response.DashboardStatsRes;
import com.apple.erp.dto.OrderRes;
import com.apple.erp.dto.DeliveryRes;
import com.apple.erp.dto.InvoiceRes;
import com.apple.erp.dto.response.RebateRes;
import com.apple.erp.service.DashboardService;
import com.apple.erp.service.OrderMainService;
import com.apple.erp.service.DeliveryMainService;
import com.apple.erp.service.InvoiceMainService;
import com.apple.erp.service.RebateService;
import com.apple.erp.service.SessionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -16,7 +21,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 首页仪表板服务实现
......@@ -35,6 +39,9 @@ public class DashboardServiceImpl implements DashboardService {
private InvoiceMainService invoiceMainService;
@Autowired
private RebateService rebateService;
@Autowired
private SessionService sessionService;
@Override
......@@ -130,14 +137,15 @@ public class DashboardServiceImpl implements DashboardService {
private List<Map<String, Object>> getRecentOrders() {
List<Map<String, Object>> activities = new ArrayList<>();
try {
// 这里应该从数据库查询最近的订单
// 暂时返回模拟数据
List<OrderRes> recentOrders = orderMainService.getRecentOrders(2);
for (OrderRes order : recentOrders) {
Map<String, Object> activity = new HashMap<>();
activity.put("id", 1);
activity.put("id", order.getOrderId());
activity.put("type", "order");
activity.put("title", "新订单 ORD-2025-001 已创建");
activity.put("time", "2分钟前");
activity.put("title", "新订单 " + order.getOrderNo() + " 已创建");
activity.put("time", formatTimeAgo(order.getCreateTime()));
activities.add(activity);
}
} catch (Exception e) {
log.error("获取最近订单活动失败", e);
}
......@@ -150,14 +158,15 @@ public class DashboardServiceImpl implements DashboardService {
private List<Map<String, Object>> getRecentDeliveries() {
List<Map<String, Object>> activities = new ArrayList<>();
try {
// 这里应该从数据库查询最近的出库记录
// 暂时返回模拟数据
List<DeliveryRes> recentDeliveries = deliveryMainService.getRecentDeliveries(2);
for (DeliveryRes delivery : recentDeliveries) {
Map<String, Object> activity = new HashMap<>();
activity.put("id", 2);
activity.put("id", delivery.getDeliveryId());
activity.put("type", "delivery");
activity.put("title", "出库单 DEL-2025-001 已完成");
activity.put("time", "15分钟前");
activity.put("title", "出库单 " + delivery.getDeliveryNo() + " 已创建");
activity.put("time", formatTimeAgo(delivery.getCreateTime()));
activities.add(activity);
}
} catch (Exception e) {
log.error("获取最近出库活动失败", e);
}
......@@ -170,14 +179,15 @@ public class DashboardServiceImpl implements DashboardService {
private List<Map<String, Object>> getRecentInvoices() {
List<Map<String, Object>> activities = new ArrayList<>();
try {
// 这里应该从数据库查询最近的发票记录
// 暂时返回模拟数据
List<InvoiceRes> recentInvoices = invoiceMainService.getRecentInvoices(2);
for (InvoiceRes invoice : recentInvoices) {
Map<String, Object> activity = new HashMap<>();
activity.put("id", 3);
activity.put("id", invoice.getInvoiceId());
activity.put("type", "invoice");
activity.put("title", "发票 INV-2025-001 已开具");
activity.put("time", "1小时前");
activity.put("title", "发票 " + invoice.getInvoiceNo() + " 已开具");
activity.put("time", formatTimeAgo(invoice.getCreateTime()));
activities.add(activity);
}
} catch (Exception e) {
log.error("获取最近发票活动失败", e);
}
......@@ -190,14 +200,15 @@ public class DashboardServiceImpl implements DashboardService {
private List<Map<String, Object>> getRecentRebates() {
List<Map<String, Object>> activities = new ArrayList<>();
try {
// 这里应该从数据库查询最近的返利记录
// 暂时返回模拟数据
List<RebateRes> recentRebates = rebateService.getRecentRebates(2);
for (RebateRes rebate : recentRebates) {
Map<String, Object> activity = new HashMap<>();
activity.put("id", 4);
activity.put("id", rebate.getRebateId());
activity.put("type", "rebate");
activity.put("title", "返利计算已完成,共处理 25 条记录");
activity.put("time", "2小时前");
activity.put("title", "返利 " + rebate.getRebateNo() + " 已计算");
activity.put("time", formatTimeAgo(rebate.getCreateTime()));
activities.add(activity);
}
} catch (Exception e) {
log.error("获取最近返利活动失败", e);
}
......@@ -294,4 +305,28 @@ public class DashboardServiceImpl implements DashboardService {
return "0%";
}
}
/**
* 格式化时间为相对时间
*/
private String formatTimeAgo(java.time.LocalDateTime dateTime) {
if (dateTime == null) {
return "未知时间";
}
java.time.LocalDateTime now = java.time.LocalDateTime.now();
long minutes = java.time.Duration.between(dateTime, now).toMinutes();
if (minutes < 1) {
return "刚刚";
} else if (minutes < 60) {
return minutes + "分钟前";
} else if (minutes < 1440) { // 24小时
long hours = minutes / 60;
return hours + "小时前";
} else {
long days = minutes / 1440;
return days + "天前";
}
}
}
......
......@@ -20,6 +20,7 @@ import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
......@@ -235,6 +236,26 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del
.eq(DeliveryMain::getDeliveryStatus, 0); // 0表示待出库
return Math.toIntExact(count(wrapper));
}
@Override
public List<DeliveryRes> getRecentDeliveries(Integer limit) {
try {
LambdaQueryWrapper<DeliveryMain> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DeliveryMain::getDelFlag, "0")
.orderByDesc(DeliveryMain::getCreateTime)
.last("LIMIT " + (limit != null ? limit : 5));
List<DeliveryMain> deliveries = list(wrapper);
return deliveries.stream().map(delivery -> {
DeliveryRes deliveryRes = new DeliveryRes();
BeanUtils.copyProperties(delivery, deliveryRes);
return deliveryRes;
}).collect(Collectors.toList());
} catch (Exception e) {
log.error("获取最近出库记录失败", e);
return new ArrayList<>();
}
}
}
......
......@@ -18,11 +18,9 @@ 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实现类
......@@ -200,4 +198,10 @@ public class ExceptionWorkorderServiceImpl extends ServiceImpl<ExceptionWorkorde
public List<ExceptionWorkorderRes> getExceptionWorkorderStats() {
return exceptionWorkorderMapper.selectExceptionWorkorderStats();
}
@Override
public List<ExceptionWorkorderRes> getExceptionWorkorderListForExport(ExceptionWorkorderQueryReq queryReq) {
// 不分页查询所有数据用于导出
return exceptionWorkorderMapper.selectExceptionWorkorderListForExport(queryReq);
}
}
......
......@@ -21,6 +21,7 @@ import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
......@@ -237,4 +238,23 @@ public class InvoiceMainServiceImpl extends ServiceImpl<InvoiceMainMapper, Invoi
return Math.toIntExact(count(wrapper));
}
@Override
public List<InvoiceRes> getRecentInvoices(Integer limit) {
try {
LambdaQueryWrapper<InvoiceMain> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(InvoiceMain::getDelFlag, "0")
.orderByDesc(InvoiceMain::getCreateTime)
.last("LIMIT " + (limit != null ? limit : 5));
List<InvoiceMain> invoices = list(wrapper);
return invoices.stream().map(invoice -> {
InvoiceRes invoiceRes = new InvoiceRes();
BeanUtils.copyProperties(invoice, invoiceRes);
return invoiceRes;
}).collect(Collectors.toList());
} catch (Exception e) {
log.error("获取最近发票记录失败", e);
return new ArrayList<>();
}
}
}
......
......@@ -16,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
......@@ -322,5 +323,25 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
return 0.0;
}
}
@Override
public List<OrderRes> getRecentOrders(Integer limit) {
try {
LambdaQueryWrapper<OrderMain> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OrderMain::getDelFlag, "0")
.orderByDesc(OrderMain::getCreateTime)
.last("LIMIT " + (limit != null ? limit : 5));
List<OrderMain> orders = list(wrapper);
return orders.stream().map(order -> {
OrderRes orderRes = new OrderRes();
BeanUtils.copyProperties(order, orderRes);
return orderRes;
}).collect(Collectors.toList());
} catch (Exception e) {
log.error("获取最近订单失败", e);
return new ArrayList<>();
}
}
}
......
......@@ -275,4 +275,24 @@ public class RebateServiceImpl extends ServiceImpl<RebateMapper, Rebate> impleme
log.info("获取返利趋势统计数据,开始日期:{},结束日期:{}", startDate, endDate);
return rebateMapper.getRebateTrendStats(startDate, endDate);
}
@Override
public List<RebateRes> getRecentRebates(Integer limit) {
try {
LambdaQueryWrapper<Rebate> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Rebate::getDelFlag, "0")
.orderByDesc(Rebate::getCreateTime)
.last("LIMIT " + (limit != null ? limit : 5));
List<Rebate> rebates = list(wrapper);
return rebates.stream().map(rebate -> {
RebateRes rebateRes = new RebateRes();
BeanUtils.copyProperties(rebate, rebateRes);
return rebateRes;
}).collect(Collectors.toList());
} catch (Exception e) {
log.error("获取最近返利记录失败", e);
return new ArrayList<>();
}
}
}
......
......@@ -150,4 +150,76 @@
AND del_flag = '0'
</update>
<!-- 获取异常工单列表用于导出 -->
<select id="selectExceptionWorkorderListForExport" 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.exception_desc,
ew.handler_user,
ew.create_by,
ew.create_time,
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>
</mapper>
......
......@@ -146,6 +146,13 @@ export const exceptionWorkorderApi = {
// 获取异常工单统计信息
getExceptionWorkorderStats: () => {
return request.get('/api/exception-workorder/stats')
},
// 导出异常工单数据
exportExceptionWorkorders: (params: ExceptionWorkorderQueryReq) => {
return request.post('/api/exception-workorder/export', params, {
responseType: 'blob'
})
}
}
......
......@@ -734,8 +734,38 @@ const handleBatchProcess = () => {
}
// 导出
const handleExport = () => {
ElMessage.info('导出功能开发中...')
const handleExport = async () => {
try {
await ElMessageBox.confirm('确定要导出异常工单数据吗?', '确认导出', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
ElMessage.info('正在导出数据,请稍候...')
const response = await exceptionWorkorderApi.exportExceptionWorkorders(searchParams.value)
// 创建下载链接
const blob = new Blob([response as unknown as BlobPart], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = `异常工单数据_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.xlsx`
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
ElMessage.success('导出成功')
} catch (error: any) {
if (error !== 'cancel') {
console.error('导出失败:', error)
ElMessage.error('导出失败: ' + (error?.message || '未知错误'))
}
}
}
// 提交新增
......