zhouhui.jiang

Merge branch 'master' of http://gitlab.erry.com/zhouhui.jiang/test_cursor

# Conflicts:
#	frontend/src/views/delivery/index.vue
1 +package com.apple.erp.dto.request;
2 +
3 +import lombok.Data;
4 +
5 +import javax.validation.constraints.*;
6 +import java.math.BigDecimal;
7 +
8 +/**
9 + * 返利新增请求DTO
10 + *
11 + * @author Apple ERP
12 + */
13 +@Data
14 +public class RebateAddReq {
15 +
16 + /**
17 + * 返利明细编号
18 + */
19 + @Size(max = 30, message = "返利明细编号不能超过30个字符")
20 + private String rebateNo;
21 +
22 + /**
23 + * 关联订单编号
24 + */
25 + @NotBlank(message = "关联订单编号不能为空")
26 + @Size(max = 30, message = "订单编号不能超过30个字符")
27 + private String orderNo;
28 +
29 + /**
30 + * 经销商编码
31 + */
32 + @NotBlank(message = "经销商编码不能为空")
33 + @Size(max = 20, message = "经销商编码不能超过20个字符")
34 + private String dealerCode;
35 +
36 + /**
37 + * 经销商名称
38 + */
39 + @NotBlank(message = "经销商名称不能为空")
40 + @Size(max = 100, message = "经销商名称不能超过100个字符")
41 + private String dealerName;
42 +
43 + /**
44 + * 产品编码
45 + */
46 + @NotBlank(message = "产品编码不能为空")
47 + @Size(max = 30, message = "产品编码不能超过30个字符")
48 + private String productCode;
49 +
50 + /**
51 + * 返利金额
52 + */
53 + @NotNull(message = "返利金额不能为空")
54 + @DecimalMin(value = "0", message = "返利金额不能小于0")
55 + private BigDecimal rebateAmount;
56 +
57 + /**
58 + * 返利记录日期
59 + */
60 + @NotBlank(message = "返利记录日期不能为空")
61 + private String rebateDate;
62 +
63 + /**
64 + * 操作类型:1-新增,2-扣减
65 + */
66 + @NotNull(message = "操作类型不能为空")
67 + @Min(value = 1, message = "操作类型值无效")
68 + @Max(value = 2, message = "操作类型值无效")
69 + private Integer operateType;
70 +
71 + /**
72 + * 返利计算状态:0-未计算,1-已计算
73 + */
74 + private Integer calcFlag;
75 +}
1 +package com.apple.erp.dto.request;
2 +
3 +import lombok.Data;
4 +
5 +/**
6 + * 返利台账明细查询请求DTO
7 + *
8 + * @author Apple ERP Team
9 + * @version 1.0.0
10 + * @since 2024-01-01
11 + */
12 +@Data
13 +public class RebateQueryReq {
14 +
15 + /**
16 + * 返利明细编号
17 + */
18 + private String rebateNo;
19 +
20 + /**
21 + * 关联订单编号
22 + */
23 + private String orderNo;
24 +
25 + /**
26 + * 经销商编码
27 + */
28 + private String dealerCode;
29 +
30 + /**
31 + * 经销商名称
32 + */
33 + private String dealerName;
34 +
35 + /**
36 + * 产品编码
37 + */
38 + private String productCode;
39 +
40 + /**
41 + * 操作类型:1-新增,2-扣减
42 + */
43 + private Integer operateType;
44 +
45 + /**
46 + * 返利计算状态:0-未计算,1-已计算
47 + */
48 + private Integer calcFlag;
49 +
50 + /**
51 + * 返利记录开始日期
52 + */
53 + private String rebateStartDate;
54 +
55 + /**
56 + * 返利记录结束日期
57 + */
58 + private String rebateEndDate;
59 +
60 + /**
61 + * 页码
62 + */
63 + private Integer pageNum = 1;
64 +
65 + /**
66 + * 页面大小
67 + */
68 + private Integer pageSize = 10;
69 +}
1 +package com.apple.erp.dto.request;
2 +
3 +import lombok.Data;
4 +
5 +import javax.validation.constraints.*;
6 +import java.math.BigDecimal;
7 +
8 +/**
9 + * 返利更新请求DTO
10 + *
11 + * @author Apple ERP
12 + */
13 +@Data
14 +public class RebateUpdateReq {
15 +
16 + /**
17 + * 返利明细ID
18 + */
19 + @NotNull(message = "返利明细ID不能为空")
20 + private Long rebateId;
21 +
22 + /**
23 + * 返利明细编号
24 + */
25 + @Size(max = 30, message = "返利明细编号不能超过30个字符")
26 + private String rebateNo;
27 +
28 + /**
29 + * 关联订单编号
30 + */
31 + @NotBlank(message = "关联订单编号不能为空")
32 + @Size(max = 30, message = "订单编号不能超过30个字符")
33 + private String orderNo;
34 +
35 + /**
36 + * 经销商编码
37 + */
38 + @NotBlank(message = "经销商编码不能为空")
39 + @Size(max = 20, message = "经销商编码不能超过20个字符")
40 + private String dealerCode;
41 +
42 + /**
43 + * 经销商名称
44 + */
45 + @NotBlank(message = "经销商名称不能为空")
46 + @Size(max = 100, message = "经销商名称不能超过100个字符")
47 + private String dealerName;
48 +
49 + /**
50 + * 产品编码
51 + */
52 + @NotBlank(message = "产品编码不能为空")
53 + @Size(max = 30, message = "产品编码不能超过30个字符")
54 + private String productCode;
55 +
56 + /**
57 + * 返利金额
58 + */
59 + @NotNull(message = "返利金额不能为空")
60 + @DecimalMin(value = "0", message = "返利金额不能小于0")
61 + private BigDecimal rebateAmount;
62 +
63 + /**
64 + * 返利记录日期
65 + */
66 + @NotBlank(message = "返利记录日期不能为空")
67 + private String rebateDate;
68 +
69 + /**
70 + * 操作类型:1-新增,2-扣减
71 + */
72 + @NotNull(message = "操作类型不能为空")
73 + @Min(value = 1, message = "操作类型值无效")
74 + @Max(value = 2, message = "操作类型值无效")
75 + private Integer operateType;
76 +
77 + /**
78 + * 返利计算状态:0-未计算,1-已计算
79 + */
80 + private Integer calcFlag;
81 +}
1 +package com.apple.erp.dto.response;
2 +
3 +import lombok.Data;
4 +
5 +import java.math.BigDecimal;
6 +import java.time.LocalDate;
7 +import java.time.LocalDateTime;
8 +
9 +/**
10 + * 返利响应DTO
11 + *
12 + * @author Apple ERP
13 + */
14 +@Data
15 +public class RebateRes {
16 +
17 + /**
18 + * 返利明细ID
19 + */
20 + private Long rebateId;
21 +
22 + /**
23 + * 返利明细编号
24 + */
25 + private String rebateNo;
26 +
27 + /**
28 + * 关联订单编号
29 + */
30 + private String orderNo;
31 +
32 + /**
33 + * 经销商编码
34 + */
35 + private String dealerCode;
36 +
37 + /**
38 + * 经销商名称
39 + */
40 + private String dealerName;
41 +
42 + /**
43 + * 产品编码
44 + */
45 + private String productCode;
46 +
47 + /**
48 + * 返利金额
49 + */
50 + private BigDecimal rebateAmount;
51 +
52 + /**
53 + * 返利记录日期
54 + */
55 + private LocalDate rebateDate;
56 +
57 + /**
58 + * 操作类型:1-新增,2-扣减
59 + */
60 + private Integer operateType;
61 +
62 + /**
63 + * 操作类型文本
64 + */
65 + private String operateTypeText;
66 +
67 + /**
68 + * 返利计算状态:0-未计算,1-已计算
69 + */
70 + private Integer calcFlag;
71 +
72 + /**
73 + * 计算状态文本
74 + */
75 + private String calcFlagText;
76 +
77 + /**
78 + * 数据上传时间
79 + */
80 + private LocalDateTime uploadTime;
81 +
82 + /**
83 + * 创建时间
84 + */
85 + private LocalDateTime createTime;
86 +
87 + /**
88 + * 更新时间
89 + */
90 + private LocalDateTime updateTime;
91 +
92 + /**
93 + * 创建者
94 + */
95 + private String createBy;
96 +
97 + /**
98 + * 更新者
99 + */
100 + private String updateBy;
101 +}
1 +package com.apple.erp.entity;
2 +
3 +import com.baomidou.mybatisplus.annotation.*;
4 +import lombok.Data;
5 +import lombok.EqualsAndHashCode;
6 +
7 +import java.math.BigDecimal;
8 +import java.time.LocalDate;
9 +import java.time.LocalDateTime;
10 +
11 +/**
12 + * 返利实体类
13 + *
14 + * @author Apple ERP
15 + */
16 +@Data
17 +@EqualsAndHashCode(callSuper = false)
18 +@TableName("t_rebate_detail")
19 +public class Rebate {
20 +
21 + /**
22 + * 返利明细ID
23 + */
24 + @TableId(value = "rebate_id", type = IdType.AUTO)
25 + private Long rebateId;
26 +
27 + /**
28 + * 返利明细编号
29 + */
30 + @TableField("rebate_no")
31 + private String rebateNo;
32 +
33 + /**
34 + * 关联订单编号
35 + */
36 + @TableField("order_no")
37 + private String orderNo;
38 +
39 + /**
40 + * 经销商编码
41 + */
42 + @TableField("dealer_code")
43 + private String dealerCode;
44 +
45 + /**
46 + * 经销商名称
47 + */
48 + @TableField("dealer_name")
49 + private String dealerName;
50 +
51 + /**
52 + * 产品编码
53 + */
54 + @TableField("product_code")
55 + private String productCode;
56 +
57 + /**
58 + * 返利金额
59 + */
60 + @TableField("rebate_amount")
61 + private BigDecimal rebateAmount;
62 +
63 + /**
64 + * 返利记录日期
65 + */
66 + @TableField("rebate_date")
67 + private LocalDate rebateDate;
68 +
69 + /**
70 + * 操作类型:1-新增,2-扣减
71 + */
72 + @TableField("operate_type")
73 + private Integer operateType;
74 +
75 + /**
76 + * 返利计算状态:0-未计算,1-已计算
77 + */
78 + @TableField("calc_flag")
79 + private Integer calcFlag;
80 +
81 + /**
82 + * 数据上传时间
83 + */
84 + @TableField("upload_time")
85 + private LocalDateTime uploadTime;
86 +
87 + /**
88 + * 创建时间
89 + */
90 + @TableField(value = "create_time", fill = FieldFill.INSERT)
91 + private LocalDateTime createTime;
92 +
93 + /**
94 + * 更新时间
95 + */
96 + @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
97 + private LocalDateTime updateTime;
98 +
99 + /**
100 + * 创建者
101 + */
102 + @TableField(value = "create_by", fill = FieldFill.INSERT)
103 + private String createBy;
104 +
105 + /**
106 + * 更新者
107 + */
108 + @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
109 + private String updateBy;
110 +
111 + /**
112 + * 删除标志:0-存在,2-删除
113 + */
114 + @TableField("del_flag")
115 + @TableLogic(value = "0", delval = "2")
116 + private String delFlag;
117 +}
1 +package com.apple.erp.mapper;
2 +
3 +import com.apple.erp.entity.Rebate;
4 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 +import com.baomidou.mybatisplus.core.metadata.IPage;
6 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
7 +import org.apache.ibatis.annotations.Mapper;
8 +import org.apache.ibatis.annotations.Param;
9 +
10 +import java.math.BigDecimal;
11 +import java.util.List;
12 +import java.util.Map;
13 +
14 +/**
15 + * 返利台账明细Mapper接口
16 + *
17 + * @author Apple ERP Team
18 + * @version 1.0.0
19 + * @since 2024-01-01
20 + */
21 +@Mapper
22 +public interface RebateMapper extends BaseMapper<Rebate> {
23 +
24 + /**
25 + * 分页查询返利明细列表
26 + *
27 + * @param page 分页参数
28 + * @param params 查询参数
29 + * @return 返利明细分页列表
30 + */
31 + IPage<Rebate> selectRebatePage(Page<Rebate> page, @Param("params") Map<String, Object> params);
32 +
33 + /**
34 + * 根据经销商编码统计返利总金额
35 + *
36 + * @param dealerCode 经销商编码
37 + * @param operateType 操作类型
38 + * @return 返利总金额
39 + */
40 + BigDecimal sumRebateAmountByDealer(@Param("dealerCode") String dealerCode, @Param("operateType") Integer operateType);
41 +
42 + /**
43 + * 根据产品编码统计返利总金额
44 + *
45 + * @param productCode 产品编码
46 + * @param operateType 操作类型
47 + * @return 返利总金额
48 + */
49 + BigDecimal sumRebateAmountByProduct(@Param("productCode") String productCode, @Param("operateType") Integer operateType);
50 +
51 + /**
52 + * 统计各操作类型的返利数量
53 + *
54 + * @return 操作类型统计
55 + */
56 + List<Map<String, Object>> countRebateByOperateType();
57 +
58 + /**
59 + * 查询未计算的返利明细列表
60 + *
61 + * @return 未计算返利明细列表
62 + */
63 + List<Rebate> selectUnCalcRebates();
64 +
65 + /**
66 + * 根据返利编号查询返利明细
67 + *
68 + * @param rebateNo 返利编号
69 + * @return 返利明细信息
70 + */
71 + Rebate selectByRebateNo(@Param("rebateNo") String rebateNo);
72 +
73 + /**
74 + * 获取返利月度统计数据
75 + *
76 + * @param year 年份
77 + * @return 月度统计数据
78 + */
79 + List<Map<String, Object>> getRebateMonthlyStats(@Param("year") Integer year);
80 +
81 + /**
82 + * 获取返利状态统计数据
83 + *
84 + * @return 状态统计数据
85 + */
86 + Map<String, Object> getRebateStatusStats();
87 +
88 + /**
89 + * 获取返利趋势统计数据
90 + *
91 + * @param startDate 开始日期
92 + * @param endDate 结束日期
93 + * @return 趋势统计数据
94 + */
95 + List<Map<String, Object>> getRebateTrendStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
96 +}
1 +package com.apple.erp.service;
2 +
3 +import com.apple.erp.dto.request.RebateAddReq;
4 +import com.apple.erp.dto.request.RebateQueryReq;
5 +import com.apple.erp.dto.request.RebateUpdateReq;
6 +import com.apple.erp.dto.response.RebateRes;
7 +import com.apple.erp.entity.Rebate;
8 +import com.baomidou.mybatisplus.core.metadata.IPage;
9 +import com.baomidou.mybatisplus.extension.service.IService;
10 +
11 +import java.math.BigDecimal;
12 +import java.util.List;
13 +import java.util.Map;
14 +
15 +/**
16 + * 返利台账明细服务接口
17 + *
18 + * @author Apple ERP Team
19 + * @version 1.0.0
20 + * @since 2024-01-01
21 + */
22 +public interface RebateService extends IService<Rebate> {
23 +
24 + /**
25 + * 分页查询返利明细列表
26 + *
27 + * @param queryReq 查询请求
28 + * @return 返利明细分页列表
29 + */
30 + IPage<RebateRes> getRebatePage(RebateQueryReq queryReq);
31 +
32 + /**
33 + * 根据ID查询返利明细详情
34 + *
35 + * @param rebateId 返利明细ID
36 + * @return 返利明细详情
37 + */
38 + RebateRes getRebateById(Long rebateId);
39 +
40 + /**
41 + * 新增返利明细
42 + *
43 + * @param addReq 新增请求
44 + * @return 是否成功
45 + */
46 + boolean addRebate(RebateAddReq addReq);
47 +
48 + /**
49 + * 更新返利明细
50 + *
51 + * @param updateReq 更新请求
52 + * @return 是否成功
53 + */
54 + boolean updateRebate(RebateUpdateReq updateReq);
55 +
56 + /**
57 + * 删除返利明细
58 + *
59 + * @param rebateId 返利明细ID
60 + * @return 是否成功
61 + */
62 + boolean deleteRebate(Long rebateId);
63 +
64 + /**
65 + * 批量删除返利明细
66 + *
67 + * @param rebateIds 返利明细ID列表
68 + * @return 是否成功
69 + */
70 + boolean batchDeleteRebate(List<Long> rebateIds);
71 +
72 + /**
73 + * 根据经销商编码统计返利总金额
74 + *
75 + * @param dealerCode 经销商编码
76 + * @param operateType 操作类型(可选)
77 + * @return 返利总金额
78 + */
79 + BigDecimal sumRebateAmountByDealer(String dealerCode, Integer operateType);
80 +
81 + /**
82 + * 根据产品编码统计返利总金额
83 + *
84 + * @param productCode 产品编码
85 + * @param operateType 操作类型(可选)
86 + * @return 返利总金额
87 + */
88 + BigDecimal sumRebateAmountByProduct(String productCode, Integer operateType);
89 +
90 + /**
91 + * 统计各操作类型的返利数量
92 + *
93 + * @return 操作类型统计
94 + */
95 + List<Map<String, Object>> countRebateByOperateType();
96 +
97 + /**
98 + * 查询未计算的返利明细列表
99 + *
100 + * @return 未计算返利明细列表
101 + */
102 + List<RebateRes> getUnCalcRebates();
103 +
104 + /**
105 + * 根据返利编号查询返利明细
106 + *
107 + * @param rebateNo 返利编号
108 + * @return 返利明细信息
109 + */
110 + RebateRes getRebateByNo(String rebateNo);
111 +
112 + /**
113 + * 生成返利编号
114 + *
115 + * @return 返利编号
116 + */
117 + String generateRebateNo();
118 +
119 + /**
120 + * 获取返利月度统计数据
121 + *
122 + * @param year 年份
123 + * @return 月度统计数据
124 + */
125 + List<Map<String, Object>> getRebateMonthlyStats(Integer year);
126 +
127 + /**
128 + * 获取返利状态统计数据
129 + *
130 + * @return 状态统计数据
131 + */
132 + Map<String, Object> getRebateStatusStats();
133 +
134 + /**
135 + * 获取返利趋势统计数据
136 + *
137 + * @param startDate 开始日期
138 + * @param endDate 结束日期
139 + * @return 趋势统计数据
140 + */
141 + List<Map<String, Object>> getRebateTrendStats(String startDate, String endDate);
142 +}
1 +package com.apple.erp.service.impl;
2 +
3 +import com.apple.erp.dto.request.RebateAddReq;
4 +import com.apple.erp.dto.request.RebateQueryReq;
5 +import com.apple.erp.dto.request.RebateUpdateReq;
6 +import com.apple.erp.dto.response.RebateRes;
7 +import com.apple.erp.entity.Rebate;
8 +import com.apple.erp.mapper.RebateMapper;
9 +import com.apple.erp.service.RebateService;
10 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
11 +import com.baomidou.mybatisplus.core.metadata.IPage;
12 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
13 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
14 +import lombok.extern.slf4j.Slf4j;
15 +import org.springframework.beans.BeanUtils;
16 +import org.springframework.beans.factory.annotation.Autowired;
17 +import org.springframework.stereotype.Service;
18 +import org.springframework.transaction.annotation.Transactional;
19 +
20 +import java.math.BigDecimal;
21 +import java.time.LocalDate;
22 +import java.time.LocalDateTime;
23 +import java.time.format.DateTimeFormatter;
24 +import java.util.*;
25 +import java.util.stream.Collectors;
26 +
27 +/**
28 + * 返利台账明细服务实现类
29 + *
30 + * @author Apple ERP Team
31 + * @version 1.0.0
32 + * @since 2024-01-01
33 + */
34 +@Slf4j
35 +@Service
36 +public class RebateServiceImpl extends ServiceImpl<RebateMapper, Rebate> implements RebateService {
37 +
38 + @Autowired
39 + private RebateMapper rebateMapper;
40 +
41 + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
42 +
43 + @Override
44 + public IPage<RebateRes> getRebatePage(RebateQueryReq queryReq) {
45 + // 构建查询参数
46 + Map<String, Object> params = buildQueryParams(queryReq);
47 +
48 + // 创建分页对象
49 + Page<Rebate> page = new Page<>(queryReq.getPageNum(), queryReq.getPageSize());
50 +
51 + // 分页查询
52 + IPage<Rebate> rebatePage = rebateMapper.selectRebatePage(page, params);
53 +
54 + // 转换为响应DTO
55 + Page<RebateRes> resultPage = new Page<>(rebatePage.getCurrent(), rebatePage.getSize(), rebatePage.getTotal());
56 + List<RebateRes> rebateResList = rebatePage.getRecords().stream()
57 + .map(this::convertToRebateRes)
58 + .collect(Collectors.toList());
59 + resultPage.setRecords(rebateResList);
60 +
61 + return resultPage;
62 + }
63 +
64 + @Override
65 + public RebateRes getRebateById(Long rebateId) {
66 + Rebate rebate = getById(rebateId);
67 + return rebate != null ? convertToRebateRes(rebate) : null;
68 + }
69 +
70 + @Override
71 + @Transactional(rollbackFor = Exception.class)
72 + public boolean addRebate(RebateAddReq addReq) {
73 + Rebate rebate = new Rebate();
74 + BeanUtils.copyProperties(addReq, rebate);
75 +
76 + // 设置返利编号(如果未提供)
77 + if (addReq.getRebateNo() == null || addReq.getRebateNo().isEmpty()) {
78 + rebate.setRebateNo(generateRebateNo());
79 + }
80 +
81 + // 转换日期字符串
82 + if (addReq.getRebateDate() != null && !addReq.getRebateDate().isEmpty()) {
83 + rebate.setRebateDate(LocalDate.parse(addReq.getRebateDate(), DATE_FORMATTER));
84 + }
85 +
86 + // 设置上传时间
87 + rebate.setUploadTime(LocalDateTime.now());
88 +
89 + // 默认计算状态为未计算
90 + if (rebate.getCalcFlag() == null) {
91 + rebate.setCalcFlag(0);
92 + }
93 +
94 + return save(rebate);
95 + }
96 +
97 + @Override
98 + @Transactional(rollbackFor = Exception.class)
99 + public boolean updateRebate(RebateUpdateReq updateReq) {
100 + Rebate rebate = getById(updateReq.getRebateId());
101 + if (rebate == null) {
102 + throw new RuntimeException("返利记录不存在");
103 + }
104 +
105 + BeanUtils.copyProperties(updateReq, rebate);
106 +
107 + // 转换日期字符串
108 + if (updateReq.getRebateDate() != null && !updateReq.getRebateDate().isEmpty()) {
109 + rebate.setRebateDate(LocalDate.parse(updateReq.getRebateDate(), DATE_FORMATTER));
110 + }
111 +
112 + return updateById(rebate);
113 + }
114 +
115 + @Override
116 + @Transactional(rollbackFor = Exception.class)
117 + public boolean deleteRebate(Long rebateId) {
118 + return removeById(rebateId);
119 + }
120 +
121 + @Override
122 + @Transactional(rollbackFor = Exception.class)
123 + public boolean batchDeleteRebate(List<Long> rebateIds) {
124 + return removeByIds(rebateIds);
125 + }
126 +
127 + @Override
128 + public BigDecimal sumRebateAmountByDealer(String dealerCode, Integer operateType) {
129 + BigDecimal amount = rebateMapper.sumRebateAmountByDealer(dealerCode, operateType);
130 + return amount != null ? amount : BigDecimal.ZERO;
131 + }
132 +
133 + @Override
134 + public BigDecimal sumRebateAmountByProduct(String productCode, Integer operateType) {
135 + BigDecimal amount = rebateMapper.sumRebateAmountByProduct(productCode, operateType);
136 + return amount != null ? amount : BigDecimal.ZERO;
137 + }
138 +
139 + @Override
140 + public List<Map<String, Object>> countRebateByOperateType() {
141 + return rebateMapper.countRebateByOperateType();
142 + }
143 +
144 + @Override
145 + public List<RebateRes> getUnCalcRebates() {
146 + List<Rebate> rebates = rebateMapper.selectUnCalcRebates();
147 + return rebates.stream()
148 + .map(this::convertToRebateRes)
149 + .collect(Collectors.toList());
150 + }
151 +
152 + @Override
153 + public RebateRes getRebateByNo(String rebateNo) {
154 + Rebate rebate = rebateMapper.selectByRebateNo(rebateNo);
155 + return rebate != null ? convertToRebateRes(rebate) : null;
156 + }
157 +
158 + @Override
159 + public String generateRebateNo() {
160 + String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
161 + String prefix = "RB" + dateStr;
162 +
163 + // 查询当天已有的返利编号数量
164 + LambdaQueryWrapper<Rebate> wrapper = new LambdaQueryWrapper<>();
165 + wrapper.likeRight(Rebate::getRebateNo, prefix);
166 + long count = count(wrapper);
167 +
168 + // 生成4位序号
169 + String sequence = String.format("%04d", count + 1);
170 +
171 + return prefix + sequence;
172 + }
173 +
174 + /**
175 + * 构建查询参数
176 + */
177 + private Map<String, Object> buildQueryParams(RebateQueryReq queryReq) {
178 + Map<String, Object> params = new HashMap<>();
179 +
180 + if (queryReq.getRebateNo() != null && !queryReq.getRebateNo().isEmpty()) {
181 + params.put("rebateNo", queryReq.getRebateNo());
182 + }
183 + if (queryReq.getOrderNo() != null && !queryReq.getOrderNo().isEmpty()) {
184 + params.put("orderNo", queryReq.getOrderNo());
185 + }
186 + if (queryReq.getDealerCode() != null && !queryReq.getDealerCode().isEmpty()) {
187 + params.put("dealerCode", queryReq.getDealerCode());
188 + }
189 + if (queryReq.getDealerName() != null && !queryReq.getDealerName().isEmpty()) {
190 + params.put("dealerName", queryReq.getDealerName());
191 + }
192 + if (queryReq.getProductCode() != null && !queryReq.getProductCode().isEmpty()) {
193 + params.put("productCode", queryReq.getProductCode());
194 + }
195 + if (queryReq.getOperateType() != null) {
196 + params.put("operateType", queryReq.getOperateType());
197 + }
198 + if (queryReq.getCalcFlag() != null) {
199 + params.put("calcFlag", queryReq.getCalcFlag());
200 + }
201 + if (queryReq.getRebateStartDate() != null && !queryReq.getRebateStartDate().isEmpty()) {
202 + params.put("rebateStartDate", queryReq.getRebateStartDate());
203 + }
204 + if (queryReq.getRebateEndDate() != null && !queryReq.getRebateEndDate().isEmpty()) {
205 + params.put("rebateEndDate", queryReq.getRebateEndDate());
206 + }
207 +
208 + return params;
209 + }
210 +
211 + /**
212 + * 转换为响应DTO
213 + */
214 + private RebateRes convertToRebateRes(Rebate rebate) {
215 + RebateRes rebateRes = new RebateRes();
216 + BeanUtils.copyProperties(rebate, rebateRes);
217 +
218 + // 设置操作类型文本
219 + rebateRes.setOperateTypeText(getOperateTypeText(rebate.getOperateType()));
220 +
221 + // 设置计算状态文本
222 + rebateRes.setCalcFlagText(getCalcFlagText(rebate.getCalcFlag()));
223 +
224 + return rebateRes;
225 + }
226 +
227 + /**
228 + * 获取操作类型文本
229 + */
230 + private String getOperateTypeText(Integer operateType) {
231 + if (operateType == null) {
232 + return "";
233 + }
234 + switch (operateType) {
235 + case 1:
236 + return "新增";
237 + case 2:
238 + return "扣减";
239 + default:
240 + return "未知";
241 + }
242 + }
243 +
244 + /**
245 + * 获取计算状态文本
246 + */
247 + private String getCalcFlagText(Integer calcFlag) {
248 + if (calcFlag == null) {
249 + return "";
250 + }
251 + switch (calcFlag) {
252 + case 0:
253 + return "未计算";
254 + case 1:
255 + return "已计算";
256 + default:
257 + return "未知";
258 + }
259 + }
260 +
261 + @Override
262 + public List<Map<String, Object>> getRebateMonthlyStats(Integer year) {
263 + log.info("获取返利月度统计数据,年份:{}", year);
264 + return rebateMapper.getRebateMonthlyStats(year);
265 + }
266 +
267 + @Override
268 + public Map<String, Object> getRebateStatusStats() {
269 + log.info("获取返利状态统计数据");
270 + return rebateMapper.getRebateStatusStats();
271 + }
272 +
273 + @Override
274 + public List<Map<String, Object>> getRebateTrendStats(String startDate, String endDate) {
275 + log.info("获取返利趋势统计数据,开始日期:{},结束日期:{}", startDate, endDate);
276 + return rebateMapper.getRebateTrendStats(startDate, endDate);
277 + }
278 +}
...@@ -17,8 +17,8 @@ spring: ...@@ -17,8 +17,8 @@ spring:
17 type: com.alibaba.druid.pool.DruidDataSource 17 type: com.alibaba.druid.pool.DruidDataSource
18 driver-class-name: com.mysql.cj.jdbc.Driver 18 driver-class-name: com.mysql.cj.jdbc.Driver
19 url: jdbc:mysql://localhost:3306/apple_erp?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true 19 url: jdbc:mysql://localhost:3306/apple_erp?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
20 - username: root 20 + username: apple_erp_app
21 - password: MySQL@123 21 + password: StrongPassw0rd!
22 druid: 22 druid:
23 # 初始连接数 23 # 初始连接数
24 initial-size: 5 24 initial-size: 5
...@@ -70,7 +70,7 @@ spring: ...@@ -70,7 +70,7 @@ spring:
70 redis: 70 redis:
71 host: localhost 71 host: localhost
72 port: 6379 72 port: 6379
73 - password: 73 + password: 123456
74 database: 0 74 database: 0
75 timeout: 10000ms 75 timeout: 10000ms
76 lettuce: 76 lettuce:
......
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 +<mapper namespace="com.apple.erp.mapper.RebateMapper">
4 +
5 + <!-- 返利明细基础字段 -->
6 + <sql id="baseColumns">
7 + rebate_id, rebate_no, order_no, dealer_code, dealer_name, product_code,
8 + rebate_amount, rebate_date, operate_type, calc_flag, upload_time,
9 + create_by, create_time, update_by, update_time
10 + </sql>
11 +
12 + <!-- 分页查询返利明细列表 -->
13 + <select id="selectRebatePage" resultType="com.apple.erp.entity.Rebate">
14 + SELECT
15 + <include refid="baseColumns"/>
16 + FROM t_rebate_detail
17 + WHERE del_flag = '0'
18 + <if test="params.rebateNo != null and params.rebateNo != ''">
19 + AND rebate_no LIKE CONCAT('%', #{params.rebateNo}, '%')
20 + </if>
21 + <if test="params.orderNo != null and params.orderNo != ''">
22 + AND order_no LIKE CONCAT('%', #{params.orderNo}, '%')
23 + </if>
24 + <if test="params.dealerCode != null and params.dealerCode != ''">
25 + AND dealer_code = #{params.dealerCode}
26 + </if>
27 + <if test="params.dealerName != null and params.dealerName != ''">
28 + AND dealer_name LIKE CONCAT('%', #{params.dealerName}, '%')
29 + </if>
30 + <if test="params.productCode != null and params.productCode != ''">
31 + AND product_code = #{params.productCode}
32 + </if>
33 + <if test="params.operateType != null">
34 + AND operate_type = #{params.operateType}
35 + </if>
36 + <if test="params.calcFlag != null">
37 + AND calc_flag = #{params.calcFlag}
38 + </if>
39 + <if test="params.rebateStartDate != null and params.rebateStartDate != ''">
40 + AND rebate_date &gt;= #{params.rebateStartDate}
41 + </if>
42 + <if test="params.rebateEndDate != null and params.rebateEndDate != ''">
43 + AND rebate_date &lt;= #{params.rebateEndDate}
44 + </if>
45 + ORDER BY create_time DESC
46 + </select>
47 +
48 + <!-- 根据经销商编码统计返利总金额 -->
49 + <select id="sumRebateAmountByDealer" resultType="java.math.BigDecimal">
50 + SELECT COALESCE(SUM(rebate_amount), 0)
51 + FROM t_rebate_detail
52 + WHERE del_flag = '0'
53 + AND dealer_code = #{dealerCode}
54 + <if test="operateType != null">
55 + AND operate_type = #{operateType}
56 + </if>
57 + </select>
58 +
59 + <!-- 根据产品编码统计返利总金额 -->
60 + <select id="sumRebateAmountByProduct" resultType="java.math.BigDecimal">
61 + SELECT COALESCE(SUM(rebate_amount), 0)
62 + FROM t_rebate_detail
63 + WHERE del_flag = '0'
64 + AND product_code = #{productCode}
65 + <if test="operateType != null">
66 + AND operate_type = #{operateType}
67 + </if>
68 + </select>
69 +
70 + <!-- 统计各操作类型的返利数量 -->
71 + <select id="countRebateByOperateType" resultType="java.util.Map">
72 + SELECT
73 + operate_type,
74 + COUNT(*) as count,
75 + COALESCE(SUM(rebate_amount), 0) as totalAmount
76 + FROM t_rebate_detail
77 + WHERE del_flag = '0'
78 + GROUP BY operate_type
79 + </select>
80 +
81 + <!-- 查询未计算的返利明细列表 -->
82 + <select id="selectUnCalcRebates" resultType="com.apple.erp.entity.Rebate">
83 + SELECT
84 + <include refid="baseColumns"/>
85 + FROM t_rebate_detail
86 + WHERE del_flag = '0'
87 + AND calc_flag = 0
88 + ORDER BY create_time ASC
89 + </select>
90 +
91 + <!-- 根据返利编号查询返利明细 -->
92 + <select id="selectByRebateNo" resultType="com.apple.erp.entity.Rebate">
93 + SELECT
94 + <include refid="baseColumns"/>
95 + FROM t_rebate_detail
96 + WHERE del_flag = '0'
97 + AND rebate_no = #{rebateNo}
98 + </select>
99 +
100 + <!-- 获取返利月度统计数据 -->
101 + <select id="getRebateMonthlyStats" resultType="java.util.Map">
102 + SELECT
103 + MONTH(rebate_date) as month,
104 + COALESCE(SUM(CASE WHEN operate_type = 1 THEN rebate_amount ELSE -rebate_amount END), 0) as totalAmount,
105 + COALESCE(SUM(CASE WHEN calc_flag = 1 AND operate_type = 1 THEN rebate_amount
106 + WHEN calc_flag = 1 AND operate_type = 2 THEN -rebate_amount
107 + ELSE 0 END), 0) as calculatedAmount,
108 + COUNT(*) as totalCount,
109 + COUNT(CASE WHEN calc_flag = 1 THEN 1 END) as calculatedCount
110 + FROM t_rebate_detail
111 + WHERE del_flag = '0'
112 + AND YEAR(rebate_date) = #{year}
113 + GROUP BY MONTH(rebate_date)
114 + ORDER BY month
115 + </select>
116 +
117 + <!-- 获取返利状态统计数据 -->
118 + <select id="getRebateStatusStats" resultType="java.util.Map">
119 + SELECT
120 + COUNT(CASE WHEN calc_flag = 1 THEN 1 END) as calculatedCount,
121 + COUNT(CASE WHEN calc_flag = 0 THEN 1 END) as unCalculatedCount,
122 + COUNT(*) as totalCount,
123 + COALESCE(SUM(CASE WHEN calc_flag = 1 AND operate_type = 1 THEN rebate_amount
124 + WHEN calc_flag = 1 AND operate_type = 2 THEN -rebate_amount
125 + ELSE 0 END), 0) as calculatedAmount,
126 + COALESCE(SUM(CASE WHEN operate_type = 1 THEN rebate_amount ELSE -rebate_amount END), 0) as totalAmount
127 + FROM t_rebate_detail
128 + WHERE del_flag = '0'
129 + </select>
130 +
131 + <!-- 获取返利趋势统计数据 -->
132 + <select id="getRebateTrendStats" resultType="java.util.Map">
133 + SELECT
134 + DATE(rebate_date) as date,
135 + COALESCE(SUM(CASE WHEN operate_type = 1 THEN rebate_amount ELSE -rebate_amount END), 0) as totalAmount,
136 + COALESCE(SUM(CASE WHEN calc_flag = 1 AND operate_type = 1 THEN rebate_amount
137 + WHEN calc_flag = 1 AND operate_type = 2 THEN -rebate_amount
138 + ELSE 0 END), 0) as calculatedAmount,
139 + COUNT(*) as totalCount,
140 + COUNT(CASE WHEN calc_flag = 1 THEN 1 END) as calculatedCount
141 + FROM t_rebate_detail
142 + WHERE del_flag = '0'
143 + <if test="startDate != null and startDate != ''">
144 + AND rebate_date >= #{startDate}
145 + </if>
146 + <if test="endDate != null and endDate != ''">
147 + AND rebate_date &lt;= #{endDate}
148 + </if>
149 + GROUP BY DATE(rebate_date)
150 + ORDER BY date
151 + </select>
152 +
153 +</mapper>
...@@ -51,7 +51,8 @@ ...@@ -51,7 +51,8 @@
51 </select> 51 </select>
52 52
53 <select id="selectMenuTreeByRoleId" parameterType="Long" resultMap="SysMenuResult"> 53 <select id="selectMenuTreeByRoleId" parameterType="Long" resultMap="SysMenuResult">
54 - select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.menu_type, m.status, m.perms, m.icon, m.create_by, m.create_time, m.update_by, m.update_time, m.del_flag 54 + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.menu_type, m.status, m.perms, m.icon, m.create_by, m.create_time, m.update_by, m.update_time, m.del_flag,
55 + m.sort
55 from t_sys_menu m 56 from t_sys_menu m
56 left join t_sys_role_menu rm on m.menu_id = rm.menu_id 57 left join t_sys_role_menu rm on m.menu_id = rm.menu_id
57 where rm.role_id = #{roleId} and m.status = 1 and m.del_flag = '0' 58 where rm.role_id = #{roleId} and m.status = 1 and m.del_flag = '0'
......
...@@ -7,21 +7,10 @@ export {} ...@@ -7,21 +7,10 @@ export {}
7 7
8 declare module 'vue' { 8 declare module 'vue' {
9 export interface GlobalComponents { 9 export interface GlobalComponents {
10 - ActionBar: typeof import('./src/components/common/ActionBar.vue')['default']
11 - DataTable: typeof import('./src/components/common/DataTable.vue')['default']
12 - ElButton: typeof import('element-plus/es')['ElButton']
13 - ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
14 - ElForm: typeof import('element-plus/es')['ElForm']
15 - ElFormItem: typeof import('element-plus/es')['ElFormItem']
16 - ElInput: typeof import('element-plus/es')['ElInput']
17 - ElLink: typeof import('element-plus/es')['ElLink']
18 Header: typeof import('./src/components/layout/Header.vue')['default'] 10 Header: typeof import('./src/components/layout/Header.vue')['default']
19 - Pagination: typeof import('./src/components/common/Pagination.vue')['default']
20 RouterLink: typeof import('vue-router')['RouterLink'] 11 RouterLink: typeof import('vue-router')['RouterLink']
21 RouterView: typeof import('vue-router')['RouterView'] 12 RouterView: typeof import('vue-router')['RouterView']
22 - SearchBar: typeof import('./src/components/common/SearchBar.vue')['default']
23 Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default'] 13 Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default']
24 SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default'] 14 SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default']
25 - TableToolbar: typeof import('./src/components/common/TableToolbar.vue')['default']
26 } 15 }
27 } 16 }
......
1 +import request from '@/utils/request'
2 +
3 +// 返利台账明细类型定义
4 +export interface Rebate {
5 + rebateId?: number
6 + rebateNo?: string
7 + orderNo: string
8 + dealerCode: string
9 + dealerName: string
10 + productCode: string
11 + rebateAmount: number
12 + rebateDate: string
13 + operateType: number
14 + operateTypeText?: string
15 + calcFlag?: number
16 + calcFlagText?: string
17 + uploadTime?: string
18 + createTime?: string
19 + updateTime?: string
20 + createBy?: string
21 + updateBy?: string
22 +}
23 +
24 +// 返利查询参数
25 +export interface RebateSearchParams {
26 + pageNum: number
27 + pageSize: number
28 + rebateNo?: string
29 + orderNo?: string
30 + dealerCode?: string
31 + dealerName?: string
32 + productCode?: string
33 + operateType?: number
34 + calcFlag?: number
35 + rebateStartDate?: string
36 + rebateEndDate?: string
37 +}
38 +
39 +// 返利新增参数
40 +export interface RebateAddParams {
41 + rebateNo?: string
42 + orderNo: string
43 + dealerCode: string
44 + dealerName: string
45 + productCode: string
46 + rebateAmount: number
47 + rebateDate: string
48 + operateType: number
49 + calcFlag?: number
50 +}
51 +
52 +// 返利更新参数
53 +export interface RebateUpdateParams extends RebateAddParams {
54 + rebateId: number
55 +}
56 +
57 +// 分页查询返利列表
58 +export const getRebatePage = (params: RebateSearchParams) => {
59 + return request({
60 + url: '/api/rebate/page',
61 + method: 'post',
62 + data: params
63 + })
64 +}
65 +
66 +// 根据ID查询返利详情
67 +export const getRebateById = (rebateId: number) => {
68 + return request({
69 + url: `/api/rebate/${rebateId}`,
70 + method: 'get'
71 + })
72 +}
73 +
74 +// 新增返利
75 +export const addRebate = (data: RebateAddParams) => {
76 + return request({
77 + url: '/api/rebate/add',
78 + method: 'post',
79 + data
80 + })
81 +}
82 +
83 +// 更新返利
84 +export const updateRebate = (data: RebateUpdateParams) => {
85 + return request({
86 + url: '/api/rebate/update',
87 + method: 'post',
88 + data
89 + })
90 +}
91 +
92 +// 删除返利
93 +export const deleteRebate = (rebateId: number) => {
94 + return request({
95 + url: `/api/rebate/${rebateId}`,
96 + method: 'delete'
97 + })
98 +}
99 +
100 +// 批量删除返利
101 +export const batchDeleteRebate = (rebateIds: number[]) => {
102 + return request({
103 + url: '/api/rebate/batchDelete',
104 + method: 'post',
105 + data: rebateIds
106 + })
107 +}
108 +
109 +// 标记返利为已计算
110 +export const markRebateCalculated = (rebateId: number) => {
111 + return request({
112 + url: `/api/rebate/markCalculated/${rebateId}`,
113 + method: 'post'
114 + })
115 +}
116 +
117 +// 批量标记返利为已计算
118 +export const batchMarkRebateCalculated = (rebateIds: number[]) => {
119 + return request({
120 + url: '/api/rebate/batchMarkCalculated',
121 + method: 'post',
122 + data: rebateIds
123 + })
124 +}
125 +
126 +// 根据经销商编码统计返利总金额
127 +export const sumRebateAmountByDealer = (dealerCode: string, operateType?: number) => {
128 + return request({
129 + url: `/api/rebate/sumByDealer/${dealerCode}`,
130 + method: 'get',
131 + params: { operateType }
132 + })
133 +}
134 +
135 +// 根据产品编码统计返利总金额
136 +export const sumRebateAmountByProduct = (productCode: string, operateType?: number) => {
137 + return request({
138 + url: `/api/rebate/sumByProduct/${productCode}`,
139 + method: 'get',
140 + params: { operateType }
141 + })
142 +}
143 +
144 +// 统计各操作类型的返利数量
145 +export const countRebateByOperateType = () => {
146 + return request({
147 + url: '/api/rebate/countByOperateType',
148 + method: 'get'
149 + })
150 +}
151 +
152 +// 查询未计算的返利明细列表
153 +export const getUnCalcRebates = () => {
154 + return request({
155 + url: '/api/rebate/unCalc',
156 + method: 'get'
157 + })
158 +}
159 +
160 +// 根据返利编号查询返利
161 +export const getRebateByNo = (rebateNo: string) => {
162 + return request({
163 + url: `/api/rebate/byNo/${rebateNo}`,
164 + method: 'get'
165 + })
166 +}
167 +
168 +// 生成返利编号
169 +export const generateRebateNo = () => {
170 + return request({
171 + url: '/api/rebate/generateNo',
172 + method: 'get'
173 + })
174 +}
175 +
176 +// 导出返利数据
177 +export const exportRebate = (params: RebateSearchParams) => {
178 + return request({
179 + url: '/api/rebate/export',
180 + method: 'post',
181 + data: params,
182 + responseType: 'blob'
183 + })
184 +}
185 +
186 +// 获取返利月度统计数据
187 +export const getRebateMonthlyStats = (year?: number) => {
188 + return request({
189 + url: '/api/rebate/monthlyStats',
190 + method: 'get',
191 + params: { year: year || new Date().getFullYear() }
192 + })
193 +}
194 +
195 +// 获取返利状态统计数据
196 +export const getRebateStatusStats = () => {
197 + return request({
198 + url: '/api/rebate/statusStats',
199 + method: 'get'
200 + })
201 +}
202 +
203 +// 获取返利趋势统计数据
204 +export const getRebateTrendStats = (startDate?: string, endDate?: string) => {
205 + return request({
206 + url: '/api/rebate/trendStats',
207 + method: 'get',
208 + params: { startDate, endDate }
209 + })
210 +}
211 +
212 +export default {
213 + getRebatePage,
214 + getRebateById,
215 + addRebate,
216 + updateRebate,
217 + deleteRebate,
218 + batchDeleteRebate,
219 + markRebateCalculated,
220 + batchMarkRebateCalculated,
221 + sumRebateAmountByDealer,
222 + sumRebateAmountByProduct,
223 + countRebateByOperateType,
224 + getUnCalcRebates,
225 + getRebateByNo,
226 + generateRebateNo,
227 + exportRebate,
228 + getRebateMonthlyStats,
229 + getRebateStatusStats,
230 + getRebateTrendStats
231 +}
...@@ -146,6 +146,7 @@ const menuItems = ref([ ...@@ -146,6 +146,7 @@ const menuItems = ref([
146 { name: '发票管理', path: '/main/invoice', icon: '🧾' }, 146 { name: '发票管理', path: '/main/invoice', icon: '🧾' },
147 { name: '产品管理', path: '/main/product', icon: '📦' }, 147 { name: '产品管理', path: '/main/product', icon: '📦' },
148 { name: '经销商管理', path: '/main/dealer', icon: '🏢' }, 148 { name: '经销商管理', path: '/main/dealer', icon: '🏢' },
149 + { name: '返利管理', path: '/main/rebate', icon: '💰' },
149 { 150 {
150 name: '系统设置', 151 name: '系统设置',
151 icon: '⚙️', 152 icon: '⚙️',
......
...@@ -99,24 +99,6 @@ const staticRoutes: RouteRecordRaw[] = [ ...@@ -99,24 +99,6 @@ const staticRoutes: RouteRecordRaw[] = [
99 } 99 }
100 }, 100 },
101 { 101 {
102 - path: 'dicts',
103 - name: 'Dicts',
104 - component: () => import('@/views/dicts/index.vue'),
105 - meta: {
106 - title: '字典管理',
107 - requiresAuth: true
108 - }
109 - },
110 - {
111 - path: 'logs',
112 - name: 'Logs',
113 - component: () => import('@/views/logs/index.vue'),
114 - meta: {
115 - title: '日志管理',
116 - requiresAuth: true
117 - }
118 - },
119 - {
120 path: 'product', 102 path: 'product',
121 name: 'Product', 103 name: 'Product',
122 component: () => import('@/views/product/index.vue'), 104 component: () => import('@/views/product/index.vue'),
...@@ -162,6 +144,15 @@ const staticRoutes: RouteRecordRaw[] = [ ...@@ -162,6 +144,15 @@ const staticRoutes: RouteRecordRaw[] = [
162 } 144 }
163 }, 145 },
164 { 146 {
147 + path: 'rebate',
148 + name: 'Rebate',
149 + component: () => import('@/views/rebate/index.vue'),
150 + meta: {
151 + title: '返利管理',
152 + requiresAuth: true
153 + }
154 + },
155 + {
165 path: 'settings', 156 path: 'settings',
166 name: 'Settings', 157 name: 'Settings',
167 component: () => import('@/views/settings/index.vue'), 158 component: () => import('@/views/settings/index.vue'),
......
...@@ -93,27 +93,27 @@ ...@@ -93,27 +93,27 @@
93 <th>出库日期</th> 93 <th>出库日期</th>
94 <th>关联订单编号</th> 94 <th>关联订单编号</th>
95 <th>出库状态</th> 95 <th>出库状态</th>
96 - <th>出库时间</th> 96 + <th>创建时间</th>
97 <th>操作</th> 97 <th>操作</th>
98 </tr> 98 </tr>
99 </thead> 99 </thead>
100 <tbody> 100 <tbody>
101 - <tr v-for="order in orderList" :key="order.deliveryId"> 101 + <tr v-for="delivery in deliveryList" :key="delivery.deliveryId">
102 - <td>{{ order.deliveryId }}</td> 102 + <td>{{ delivery.deliveryId }}</td>
103 - <td>{{ order.deliveryNo }}</td> 103 + <td>{{ delivery.deliveryNo }}</td>
104 - <td>{{ order.dealerCode }}</td> 104 + <td>{{ delivery.dealerCode }}</td>
105 - <td>{{ order.dealerName }}</td> 105 + <td>{{ delivery.dealerName }}</td>
106 - <td>{{ formatDate(order.deliveryDate) }}</td> 106 + <td>{{ formatDate(delivery.deliveryDate) }}</td>
107 - <td>{{ order.orderNo }}</td> 107 + <td>{{ delivery.orderNo }}</td>
108 <td> 108 <td>
109 - <span :class="getDeliveryStatusClass(order.deliveryStatus)"> 109 + <span :class="getDeliveryStatusClass(delivery.deliveryStatus)">
110 - {{ getDeliveryStatusText(order.deliveryStatus) }} 110 + {{ getDeliveryStatusText(delivery.deliveryStatus) }}
111 </span> 111 </span>
112 </td> 112 </td>
113 - <td>{{ formatTime(order.uploadTime || '') }}</td> 113 + <td>{{ formatTime(delivery.createTime || '') }}</td>
114 <td class="action-col"> 114 <td class="action-col">
115 - <button @click="handleView(order)" class="view-btn">👁️ 查看</button> 115 + <button @click="handleView(delivery)" class="view-btn">👁️ 查看</button>
116 - <button @click="handleDelete(order)" class="delete-btn">🗑️ 删除</button> 116 + <button @click="handleDelete(delivery)" class="delete-btn">🗑️ 删除</button>
117 </td> 117 </td>
118 </tr> 118 </tr>
119 </tbody> 119 </tbody>
...@@ -173,7 +173,7 @@ ...@@ -173,7 +173,7 @@
173 <button @click="closeDetailDialog" class="close-btn">×</button> 173 <button @click="closeDetailDialog" class="close-btn">×</button>
174 </div> 174 </div>
175 <div class="dialog-body"> 175 <div class="dialog-body">
176 - <div v-if="orderDetail" class="detail-content"> 176 + <div v-if="deliveryDetail" class="detail-content">
177 <div class="detail-section"> 177 <div class="detail-section">
178 <h4>出库基本信息</h4> 178 <h4>出库基本信息</h4>
179 <div class="detail-grid"> 179 <div class="detail-grid">
...@@ -190,12 +190,16 @@ ...@@ -190,12 +190,16 @@
190 <span>{{ orderDetail.orderNo }}</span> 190 <span>{{ orderDetail.orderNo }}</span>
191 </div> 191 </div>
192 <div class="detail-item"> 192 <div class="detail-item">
193 + <label>关联订单编号:</label>
194 + <span>{{ deliveryDetail.orderNo }}</span>
195 + </div>
196 + <div class="detail-item">
193 <label>经销商编码:</label> 197 <label>经销商编码:</label>
194 - <span>{{ orderDetail.dealerCode }}</span> 198 + <span>{{ deliveryDetail.dealerCode }}</span>
195 </div> 199 </div>
196 <div class="detail-item"> 200 <div class="detail-item">
197 <label>经销商名称:</label> 201 <label>经销商名称:</label>
198 - <span>{{ orderDetail.dealerName }}</span> 202 + <span>{{ deliveryDetail.dealerName }}</span>
199 </div> 203 </div>
200 <div class="detail-item"> 204 <div class="detail-item">
201 <label>出库日期:</label> 205 <label>出库日期:</label>
...@@ -203,8 +207,8 @@ ...@@ -203,8 +207,8 @@
203 </div> 207 </div>
204 <div class="detail-item"> 208 <div class="detail-item">
205 <label>出库状态:</label> 209 <label>出库状态:</label>
206 - <span :class="getDeliveryStatusClass(orderDetail.deliveryStatus)"> 210 + <span :class="getDeliveryStatusClass(deliveryDetail.deliveryStatus)">
207 - {{ getDeliveryStatusText(orderDetail.deliveryStatus) }} 211 + {{ getDeliveryStatusText(deliveryDetail.deliveryStatus) }}
208 </span> 212 </span>
209 </div> 213 </div>
210 <div class="detail-item"> 214 <div class="detail-item">
...@@ -433,9 +437,9 @@ import { deliveryApi, type DeliveryAddReq, type DeliveryInfo, type DeliveryQuery ...@@ -433,9 +437,9 @@ import { deliveryApi, type DeliveryAddReq, type DeliveryInfo, type DeliveryQuery
433 437
434 // 响应式数据 438 // 响应式数据
435 const loading = ref(false) 439 const loading = ref(false)
436 -const orderList = ref<DeliveryInfo[]>([]) 440 +const deliveryList = ref<DeliveryInfo[]>([])
437 const showDetailDialog = ref(false) 441 const showDetailDialog = ref(false)
438 -const orderDetail = ref<DeliveryInfo | null>(null) 442 +const deliveryDetail = ref<DeliveryInfo | null>(null)
439 443
440 // 新增出库相关数据 444 // 新增出库相关数据
441 const showAddDialog = ref(false) 445 const showAddDialog = ref(false)
...@@ -453,6 +457,7 @@ const addFormData = reactive({ ...@@ -453,6 +457,7 @@ const addFormData = reactive({
453 457
454 // 搜索参数 458 // 搜索参数
455 const searchParams = reactive({ 459 const searchParams = reactive({
460 + orderNo: '',
456 deliveryNo: '', 461 deliveryNo: '',
457 dealerCode: '', 462 dealerCode: '',
458 dealerName: '', 463 dealerName: '',
...@@ -461,6 +466,8 @@ const searchParams = reactive({ ...@@ -461,6 +466,8 @@ const searchParams = reactive({
461 dataSource: '', 466 dataSource: '',
462 deliveryStartDate: '', 467 deliveryStartDate: '',
463 deliveryEndDate: '', 468 deliveryEndDate: '',
469 + startDate: '',
470 + endDate: '',
464 pageNum: 1, 471 pageNum: 1,
465 pageSize: 10 472 pageSize: 10
466 }) 473 })
...@@ -529,7 +536,7 @@ const getPageNumbers = () => { ...@@ -529,7 +536,7 @@ const getPageNumbers = () => {
529 } 536 }
530 537
531 // 方法 538 // 方法
532 -const fetchOrders = async () => { 539 +const fetchDeliveries = async () => {
533 try { 540 try {
534 loading.value = true 541 loading.value = true
535 const params = { ...searchParams, pageNum: pagination.pageNum, pageSize: pagination.pageSize } 542 const params = { ...searchParams, pageNum: pagination.pageNum, pageSize: pagination.pageSize }
...@@ -538,12 +545,12 @@ const fetchOrders = async () => { ...@@ -538,12 +545,12 @@ const fetchOrders = async () => {
538 545
539 // 由于request.ts的响应拦截器已经处理了code=200的情况,直接返回data 546 // 由于request.ts的响应拦截器已经处理了code=200的情况,直接返回data
540 if (response && response.records) { 547 if (response && response.records) {
541 - orderList.value = response.records || [] 548 + deliveryList.value = response.records || []
542 pagination.total = response.total || 0 549 pagination.total = response.total || 0
543 pagination.pageNum = response.current || 1 550 pagination.pageNum = response.current || 1
544 pagination.pageSize = response.size || 10 551 pagination.pageSize = response.size || 10
545 } else { 552 } else {
546 - orderList.value = [] 553 + deliveryList.value = []
547 pagination.total = 0 554 pagination.total = 0
548 showMessage('获取出库列表失败', 'error') 555 showMessage('获取出库列表失败', 'error')
549 } 556 }
...@@ -557,7 +564,7 @@ const fetchOrders = async () => { ...@@ -557,7 +564,7 @@ const fetchOrders = async () => {
557 564
558 const handleSearch = () => { 565 const handleSearch = () => {
559 pagination.pageNum = 1 566 pagination.pageNum = 1
560 - fetchOrders() 567 + fetchDeliveries()
561 } 568 }
562 569
563 const handleReset = () => { 570 const handleReset = () => {
...@@ -570,33 +577,33 @@ const handleReset = () => { ...@@ -570,33 +577,33 @@ const handleReset = () => {
570 endDate: '' 577 endDate: ''
571 }) 578 })
572 pagination.pageNum = 1 579 pagination.pageNum = 1
573 - fetchOrders() 580 + fetchDeliveries()
574 } 581 }
575 582
576 -const handleView = async (order: DeliveryInfo) => { 583 +const handleView = async (delivery: DeliveryInfo) => {
577 try { 584 try {
578 - const response = await deliveryApi.getDeliveryDetail(order.deliveryId) as any 585 + const response = await deliveryApi.getDeliveryDetail(delivery.deliveryId) as any
579 console.log('出库查询详情API响应:', response) 586 console.log('出库查询详情API响应:', response)
580 587
581 // 由于request.ts的响应拦截器已经处理了code=200的情况,直接返回data 588 // 由于request.ts的响应拦截器已经处理了code=200的情况,直接返回data
582 if (response && response.deliveryId) { 589 if (response && response.deliveryId) {
583 - orderDetail.value = response 590 + deliveryDetail.value = response
584 showDetailDialog.value = true 591 showDetailDialog.value = true
585 } else { 592 } else {
586 - showMessage('获取订单详情失败', 'error') 593 + showMessage('获取出库详情失败', 'error')
587 } 594 }
588 } catch (error) { 595 } catch (error) {
589 - console.error('获取订单详情失败:', error) 596 + console.error('获取出库详情失败:', error)
590 - showMessage('获取订单详情失败, 请重试', 'error') 597 + showMessage('获取出库详情失败, 请重试', 'error')
591 } 598 }
592 } 599 }
593 600
594 -const handleDelete = async (order: DeliveryInfo) => { 601 +const handleDelete = async (delivery: DeliveryInfo) => {
595 - if (confirm(`确定要删除出库单"${order.deliveryNo}"吗?`)) { 602 + if (confirm(`确定要删除出库单"${delivery.deliveryNo}"吗?`)) {
596 try { 603 try {
597 - await deliveryApi.deleteDelivery(order.deliveryId) 604 + await deliveryApi.deleteDelivery(delivery.deliveryId)
598 showMessage('删除出库单成功', 'success') 605 showMessage('删除出库单成功', 'success')
599 - fetchOrders() // 刷新列表 606 + fetchDeliveries() // 刷新列表
600 } catch (error) { 607 } catch (error) {
601 console.error('删除出库单失败:', error) 608 console.error('删除出库单失败:', error)
602 showMessage('删除出库单失败, 请重试', 'error') 609 showMessage('删除出库单失败, 请重试', 'error')
...@@ -673,16 +680,16 @@ const handleSubmitAdd = async () => { ...@@ -673,16 +680,16 @@ const handleSubmitAdd = async () => {
673 deliveryItems: addFormData.deliveryItems.map(item => ({ 680 deliveryItems: addFormData.deliveryItems.map(item => ({
674 productCode: item.productCode, 681 productCode: item.productCode,
675 productName: item.productName, 682 productName: item.productName,
676 - deliveryQty: item.deliveryQty, 683 + productQty: item.deliveryQty,
677 - deliveryPrice: item.deliveryPrice, 684 + unitPrice: item.deliveryPrice,
678 - deliveryAmount: item.deliveryAmount 685 + totalPrice: item.deliveryAmount
679 })) 686 }))
680 } 687 }
681 688
682 await deliveryApi.addDelivery(deliveryData) 689 await deliveryApi.addDelivery(deliveryData)
683 showMessage('新增出库成功', 'success') 690 showMessage('新增出库成功', 'success')
684 closeAddDialog() 691 closeAddDialog()
685 - fetchOrders() // 刷新列表 692 + fetchDeliveries() // 刷新列表
686 } catch (error) { 693 } catch (error) {
687 console.error('新增出库失败:', error) 694 console.error('新增出库失败:', error)
688 showMessage('新增出库失败, 请重试', 'error') 695 showMessage('新增出库失败, 请重试', 'error')
...@@ -694,13 +701,13 @@ const handleSubmitAdd = async () => { ...@@ -694,13 +701,13 @@ const handleSubmitAdd = async () => {
694 const handlePageChange = (page: number) => { 701 const handlePageChange = (page: number) => {
695 if (page >= 1 && page <= totalPages.value) { 702 if (page >= 1 && page <= totalPages.value) {
696 pagination.pageNum = page 703 pagination.pageNum = page
697 - fetchOrders() 704 + fetchDeliveries()
698 } 705 }
699 } 706 }
700 707
701 const handlePageSizeChange = () => { 708 const handlePageSizeChange = () => {
702 pagination.pageNum = 1 709 pagination.pageNum = 1
703 - fetchOrders() 710 + fetchDeliveries()
704 } 711 }
705 712
706 const handleTableSearch = () => { 713 const handleTableSearch = () => {
...@@ -708,7 +715,7 @@ const handleTableSearch = () => { ...@@ -708,7 +715,7 @@ const handleTableSearch = () => {
708 } 715 }
709 716
710 const handleTableRefresh = () => { 717 const handleTableRefresh = () => {
711 - fetchOrders() 718 + fetchDeliveries()
712 } 719 }
713 720
714 const handleTableExport = () => { 721 const handleTableExport = () => {
...@@ -721,12 +728,12 @@ const handleTableViewToggle = () => { ...@@ -721,12 +728,12 @@ const handleTableViewToggle = () => {
721 728
722 const closeDetailDialog = () => { 729 const closeDetailDialog = () => {
723 showDetailDialog.value = false 730 showDetailDialog.value = false
724 - orderDetail.value = null 731 + deliveryDetail.value = null
725 } 732 }
726 733
727 // 生命周期 734 // 生命周期
728 onMounted(() => { 735 onMounted(() => {
729 - fetchOrders() 736 + fetchDeliveries()
730 }) 737 })
731 </script> 738 </script>
732 739
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.