zhouhui.jiang

update 订单、出库 、发票

...@@ -997,6 +997,47 @@ ...@@ -997,6 +997,47 @@
997 } 997 }
998 ``` 998 ```
999 999
1000 +### 7.9 获取所有产品
1001 +
1002 +**接口路径:** `GET /api/product/all`
1003 +
1004 +**功能描述:** 获取所有启用的产品信息,用于下拉选择
1005 +
1006 +**权限要求:**
1007 +
1008 +**请求参数:**
1009 +
1010 +**响应示例:**
1011 +```json
1012 +{
1013 + "code": 200,
1014 + "message": "操作成功",
1015 + "data": [
1016 + {
1017 + "productId": 1,
1018 + "productCode": "APL-IP15-128G-BK",
1019 + "productName": "iPhone 15|A2848|iPhone|黑色"
1020 + },
1021 + {
1022 + "productId": 2,
1023 + "productCode": "APL-IP15-256G-BK",
1024 + "productName": "iPhone 15|A2848|iPhone|黑色"
1025 + },
1026 + {
1027 + "productId": 3,
1028 + "productCode": "APL-IP15-128G-WH",
1029 + "productName": "iPhone 15|A2848|iPhone|白色"
1030 + }
1031 + ]
1032 +}
1033 +```
1034 +
1035 +**响应字段说明:**
1036 +- 只返回未删除且销售状态为在售的产品
1037 +- 按产品编码升序排列
1038 +- 产品名称格式:`产品名称|产品型号|产品类别|产品颜色`
1039 +- 主要用于订单管理等模块的下拉选择
1040 +
1000 ## 8. 经销商管理 (DealerInfoController) 1041 ## 8. 经销商管理 (DealerInfoController)
1001 1042
1002 ### 8.1 分页查询经销商列表 1043 ### 8.1 分页查询经销商列表
...@@ -1328,6 +1369,81 @@ ...@@ -1328,6 +1369,81 @@
1328 } 1369 }
1329 ``` 1370 ```
1330 1371
1372 +### 8.9 获取所有经销商
1373 +
1374 +**接口路径:** `GET /api/dealer/all`
1375 +
1376 +**功能描述:** 获取所有启用的经销商信息,用于下拉选择
1377 +
1378 +**权限要求:**
1379 +
1380 +**请求参数:**
1381 +
1382 +**响应示例:**
1383 +```json
1384 +{
1385 + "code": 200,
1386 + "message": "操作成功",
1387 + "data": [
1388 + {
1389 + "dealerId": 1,
1390 + "dealerCode": "DL001",
1391 + "dealerName": "北京经销商",
1392 + "creditCode": "91110000123456789X",
1393 + "dealerLevel": 1,
1394 + "region": "北京",
1395 + "contactPerson": "张三",
1396 + "contactPhone": "13800138000",
1397 + "cooperateStartDate": "2024-01-01",
1398 + "cooperateStatus": 1,
1399 + "businessLicenseUrl": "https://example.com/license.jpg",
1400 + "cooperationAgreementUrl": "https://example.com/agreement.pdf",
1401 + "qualificationAuditStatus": 2,
1402 + "auditOpinion": "审核通过",
1403 + "totalRebateAmount": 10000.00,
1404 + "usedRebateAmount": 5000.00,
1405 + "pendingRebateAmount": 5000.00,
1406 + "lastRebateUpdateTime": "2024-01-01 10:00:00",
1407 + "createBy": "admin",
1408 + "createTime": "2024-01-01 10:00:00",
1409 + "updateBy": "admin",
1410 + "updateTime": "2024-01-01 10:00:00",
1411 + "delFlag": "0"
1412 + },
1413 + {
1414 + "dealerId": 2,
1415 + "dealerCode": "DL002",
1416 + "dealerName": "上海经销商",
1417 + "creditCode": "91310000123456789Y",
1418 + "dealerLevel": 2,
1419 + "region": "上海",
1420 + "contactPerson": "李四",
1421 + "contactPhone": "13900139000",
1422 + "cooperateStartDate": "2024-02-01",
1423 + "cooperateStatus": 1,
1424 + "businessLicenseUrl": "https://example.com/license2.jpg",
1425 + "cooperationAgreementUrl": "https://example.com/agreement2.pdf",
1426 + "qualificationAuditStatus": 2,
1427 + "auditOpinion": "审核通过",
1428 + "totalRebateAmount": 15000.00,
1429 + "usedRebateAmount": 8000.00,
1430 + "pendingRebateAmount": 7000.00,
1431 + "lastRebateUpdateTime": "2024-02-01 10:00:00",
1432 + "createBy": "admin",
1433 + "createTime": "2024-02-01 10:00:00",
1434 + "updateBy": "admin",
1435 + "updateTime": "2024-02-01 10:00:00",
1436 + "delFlag": "0"
1437 + }
1438 + ]
1439 +}
1440 +```
1441 +
1442 +**响应字段说明:**
1443 +- 只返回未删除且合作状态为正常的经销商
1444 +- 按经销商编码升序排列
1445 +- 主要用于订单管理等模块的下拉选择
1446 +
1331 ## 数据字典 1447 ## 数据字典
1332 1448
1333 ### 销售状态(saleStatus) 1449 ### 销售状态(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:
......
...@@ -7,10 +7,30 @@ export {} ...@@ -7,10 +7,30 @@ export {}
7 7
8 declare module 'vue' { 8 declare module 'vue' {
9 export interface GlobalComponents { 9 export interface GlobalComponents {
10 + ElButton: typeof import('element-plus/es')['ElButton']
11 + ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
12 + ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
13 + ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
14 + ElDialog: typeof import('element-plus/es')['ElDialog']
15 + ElForm: typeof import('element-plus/es')['ElForm']
16 + ElFormItem: typeof import('element-plus/es')['ElFormItem']
17 + ElInput: typeof import('element-plus/es')['ElInput']
18 + ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
19 + ElOption: typeof import('element-plus/es')['ElOption']
20 + ElPagination: typeof import('element-plus/es')['ElPagination']
21 + ElRadio: typeof import('element-plus/es')['ElRadio']
22 + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
23 + ElSelect: typeof import('element-plus/es')['ElSelect']
24 + ElTable: typeof import('element-plus/es')['ElTable']
25 + ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
26 + ElTag: typeof import('element-plus/es')['ElTag']
10 Header: typeof import('./src/components/layout/Header.vue')['default'] 27 Header: typeof import('./src/components/layout/Header.vue')['default']
11 RouterLink: typeof import('vue-router')['RouterLink'] 28 RouterLink: typeof import('vue-router')['RouterLink']
12 RouterView: typeof import('vue-router')['RouterView'] 29 RouterView: typeof import('vue-router')['RouterView']
13 Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default'] 30 Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default']
14 SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default'] 31 SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default']
15 } 32 }
33 + export interface ComponentCustomProperties {
34 + vLoading: typeof import('element-plus/es')['ElLoadingDirective']
35 + }
16 } 36 }
......
...@@ -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.
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
5 <div class="search-row"> 5 <div class="search-row">
6 <div class="search-item"> 6 <div class="search-item">
7 <label>发票编号:</label> 7 <label>发票编号:</label>
8 - <input 8 + <input
9 - v-model="searchParams.invoiceNo" 9 + v-model="searchParams.invoiceNo"
10 - class="search-input" 10 + class="search-input"
11 placeholder="请输入发票编号" 11 placeholder="请输入发票编号"
12 /> 12 />
13 </div> 13 </div>
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
48 <div class="search-item"> 48 <div class="search-item">
49 <label>开票开始日期:</label> 49 <label>开票开始日期:</label>
50 <input 50 <input
51 - v-model="searchParams.invoiceStartDate" 51 + v-model="searchParams.invoiceStartDate"
52 class="search-input" 52 class="search-input"
53 type="date" 53 type="date"
54 /> 54 />
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
56 <div class="search-item"> 56 <div class="search-item">
57 <label>开票结束日期:</label> 57 <label>开票结束日期:</label>
58 <input 58 <input
59 - v-model="searchParams.invoiceEndDate" 59 + v-model="searchParams.invoiceEndDate"
60 class="search-input" 60 class="search-input"
61 type="date" 61 type="date"
62 /> 62 />
...@@ -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>
...@@ -508,6 +518,9 @@ ...@@ -508,6 +518,9 @@
508 <script setup lang="ts"> 518 <script setup lang="ts">
509 import { ref, reactive, computed, onMounted } from 'vue' 519 import { ref, reactive, computed, onMounted } from 'vue'
510 import { invoiceApi, type InvoiceInfo, type InvoiceQueryReq } from '../../api/invoice' 520 import { invoiceApi, type InvoiceInfo, type InvoiceQueryReq } from '../../api/invoice'
521 +import { dealerApi, type DealerInfo } from '../../api/dealer'
522 +import { productApi } from '../../api/product'
523 +import type { ProductSimpleRes } from '../../api/product'
511 524
512 // 响应式数据 525 // 响应式数据
513 const loading = ref(false) 526 const loading = ref(false)
...@@ -516,6 +529,8 @@ const showDialog = ref(false) ...@@ -516,6 +529,8 @@ const showDialog = ref(false)
516 const showDetailDialog = ref(false) 529 const showDetailDialog = ref(false)
517 const isEdit = ref(false) 530 const isEdit = ref(false)
518 const invoiceDetail = ref<InvoiceInfo | null>(null) 531 const invoiceDetail = ref<InvoiceInfo | null>(null)
532 +const dealerList = ref<DealerInfo[]>([])
533 +const productList = ref<ProductSimpleRes[]>([])
519 534
520 // 搜索参数 535 // 搜索参数
521 const searchParams = reactive({ 536 const searchParams = reactive({
...@@ -950,6 +965,48 @@ const handleTableViewToggle = () => { ...@@ -950,6 +965,48 @@ const handleTableViewToggle = () => {
950 showMessage('视图切换功能开发中...', 'warning') 965 showMessage('视图切换功能开发中...', 'warning')
951 } 966 }
952 967
968 +// 加载经销商列表
969 +const loadDealers = async () => {
970 + try {
971 + const response = await dealerApi.getAllDealers() as any
972 + if (response && response.data && Array.isArray(response.data)) {
973 + dealerList.value = response.data
974 + }
975 + } catch (error) {
976 + console.error('加载经销商列表失败:', error)
977 + showMessage('加载经销商列表失败', 'error')
978 + }
979 +}
980 +
981 +// 经销商选择变化处理
982 +const handleDealerChange = () => {
983 + const selectedDealer = dealerList.value.find(dealer => dealer.dealerName === formData.dealerName)
984 + if (selectedDealer) {
985 + formData.dealerCode = selectedDealer.dealerCode
986 + }
987 +}
988 +
989 +// 加载产品列表
990 +const loadProducts = async () => {
991 + try {
992 + const response = await productApi.getAllProducts() as any
993 + if (response && response.data && Array.isArray(response.data)) {
994 + productList.value = response.data
995 + }
996 + } catch (error) {
997 + console.error('加载产品列表失败:', error)
998 + showMessage('加载产品列表失败', 'error')
999 + }
1000 +}
1001 +
1002 +// 产品选择变化处理
1003 +const handleProductChange = (index: number) => {
1004 + const selectedProduct = productList.value.find((product: ProductSimpleRes) => product.productName === formData.invoiceItems[index].productName)
1005 + if (selectedProduct) {
1006 + formData.invoiceItems[index].productCode = selectedProduct.productCode
1007 + }
1008 +}
1009 +
953 const closeDialog = () => { 1010 const closeDialog = () => {
954 showDialog.value = false 1011 showDialog.value = false
955 } 1012 }
...@@ -962,6 +1019,8 @@ const closeDetailDialog = () => { ...@@ -962,6 +1019,8 @@ const closeDetailDialog = () => {
962 // 生命周期 1019 // 生命周期
963 onMounted(() => { 1020 onMounted(() => {
964 fetchOrders() 1021 fetchOrders()
1022 + loadDealers()
1023 + loadProducts()
965 }) 1024 })
966 </script> 1025 </script>
967 1026
......
This diff is collapsed. Click to expand it.