Showing
17 changed files
with
750 additions
and
39 deletions
| ... | @@ -2539,8 +2539,418 @@ Authorization: Bearer <JWT_TOKEN> | ... | @@ -2539,8 +2539,418 @@ Authorization: Bearer <JWT_TOKEN> |
| 2539 | 2539 | ||
| 2540 | **响应:** 返回Excel文件流,文件名格式:`发票数据_yyyyMMdd_HHmmss.xlsx` | 2540 | **响应:** 返回Excel文件流,文件名格式:`发票数据_yyyyMMdd_HHmmss.xlsx` |
| 2541 | 2541 | ||
| 2542 | +### 4. 异常工单数据导出 | ||
| 2543 | + | ||
| 2544 | +**接口路径:** `POST /api/exception-workorder/export` | ||
| 2545 | +**请求方法:** POST | ||
| 2546 | +**权限要求:** `exception:workorder:export` | ||
| 2547 | + | ||
| 2548 | +**请求参数:** 同异常工单查询接口参数 | ||
| 2549 | + | ||
| 2550 | +**响应:** 返回Excel文件流,文件名格式:`异常工单数据_yyyyMMdd_HHmmss.xlsx` | ||
| 2551 | + | ||
| 2552 | +## 12. 异常工单管理 (ExceptionWorkorderController) | ||
| 2553 | + | ||
| 2554 | +### 12.1 分页查询异常工单列表 | ||
| 2555 | + | ||
| 2556 | +**接口路径:** `GET /api/exception-workorder/list` | ||
| 2557 | + | ||
| 2558 | +**功能描述:** 根据条件分页查询异常工单列表 | ||
| 2559 | + | ||
| 2560 | +**请求头:** | ||
| 2561 | +``` | ||
| 2562 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2563 | +``` | ||
| 2564 | + | ||
| 2565 | +**请求参数:** | ||
| 2566 | +| 参数名 | 类型 | 必填 | 说明 | | ||
| 2567 | +|--------|------|------|------| | ||
| 2568 | +| workorderNo | String | 否 | 工单编号(模糊查询) | | ||
| 2569 | +| orderNo | String | 否 | 关联订单号(模糊查询) | | ||
| 2570 | +| dealerCode | String | 否 | 经销商编码 | | ||
| 2571 | +| dealerName | String | 否 | 经销商名称(模糊查询) | | ||
| 2572 | +| workorderStatus | Integer | 否 | 工单状态(1-待处理/2-处理中/3-已解决/4-已关闭) | | ||
| 2573 | +| exceptionType | Integer | 否 | 异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常) | | ||
| 2574 | +| severityLevel | Integer | 否 | 严重程度(1-高/2-中/3-低) | | ||
| 2575 | +| handlerUser | String | 否 | 处理人(模糊查询) | | ||
| 2576 | +| startTime | String | 否 | 创建开始时间(yyyy-MM-dd HH:mm:ss) | | ||
| 2577 | +| endTime | String | 否 | 创建结束时间(yyyy-MM-dd HH:mm:ss) | | ||
| 2578 | +| pageNum | Integer | 是 | 页码,默认1 | | ||
| 2579 | +| pageSize | Integer | 是 | 每页大小,默认10 | | ||
| 2580 | + | ||
| 2581 | +**权限要求:** `exception:workorder:list` | ||
| 2582 | + | ||
| 2583 | +**响应示例:** | ||
| 2584 | +```json | ||
| 2585 | +{ | ||
| 2586 | + "code": 200, | ||
| 2587 | + "message": "操作成功", | ||
| 2588 | + "data": { | ||
| 2589 | + "records": [ | ||
| 2590 | + { | ||
| 2591 | + "workorderId": 1, | ||
| 2592 | + "workorderNo": "EW202501290001", | ||
| 2593 | + "orderNo": "ORD202501290001", | ||
| 2594 | + "dealerCode": "D001", | ||
| 2595 | + "dealerName": "北京经销商", | ||
| 2596 | + "exceptionType": 1, | ||
| 2597 | + "exceptionTypeName": "逻辑验证异常", | ||
| 2598 | + "severityLevel": 1, | ||
| 2599 | + "severityLevelName": "高", | ||
| 2600 | + "workorderStatus": 1, | ||
| 2601 | + "workorderStatusName": "待处理", | ||
| 2602 | + "createTime": "2025-01-29 10:00:00", | ||
| 2603 | + "expectCompleteTime": "2025-01-30 18:00:00", | ||
| 2604 | + "handlerUser": "张三", | ||
| 2605 | + "exceptionDesc": "订单金额与产品单价不匹配", | ||
| 2606 | + "handleSuggest": "请核实订单明细", | ||
| 2607 | + "dataSource": "系统自动生成", | ||
| 2608 | + "createBy": "system", | ||
| 2609 | + "updateBy": null, | ||
| 2610 | + "updateTime": null, | ||
| 2611 | + "workorderLogs": [] | ||
| 2612 | + } | ||
| 2613 | + ], | ||
| 2614 | + "total": 1, | ||
| 2615 | + "size": 10, | ||
| 2616 | + "current": 1, | ||
| 2617 | + "pages": 1 | ||
| 2618 | + } | ||
| 2619 | +} | ||
| 2620 | +``` | ||
| 2621 | + | ||
| 2622 | +### 12.2 获取异常工单详情 | ||
| 2623 | + | ||
| 2624 | +**接口路径:** `GET /api/exception-workorder/{workorderId}` | ||
| 2625 | + | ||
| 2626 | +**功能描述:** 根据工单ID获取异常工单详细信息,包含处理日志 | ||
| 2627 | + | ||
| 2628 | +**请求头:** | ||
| 2629 | +``` | ||
| 2630 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2631 | +``` | ||
| 2632 | + | ||
| 2633 | +**路径参数:** | ||
| 2634 | +| 参数名 | 类型 | 必填 | 说明 | | ||
| 2635 | +|--------|------|------|------| | ||
| 2636 | +| workorderId | Long | 是 | 工单ID | | ||
| 2637 | + | ||
| 2638 | +**权限要求:** `exception:workorder:detail` | ||
| 2639 | + | ||
| 2640 | +**响应示例:** | ||
| 2641 | +```json | ||
| 2642 | +{ | ||
| 2643 | + "code": 200, | ||
| 2644 | + "message": "操作成功", | ||
| 2645 | + "data": { | ||
| 2646 | + "workorderId": 1, | ||
| 2647 | + "workorderNo": "EW202501290001", | ||
| 2648 | + "orderNo": "ORD202501290001", | ||
| 2649 | + "dealerCode": "D001", | ||
| 2650 | + "dealerName": "北京经销商", | ||
| 2651 | + "exceptionType": 1, | ||
| 2652 | + "exceptionTypeName": "逻辑验证异常", | ||
| 2653 | + "severityLevel": 1, | ||
| 2654 | + "severityLevelName": "高", | ||
| 2655 | + "workorderStatus": 2, | ||
| 2656 | + "workorderStatusName": "处理中", | ||
| 2657 | + "createTime": "2025-01-29 10:00:00", | ||
| 2658 | + "expectCompleteTime": "2025-01-30 18:00:00", | ||
| 2659 | + "handlerUser": "张三", | ||
| 2660 | + "exceptionDesc": "订单金额与产品单价不匹配", | ||
| 2661 | + "handleSuggest": "请核实订单明细", | ||
| 2662 | + "dataSource": "系统自动生成", | ||
| 2663 | + "createBy": "system", | ||
| 2664 | + "updateBy": "张三", | ||
| 2665 | + "updateTime": "2025-01-29 11:00:00", | ||
| 2666 | + "workorderLogs": [ | ||
| 2667 | + { | ||
| 2668 | + "logId": 1, | ||
| 2669 | + "workorderId": 1, | ||
| 2670 | + "workorderNo": "EW202501290001", | ||
| 2671 | + "handleUser": "张三", | ||
| 2672 | + "handleTime": "2025-01-29 11:00:00", | ||
| 2673 | + "beforeStatus": 1, | ||
| 2674 | + "beforeStatusName": "待处理", | ||
| 2675 | + "afterStatus": 2, | ||
| 2676 | + "afterStatusName": "处理中", | ||
| 2677 | + "handleOpinion": "开始处理此工单", | ||
| 2678 | + "attachUrl": null, | ||
| 2679 | + "createBy": "张三", | ||
| 2680 | + "createTime": "2025-01-29 11:00:00" | ||
| 2681 | + } | ||
| 2682 | + ] | ||
| 2683 | + } | ||
| 2684 | +} | ||
| 2685 | +``` | ||
| 2686 | + | ||
| 2687 | +### 12.3 新增异常工单 | ||
| 2688 | + | ||
| 2689 | +**接口路径:** `POST /api/exception-workorder` | ||
| 2690 | + | ||
| 2691 | +**功能描述:** 创建新的异常工单 | ||
| 2692 | + | ||
| 2693 | +**请求头:** | ||
| 2694 | +``` | ||
| 2695 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2696 | +Content-Type: application/json | ||
| 2697 | +``` | ||
| 2698 | + | ||
| 2699 | +**请求体:** | ||
| 2700 | +```json | ||
| 2701 | +{ | ||
| 2702 | + "workorderNo": "EW202501290002", | ||
| 2703 | + "orderNo": "ORD202501290002", | ||
| 2704 | + "dealerCode": "D002", | ||
| 2705 | + "dealerName": "上海经销商", | ||
| 2706 | + "exceptionType": 2, | ||
| 2707 | + "severityLevel": 2, | ||
| 2708 | + "workorderStatus": 1, | ||
| 2709 | + "expectCompleteTime": "2025-01-30 18:00:00", | ||
| 2710 | + "handlerUser": "李四", | ||
| 2711 | + "exceptionDesc": "经销商信息不完整", | ||
| 2712 | + "handleSuggest": "请补充经销商详细信息", | ||
| 2713 | + "dataSource": "手动创建" | ||
| 2714 | +} | ||
| 2715 | +``` | ||
| 2716 | + | ||
| 2717 | +**权限要求:** `exception:workorder:add` | ||
| 2718 | + | ||
| 2719 | +**响应示例:** | ||
| 2720 | +```json | ||
| 2721 | +{ | ||
| 2722 | + "code": 200, | ||
| 2723 | + "message": "新增异常工单成功", | ||
| 2724 | + "data": null | ||
| 2725 | +} | ||
| 2726 | +``` | ||
| 2727 | + | ||
| 2728 | +### 12.4 更新异常工单 | ||
| 2729 | + | ||
| 2730 | +**接口路径:** `PUT /api/exception-workorder` | ||
| 2731 | + | ||
| 2732 | +**功能描述:** 更新异常工单信息 | ||
| 2733 | + | ||
| 2734 | +**请求头:** | ||
| 2735 | +``` | ||
| 2736 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2737 | +Content-Type: application/json | ||
| 2738 | +``` | ||
| 2739 | + | ||
| 2740 | +**请求体:** | ||
| 2741 | +```json | ||
| 2742 | +{ | ||
| 2743 | + "workorderId": 1, | ||
| 2744 | + "workorderNo": "EW202501290001", | ||
| 2745 | + "orderNo": "ORD202501290001", | ||
| 2746 | + "dealerCode": "D001", | ||
| 2747 | + "dealerName": "北京经销商", | ||
| 2748 | + "exceptionType": 1, | ||
| 2749 | + "severityLevel": 1, | ||
| 2750 | + "workorderStatus": 2, | ||
| 2751 | + "expectCompleteTime": "2025-01-30 18:00:00", | ||
| 2752 | + "handlerUser": "张三", | ||
| 2753 | + "exceptionDesc": "订单金额与产品单价不匹配", | ||
| 2754 | + "handleSuggest": "请核实订单明细并联系客户确认", | ||
| 2755 | + "dataSource": "系统自动生成" | ||
| 2756 | +} | ||
| 2757 | +``` | ||
| 2758 | + | ||
| 2759 | +**权限要求:** `exception:workorder:edit` | ||
| 2760 | + | ||
| 2761 | +**响应示例:** | ||
| 2762 | +```json | ||
| 2763 | +{ | ||
| 2764 | + "code": 200, | ||
| 2765 | + "message": "更新异常工单成功", | ||
| 2766 | + "data": null | ||
| 2767 | +} | ||
| 2768 | +``` | ||
| 2769 | + | ||
| 2770 | +### 12.5 更新工单状态 | ||
| 2771 | + | ||
| 2772 | +**接口路径:** `POST /api/exception-workorder/status` | ||
| 2773 | + | ||
| 2774 | +**功能描述:** 更新异常工单状态并记录处理日志 | ||
| 2775 | + | ||
| 2776 | +**请求头:** | ||
| 2777 | +``` | ||
| 2778 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2779 | +Content-Type: application/json | ||
| 2780 | +``` | ||
| 2781 | + | ||
| 2782 | +**请求体:** | ||
| 2783 | +```json | ||
| 2784 | +{ | ||
| 2785 | + "workorderId": 1, | ||
| 2786 | + "workorderStatus": 3, | ||
| 2787 | + "handlerUser": "张三", | ||
| 2788 | + "handleOpinion": "问题已解决,客户确认无误", | ||
| 2789 | + "attachUrl": "http://example.com/attachment.pdf" | ||
| 2790 | +} | ||
| 2791 | +``` | ||
| 2792 | + | ||
| 2793 | +**权限要求:** `exception:workorder:edit` | ||
| 2794 | + | ||
| 2795 | +**响应示例:** | ||
| 2796 | +```json | ||
| 2797 | +{ | ||
| 2798 | + "code": 200, | ||
| 2799 | + "message": "更新工单状态成功", | ||
| 2800 | + "data": null | ||
| 2801 | +} | ||
| 2802 | +``` | ||
| 2803 | + | ||
| 2804 | +### 12.6 删除异常工单 | ||
| 2805 | + | ||
| 2806 | +**接口路径:** `DELETE /api/exception-workorder/{workorderId}` | ||
| 2807 | + | ||
| 2808 | +**功能描述:** 根据工单ID逻辑删除异常工单 | ||
| 2809 | + | ||
| 2810 | +**请求头:** | ||
| 2811 | +``` | ||
| 2812 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2813 | +``` | ||
| 2814 | + | ||
| 2815 | +**路径参数:** | ||
| 2816 | +| 参数名 | 类型 | 必填 | 说明 | | ||
| 2817 | +|--------|------|------|------| | ||
| 2818 | +| workorderId | Long | 是 | 工单ID | | ||
| 2819 | + | ||
| 2820 | +**权限要求:** `exception:workorder:delete` | ||
| 2821 | + | ||
| 2822 | +**响应示例:** | ||
| 2823 | +```json | ||
| 2824 | +{ | ||
| 2825 | + "code": 200, | ||
| 2826 | + "message": "删除异常工单成功", | ||
| 2827 | + "data": null | ||
| 2828 | +} | ||
| 2829 | +``` | ||
| 2830 | + | ||
| 2831 | +### 12.7 批量删除异常工单 | ||
| 2832 | + | ||
| 2833 | +**接口路径:** `DELETE /api/exception-workorder/batch` | ||
| 2834 | + | ||
| 2835 | +**功能描述:** 根据工单ID列表批量逻辑删除异常工单 | ||
| 2836 | + | ||
| 2837 | +**请求头:** | ||
| 2838 | +``` | ||
| 2839 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2840 | +Content-Type: application/json | ||
| 2841 | +``` | ||
| 2842 | + | ||
| 2843 | +**请求体:** | ||
| 2844 | +```json | ||
| 2845 | +[1, 2, 3] | ||
| 2846 | +``` | ||
| 2847 | + | ||
| 2848 | +**权限要求:** `exception:workorder:delete` | ||
| 2849 | + | ||
| 2850 | +**响应示例:** | ||
| 2851 | +```json | ||
| 2852 | +{ | ||
| 2853 | + "code": 200, | ||
| 2854 | + "message": "批量删除异常工单成功", | ||
| 2855 | + "data": null | ||
| 2856 | +} | ||
| 2857 | +``` | ||
| 2858 | + | ||
| 2859 | +### 12.8 批量更新工单状态 | ||
| 2860 | + | ||
| 2861 | +**接口路径:** `POST /api/exception-workorder/batch-status` | ||
| 2862 | + | ||
| 2863 | +**功能描述:** 批量更新异常工单状态 | ||
| 2864 | + | ||
| 2865 | +**请求头:** | ||
| 2866 | +``` | ||
| 2867 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2868 | +``` | ||
| 2869 | + | ||
| 2870 | +**请求参数:** | ||
| 2871 | +| 参数名 | 类型 | 必填 | 说明 | | ||
| 2872 | +|--------|------|------|------| | ||
| 2873 | +| workorderIds | String | 是 | 工单ID列表,逗号分隔 | | ||
| 2874 | +| workorderStatus | Integer | 是 | 工单状态 | | ||
| 2875 | +| handlerUser | String | 是 | 处理人 | | ||
| 2876 | + | ||
| 2877 | +**权限要求:** `exception:workorder:edit` | ||
| 2878 | + | ||
| 2879 | +**响应示例:** | ||
| 2880 | +```json | ||
| 2881 | +{ | ||
| 2882 | + "code": 200, | ||
| 2883 | + "message": "批量更新工单状态成功", | ||
| 2884 | + "data": null | ||
| 2885 | +} | ||
| 2886 | +``` | ||
| 2887 | + | ||
| 2888 | +### 12.9 获取异常工单统计信息 | ||
| 2889 | + | ||
| 2890 | +**接口路径:** `GET /api/exception-workorder/stats` | ||
| 2891 | + | ||
| 2892 | +**功能描述:** 获取异常工单的统计信息 | ||
| 2893 | + | ||
| 2894 | +**请求头:** | ||
| 2895 | +``` | ||
| 2896 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2897 | +``` | ||
| 2898 | + | ||
| 2899 | +**权限要求:** `exception:workorder:list` | ||
| 2900 | + | ||
| 2901 | +**响应示例:** | ||
| 2902 | +```json | ||
| 2903 | +{ | ||
| 2904 | + "code": 200, | ||
| 2905 | + "message": "操作成功", | ||
| 2906 | + "data": [ | ||
| 2907 | + { | ||
| 2908 | + "workorderNo": "total", | ||
| 2909 | + "workorderId": 10, | ||
| 2910 | + "exceptionType": 3, | ||
| 2911 | + "severityLevel": 2, | ||
| 2912 | + "workorderStatus": 4, | ||
| 2913 | + "handlerUser": 1, | ||
| 2914 | + "exceptionDesc": 5, | ||
| 2915 | + "handleSuggest": 3, | ||
| 2916 | + "dataSource": 2 | ||
| 2917 | + } | ||
| 2918 | + ] | ||
| 2919 | +} | ||
| 2920 | +``` | ||
| 2921 | + | ||
| 2922 | +### 12.10 导出异常工单数据 | ||
| 2923 | + | ||
| 2924 | +**接口路径:** `POST /api/exception-workorder/export` | ||
| 2925 | + | ||
| 2926 | +**功能描述:** 根据查询条件导出异常工单数据到Excel | ||
| 2927 | + | ||
| 2928 | +**请求头:** | ||
| 2929 | +``` | ||
| 2930 | +Authorization: Bearer <JWT_TOKEN> | ||
| 2931 | +Content-Type: application/json | ||
| 2932 | +``` | ||
| 2933 | + | ||
| 2934 | +**请求体:** 同异常工单查询接口参数(可选,为空时导出所有数据) | ||
| 2935 | + | ||
| 2936 | +**权限要求:** `exception:workorder:export` | ||
| 2937 | + | ||
| 2938 | +**响应:** 返回Excel文件流,文件名格式:`异常工单数据_yyyyMMdd_HHmmss.xlsx` | ||
| 2939 | + | ||
| 2940 | +**导出字段:** | ||
| 2941 | +- 工单ID | ||
| 2942 | +- 工单编号 | ||
| 2943 | +- 工单类型(异常类型名称) | ||
| 2944 | +- 严重程度(严重程度名称) | ||
| 2945 | +- 工单状态(工单状态名称) | ||
| 2946 | +- 问题描述 | ||
| 2947 | +- 处理人 | ||
| 2948 | +- 创建人 | ||
| 2949 | +- 创建时间 | ||
| 2950 | +- 更新时间 | ||
| 2951 | + | ||
| 2542 | --- | 2952 | --- |
| 2543 | 2953 | ||
| 2544 | **文档版本:** 1.0.0 | 2954 | **文档版本:** 1.0.0 |
| 2545 | -**最后更新:** 2025-01-27 | 2955 | +**最后更新:** 2025-01-29 |
| 2546 | **维护人员:** Apple ERP Team | 2956 | **维护人员:** Apple ERP Team | ... | ... |
| ... | @@ -6,12 +6,14 @@ import com.apple.erp.dto.ExceptionWorkorderRes; | ... | @@ -6,12 +6,14 @@ import com.apple.erp.dto.ExceptionWorkorderRes; |
| 6 | import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq; | 6 | import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq; |
| 7 | import com.apple.erp.dto.ExceptionWorkorderUpdateReq; | 7 | import com.apple.erp.dto.ExceptionWorkorderUpdateReq; |
| 8 | import com.apple.erp.service.ExceptionWorkorderService; | 8 | import com.apple.erp.service.ExceptionWorkorderService; |
| 9 | +import com.apple.erp.service.ExcelExportService; | ||
| 9 | import com.apple.erp.dto.response.ApiRes; | 10 | import com.apple.erp.dto.response.ApiRes; |
| 10 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 11 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 11 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 12 | import io.swagger.v3.oas.annotations.Parameter; | 13 | import io.swagger.v3.oas.annotations.Parameter; |
| 13 | import io.swagger.v3.oas.annotations.tags.Tag; | 14 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 14 | import org.springframework.beans.factory.annotation.Autowired; | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| 16 | +import org.springframework.http.ResponseEntity; | ||
| 15 | import org.springframework.security.access.prepost.PreAuthorize; | 17 | import org.springframework.security.access.prepost.PreAuthorize; |
| 16 | import org.springframework.validation.annotation.Validated; | 18 | import org.springframework.validation.annotation.Validated; |
| 17 | import org.springframework.web.bind.annotation.*; | 19 | import org.springframework.web.bind.annotation.*; |
| ... | @@ -33,6 +35,9 @@ public class ExceptionWorkorderController { | ... | @@ -33,6 +35,9 @@ public class ExceptionWorkorderController { |
| 33 | 35 | ||
| 34 | @Autowired | 36 | @Autowired |
| 35 | private ExceptionWorkorderService exceptionWorkorderService; | 37 | private ExceptionWorkorderService exceptionWorkorderService; |
| 38 | + | ||
| 39 | + @Autowired | ||
| 40 | + private ExcelExportService excelExportService; | ||
| 36 | 41 | ||
| 37 | @Operation(summary = "分页查询异常工单列表", description = "根据条件分页查询异常工单列表") | 42 | @Operation(summary = "分页查询异常工单列表", description = "根据条件分页查询异常工单列表") |
| 38 | @GetMapping("/list") | 43 | @GetMapping("/list") |
| ... | @@ -168,4 +173,22 @@ public class ExceptionWorkorderController { | ... | @@ -168,4 +173,22 @@ public class ExceptionWorkorderController { |
| 168 | List<ExceptionWorkorderRes> stats = exceptionWorkorderService.getExceptionWorkorderStats(); | 173 | List<ExceptionWorkorderRes> stats = exceptionWorkorderService.getExceptionWorkorderStats(); |
| 169 | return ApiRes.success(stats); | 174 | return ApiRes.success(stats); |
| 170 | } | 175 | } |
| 176 | + | ||
| 177 | + @Operation(summary = "导出异常工单数据", description = "根据查询条件导出异常工单数据到Excel") | ||
| 178 | + @PostMapping("/export") | ||
| 179 | + @PreAuthorize("hasAuthority('exception:workorder:export')") | ||
| 180 | + public ResponseEntity<byte[]> exportExceptionWorkorders(@RequestBody(required = false) ExceptionWorkorderQueryReq queryReq) { | ||
| 181 | + try { | ||
| 182 | + // 如果请求体为空,创建默认查询条件 | ||
| 183 | + if (queryReq == null) { | ||
| 184 | + queryReq = new ExceptionWorkorderQueryReq(); | ||
| 185 | + } | ||
| 186 | + // 获取异常工单数据 | ||
| 187 | + List<ExceptionWorkorderRes> workorders = exceptionWorkorderService.getExceptionWorkorderListForExport(queryReq); | ||
| 188 | + // 导出Excel | ||
| 189 | + return excelExportService.exportExceptionWorkorders(workorders); | ||
| 190 | + } catch (Exception e) { | ||
| 191 | + throw new RuntimeException("导出异常工单数据失败: " + e.getMessage()); | ||
| 192 | + } | ||
| 193 | + } | ||
| 171 | } | 194 | } | ... | ... |
| ... | @@ -54,4 +54,12 @@ public interface ExceptionWorkorderMapper extends BaseMapper<ExceptionWorkorder> | ... | @@ -54,4 +54,12 @@ public interface ExceptionWorkorderMapper extends BaseMapper<ExceptionWorkorder> |
| 54 | int batchUpdateWorkorderStatus(@Param("workorderIds") List<Long> workorderIds, | 54 | int batchUpdateWorkorderStatus(@Param("workorderIds") List<Long> workorderIds, |
| 55 | @Param("workorderStatus") Integer workorderStatus, | 55 | @Param("workorderStatus") Integer workorderStatus, |
| 56 | @Param("handlerUser") String handlerUser); | 56 | @Param("handlerUser") String handlerUser); |
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * 获取异常工单列表用于导出 | ||
| 60 | + * | ||
| 61 | + * @param queryReq 查询条件 | ||
| 62 | + * @return 异常工单列表(不分页) | ||
| 63 | + */ | ||
| 64 | + List<ExceptionWorkorderRes> selectExceptionWorkorderListForExport(@Param("query") ExceptionWorkorderQueryReq queryReq); | ||
| 57 | } | 65 | } | ... | ... |
| ... | @@ -73,6 +73,14 @@ public interface DeliveryMainService extends IService<DeliveryMain> { | ... | @@ -73,6 +73,14 @@ public interface DeliveryMainService extends IService<DeliveryMain> { |
| 73 | * @return 待出库数量 | 73 | * @return 待出库数量 |
| 74 | */ | 74 | */ |
| 75 | Integer getPendingDeliveryCount(); | 75 | Integer getPendingDeliveryCount(); |
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * 获取最近的出库记录 | ||
| 79 | + * | ||
| 80 | + * @param limit 限制数量 | ||
| 81 | + * @return 最近出库列表 | ||
| 82 | + */ | ||
| 83 | + List<DeliveryRes> getRecentDeliveries(Integer limit); | ||
| 76 | } | 84 | } |
| 77 | 85 | ||
| 78 | 86 | ... | ... |
| ... | @@ -91,4 +91,12 @@ public interface ExceptionWorkorderService extends IService<ExceptionWorkorder> | ... | @@ -91,4 +91,12 @@ public interface ExceptionWorkorderService extends IService<ExceptionWorkorder> |
| 91 | * @return 统计信息 | 91 | * @return 统计信息 |
| 92 | */ | 92 | */ |
| 93 | List<ExceptionWorkorderRes> getExceptionWorkorderStats(); | 93 | List<ExceptionWorkorderRes> getExceptionWorkorderStats(); |
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * 获取异常工单列表用于导出 | ||
| 97 | + * | ||
| 98 | + * @param queryReq 查询条件 | ||
| 99 | + * @return 异常工单列表(不分页) | ||
| 100 | + */ | ||
| 101 | + List<ExceptionWorkorderRes> getExceptionWorkorderListForExport(ExceptionWorkorderQueryReq queryReq); | ||
| 94 | } | 102 | } | ... | ... |
| ... | @@ -73,6 +73,14 @@ public interface InvoiceMainService extends IService<InvoiceMain> { | ... | @@ -73,6 +73,14 @@ public interface InvoiceMainService extends IService<InvoiceMain> { |
| 73 | * @return 待开票数量 | 73 | * @return 待开票数量 |
| 74 | */ | 74 | */ |
| 75 | Integer getPendingInvoiceCount(); | 75 | Integer getPendingInvoiceCount(); |
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * 获取最近的发票记录 | ||
| 79 | + * | ||
| 80 | + * @param limit 限制数量 | ||
| 81 | + * @return 最近发票列表 | ||
| 82 | + */ | ||
| 83 | + List<InvoiceRes> getRecentInvoices(Integer limit); | ||
| 76 | } | 84 | } |
| 77 | 85 | ||
| 78 | 86 | ... | ... |
| ... | @@ -108,5 +108,13 @@ public interface OrderMainService extends IService<OrderMain> { | ... | @@ -108,5 +108,13 @@ public interface OrderMainService extends IService<OrderMain> { |
| 108 | * @return 销售额 | 108 | * @return 销售额 |
| 109 | */ | 109 | */ |
| 110 | Double getTodaySalesAmount(String date); | 110 | Double getTodaySalesAmount(String date); |
| 111 | + | ||
| 112 | + /** | ||
| 113 | + * 获取最近的订单记录 | ||
| 114 | + * | ||
| 115 | + * @param limit 限制数量 | ||
| 116 | + * @return 最近订单列表 | ||
| 117 | + */ | ||
| 118 | + List<OrderRes> getRecentOrders(Integer limit); | ||
| 111 | } | 119 | } |
| 112 | 120 | ... | ... |
| ... | @@ -139,4 +139,12 @@ public interface RebateService extends IService<Rebate> { | ... | @@ -139,4 +139,12 @@ public interface RebateService extends IService<Rebate> { |
| 139 | * @return 趋势统计数据 | 139 | * @return 趋势统计数据 |
| 140 | */ | 140 | */ |
| 141 | List<Map<String, Object>> getRebateTrendStats(String startDate, String endDate); | 141 | List<Map<String, Object>> getRebateTrendStats(String startDate, String endDate); |
| 142 | + | ||
| 143 | + /** | ||
| 144 | + * 获取最近的返利记录 | ||
| 145 | + * | ||
| 146 | + * @param limit 限制数量 | ||
| 147 | + * @return 最近返利列表 | ||
| 148 | + */ | ||
| 149 | + List<RebateRes> getRecentRebates(Integer limit); | ||
| 142 | } | 150 | } | ... | ... |
| 1 | package com.apple.erp.service.impl; | 1 | package com.apple.erp.service.impl; |
| 2 | 2 | ||
| 3 | import com.apple.erp.dto.response.DashboardStatsRes; | 3 | import com.apple.erp.dto.response.DashboardStatsRes; |
| 4 | +import com.apple.erp.dto.OrderRes; | ||
| 5 | +import com.apple.erp.dto.DeliveryRes; | ||
| 6 | +import com.apple.erp.dto.InvoiceRes; | ||
| 7 | +import com.apple.erp.dto.response.RebateRes; | ||
| 4 | import com.apple.erp.service.DashboardService; | 8 | import com.apple.erp.service.DashboardService; |
| 5 | import com.apple.erp.service.OrderMainService; | 9 | import com.apple.erp.service.OrderMainService; |
| 6 | import com.apple.erp.service.DeliveryMainService; | 10 | import com.apple.erp.service.DeliveryMainService; |
| 7 | import com.apple.erp.service.InvoiceMainService; | 11 | import com.apple.erp.service.InvoiceMainService; |
| 12 | +import com.apple.erp.service.RebateService; | ||
| 8 | import com.apple.erp.service.SessionService; | 13 | import com.apple.erp.service.SessionService; |
| 9 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| 10 | import org.springframework.beans.factory.annotation.Autowired; | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | @@ -16,7 +21,6 @@ import java.util.ArrayList; | ... | @@ -16,7 +21,6 @@ import java.util.ArrayList; |
| 16 | import java.util.HashMap; | 21 | import java.util.HashMap; |
| 17 | import java.util.List; | 22 | import java.util.List; |
| 18 | import java.util.Map; | 23 | import java.util.Map; |
| 19 | -import java.util.Set; | ||
| 20 | 24 | ||
| 21 | /** | 25 | /** |
| 22 | * 首页仪表板服务实现 | 26 | * 首页仪表板服务实现 |
| ... | @@ -35,6 +39,9 @@ public class DashboardServiceImpl implements DashboardService { | ... | @@ -35,6 +39,9 @@ public class DashboardServiceImpl implements DashboardService { |
| 35 | private InvoiceMainService invoiceMainService; | 39 | private InvoiceMainService invoiceMainService; |
| 36 | 40 | ||
| 37 | @Autowired | 41 | @Autowired |
| 42 | + private RebateService rebateService; | ||
| 43 | + | ||
| 44 | + @Autowired | ||
| 38 | private SessionService sessionService; | 45 | private SessionService sessionService; |
| 39 | 46 | ||
| 40 | @Override | 47 | @Override |
| ... | @@ -130,14 +137,15 @@ public class DashboardServiceImpl implements DashboardService { | ... | @@ -130,14 +137,15 @@ public class DashboardServiceImpl implements DashboardService { |
| 130 | private List<Map<String, Object>> getRecentOrders() { | 137 | private List<Map<String, Object>> getRecentOrders() { |
| 131 | List<Map<String, Object>> activities = new ArrayList<>(); | 138 | List<Map<String, Object>> activities = new ArrayList<>(); |
| 132 | try { | 139 | try { |
| 133 | - // 这里应该从数据库查询最近的订单 | 140 | + List<OrderRes> recentOrders = orderMainService.getRecentOrders(2); |
| 134 | - // 暂时返回模拟数据 | 141 | + for (OrderRes order : recentOrders) { |
| 135 | - Map<String, Object> activity = new HashMap<>(); | 142 | + Map<String, Object> activity = new HashMap<>(); |
| 136 | - activity.put("id", 1); | 143 | + activity.put("id", order.getOrderId()); |
| 137 | - activity.put("type", "order"); | 144 | + activity.put("type", "order"); |
| 138 | - activity.put("title", "新订单 ORD-2025-001 已创建"); | 145 | + activity.put("title", "新订单 " + order.getOrderNo() + " 已创建"); |
| 139 | - activity.put("time", "2分钟前"); | 146 | + activity.put("time", formatTimeAgo(order.getCreateTime())); |
| 140 | - activities.add(activity); | 147 | + activities.add(activity); |
| 148 | + } | ||
| 141 | } catch (Exception e) { | 149 | } catch (Exception e) { |
| 142 | log.error("获取最近订单活动失败", e); | 150 | log.error("获取最近订单活动失败", e); |
| 143 | } | 151 | } |
| ... | @@ -150,14 +158,15 @@ public class DashboardServiceImpl implements DashboardService { | ... | @@ -150,14 +158,15 @@ public class DashboardServiceImpl implements DashboardService { |
| 150 | private List<Map<String, Object>> getRecentDeliveries() { | 158 | private List<Map<String, Object>> getRecentDeliveries() { |
| 151 | List<Map<String, Object>> activities = new ArrayList<>(); | 159 | List<Map<String, Object>> activities = new ArrayList<>(); |
| 152 | try { | 160 | try { |
| 153 | - // 这里应该从数据库查询最近的出库记录 | 161 | + List<DeliveryRes> recentDeliveries = deliveryMainService.getRecentDeliveries(2); |
| 154 | - // 暂时返回模拟数据 | 162 | + for (DeliveryRes delivery : recentDeliveries) { |
| 155 | - Map<String, Object> activity = new HashMap<>(); | 163 | + Map<String, Object> activity = new HashMap<>(); |
| 156 | - activity.put("id", 2); | 164 | + activity.put("id", delivery.getDeliveryId()); |
| 157 | - activity.put("type", "delivery"); | 165 | + activity.put("type", "delivery"); |
| 158 | - activity.put("title", "出库单 DEL-2025-001 已完成"); | 166 | + activity.put("title", "出库单 " + delivery.getDeliveryNo() + " 已创建"); |
| 159 | - activity.put("time", "15分钟前"); | 167 | + activity.put("time", formatTimeAgo(delivery.getCreateTime())); |
| 160 | - activities.add(activity); | 168 | + activities.add(activity); |
| 169 | + } | ||
| 161 | } catch (Exception e) { | 170 | } catch (Exception e) { |
| 162 | log.error("获取最近出库活动失败", e); | 171 | log.error("获取最近出库活动失败", e); |
| 163 | } | 172 | } |
| ... | @@ -170,14 +179,15 @@ public class DashboardServiceImpl implements DashboardService { | ... | @@ -170,14 +179,15 @@ public class DashboardServiceImpl implements DashboardService { |
| 170 | private List<Map<String, Object>> getRecentInvoices() { | 179 | private List<Map<String, Object>> getRecentInvoices() { |
| 171 | List<Map<String, Object>> activities = new ArrayList<>(); | 180 | List<Map<String, Object>> activities = new ArrayList<>(); |
| 172 | try { | 181 | try { |
| 173 | - // 这里应该从数据库查询最近的发票记录 | 182 | + List<InvoiceRes> recentInvoices = invoiceMainService.getRecentInvoices(2); |
| 174 | - // 暂时返回模拟数据 | 183 | + for (InvoiceRes invoice : recentInvoices) { |
| 175 | - Map<String, Object> activity = new HashMap<>(); | 184 | + Map<String, Object> activity = new HashMap<>(); |
| 176 | - activity.put("id", 3); | 185 | + activity.put("id", invoice.getInvoiceId()); |
| 177 | - activity.put("type", "invoice"); | 186 | + activity.put("type", "invoice"); |
| 178 | - activity.put("title", "发票 INV-2025-001 已开具"); | 187 | + activity.put("title", "发票 " + invoice.getInvoiceNo() + " 已开具"); |
| 179 | - activity.put("time", "1小时前"); | 188 | + activity.put("time", formatTimeAgo(invoice.getCreateTime())); |
| 180 | - activities.add(activity); | 189 | + activities.add(activity); |
| 190 | + } | ||
| 181 | } catch (Exception e) { | 191 | } catch (Exception e) { |
| 182 | log.error("获取最近发票活动失败", e); | 192 | log.error("获取最近发票活动失败", e); |
| 183 | } | 193 | } |
| ... | @@ -190,14 +200,15 @@ public class DashboardServiceImpl implements DashboardService { | ... | @@ -190,14 +200,15 @@ public class DashboardServiceImpl implements DashboardService { |
| 190 | private List<Map<String, Object>> getRecentRebates() { | 200 | private List<Map<String, Object>> getRecentRebates() { |
| 191 | List<Map<String, Object>> activities = new ArrayList<>(); | 201 | List<Map<String, Object>> activities = new ArrayList<>(); |
| 192 | try { | 202 | try { |
| 193 | - // 这里应该从数据库查询最近的返利记录 | 203 | + List<RebateRes> recentRebates = rebateService.getRecentRebates(2); |
| 194 | - // 暂时返回模拟数据 | 204 | + for (RebateRes rebate : recentRebates) { |
| 195 | - Map<String, Object> activity = new HashMap<>(); | 205 | + Map<String, Object> activity = new HashMap<>(); |
| 196 | - activity.put("id", 4); | 206 | + activity.put("id", rebate.getRebateId()); |
| 197 | - activity.put("type", "rebate"); | 207 | + activity.put("type", "rebate"); |
| 198 | - activity.put("title", "返利计算已完成,共处理 25 条记录"); | 208 | + activity.put("title", "返利 " + rebate.getRebateNo() + " 已计算"); |
| 199 | - activity.put("time", "2小时前"); | 209 | + activity.put("time", formatTimeAgo(rebate.getCreateTime())); |
| 200 | - activities.add(activity); | 210 | + activities.add(activity); |
| 211 | + } | ||
| 201 | } catch (Exception e) { | 212 | } catch (Exception e) { |
| 202 | log.error("获取最近返利活动失败", e); | 213 | log.error("获取最近返利活动失败", e); |
| 203 | } | 214 | } |
| ... | @@ -294,4 +305,28 @@ public class DashboardServiceImpl implements DashboardService { | ... | @@ -294,4 +305,28 @@ public class DashboardServiceImpl implements DashboardService { |
| 294 | return "0%"; | 305 | return "0%"; |
| 295 | } | 306 | } |
| 296 | } | 307 | } |
| 308 | + | ||
| 309 | + /** | ||
| 310 | + * 格式化时间为相对时间 | ||
| 311 | + */ | ||
| 312 | + private String formatTimeAgo(java.time.LocalDateTime dateTime) { | ||
| 313 | + if (dateTime == null) { | ||
| 314 | + return "未知时间"; | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + java.time.LocalDateTime now = java.time.LocalDateTime.now(); | ||
| 318 | + long minutes = java.time.Duration.between(dateTime, now).toMinutes(); | ||
| 319 | + | ||
| 320 | + if (minutes < 1) { | ||
| 321 | + return "刚刚"; | ||
| 322 | + } else if (minutes < 60) { | ||
| 323 | + return minutes + "分钟前"; | ||
| 324 | + } else if (minutes < 1440) { // 24小时 | ||
| 325 | + long hours = minutes / 60; | ||
| 326 | + return hours + "小时前"; | ||
| 327 | + } else { | ||
| 328 | + long days = minutes / 1440; | ||
| 329 | + return days + "天前"; | ||
| 330 | + } | ||
| 331 | + } | ||
| 297 | } | 332 | } | ... | ... |
| ... | @@ -20,6 +20,7 @@ import org.springframework.util.StringUtils; | ... | @@ -20,6 +20,7 @@ import org.springframework.util.StringUtils; |
| 20 | 20 | ||
| 21 | import java.time.LocalDateTime; | 21 | import java.time.LocalDateTime; |
| 22 | import java.time.format.DateTimeFormatter; | 22 | import java.time.format.DateTimeFormatter; |
| 23 | +import java.util.ArrayList; | ||
| 23 | import java.util.List; | 24 | import java.util.List; |
| 24 | import java.util.stream.Collectors; | 25 | import java.util.stream.Collectors; |
| 25 | 26 | ||
| ... | @@ -235,6 +236,26 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del | ... | @@ -235,6 +236,26 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del |
| 235 | .eq(DeliveryMain::getDeliveryStatus, 0); // 0表示待出库 | 236 | .eq(DeliveryMain::getDeliveryStatus, 0); // 0表示待出库 |
| 236 | return Math.toIntExact(count(wrapper)); | 237 | return Math.toIntExact(count(wrapper)); |
| 237 | } | 238 | } |
| 239 | + | ||
| 240 | + @Override | ||
| 241 | + public List<DeliveryRes> getRecentDeliveries(Integer limit) { | ||
| 242 | + try { | ||
| 243 | + LambdaQueryWrapper<DeliveryMain> wrapper = new LambdaQueryWrapper<>(); | ||
| 244 | + wrapper.eq(DeliveryMain::getDelFlag, "0") | ||
| 245 | + .orderByDesc(DeliveryMain::getCreateTime) | ||
| 246 | + .last("LIMIT " + (limit != null ? limit : 5)); | ||
| 247 | + | ||
| 248 | + List<DeliveryMain> deliveries = list(wrapper); | ||
| 249 | + return deliveries.stream().map(delivery -> { | ||
| 250 | + DeliveryRes deliveryRes = new DeliveryRes(); | ||
| 251 | + BeanUtils.copyProperties(delivery, deliveryRes); | ||
| 252 | + return deliveryRes; | ||
| 253 | + }).collect(Collectors.toList()); | ||
| 254 | + } catch (Exception e) { | ||
| 255 | + log.error("获取最近出库记录失败", e); | ||
| 256 | + return new ArrayList<>(); | ||
| 257 | + } | ||
| 258 | + } | ||
| 238 | } | 259 | } |
| 239 | 260 | ||
| 240 | 261 | ... | ... |
| ... | @@ -18,11 +18,9 @@ import org.springframework.beans.BeanUtils; | ... | @@ -18,11 +18,9 @@ import org.springframework.beans.BeanUtils; |
| 18 | import org.springframework.beans.factory.annotation.Autowired; | 18 | import org.springframework.beans.factory.annotation.Autowired; |
| 19 | import org.springframework.stereotype.Service; | 19 | import org.springframework.stereotype.Service; |
| 20 | import org.springframework.transaction.annotation.Transactional; | 20 | import org.springframework.transaction.annotation.Transactional; |
| 21 | -import org.springframework.util.StringUtils; | ||
| 22 | 21 | ||
| 23 | import java.time.LocalDateTime; | 22 | import java.time.LocalDateTime; |
| 24 | import java.util.List; | 23 | import java.util.List; |
| 25 | -import java.util.stream.Collectors; | ||
| 26 | 24 | ||
| 27 | /** | 25 | /** |
| 28 | * 异常工单Service实现类 | 26 | * 异常工单Service实现类 |
| ... | @@ -200,4 +198,10 @@ public class ExceptionWorkorderServiceImpl extends ServiceImpl<ExceptionWorkorde | ... | @@ -200,4 +198,10 @@ public class ExceptionWorkorderServiceImpl extends ServiceImpl<ExceptionWorkorde |
| 200 | public List<ExceptionWorkorderRes> getExceptionWorkorderStats() { | 198 | public List<ExceptionWorkorderRes> getExceptionWorkorderStats() { |
| 201 | return exceptionWorkorderMapper.selectExceptionWorkorderStats(); | 199 | return exceptionWorkorderMapper.selectExceptionWorkorderStats(); |
| 202 | } | 200 | } |
| 201 | + | ||
| 202 | + @Override | ||
| 203 | + public List<ExceptionWorkorderRes> getExceptionWorkorderListForExport(ExceptionWorkorderQueryReq queryReq) { | ||
| 204 | + // 不分页查询所有数据用于导出 | ||
| 205 | + return exceptionWorkorderMapper.selectExceptionWorkorderListForExport(queryReq); | ||
| 206 | + } | ||
| 203 | } | 207 | } | ... | ... |
| ... | @@ -21,6 +21,7 @@ import org.springframework.util.StringUtils; | ... | @@ -21,6 +21,7 @@ import org.springframework.util.StringUtils; |
| 21 | import java.time.LocalDate; | 21 | import java.time.LocalDate; |
| 22 | import java.time.LocalDateTime; | 22 | import java.time.LocalDateTime; |
| 23 | import java.time.format.DateTimeFormatter; | 23 | import java.time.format.DateTimeFormatter; |
| 24 | +import java.util.ArrayList; | ||
| 24 | import java.util.List; | 25 | import java.util.List; |
| 25 | import java.util.stream.Collectors; | 26 | import java.util.stream.Collectors; |
| 26 | 27 | ||
| ... | @@ -236,5 +237,24 @@ public class InvoiceMainServiceImpl extends ServiceImpl<InvoiceMainMapper, Invoi | ... | @@ -236,5 +237,24 @@ public class InvoiceMainServiceImpl extends ServiceImpl<InvoiceMainMapper, Invoi |
| 236 | .eq(InvoiceMain::getInvoiceStatus, 0); // 0表示待开票 | 237 | .eq(InvoiceMain::getInvoiceStatus, 0); // 0表示待开票 |
| 237 | return Math.toIntExact(count(wrapper)); | 238 | return Math.toIntExact(count(wrapper)); |
| 238 | } | 239 | } |
| 239 | - | 240 | + |
| 241 | + @Override | ||
| 242 | + public List<InvoiceRes> getRecentInvoices(Integer limit) { | ||
| 243 | + try { | ||
| 244 | + LambdaQueryWrapper<InvoiceMain> wrapper = new LambdaQueryWrapper<>(); | ||
| 245 | + wrapper.eq(InvoiceMain::getDelFlag, "0") | ||
| 246 | + .orderByDesc(InvoiceMain::getCreateTime) | ||
| 247 | + .last("LIMIT " + (limit != null ? limit : 5)); | ||
| 248 | + | ||
| 249 | + List<InvoiceMain> invoices = list(wrapper); | ||
| 250 | + return invoices.stream().map(invoice -> { | ||
| 251 | + InvoiceRes invoiceRes = new InvoiceRes(); | ||
| 252 | + BeanUtils.copyProperties(invoice, invoiceRes); | ||
| 253 | + return invoiceRes; | ||
| 254 | + }).collect(Collectors.toList()); | ||
| 255 | + } catch (Exception e) { | ||
| 256 | + log.error("获取最近发票记录失败", e); | ||
| 257 | + return new ArrayList<>(); | ||
| 258 | + } | ||
| 259 | + } | ||
| 240 | } | 260 | } | ... | ... |
| ... | @@ -16,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional; | ... | @@ -16,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional; |
| 16 | import org.springframework.util.StringUtils; | 16 | import org.springframework.util.StringUtils; |
| 17 | 17 | ||
| 18 | import java.time.LocalDateTime; | 18 | import java.time.LocalDateTime; |
| 19 | +import java.util.ArrayList; | ||
| 19 | import java.util.List; | 20 | import java.util.List; |
| 20 | import java.util.stream.Collectors; | 21 | import java.util.stream.Collectors; |
| 21 | 22 | ||
| ... | @@ -322,5 +323,25 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain | ... | @@ -322,5 +323,25 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain |
| 322 | return 0.0; | 323 | return 0.0; |
| 323 | } | 324 | } |
| 324 | } | 325 | } |
| 326 | + | ||
| 327 | + @Override | ||
| 328 | + public List<OrderRes> getRecentOrders(Integer limit) { | ||
| 329 | + try { | ||
| 330 | + LambdaQueryWrapper<OrderMain> wrapper = new LambdaQueryWrapper<>(); | ||
| 331 | + wrapper.eq(OrderMain::getDelFlag, "0") | ||
| 332 | + .orderByDesc(OrderMain::getCreateTime) | ||
| 333 | + .last("LIMIT " + (limit != null ? limit : 5)); | ||
| 334 | + | ||
| 335 | + List<OrderMain> orders = list(wrapper); | ||
| 336 | + return orders.stream().map(order -> { | ||
| 337 | + OrderRes orderRes = new OrderRes(); | ||
| 338 | + BeanUtils.copyProperties(order, orderRes); | ||
| 339 | + return orderRes; | ||
| 340 | + }).collect(Collectors.toList()); | ||
| 341 | + } catch (Exception e) { | ||
| 342 | + log.error("获取最近订单失败", e); | ||
| 343 | + return new ArrayList<>(); | ||
| 344 | + } | ||
| 345 | + } | ||
| 325 | } | 346 | } |
| 326 | 347 | ... | ... |
| ... | @@ -275,4 +275,24 @@ public class RebateServiceImpl extends ServiceImpl<RebateMapper, Rebate> impleme | ... | @@ -275,4 +275,24 @@ public class RebateServiceImpl extends ServiceImpl<RebateMapper, Rebate> impleme |
| 275 | log.info("获取返利趋势统计数据,开始日期:{},结束日期:{}", startDate, endDate); | 275 | log.info("获取返利趋势统计数据,开始日期:{},结束日期:{}", startDate, endDate); |
| 276 | return rebateMapper.getRebateTrendStats(startDate, endDate); | 276 | return rebateMapper.getRebateTrendStats(startDate, endDate); |
| 277 | } | 277 | } |
| 278 | + | ||
| 279 | + @Override | ||
| 280 | + public List<RebateRes> getRecentRebates(Integer limit) { | ||
| 281 | + try { | ||
| 282 | + LambdaQueryWrapper<Rebate> wrapper = new LambdaQueryWrapper<>(); | ||
| 283 | + wrapper.eq(Rebate::getDelFlag, "0") | ||
| 284 | + .orderByDesc(Rebate::getCreateTime) | ||
| 285 | + .last("LIMIT " + (limit != null ? limit : 5)); | ||
| 286 | + | ||
| 287 | + List<Rebate> rebates = list(wrapper); | ||
| 288 | + return rebates.stream().map(rebate -> { | ||
| 289 | + RebateRes rebateRes = new RebateRes(); | ||
| 290 | + BeanUtils.copyProperties(rebate, rebateRes); | ||
| 291 | + return rebateRes; | ||
| 292 | + }).collect(Collectors.toList()); | ||
| 293 | + } catch (Exception e) { | ||
| 294 | + log.error("获取最近返利记录失败", e); | ||
| 295 | + return new ArrayList<>(); | ||
| 296 | + } | ||
| 297 | + } | ||
| 278 | } | 298 | } | ... | ... |
| ... | @@ -150,4 +150,76 @@ | ... | @@ -150,4 +150,76 @@ |
| 150 | AND del_flag = '0' | 150 | AND del_flag = '0' |
| 151 | </update> | 151 | </update> |
| 152 | 152 | ||
| 153 | + <!-- 获取异常工单列表用于导出 --> | ||
| 154 | + <select id="selectExceptionWorkorderListForExport" resultType="com.apple.erp.dto.ExceptionWorkorderRes"> | ||
| 155 | + SELECT | ||
| 156 | + ew.workorder_id, | ||
| 157 | + ew.workorder_no, | ||
| 158 | + ew.order_no, | ||
| 159 | + ew.dealer_code, | ||
| 160 | + ew.dealer_name, | ||
| 161 | + ew.exception_type, | ||
| 162 | + CASE ew.exception_type | ||
| 163 | + WHEN 1 THEN '逻辑验证异常' | ||
| 164 | + WHEN 2 THEN '源头验证异常' | ||
| 165 | + WHEN 3 THEN '交叉验证异常' | ||
| 166 | + ELSE '未知类型' | ||
| 167 | + END AS exception_type_name, | ||
| 168 | + ew.severity_level, | ||
| 169 | + CASE ew.severity_level | ||
| 170 | + WHEN 1 THEN '高' | ||
| 171 | + WHEN 2 THEN '中' | ||
| 172 | + WHEN 3 THEN '低' | ||
| 173 | + ELSE '未知' | ||
| 174 | + END AS severity_level_name, | ||
| 175 | + ew.workorder_status, | ||
| 176 | + CASE ew.workorder_status | ||
| 177 | + WHEN 1 THEN '待处理' | ||
| 178 | + WHEN 2 THEN '处理中' | ||
| 179 | + WHEN 3 THEN '已解决' | ||
| 180 | + WHEN 4 THEN '已关闭' | ||
| 181 | + ELSE '未知状态' | ||
| 182 | + END AS workorder_status_name, | ||
| 183 | + ew.exception_desc, | ||
| 184 | + ew.handler_user, | ||
| 185 | + ew.create_by, | ||
| 186 | + ew.create_time, | ||
| 187 | + ew.update_time | ||
| 188 | + FROM t_exception_workorder ew | ||
| 189 | + <where> | ||
| 190 | + ew.del_flag = '0' | ||
| 191 | + <if test="query.workorderNo != null and query.workorderNo != ''"> | ||
| 192 | + AND ew.workorder_no LIKE CONCAT('%', #{query.workorderNo}, '%') | ||
| 193 | + </if> | ||
| 194 | + <if test="query.orderNo != null and query.orderNo != ''"> | ||
| 195 | + AND ew.order_no LIKE CONCAT('%', #{query.orderNo}, '%') | ||
| 196 | + </if> | ||
| 197 | + <if test="query.dealerCode != null and query.dealerCode != ''"> | ||
| 198 | + AND ew.dealer_code = #{query.dealerCode} | ||
| 199 | + </if> | ||
| 200 | + <if test="query.dealerName != null and query.dealerName != ''"> | ||
| 201 | + AND ew.dealer_name LIKE CONCAT('%', #{query.dealerName}, '%') | ||
| 202 | + </if> | ||
| 203 | + <if test="query.workorderStatus != null"> | ||
| 204 | + AND ew.workorder_status = #{query.workorderStatus} | ||
| 205 | + </if> | ||
| 206 | + <if test="query.exceptionType != null"> | ||
| 207 | + AND ew.exception_type = #{query.exceptionType} | ||
| 208 | + </if> | ||
| 209 | + <if test="query.severityLevel != null"> | ||
| 210 | + AND ew.severity_level = #{query.severityLevel} | ||
| 211 | + </if> | ||
| 212 | + <if test="query.handlerUser != null and query.handlerUser != ''"> | ||
| 213 | + AND ew.handler_user LIKE CONCAT('%', #{query.handlerUser}, '%') | ||
| 214 | + </if> | ||
| 215 | + <if test="query.startTime != null"> | ||
| 216 | + AND ew.create_time >= #{query.startTime} | ||
| 217 | + </if> | ||
| 218 | + <if test="query.endTime != null"> | ||
| 219 | + AND ew.create_time <= #{query.endTime} | ||
| 220 | + </if> | ||
| 221 | + </where> | ||
| 222 | + ORDER BY ew.create_time DESC | ||
| 223 | + </select> | ||
| 224 | + | ||
| 153 | </mapper> | 225 | </mapper> | ... | ... |
| ... | @@ -146,6 +146,13 @@ export const exceptionWorkorderApi = { | ... | @@ -146,6 +146,13 @@ export const exceptionWorkorderApi = { |
| 146 | // 获取异常工单统计信息 | 146 | // 获取异常工单统计信息 |
| 147 | getExceptionWorkorderStats: () => { | 147 | getExceptionWorkorderStats: () => { |
| 148 | return request.get('/api/exception-workorder/stats') | 148 | return request.get('/api/exception-workorder/stats') |
| 149 | + }, | ||
| 150 | + | ||
| 151 | + // 导出异常工单数据 | ||
| 152 | + exportExceptionWorkorders: (params: ExceptionWorkorderQueryReq) => { | ||
| 153 | + return request.post('/api/exception-workorder/export', params, { | ||
| 154 | + responseType: 'blob' | ||
| 155 | + }) | ||
| 149 | } | 156 | } |
| 150 | } | 157 | } |
| 151 | 158 | ... | ... |
| ... | @@ -734,8 +734,38 @@ const handleBatchProcess = () => { | ... | @@ -734,8 +734,38 @@ const handleBatchProcess = () => { |
| 734 | } | 734 | } |
| 735 | 735 | ||
| 736 | // 导出 | 736 | // 导出 |
| 737 | -const handleExport = () => { | 737 | +const handleExport = async () => { |
| 738 | - ElMessage.info('导出功能开发中...') | 738 | + try { |
| 739 | + await ElMessageBox.confirm('确定要导出异常工单数据吗?', '确认导出', { | ||
| 740 | + confirmButtonText: '确定', | ||
| 741 | + cancelButtonText: '取消', | ||
| 742 | + type: 'warning' | ||
| 743 | + }) | ||
| 744 | + | ||
| 745 | + ElMessage.info('正在导出数据,请稍候...') | ||
| 746 | + | ||
| 747 | + const response = await exceptionWorkorderApi.exportExceptionWorkorders(searchParams.value) | ||
| 748 | + | ||
| 749 | + // 创建下载链接 | ||
| 750 | + const blob = new Blob([response as unknown as BlobPart], { | ||
| 751 | + type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' | ||
| 752 | + }) | ||
| 753 | + const url = window.URL.createObjectURL(blob) | ||
| 754 | + const link = document.createElement('a') | ||
| 755 | + link.href = url | ||
| 756 | + link.download = `异常工单数据_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.xlsx` | ||
| 757 | + document.body.appendChild(link) | ||
| 758 | + link.click() | ||
| 759 | + document.body.removeChild(link) | ||
| 760 | + window.URL.revokeObjectURL(url) | ||
| 761 | + | ||
| 762 | + ElMessage.success('导出成功') | ||
| 763 | + } catch (error: any) { | ||
| 764 | + if (error !== 'cancel') { | ||
| 765 | + console.error('导出失败:', error) | ||
| 766 | + ElMessage.error('导出失败: ' + (error?.message || '未知错误')) | ||
| 767 | + } | ||
| 768 | + } | ||
| 739 | } | 769 | } |
| 740 | 770 | ||
| 741 | // 提交新增 | 771 | // 提交新增 | ... | ... |
-
Please register or login to post a comment