Showing
17 changed files
with
330 additions
and
47 deletions
| ... | @@ -1080,6 +1080,47 @@ Authorization: Bearer <JWT_TOKEN> | ... | @@ -1080,6 +1080,47 @@ Authorization: Bearer <JWT_TOKEN> |
| 1080 | } | 1080 | } |
| 1081 | ``` | 1081 | ``` |
| 1082 | 1082 | ||
| 1083 | +### 7.9 获取所有产品 | ||
| 1084 | + | ||
| 1085 | +**接口路径:** `GET /api/product/all` | ||
| 1086 | + | ||
| 1087 | +**功能描述:** 获取所有启用的产品信息,用于下拉选择 | ||
| 1088 | + | ||
| 1089 | +**权限要求:** 无 | ||
| 1090 | + | ||
| 1091 | +**请求参数:** 无 | ||
| 1092 | + | ||
| 1093 | +**响应示例:** | ||
| 1094 | +```json | ||
| 1095 | +{ | ||
| 1096 | + "code": 200, | ||
| 1097 | + "message": "操作成功", | ||
| 1098 | + "data": [ | ||
| 1099 | + { | ||
| 1100 | + "productId": 1, | ||
| 1101 | + "productCode": "APL-IP15-128G-BK", | ||
| 1102 | + "productName": "iPhone 15|A2848|iPhone|黑色" | ||
| 1103 | + }, | ||
| 1104 | + { | ||
| 1105 | + "productId": 2, | ||
| 1106 | + "productCode": "APL-IP15-256G-BK", | ||
| 1107 | + "productName": "iPhone 15|A2848|iPhone|黑色" | ||
| 1108 | + }, | ||
| 1109 | + { | ||
| 1110 | + "productId": 3, | ||
| 1111 | + "productCode": "APL-IP15-128G-WH", | ||
| 1112 | + "productName": "iPhone 15|A2848|iPhone|白色" | ||
| 1113 | + } | ||
| 1114 | + ] | ||
| 1115 | +} | ||
| 1116 | +``` | ||
| 1117 | + | ||
| 1118 | +**响应字段说明:** | ||
| 1119 | +- 只返回未删除且销售状态为在售的产品 | ||
| 1120 | +- 按产品编码升序排列 | ||
| 1121 | +- 产品名称格式:`产品名称|产品型号|产品类别|产品颜色` | ||
| 1122 | +- 主要用于订单管理等模块的下拉选择 | ||
| 1123 | + | ||
| 1083 | ## 8. 经销商管理 (DealerInfoController) | 1124 | ## 8. 经销商管理 (DealerInfoController) |
| 1084 | 1125 | ||
| 1085 | ### 8.1 分页查询经销商列表 | 1126 | ### 8.1 分页查询经销商列表 |
| ... | @@ -1411,6 +1452,81 @@ Authorization: Bearer <JWT_TOKEN> | ... | @@ -1411,6 +1452,81 @@ Authorization: Bearer <JWT_TOKEN> |
| 1411 | } | 1452 | } |
| 1412 | ``` | 1453 | ``` |
| 1413 | 1454 | ||
| 1455 | +### 8.9 获取所有经销商 | ||
| 1456 | + | ||
| 1457 | +**接口路径:** `GET /api/dealer/all` | ||
| 1458 | + | ||
| 1459 | +**功能描述:** 获取所有启用的经销商信息,用于下拉选择 | ||
| 1460 | + | ||
| 1461 | +**权限要求:** 无 | ||
| 1462 | + | ||
| 1463 | +**请求参数:** 无 | ||
| 1464 | + | ||
| 1465 | +**响应示例:** | ||
| 1466 | +```json | ||
| 1467 | +{ | ||
| 1468 | + "code": 200, | ||
| 1469 | + "message": "操作成功", | ||
| 1470 | + "data": [ | ||
| 1471 | + { | ||
| 1472 | + "dealerId": 1, | ||
| 1473 | + "dealerCode": "DL001", | ||
| 1474 | + "dealerName": "北京经销商", | ||
| 1475 | + "creditCode": "91110000123456789X", | ||
| 1476 | + "dealerLevel": 1, | ||
| 1477 | + "region": "北京", | ||
| 1478 | + "contactPerson": "张三", | ||
| 1479 | + "contactPhone": "13800138000", | ||
| 1480 | + "cooperateStartDate": "2024-01-01", | ||
| 1481 | + "cooperateStatus": 1, | ||
| 1482 | + "businessLicenseUrl": "https://example.com/license.jpg", | ||
| 1483 | + "cooperationAgreementUrl": "https://example.com/agreement.pdf", | ||
| 1484 | + "qualificationAuditStatus": 2, | ||
| 1485 | + "auditOpinion": "审核通过", | ||
| 1486 | + "totalRebateAmount": 10000.00, | ||
| 1487 | + "usedRebateAmount": 5000.00, | ||
| 1488 | + "pendingRebateAmount": 5000.00, | ||
| 1489 | + "lastRebateUpdateTime": "2024-01-01 10:00:00", | ||
| 1490 | + "createBy": "admin", | ||
| 1491 | + "createTime": "2024-01-01 10:00:00", | ||
| 1492 | + "updateBy": "admin", | ||
| 1493 | + "updateTime": "2024-01-01 10:00:00", | ||
| 1494 | + "delFlag": "0" | ||
| 1495 | + }, | ||
| 1496 | + { | ||
| 1497 | + "dealerId": 2, | ||
| 1498 | + "dealerCode": "DL002", | ||
| 1499 | + "dealerName": "上海经销商", | ||
| 1500 | + "creditCode": "91310000123456789Y", | ||
| 1501 | + "dealerLevel": 2, | ||
| 1502 | + "region": "上海", | ||
| 1503 | + "contactPerson": "李四", | ||
| 1504 | + "contactPhone": "13900139000", | ||
| 1505 | + "cooperateStartDate": "2024-02-01", | ||
| 1506 | + "cooperateStatus": 1, | ||
| 1507 | + "businessLicenseUrl": "https://example.com/license2.jpg", | ||
| 1508 | + "cooperationAgreementUrl": "https://example.com/agreement2.pdf", | ||
| 1509 | + "qualificationAuditStatus": 2, | ||
| 1510 | + "auditOpinion": "审核通过", | ||
| 1511 | + "totalRebateAmount": 15000.00, | ||
| 1512 | + "usedRebateAmount": 8000.00, | ||
| 1513 | + "pendingRebateAmount": 7000.00, | ||
| 1514 | + "lastRebateUpdateTime": "2024-02-01 10:00:00", | ||
| 1515 | + "createBy": "admin", | ||
| 1516 | + "createTime": "2024-02-01 10:00:00", | ||
| 1517 | + "updateBy": "admin", | ||
| 1518 | + "updateTime": "2024-02-01 10:00:00", | ||
| 1519 | + "delFlag": "0" | ||
| 1520 | + } | ||
| 1521 | + ] | ||
| 1522 | +} | ||
| 1523 | +``` | ||
| 1524 | + | ||
| 1525 | +**响应字段说明:** | ||
| 1526 | +- 只返回未删除且合作状态为正常的经销商 | ||
| 1527 | +- 按经销商编码升序排列 | ||
| 1528 | +- 主要用于订单管理等模块的下拉选择 | ||
| 1529 | + | ||
| 1414 | ## 数据字典 | 1530 | ## 数据字典 |
| 1415 | 1531 | ||
| 1416 | ### 销售状态(saleStatus) | 1532 | ### 销售状态(saleStatus) | ... | ... |
| ... | @@ -33,6 +33,13 @@ public class DealerInfoController { | ... | @@ -33,6 +33,13 @@ public class DealerInfoController { |
| 33 | return ApiRes.success(page); | 33 | return ApiRes.success(page); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | + @Operation(summary = "获取所有经销商", description = "获取所有启用的经销商信息,用于下拉选择") | ||
| 37 | + @GetMapping("/all") | ||
| 38 | + public ApiRes<List<DealerInfo>> getAllDealers() { | ||
| 39 | + List<DealerInfo> dealers = dealerInfoService.getAllDealers(); | ||
| 40 | + return ApiRes.success(dealers); | ||
| 41 | + } | ||
| 42 | + | ||
| 36 | @Operation(summary = "获取经销商详情", description = "根据经销商ID获取经销商详细信息") | 43 | @Operation(summary = "获取经销商详情", description = "根据经销商ID获取经销商详细信息") |
| 37 | @GetMapping("/{dealerId}") | 44 | @GetMapping("/{dealerId}") |
| 38 | @PreAuthorize("hasAuthority('dealer:detail')") | 45 | @PreAuthorize("hasAuthority('dealer:detail')") | ... | ... |
| ... | @@ -3,6 +3,7 @@ package com.apple.erp.controller; | ... | @@ -3,6 +3,7 @@ package com.apple.erp.controller; |
| 3 | import com.apple.erp.dto.ProductAddReq; | 3 | import com.apple.erp.dto.ProductAddReq; |
| 4 | import com.apple.erp.dto.ProductQueryReq; | 4 | import com.apple.erp.dto.ProductQueryReq; |
| 5 | import com.apple.erp.dto.ProductUpdateReq; | 5 | import com.apple.erp.dto.ProductUpdateReq; |
| 6 | +import com.apple.erp.dto.ProductSimpleRes; | ||
| 6 | import com.apple.erp.entity.ProductInfo; | 7 | import com.apple.erp.entity.ProductInfo; |
| 7 | import com.apple.erp.service.ProductInfoService; | 8 | import com.apple.erp.service.ProductInfoService; |
| 8 | import com.apple.erp.dto.response.ApiRes; | 9 | import com.apple.erp.dto.response.ApiRes; |
| ... | @@ -174,4 +175,15 @@ public class ProductInfoController { | ... | @@ -174,4 +175,15 @@ public class ProductInfoController { |
| 174 | return ApiRes.error("修改返利标识失败:" + e.getMessage()); | 175 | return ApiRes.error("修改返利标识失败:" + e.getMessage()); |
| 175 | } | 176 | } |
| 176 | } | 177 | } |
| 178 | + | ||
| 179 | + @Operation(summary = "获取所有产品", description = "获取所有启用的产品信息,用于下拉选择") | ||
| 180 | + @GetMapping("/all") | ||
| 181 | + public ApiRes<List<ProductSimpleRes>> getAllProducts() { | ||
| 182 | + try { | ||
| 183 | + List<ProductSimpleRes> products = productInfoService.getAllProducts(); | ||
| 184 | + return ApiRes.success(products); | ||
| 185 | + } catch (Exception e) { | ||
| 186 | + return ApiRes.error("获取产品列表失败:" + e.getMessage()); | ||
| 187 | + } | ||
| 188 | + } | ||
| 177 | } | 189 | } | ... | ... |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 产品简单信息响应DTO | ||
| 8 | + * 用于下拉选择等场景 | ||
| 9 | + * | ||
| 10 | + * @author Apple ERP Team | ||
| 11 | + * @since 2025-01-27 | ||
| 12 | + */ | ||
| 13 | +@Data | ||
| 14 | +@Schema(description = "产品简单信息") | ||
| 15 | +public class ProductSimpleRes { | ||
| 16 | + | ||
| 17 | + @Schema(description = "产品ID") | ||
| 18 | + private Long productId; | ||
| 19 | + | ||
| 20 | + @Schema(description = "产品编码") | ||
| 21 | + private String productCode; | ||
| 22 | + | ||
| 23 | + @Schema(description = "产品名称") | ||
| 24 | + private String productName; | ||
| 25 | +} |
| ... | @@ -69,4 +69,10 @@ public interface DealerInfoService extends IService<DealerInfo> { | ... | @@ -69,4 +69,10 @@ public interface DealerInfoService extends IService<DealerInfo> { |
| 69 | * @return 是否成功 | 69 | * @return 是否成功 |
| 70 | */ | 70 | */ |
| 71 | boolean updateDealerAuditStatus(Long dealerId, Integer qualificationAuditStatus, String auditOpinion); | 71 | boolean updateDealerAuditStatus(Long dealerId, Integer qualificationAuditStatus, String auditOpinion); |
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * 获取所有启用的经销商 | ||
| 75 | + * @return 经销商列表 | ||
| 76 | + */ | ||
| 77 | + List<DealerInfo> getAllDealers(); | ||
| 72 | } | 78 | } | ... | ... |
| ... | @@ -3,6 +3,7 @@ package com.apple.erp.service; | ... | @@ -3,6 +3,7 @@ package com.apple.erp.service; |
| 3 | import com.apple.erp.dto.ProductAddReq; | 3 | import com.apple.erp.dto.ProductAddReq; |
| 4 | import com.apple.erp.dto.ProductQueryReq; | 4 | import com.apple.erp.dto.ProductQueryReq; |
| 5 | import com.apple.erp.dto.ProductUpdateReq; | 5 | import com.apple.erp.dto.ProductUpdateReq; |
| 6 | +import com.apple.erp.dto.ProductSimpleRes; | ||
| 6 | import com.apple.erp.entity.ProductInfo; | 7 | import com.apple.erp.entity.ProductInfo; |
| 7 | import com.baomidou.mybatisplus.core.metadata.IPage; | 8 | import com.baomidou.mybatisplus.core.metadata.IPage; |
| 8 | import com.baomidou.mybatisplus.extension.service.IService; | 9 | import com.baomidou.mybatisplus.extension.service.IService; |
| ... | @@ -91,4 +92,11 @@ public interface ProductInfoService extends IService<ProductInfo> { | ... | @@ -91,4 +92,11 @@ public interface ProductInfoService extends IService<ProductInfo> { |
| 91 | * @return 是否存在 | 92 | * @return 是否存在 |
| 92 | */ | 93 | */ |
| 93 | boolean checkProductCodeExists(String productCode, Long productId); | 94 | boolean checkProductCodeExists(String productCode, Long productId); |
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * 获取所有启用的产品简单信息 | ||
| 98 | + * | ||
| 99 | + * @return 产品简单信息列表 | ||
| 100 | + */ | ||
| 101 | + List<ProductSimpleRes> getAllProducts(); | ||
| 94 | } | 102 | } | ... | ... |
| ... | @@ -234,4 +234,13 @@ public class DealerInfoServiceImpl extends ServiceImpl<DealerInfoMapper, DealerI | ... | @@ -234,4 +234,13 @@ public class DealerInfoServiceImpl extends ServiceImpl<DealerInfoMapper, DealerI |
| 234 | } | 234 | } |
| 235 | return count(queryWrapper) > 0; | 235 | return count(queryWrapper) > 0; |
| 236 | } | 236 | } |
| 237 | + | ||
| 238 | + @Override | ||
| 239 | + public List<DealerInfo> getAllDealers() { | ||
| 240 | + LambdaQueryWrapper<DealerInfo> queryWrapper = new LambdaQueryWrapper<>(); | ||
| 241 | + queryWrapper.eq(DealerInfo::getDelFlag, "0") // 未删除 | ||
| 242 | + .eq(DealerInfo::getCooperateStatus, 1) // 正常合作状态 | ||
| 243 | + .orderByAsc(DealerInfo::getDealerCode); // 按经销商编码排序 | ||
| 244 | + return list(queryWrapper); | ||
| 245 | + } | ||
| 237 | } | 246 | } | ... | ... |
| ... | @@ -3,6 +3,7 @@ package com.apple.erp.service.impl; | ... | @@ -3,6 +3,7 @@ package com.apple.erp.service.impl; |
| 3 | import com.apple.erp.dto.ProductAddReq; | 3 | import com.apple.erp.dto.ProductAddReq; |
| 4 | import com.apple.erp.dto.ProductQueryReq; | 4 | import com.apple.erp.dto.ProductQueryReq; |
| 5 | import com.apple.erp.dto.ProductUpdateReq; | 5 | import com.apple.erp.dto.ProductUpdateReq; |
| 6 | +import com.apple.erp.dto.ProductSimpleRes; | ||
| 6 | import com.apple.erp.entity.ProductInfo; | 7 | import com.apple.erp.entity.ProductInfo; |
| 7 | import com.apple.erp.mapper.ProductInfoMapper; | 8 | import com.apple.erp.mapper.ProductInfoMapper; |
| 8 | import com.apple.erp.service.ProductInfoService; | 9 | import com.apple.erp.service.ProductInfoService; |
| ... | @@ -192,4 +193,40 @@ public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper, Produ | ... | @@ -192,4 +193,40 @@ public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper, Produ |
| 192 | 193 | ||
| 193 | return queryWrapper; | 194 | return queryWrapper; |
| 194 | } | 195 | } |
| 196 | + | ||
| 197 | + @Override | ||
| 198 | + public List<ProductSimpleRes> getAllProducts() { | ||
| 199 | + LambdaQueryWrapper<ProductInfo> queryWrapper = new LambdaQueryWrapper<>(); | ||
| 200 | + queryWrapper.eq(ProductInfo::getDelFlag, "0") // 未删除 | ||
| 201 | + .eq(ProductInfo::getSaleStatus, 1) // 在售状态 | ||
| 202 | + .orderByAsc(ProductInfo::getProductCode); // 按产品编码排序 | ||
| 203 | + | ||
| 204 | + List<ProductInfo> products = list(queryWrapper); | ||
| 205 | + return products.stream() | ||
| 206 | + .map(product -> { | ||
| 207 | + ProductSimpleRes res = new ProductSimpleRes(); | ||
| 208 | + res.setProductId(product.getProductId()); | ||
| 209 | + res.setProductCode(product.getProductCode()); | ||
| 210 | + | ||
| 211 | + // 拼接产品名称:产品名称|产品型号|产品类别|产品颜色 | ||
| 212 | + StringBuilder productNameBuilder = new StringBuilder(); | ||
| 213 | + productNameBuilder.append(product.getProductName() != null ? product.getProductName() : ""); | ||
| 214 | + | ||
| 215 | + if (product.getProductModel() != null && !product.getProductModel().trim().isEmpty()) { | ||
| 216 | + productNameBuilder.append("|").append(product.getProductModel()); | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + if (product.getProductType() != null && !product.getProductType().trim().isEmpty()) { | ||
| 220 | + productNameBuilder.append("|").append(product.getProductType()); | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + if (product.getColor() != null && !product.getColor().trim().isEmpty()) { | ||
| 224 | + productNameBuilder.append("|").append(product.getColor()); | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + res.setProductName(productNameBuilder.toString()); | ||
| 228 | + return res; | ||
| 229 | + }) | ||
| 230 | + .collect(java.util.stream.Collectors.toList()); | ||
| 231 | + } | ||
| 195 | } | 232 | } | ... | ... |
| ... | @@ -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: apple_erp_app | 20 | + username: root |
| 21 | - password: StrongPassw0rd! | 21 | + password: MySQL@123 |
| 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: 123456 | 73 | + password: |
| 74 | database: 0 | 74 | database: 0 |
| 75 | timeout: 10000ms | 75 | timeout: 10000ms |
| 76 | lettuce: | 76 | lettuce: | ... | ... |
| ... | @@ -8,32 +8,19 @@ export {} | ... | @@ -8,32 +8,19 @@ export {} |
| 8 | declare module 'vue' { | 8 | declare module 'vue' { |
| 9 | export interface GlobalComponents { | 9 | export interface GlobalComponents { |
| 10 | ElButton: typeof import('element-plus/es')['ElButton'] | 10 | ElButton: typeof import('element-plus/es')['ElButton'] |
| 11 | - ElCard: typeof import('element-plus/es')['ElCard'] | ||
| 12 | ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] | 11 | ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] |
| 13 | - ElDescriptions: typeof import('element-plus/es')['ElDescriptions'] | ||
| 14 | - ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem'] | ||
| 15 | ElDialog: typeof import('element-plus/es')['ElDialog'] | 12 | ElDialog: typeof import('element-plus/es')['ElDialog'] |
| 16 | ElForm: typeof import('element-plus/es')['ElForm'] | 13 | ElForm: typeof import('element-plus/es')['ElForm'] |
| 17 | ElFormItem: typeof import('element-plus/es')['ElFormItem'] | 14 | ElFormItem: typeof import('element-plus/es')['ElFormItem'] |
| 18 | - ElIcon: typeof import('element-plus/es')['ElIcon'] | ||
| 19 | ElInput: typeof import('element-plus/es')['ElInput'] | 15 | ElInput: typeof import('element-plus/es')['ElInput'] |
| 20 | - ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | ||
| 21 | ElOption: typeof import('element-plus/es')['ElOption'] | 16 | ElOption: typeof import('element-plus/es')['ElOption'] |
| 22 | - ElPagination: typeof import('element-plus/es')['ElPagination'] | ||
| 23 | - ElRadio: typeof import('element-plus/es')['ElRadio'] | ||
| 24 | - ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] | ||
| 25 | ElSelect: typeof import('element-plus/es')['ElSelect'] | 17 | ElSelect: typeof import('element-plus/es')['ElSelect'] |
| 26 | ElTable: typeof import('element-plus/es')['ElTable'] | 18 | ElTable: typeof import('element-plus/es')['ElTable'] |
| 27 | ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | 19 | ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] |
| 28 | - ElTag: typeof import('element-plus/es')['ElTag'] | ||
| 29 | - ElText: typeof import('element-plus/es')['ElText'] | ||
| 30 | Header: typeof import('./src/components/layout/Header.vue')['default'] | 20 | Header: typeof import('./src/components/layout/Header.vue')['default'] |
| 31 | RouterLink: typeof import('vue-router')['RouterLink'] | 21 | RouterLink: typeof import('vue-router')['RouterLink'] |
| 32 | RouterView: typeof import('vue-router')['RouterView'] | 22 | RouterView: typeof import('vue-router')['RouterView'] |
| 33 | Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default'] | 23 | Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default'] |
| 34 | SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default'] | 24 | SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default'] |
| 35 | } | 25 | } |
| 36 | - export interface ComponentCustomProperties { | ||
| 37 | - vLoading: typeof import('element-plus/es')['ElLoadingDirective'] | ||
| 38 | - } | ||
| 39 | } | 26 | } | ... | ... |
| ... | @@ -162,5 +162,10 @@ export const dealerApi = { | ... | @@ -162,5 +162,10 @@ export const dealerApi = { |
| 162 | return api.post<ApiResponse>(`/dealer/${dealerId}/auditStatus`, null, { | 162 | return api.post<ApiResponse>(`/dealer/${dealerId}/auditStatus`, null, { |
| 163 | params: { qualificationAuditStatus, auditOpinion } | 163 | params: { qualificationAuditStatus, auditOpinion } |
| 164 | }) | 164 | }) |
| 165 | + }, | ||
| 166 | + | ||
| 167 | + // 获取所有经销商(用于下拉选择) | ||
| 168 | + getAllDealers: () => { | ||
| 169 | + return api.get<ApiResponse<DealerInfo[]>>('/dealer/all') | ||
| 165 | } | 170 | } |
| 166 | } | 171 | } | ... | ... |
| ... | @@ -55,6 +55,13 @@ export interface ProductInfo { | ... | @@ -55,6 +55,13 @@ export interface ProductInfo { |
| 55 | updateTime: string | 55 | updateTime: string |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | +// 产品简单信息接口(用于下拉选择) | ||
| 59 | +export interface ProductSimpleRes { | ||
| 60 | + productId: number | ||
| 61 | + productCode: string | ||
| 62 | + productName: string | ||
| 63 | +} | ||
| 64 | + | ||
| 58 | // 产品查询请求参数 | 65 | // 产品查询请求参数 |
| 59 | export interface ProductQueryReq { | 66 | export interface ProductQueryReq { |
| 60 | productCode?: string | 67 | productCode?: string |
| ... | @@ -157,5 +164,10 @@ export const productApi = { | ... | @@ -157,5 +164,10 @@ export const productApi = { |
| 157 | // 修改返利标识 | 164 | // 修改返利标识 |
| 158 | updateRebateFlag: (productId: number, rebateFlag: number) => { | 165 | updateRebateFlag: (productId: number, rebateFlag: number) => { |
| 159 | return api.post(`/product/${productId}/rebate`, null, { params: { rebateFlag } }) | 166 | return api.post(`/product/${productId}/rebate`, null, { params: { rebateFlag } }) |
| 167 | + }, | ||
| 168 | + | ||
| 169 | + // 获取所有产品(用于下拉选择) | ||
| 170 | + getAllProducts: () => { | ||
| 171 | + return api.get<ApiResponse<ProductSimpleRes[]>>('/product/all') | ||
| 160 | } | 172 | } |
| 161 | } | 173 | } | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -101,7 +101,7 @@ | ... | @@ -101,7 +101,7 @@ |
| 101 | <th>开票日期</th> | 101 | <th>开票日期</th> |
| 102 | <th>发票金额</th> | 102 | <th>发票金额</th> |
| 103 | <th>开票状态</th> | 103 | <th>开票状态</th> |
| 104 | - <th>上传时间</th> | 104 | + <th>开票时间</th> |
| 105 | <th>关联订单编号</th> | 105 | <th>关联订单编号</th> |
| 106 | <th>操作</th> | 106 | <th>操作</th> |
| 107 | </tr> | 107 | </tr> |
| ... | @@ -187,20 +187,20 @@ | ... | @@ -187,20 +187,20 @@ |
| 187 | <form @submit.prevent="handleSubmit"> | 187 | <form @submit.prevent="handleSubmit"> |
| 188 | <div class="form-row"> | 188 | <div class="form-row"> |
| 189 | <div class="form-item"> | 189 | <div class="form-item"> |
| 190 | - <label class="required">订单编号:</label> | 190 | + <label class="required">发票号码:</label> |
| 191 | <input | 191 | <input |
| 192 | - v-model="formData.orderNo" | 192 | + v-model="formData.invoiceNo" |
| 193 | class="form-input" | 193 | class="form-input" |
| 194 | - placeholder="请输入订单编号" | 194 | + placeholder="请输入发票号码" |
| 195 | required | 195 | required |
| 196 | /> | 196 | /> |
| 197 | </div> | 197 | </div> |
| 198 | <div class="form-item"> | 198 | <div class="form-item"> |
| 199 | - <label class="required">发票号码:</label> | 199 | + <label class="required">订单编号:</label> |
| 200 | <input | 200 | <input |
| 201 | - v-model="formData.invoiceNo" | 201 | + v-model="formData.orderNo" |
| 202 | class="form-input" | 202 | class="form-input" |
| 203 | - placeholder="请输入发票号码" | 203 | + placeholder="请输入订单编号" |
| 204 | required | 204 | required |
| 205 | /> | 205 | /> |
| 206 | </div> | 206 | </div> |
| ... | @@ -215,27 +215,28 @@ | ... | @@ -215,27 +215,28 @@ |
| 215 | /> | 215 | /> |
| 216 | </div> | 216 | </div> |
| 217 | <div class="form-item"> | 217 | <div class="form-item"> |
| 218 | - <label class="required">经销商编码:</label> | ||
| 219 | - <input | ||
| 220 | - v-model="formData.dealerCode" | ||
| 221 | - class="form-input" | ||
| 222 | - placeholder="请输入经销商编码" | ||
| 223 | - required | ||
| 224 | - /> | ||
| 225 | - </div> | ||
| 226 | - </div> | ||
| 227 | - <div class="form-row"> | ||
| 228 | - <div class="form-item"> | ||
| 229 | <label class="required">经销商名称:</label> | 218 | <label class="required">经销商名称:</label> |
| 230 | - <input | 219 | + <select |
| 231 | v-model="formData.dealerName" | 220 | v-model="formData.dealerName" |
| 232 | class="form-input" | 221 | class="form-input" |
| 233 | - placeholder="请输入经销商名称" | 222 | + @change="handleDealerChange" |
| 234 | required | 223 | required |
| 235 | - /> | 224 | + > |
| 225 | + <option value="">请选择经销商</option> | ||
| 226 | + <option | ||
| 227 | + v-for="dealer in dealerList" | ||
| 228 | + :key="dealer.dealerId" | ||
| 229 | + :value="dealer.dealerName" | ||
| 230 | + > | ||
| 231 | + {{ dealer.dealerName }} | ||
| 232 | + </option> | ||
| 233 | + </select> | ||
| 236 | </div> | 234 | </div> |
| 237 | </div> | 235 | </div> |
| 238 | <div class="form-row"> | 236 | <div class="form-row"> |
| 237 | + <input v-model="formData.dealerCode" type="hidden"/> | ||
| 238 | + </div> | ||
| 239 | + <div class="form-row"> | ||
| 239 | <div class="form-item"> | 240 | <div class="form-item"> |
| 240 | <label class="required">开票日期:</label> | 241 | <label class="required">开票日期:</label> |
| 241 | <input | 242 | <input |
| ... | @@ -292,6 +293,23 @@ | ... | @@ -292,6 +293,23 @@ |
| 292 | <div class="invoice-items-container"> | 293 | <div class="invoice-items-container"> |
| 293 | <div v-for="(item, index) in formData.invoiceItems" :key="index" class="invoice-item"> | 294 | <div v-for="(item, index) in formData.invoiceItems" :key="index" class="invoice-item"> |
| 294 | <div class="item-row-single"> | 295 | <div class="item-row-single"> |
| 296 | + <div class="form-item" style="flex: 1 1 200px; min-width: 150px;"> | ||
| 297 | + <label>产品名称:</label> | ||
| 298 | + <select | ||
| 299 | + v-model="item.productName" | ||
| 300 | + class="form-input" | ||
| 301 | + @change="handleProductChange(index)" | ||
| 302 | + > | ||
| 303 | + <option value="">请选择产品</option> | ||
| 304 | + <option | ||
| 305 | + v-for="product in productList" | ||
| 306 | + :key="product.productId" | ||
| 307 | + :value="product.productName" | ||
| 308 | + > | ||
| 309 | + {{ product.productName }} | ||
| 310 | + </option> | ||
| 311 | + </select> | ||
| 312 | + </div> | ||
| 295 | <div class="form-item" style="flex: 0 0 120px;"> | 313 | <div class="form-item" style="flex: 0 0 120px;"> |
| 296 | <label>产品编码:</label> | 314 | <label>产品编码:</label> |
| 297 | <input | 315 | <input |
| ... | @@ -300,14 +318,6 @@ | ... | @@ -300,14 +318,6 @@ |
| 300 | placeholder="产品编码" | 318 | placeholder="产品编码" |
| 301 | /> | 319 | /> |
| 302 | </div> | 320 | </div> |
| 303 | - <div class="form-item" style="flex: 1 1 200px; min-width: 150px;"> | ||
| 304 | - <label>产品名称:</label> | ||
| 305 | - <input | ||
| 306 | - v-model="item.productName" | ||
| 307 | - class="form-input" | ||
| 308 | - placeholder="产品名称" | ||
| 309 | - /> | ||
| 310 | - </div> | ||
| 311 | <div class="form-item" style="flex: 0 0 80px;"> | 321 | <div class="form-item" style="flex: 0 0 80px;"> |
| 312 | <label>数量:</label> | 322 | <label>数量:</label> |
| 313 | <input | 323 | <input |
| ... | @@ -460,8 +470,8 @@ | ... | @@ -460,8 +470,8 @@ |
| 460 | <table class="detail-table"> | 470 | <table class="detail-table"> |
| 461 | <thead> | 471 | <thead> |
| 462 | <tr> | 472 | <tr> |
| 463 | - <th>产品编码</th> | ||
| 464 | <th>产品名称</th> | 473 | <th>产品名称</th> |
| 474 | + <th>产品编码</th> | ||
| 465 | <th>数量</th> | 475 | <th>数量</th> |
| 466 | <th>单价</th> | 476 | <th>单价</th> |
| 467 | <th>金额</th> | 477 | <th>金额</th> |
| ... | @@ -471,8 +481,8 @@ | ... | @@ -471,8 +481,8 @@ |
| 471 | </thead> | 481 | </thead> |
| 472 | <tbody> | 482 | <tbody> |
| 473 | <tr v-for="item in invoiceDetail.invoiceItems" :key="item.invoiceItemId"> | 483 | <tr v-for="item in invoiceDetail.invoiceItems" :key="item.invoiceItemId"> |
| 474 | - <td>{{ item.productCode }}</td> | ||
| 475 | <td>{{ item.productName }}</td> | 484 | <td>{{ item.productName }}</td> |
| 485 | + <td>{{ item.productCode }}</td> | ||
| 476 | <td>{{ item.invoiceQty }}</td> | 486 | <td>{{ item.invoiceQty }}</td> |
| 477 | <td>{{ formatCurrency(item.unitPriceNoTax) }}</td> | 487 | <td>{{ formatCurrency(item.unitPriceNoTax) }}</td> |
| 478 | <td class="amount-text">{{ formatCurrency(item.amountNoTax) }}</td> | 488 | <td class="amount-text">{{ formatCurrency(item.amountNoTax) }}</td> |
| ... | @@ -509,6 +519,9 @@ | ... | @@ -509,6 +519,9 @@ |
| 509 | import { ref, reactive, computed, onMounted } from 'vue' | 519 | import { ref, reactive, computed, onMounted } from 'vue' |
| 510 | import { ElMessage, ElMessageBox } from 'element-plus' | 520 | import { ElMessage, ElMessageBox } from 'element-plus' |
| 511 | import { invoiceApi, type InvoiceInfo, type InvoiceQueryReq } from '../../api/invoice' | 521 | import { invoiceApi, type InvoiceInfo, type InvoiceQueryReq } from '../../api/invoice' |
| 522 | +import { dealerApi, type DealerInfo } from '../../api/dealer' | ||
| 523 | +import { productApi } from '../../api/product' | ||
| 524 | +import type { ProductSimpleRes } from '../../api/product' | ||
| 512 | 525 | ||
| 513 | // 响应式数据 | 526 | // 响应式数据 |
| 514 | const loading = ref(false) | 527 | const loading = ref(false) |
| ... | @@ -517,6 +530,8 @@ const showDialog = ref(false) | ... | @@ -517,6 +530,8 @@ const showDialog = ref(false) |
| 517 | const showDetailDialog = ref(false) | 530 | const showDetailDialog = ref(false) |
| 518 | const isEdit = ref(false) | 531 | const isEdit = ref(false) |
| 519 | const invoiceDetail = ref<InvoiceInfo | null>(null) | 532 | const invoiceDetail = ref<InvoiceInfo | null>(null) |
| 533 | +const dealerList = ref<DealerInfo[]>([]) | ||
| 534 | +const productList = ref<ProductSimpleRes[]>([]) | ||
| 520 | 535 | ||
| 521 | // 搜索参数 | 536 | // 搜索参数 |
| 522 | const searchParams = reactive({ | 537 | const searchParams = reactive({ |
| ... | @@ -1029,6 +1044,48 @@ const handleTableViewToggle = () => { | ... | @@ -1029,6 +1044,48 @@ const handleTableViewToggle = () => { |
| 1029 | showMessage('视图切换功能开发中...', 'warning') | 1044 | showMessage('视图切换功能开发中...', 'warning') |
| 1030 | } | 1045 | } |
| 1031 | 1046 | ||
| 1047 | +// 加载经销商列表 | ||
| 1048 | +const loadDealers = async () => { | ||
| 1049 | + try { | ||
| 1050 | + const response = await dealerApi.getAllDealers() as any | ||
| 1051 | + if (response && response.data && Array.isArray(response.data)) { | ||
| 1052 | + dealerList.value = response.data | ||
| 1053 | + } | ||
| 1054 | + } catch (error) { | ||
| 1055 | + console.error('加载经销商列表失败:', error) | ||
| 1056 | + showMessage('加载经销商列表失败', 'error') | ||
| 1057 | + } | ||
| 1058 | +} | ||
| 1059 | + | ||
| 1060 | +// 经销商选择变化处理 | ||
| 1061 | +const handleDealerChange = () => { | ||
| 1062 | + const selectedDealer = dealerList.value.find(dealer => dealer.dealerName === formData.dealerName) | ||
| 1063 | + if (selectedDealer) { | ||
| 1064 | + formData.dealerCode = selectedDealer.dealerCode | ||
| 1065 | + } | ||
| 1066 | +} | ||
| 1067 | + | ||
| 1068 | +// 加载产品列表 | ||
| 1069 | +const loadProducts = async () => { | ||
| 1070 | + try { | ||
| 1071 | + const response = await productApi.getAllProducts() as any | ||
| 1072 | + if (response && response.data && Array.isArray(response.data)) { | ||
| 1073 | + productList.value = response.data | ||
| 1074 | + } | ||
| 1075 | + } catch (error) { | ||
| 1076 | + console.error('加载产品列表失败:', error) | ||
| 1077 | + showMessage('加载产品列表失败', 'error') | ||
| 1078 | + } | ||
| 1079 | +} | ||
| 1080 | + | ||
| 1081 | +// 产品选择变化处理 | ||
| 1082 | +const handleProductChange = (index: number) => { | ||
| 1083 | + const selectedProduct = productList.value.find((product: ProductSimpleRes) => product.productName === formData.invoiceItems[index].productName) | ||
| 1084 | + if (selectedProduct) { | ||
| 1085 | + formData.invoiceItems[index].productCode = selectedProduct.productCode | ||
| 1086 | + } | ||
| 1087 | +} | ||
| 1088 | + | ||
| 1032 | const closeDialog = () => { | 1089 | const closeDialog = () => { |
| 1033 | showDialog.value = false | 1090 | showDialog.value = false |
| 1034 | } | 1091 | } |
| ... | @@ -1041,6 +1098,8 @@ const closeDetailDialog = () => { | ... | @@ -1041,6 +1098,8 @@ const closeDetailDialog = () => { |
| 1041 | // 生命周期 | 1098 | // 生命周期 |
| 1042 | onMounted(() => { | 1099 | onMounted(() => { |
| 1043 | fetchOrders() | 1100 | fetchOrders() |
| 1101 | + loadDealers() | ||
| 1102 | + loadProducts() | ||
| 1044 | }) | 1103 | }) |
| 1045 | </script> | 1104 | </script> |
| 1046 | 1105 | ... | ... |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment