jiaxing.zhou

Merge remote-tracking branch 'origin/master'

...@@ -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.