feat(sales): 添加客户交易详情中的付款金额字段
- 在CustomerTransactionsVo中添加付款金额字段用于显示客户往来付款累计金额
- 在CustomerTransactionsDetailsVo中添加付款金额字段用于详细交易信息展示
- 修改CustomerMapper.xml查询语句增加付款金额相关统计逻辑
- 从payment_record表中获取供应商收款金额并关联到供应商交易查询中
- 优化会议参会人员ID解析逻辑,解决多条历史记录导致的异常问题
- 更新油罐基础信息实体类的时间戳更新策略
- 为采购记录添加台账ID支持精确反显功能
- 实现出库批次管理和销售出库自动生成发货台账功能
- 添加备件领用时的出库流水记录功能
- 完善采购台账新增时的备件库存回写机制
- 优化库存查询和发货单管理的相关功能实现
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 徿¥ä»æ¬¾åæ¬¾æµæ°´è¡¨ |
| | | # 客æ·å¾æ¥å party_type=1 and direction=1 ä½ä¸ºã仿¬¾ãå |
| | | # ä¾åºå徿¥å party_type=2 and direction=2 ä½ä¸ºã忬¾ãå |
| | | drop table if exists payment_record; |
| | | create table payment_record |
| | | ( |
| | | id bigint auto_increment primary key, |
| | | party_type tinyint not null comment '徿¥æ¹ç±»å 1å®¢æ· 2ä¾åºå', |
| | | party_id bigint not null comment '客æ·idæä¾åºåid', |
| | | direction tinyint not null comment 'æ¹å 1仿¬¾ 2忬¾', |
| | | amount decimal(18, 2) not null default 0 comment 'éé¢', |
| | | record_date date null comment 'åçæ¥æ', |
| | | payment_method varchar(64) null comment '仿¬¾/忬¾æ¹å¼', |
| | | remark varchar(500) null comment '夿³¨', |
| | | tenant_id bigint null comment 'ç§æ·ID', |
| | | dept_id bigint null comment 'é¨é¨ID', |
| | | create_user int null comment 'å建人ID', |
| | | create_time datetime null comment 'å建æ¶é´', |
| | | update_user int null comment 'æ´æ°äººID', |
| | | update_time datetime null comment 'æ´æ°æ¶é´', |
| | | index idx_party (party_type, party_id), |
| | | index idx_direction (direction) |
| | | ); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #éè´ç³è¯·å表 |
| | | drop table if exists purchase_application; |
| | | create table purchase_application |
| | | ( |
| | | id bigint auto_increment primary key, |
| | | application_no varchar(50) not null comment 'ç³è¯·åå·', |
| | | supplier_id bigint null comment 'ä¾åºåid', |
| | | supplier_name varchar(100) null comment 'ä¾åºååç§°', |
| | | project_name varchar(100) null comment '项ç®åç§°', |
| | | sales_contract_no varchar(50) null comment 'éå®ååå·', |
| | | sales_ledger_id int null comment 'å
³èéå®å°è´¦ä¸»è¡¨ä¸»é®', |
| | | applicant_id bigint null comment 'ç³è¯·äººid', |
| | | applicant_name varchar(50) null comment 'ç³è¯·äººå§å', |
| | | apply_date date null comment 'ç³è¯·æ¥æ', |
| | | expected_arrival_date date null comment 'ææå°è´§æ¥æ', |
| | | contract_amount decimal(10, 2) null comment 'ç³è¯·éé¢ï¼å«ç¨æ»ä»·ï¼', |
| | | payment_method varchar(255) null comment '仿¬¾æ¹å¼', |
| | | remarks text null comment '夿³¨', |
| | | status tinyint not null default 0 comment 'ç¶æ 0è稿 1å·²çæè®¢å', |
| | | purchase_ledger_id bigint null comment '转订ååçæçéè´å°è´¦id', |
| | | convert_time datetime null comment 'è½¬è®¢åæ¶é´', |
| | | tenant_id bigint null comment 'ç§æ·ID', |
| | | dept_id bigint null comment 'é¨é¨ID', |
| | | create_user bigint null comment 'å建人ID', |
| | | create_time datetime null comment 'å建æ¶é´', |
| | | update_time datetime null comment 'æ´æ°æ¶é´', |
| | | index idx_application_no (application_no), |
| | | index idx_supplier_id (supplier_id), |
| | | index idx_purchase_ledger_id (purchase_ledger_id) |
| | | ); |
| | | |
| | | #éè´ç³è¯·äº§åæç»è¡¨ |
| | | drop table if exists purchase_application_product; |
| | | create table purchase_application_product |
| | | ( |
| | | id bigint auto_increment primary key, |
| | | purchase_application_id bigint not null comment 'éè´ç³è¯·åid', |
| | | product_id bigint null comment '产åid', |
| | | product_model_id bigint null comment '产åè§æ ¼id', |
| | | product_category varchar(100) null comment '产å大类', |
| | | specification_model varchar(100) null comment 'è§æ ¼åå·', |
| | | unit varchar(20) null comment 'åä½', |
| | | quantity decimal(18, 2) not null default 0 comment 'æ°é', |
| | | tax_rate decimal(5, 0) null comment 'ç¨ç', |
| | | tax_inclusive_unit_price decimal(18, 2) null comment 'å«ç¨åä»·', |
| | | tax_inclusive_total_price decimal(18, 2) null comment 'å«ç¨æ»ä»·', |
| | | tax_exclusive_total_price decimal(18, 2) null comment 'ä¸å«ç¨æ»ä»·', |
| | | invoice_type varchar(50) null comment 'å票类å', |
| | | is_checked tinyint(1) not null default 1 comment 'æ¯å¦æ¨éè´¨æ£', |
| | | remark varchar(255) null comment '夿³¨', |
| | | tenant_id bigint null comment 'ç§æ·ID', |
| | | dept_id bigint null comment 'é¨é¨ID', |
| | | create_user bigint null comment 'å建人ID', |
| | | create_time datetime null comment 'å建æ¶é´', |
| | | update_time datetime null comment 'æ´æ°æ¶é´', |
| | | index idx_purchase_application_id (purchase_application_id) |
| | | ); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- éè´å®¡æ ¸ èåæ¹å为 éè´ç³è¯·ï¼å»æå®¡æ ¸è¯ä¹ï¼ |
| | | -- å端éè¦åæ¥æ°å¢é¡µé¢ï¼procurementManagement/purchaseApplication/index |
| | | UPDATE sys_menu |
| | | SET menu_name = 'éè´ç³è¯·', |
| | | path = 'purchaseApplication', |
| | | component = 'procurementManagement/purchaseApplication/index' |
| | | WHERE menu_id = 2355; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å¤ä»¶å
³èäº§åæ°æ®ï¼äº§å大类 + è§æ ¼åå·ï¼ï¼ä½¿å¤ä»¶å¯èµ°éè´å°è´¦æç» |
| | | alter table spare_parts |
| | | add column product_id bigint null comment 'å
³è产å大类id', |
| | | add column product_model_id bigint null comment 'å
³è产åè§æ ¼id'; |
| | | |
| | | alter table spare_parts |
| | | add index idx_product_model_id (product_model_id); |
| | | |
| | | # å¤ä»¶åºå
¥åºæµæ°´ |
| | | drop table if exists spare_parts_record; |
| | | create table spare_parts_record |
| | | ( |
| | | id bigint auto_increment primary key, |
| | | spare_parts_id bigint not null comment 'å¤ä»¶id', |
| | | direction tinyint not null comment 'æ¹å 1å
¥åº 2åºåº', |
| | | quantity decimal(18, 2) not null default 0 comment 'æ°é', |
| | | source_type tinyint null comment 'æ¥æº 1éè´å
¥åº 2ç»´ä¿®é¢ç¨ 3ä¿å
»é¢ç¨', |
| | | source_id bigint null comment 'æ¥æºåæ®id', |
| | | source_no varchar(64) null comment 'æ¥æºåå·', |
| | | remark varchar(500) null comment '夿³¨', |
| | | tenant_id bigint null comment 'ç§æ·ID', |
| | | dept_id bigint null comment 'é¨é¨ID', |
| | | create_user int null comment 'å建人ID', |
| | | create_time datetime null comment 'å建æ¶é´', |
| | | update_user int null comment 'æ´æ°äººID', |
| | | update_time datetime null comment 'æ´æ°æ¶é´', |
| | | index idx_spare_parts_id (spare_parts_id), |
| | | index idx_source (source_type, source_id) |
| | | ); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # åºåºå°è´¦ä¸åè´§å°è´¦å
³èï¼æ²¹ååºåºå³åè´§ |
| | | # procurement_record_out å¢å åè´§åå
³èä¸åºåºæ¹æ¬¡ï¼æ£åºåå¿
éï¼ |
| | | alter table procurement_record_out |
| | | add column shipping_info_id bigint null comment 'èªå¨çæçåè´§å°è´¦id', |
| | | add column batch_no varchar(64) null comment 'åºåºæ¹æ¬¡ï¼æ£åºåç¨ï¼'; |
| | | |
| | | alter table procurement_record_out |
| | | add index idx_shipping_info_id (shipping_info_id); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å¨ç½å·ï¼å¨ç½åç±»ï¼å¸¦å
¥åºå å端èè°ææ¡£ |
| | | |
| | | æ´æ°æ¶é´ï¼2026-09-20 |
| | | éç¨çæ¬ï¼æ¬æ¬¡åç«¯åæ´å |
| | | 对åºéæ±ï¼éæ±æ¸
å第 12 æ¡ |
| | | |
| | | å®ç°æ¹å¼è¯´æï¼**䏿¯æ°å代ç ï¼èæ¯æä¸æ¸¸ `dev_New_pro` ä¸å·²æçå®ç°æ¿è¿æ¥**ââcherry-pick äº `d8c86797a`ï¼æ²¹åº/å¨ç½æ¨¡å + åºååºå
¥åºå段å
¨é¾è·¯ï¼å `50921bdc2` çåºåæåºä¿®å¤ï¼åè¡¥äº 2 å¤è¯¥æäº¤æ¼æçå±ç¤ºé¢ï¼åºå管çå表ãå¯¼åº Excelï¼ãå æ¤**åºè¡¨ååèåå端æ¤å卿¬åæ¯æ¯ç¼ºå¤±ç**ï¼èå 2353/2354 ç¹å¼ä¸ç´æ¥éï¼æ¬æ¬¡ä¸å¹¶ä¿®å¥½ã |
| | | |
| | | --- |
| | | |
| | | ## 1. åæ´èå´ |
| | | |
| | | | å
容 | å½±åé¢ | |
| | | | --- | --- | |
| | | | æ²¹åºä¿¡æ¯ãå¨ç½ä¿¡æ¯ä¸¤ä¸ªä¸»æ°æ®æ¨¡ååç«¯è¡¥é½ | èå 2353 æ²¹åºä¿¡æ¯ã2354 å¨ç½ä¿¡æ¯ | |
| | | | å¨ç½å· `tankNo` 带å
¥åºå | åºå管çå表ãåºå详æ
/æ¹å·æç»ãå¯¼åº Excelãå
¥åºç®¡çå表 | |
| | | | å
¥åºè®°å½æ°å¢æ²¹å/å¨ç½/ç©æµ/è¿ç£
ç 28 ä¸ªåæ®µ | æ°å¢å
¥åºè¡¨åãå
¥åºç®¡çå表 | |
| | | | åºåºè®°å½æ°å¢æ²¹å/å¨ç½/ç©æµ/è¿ç£
çåæ®µ | æ°å¢åºåºè¡¨åãåºåºè®°å½å表 | |
| | | | æ°å¢ãä»
å建åºåºè®°å½ãæ¥å£ | æ²¹ååºåºè¡¨å | |
| | | |
| | | > **å£å¾**ï¼éæ±æ¹ç¡®è®¤ãå¨ç½å·å°±æ¯å¨ç½åç±»ãï¼ä¸å¦å»ºåç±»åæ®µãå¨ç½çã大类ãå¨ `tank_info.category`ï¼å¨ç½å·æ¯ `tank_info.tank_no`ï¼åºåå页å±ç¤ºçæ¯åè
ã |
| | | |
| | | --- |
| | | |
| | | ## 2. åæï¼å
å»ºä¸»æ°æ®ï¼å¦åå¨ç½å·æ°¸è¿æ¯ç©º |
| | | |
| | | å¨ç½å·æ¯ä»**å
¥åºè®°å½**å¸¦åºæ¥çï¼`stock_inventory(product_model_id + batch_no)` â `stock_in_record(product_model_id + batch_no)` â `tank_no`ãæä»¥**å¿
é¡»å
æå¨ç½ä¸»æ°æ®ãä¸å
¥åºæ¶éäºå¨ç½**ï¼åºå页ææå¼ã |
| | | |
| | | ### 2.1 æ²¹åºä¿¡æ¯ |
| | | |
| | | åç¼ `/basic/oilDepot`ã |
| | | |
| | | | æ¥å£ | æ¹æ³ | 说æ | |
| | | | --- | --- | --- | |
| | | | `/basic/oilDepot/list` | GET | å页æ¥è¯¢ï¼è¿å `R.data.records` | |
| | | | `/basic/oilDepot/all` | GET | å
¨éï¼ä¾ä¸æéæ© | |
| | | | `/basic/oilDepot/{id}` | GET | 详æ
| |
| | | | `/basic/oilDepot/add` | POST | æ°å¢ | |
| | | | `/basic/oilDepot/update` | POST | ä¿®æ¹ï¼å¿
须带 `id` | |
| | | | `/basic/oilDepot/del` | DELETE | æ¹éå é¤ï¼body 为 id æ°ç» | |
| | | |
| | | åæ®µï¼`id`ã`depotName`ï¼æ²¹åºåç§°ï¼ã`chargePerson`ï¼è´è´£äººï¼ã`phone`ã`enableDate`ï¼å¯ç¨æ¥æ `yyyy-MM-dd`ï¼ã`company`ï¼æå±å
¬å¸ï¼ã |
| | | |
| | | ### 2.2 å¨ç½ä¿¡æ¯ |
| | | |
| | | åç¼ `/basic/tankInfo`ï¼æ¥å£å½¢æä¸æ²¹åºå®å
¨ä¸è´ï¼`list` / `all` / `{id}` / `add` / `update` / `del`ï¼ã |
| | | |
| | | åæ®µï¼`id`ã`tankNo`ï¼**å¨ç½å·**ï¼å¦ `01#`ï¼ã`category`ï¼å¤§ç±»ï¼å¦ `æåæ²¹`ï¼ã`oilProduct`ï¼æ²¹åï¼å¦ `æ´#0`ï¼ã`capacity`ï¼ç½å®¹ï¼ã`remaining`ï¼åºåä½é m³ï¼ã`tenantInfo`ï¼ç§å®¢ä¿¡æ¯ï¼ã |
| | | |
| | | **å端**ï¼å¨ç½ä¿¡æ¯è¡¨åçã大类ããæ²¹åã建议åæä¸æï¼å½ååºå
å¼ä¸º 大类=`æåæ²¹`ãæ²¹å=`æ´#0`/`æ´#-35`/`æ±½#92`/`æ±½#95`ï¼å¯ä¸äº§åè§æ ¼å£å¾å¯¹é½ååå®ï¼ã |
| | | |
| | | --- |
| | | |
| | | ## 3. æ°å¢å
¥åºï¼åæ®µä¸æ¥å£ï¼**æä¸ªåï¼å¿
ç**ï¼ |
| | | |
| | | ### 3.1 åªæ `addStockInRecordOnly` ä¼éä¼ æ²¹å/å¨ç½å段 |
| | | |
| | | | æ¥å£ | æ¯å¦éä¼ æ²¹å/å¨ç½/ç©æµ/è¿ç£
åæ®µ | |
| | | | --- | --- | |
| | | | `POST /stockInventory/addStockInRecordOnly` | **æ¯**ï¼28 ä¸ªåæ®µå
¨éä¼ ï¼å¹¶æ id 忥åå¡«æ²¹åºåç§°ãå¨ç½å·ï¼ | |
| | | | `POST /stockInventory/addstockInventory` | **å¦**ï¼åªå recordType/batchNo/productModelId/æ°é/夿³¨/é¢è¦æ°éï¼ä¼ äºè¿äºå段ä¼è¢«éé»ä¸¢å¼ï¼ | |
| | | |
| | | 两è
é½ä¼å䏿¡ `stock_in_record`ï¼åºå«æ¯ `addStockInRecordOnly` **ä¸å¨** `stock_inventory`ï¼ä»
å建记å½ï¼ï¼`addstockInventory` ä¼åæ¶å¢ååºåã**æ°å¢å
¥åºè¡¨åè¥è¦åä¸å¨ç½å·ï¼å¿
须走 `addStockInRecordOnly`ã** |
| | | |
| | | > è¿ä¸ç¹æ¯ä¸æ¸¸å®ç°çåæ ·è¡ä¸ºï¼æ¬æ¬¡æªæ¹å¨ãè¥ä¸å¡ä¸æ°å¢å
¥åºéè¦ãæ¢åæ²¹å/å¨ç½å段ãåå åºåãï¼éå¦è¡ç¡®è®¤è°ç¨é¡ºåºï¼å
建记å½åå åºåä¼å两æ¡è®°å½ï¼ï¼**å±éä¸éæ±æ¹ç¡®è®¤çèè°ç¹**ã |
| | | |
| | | ### 3.2 请æ±ä½å段ï¼`StockInventoryDto`ï¼ |
| | | |
| | | å¿
填沿ç¨åæï¼`productModelId`ã`qualitity`ï¼`batchNo` 为空æ¶å端æ `yyyyMMdd-产åç¼ç -åºå·` èªå¨çæã |
| | | |
| | | æ°å¢åæ®µï¼ |
| | | |
| | | | åç» | åæ®µ | ç±»å | 说æ | |
| | | | --- | --- | --- | --- | |
| | | | æ²¹åºå¨ç½ | `oilDepotId` | Long | æ²¹åº idï¼ä¼ äº id 使²¡ä¼ åç§°æ¶åç«¯åæ¥åå¡« | |
| | | | | `oilDepotName` | String | æ²¹åºåç§°ï¼å¯åªä¼ idï¼ | |
| | | | | `inboundCategory` | String | å
¥åºç±»å«ï¼èªè´å
¥åº / 代å¨å
¥åº | |
| | | | | `tankId` | Long | å¨ç½ idï¼ä¼ äº id 使²¡ä¼ ç½å·æ¶åç«¯åæ¥åå¡« | |
| | | | | `tankNo` | String | **å¨ç½å·**ï¼å¯åªä¼ `tankId`ï¼ | |
| | | | | `inboundTime` | String | å
¥åºæ¶é´ `yyyy-MM-dd HH:mm:ss` | |
| | | | | `oilProduct` | String | æ²¹åï¼æ±½#92 / æ±½#95 / æ´#0 / æ´#-35 | |
| | | | | `originalQuantity` | BigDecimal | ååæ°é(å¨) | |
| | | | å®¢æ· | `customerId` | Long | ä¼ äº id 使²¡ä¼ åç§°æ¶åç«¯åæ¥åå¡« | |
| | | | | `customerName` / `contactPerson` / `contactPhone` | String | 客æ·åç§° / 对æ¥äºº / çµè¯ | |
| | | | ç©æµ | `driverName` / `driverPhone` | String | 叿ºå§å / çµè¯ | |
| | | | | `escortName` / `escortPhone` | String | æ¼è¿åå§å / çµè¯ | |
| | | | | `truckPlateNo` / `trailerPlateNo` | String | 车çå· / 车æçå· | |
| | | | 叿²¹æä½ | `tankInspectionStatus` | String | 车ä½/é
å°æ£éªï¼æ£å¸¸ / å¼å¸¸ | |
| | | | | `unloadingCranePosition` | String | å¸è½¦é¹¤ä½ï¼1#æ¬è£
/ 2#æ¬è£
/ ä¸´æ¶æ³µ | |
| | | | | `density` | String | å¯åº¦ kg/L | |
| | | | | `unloadPhotos` | **æ°ç»** | 叿²¹å
³é®ç¯èä¸è½¦è¾å
³é®ä½ç½®æç
§ | |
| | | | è¿ç£
| `grossWeight` / `tareWeight` / `netWeight` | BigDecimal | æ¯é / ç®é / åé(å¨) | |
| | | | | `lossQuantity` | BigDecimal | äºé(å¨) | |
| | | | | `actualVolume` | BigDecimal | å®é
å
¥åºä½ç§¯(å) | |
| | | | | `poundPhotos` | **æ°ç»** | ç£
åä¸ä¼ | |
| | | |
| | | **ç
§çåæ®µçå
¥å/åºåå½¢æä¸ä¸è´ï¼å¡å¿
注æ**ï¼ |
| | | |
| | | - **å
¥å**ä¼ æ°ç»ï¼åç«¯ç¨ `JSON.toJSONString` ååºï¼ |
| | | - **åºå**æ¯ JSON **å符串**ï¼`"[{\"uidFilename\":...}]"`ï¼ï¼å端é `JSON.parse` å忏²æ |
| | | - åºåéç URL ä¼è¿æï¼ç¾å 2 å°æ¶ï¼ï¼æä»¥**æ¹å·æç»æ¥å£è¿ååä¼éæ°ç¾å**ï¼è§ 4.2ï¼ï¼å
¶ä»æ¥å£è¥ç´æ¥è¿ååºéçæ§ä¸²ï¼å¾çå¯è½å 载失败 |
| | | |
| | | --- |
| | | |
| | | ## 4. åå¤å±ç¤ºè½ç¹ |
| | | |
| | | ### 4.1 åºå管çå表 ââ `GET /stockInventory/pageListCombinedStockInventory` |
| | | |
| | | è¿å `R.data.records`ãæ¬æ¬¡æ°å¢åï¼**åªå¤ä¸å°ï¼åæå段ä¸å**ï¼ï¼ |
| | | |
| | | | åæ®µ | 说æ | |
| | | | --- | --- | |
| | | | `tankNo` | **å¨ç½å·**ï¼æ¬æ¬¡éæ±ä¸»åæ®µï¼ | |
| | | | `oilProduct` | æ²¹å | |
| | | | `tankInspectionStatus` / `unloadingCranePosition` | 车ä½é
å°æ£éª / å¸è½¦é¹¤ä½ | |
| | | | `density` | å¯åº¦ | |
| | | | `grossWeight` / `tareWeight` / `netWeight` / `lossQuantity` / `actualVolume` | æ¯é/ç®é/åé/äºé/å®é
ä½ç§¯ | |
| | | | `unloadPhotos` / `poundPhotos` | 叿²¹æç
§ / ç£
åï¼JSON åç¬¦ä¸²ï¼ | |
| | | |
| | | > 该æ¥å£**ä¸è¿å** `oilDepotName`ã`inboundCategory`ã`inboundTime`ã`tankId`ââè¦è¿äºè¯·ç¨ 4.2 ç详æ
æ¥å£ã |
| | | > |
| | | > **åæ°å£å¾**ï¼æ¬é¡µæ**è§æ ¼åå·**èåï¼ä¸è¡ä¸ä¸ªè§æ ¼ï¼ï¼æä»¥ `tankNo` åçæ¯è¯¥è§æ ¼**æè¿ä¸æ¬¡å
¥åºè®°å½**çå¨ç½ãåè§æ ¼åå¸å¨å¤ä¸ªç½æ¶åªæ¾ç¤ºä¸ä¸ªï¼è¯¦è§ç¬¬ 6 èéå¶ã |
| | | |
| | | ### 4.2 åºå详æ
/ æ¹å·æç» ââ `GET /stockInventory/getBatchNoQty` |
| | | |
| | | æ `productModelId`ï¼å¯é `productId`ï¼æ¥ï¼è¿å `R.data.records`ãè¿ä¸é¡µæ¯**ææ¹æ¬¡ç²¾ç¡®å
³è**çï¼å¨ç½å·åç¡®ã |
| | | |
| | | æ°å¢å
¥åºä¾§åï¼ |
| | | |
| | | | åæ®µ | 说æ | |
| | | | --- | --- | |
| | | | `tankNo` | **å¨ç½å·** | |
| | | | `oilDepotName` / `oilProduct` / `inboundCategory` / `inboundTime` | æ²¹åºåç§° / æ²¹å / å
¥åºç±»å« / å
¥åºæ¶é´ | |
| | | | `tankInspectionStatus` / `unloadingCranePosition` / `density` | æ£éª / é¹¤ä½ / å¯åº¦ | |
| | | | `grossWeight` / `tareWeight` / `netWeight` / `lossQuantity` / `actualVolume` | è¿ç£
æ°æ® | |
| | | | `unloadPhotos` / `poundPhotos` | JSON å符串ï¼**已鿰ç¾å URLï¼å¯ç´æ¥ç¨** | |
| | | |
| | | æ°å¢åºåºä¾§åï¼åè¯¥è§æ ¼**ææ°ä¸æ¡åºåºè®°å½**ï¼ç»ä¸ `out` åç¼ï¼ï¼ |
| | | |
| | | `outCategory`ï¼åºåºç±»å«ï¼å®¢å/代å¨/éå®ï¼ã`outDate`ã`outTonnage`ã`outCustomerName`ã`outContactPerson`ã`outContactPhone`ã`outOilDepotName`ã`outTankNo`ã`outOilProduct`ã`outDensity`ã`outDriverName`ã`outDriverPhone`ã`outEscortName`ã`outEscortPhone`ã`outTruckPlateNo`ã`outTrailerPlateNo`ã`outGrossWeight`ã`outTareWeight`ã`outNetWeight`ã`outLossQuantity`ã`outActualVolume`ã`outPoundPhotos` |
| | | |
| | | å¦æä¸¤ä¸ªæªå åç¼ãä½åå±åºåºä¾§çåï¼`loadingInspectionStatus`ï¼è£
车æ£éªï¼ã`loadingCranePosition`ï¼è£
车鹤ä½ï¼ã`loadingPhotos`ï¼è£
车æç
§ï¼JSON å符串ï¼åæ ·å·²éç¾ URLï¼ã |
| | | |
| | | **æåºè¡ä¸ºåæ´ï¼`50921bdc2`ï¼**ï¼æåºç± `order by batch_no` æ¹ä¸º **`order by MAX(update_time) desc`**ï¼å³**ææ´æ°æ¶é´ååº**ãå端è¥åæ¬ä¾èµæ¹å·é¡ºåºå±ç¤ºï¼éè¦æ¹ææ¾å¼æåºææ¥åæ°é¡ºåºã |
| | | |
| | | ### 4.3 å¯¼åº Excel ââ `POST /stockInventory/exportStockInventory` |
| | | |
| | | å¯¼åºæä»¶**æ«å°¾æ°å¢ãå¨ç½å·ãå**ã |
| | | |
| | | - 该åå¨åç«¯æ æ³¨ä¸ºãä»
导åºãï¼æä»¥**ä¸è½½å¯¼å
¥æ¨¡æ¿ï¼`POST /stockInventory/downloadStockInventory`ï¼ä¸ä¼åºç°å¨ç½å·å** |
| | | - **导å
¥ä¸æ¯æå¡«å¨ç½å·**ï¼å¯¼å
¥ä»æã产ååç§° | è§æ ¼ãå¹é
产åï¼å¨ç½å·ä¸åä¸è§£æãè¥ä¸å¡éè¦æ¹é导å
¥å¨ç½å·ï¼é妿鿱 |
| | | |
| | | ### 4.4 å
¥åºç®¡çå表 ââ `GET /stockInRecord/listPage` |
| | | |
| | | åºå±ç¨ `select sir.*`ï¼æä»¥æ¬æ¬¡å
¥åºè®°å½æ°å¢çåæ®µ**å
¨é¨èªå¨å¸¦åº**ï¼åç«¯ç´æ¥ç¨å³å¯ï¼ |
| | | |
| | | `tankNo`ã`tankId`ã`oilDepotId`ã`oilDepotName`ã`inboundCategory`ã`inboundTime`ã`oilProduct`ã`originalQuantity`ã`customerId`ã`customerName`ã`contactPerson`ã`contactPhone`ã`driverName`ã`driverPhone`ã`escortName`ã`escortPhone`ã`truckPlateNo`ã`trailerPlateNo`ã`tankInspectionStatus`ã`unloadingCranePosition`ã`density`ã`unloadPhotos`ã`grossWeight`ã`tareWeight`ã`netWeight`ã`lossQuantity`ã`actualVolume`ã`poundPhotos` |
| | | |
| | | ### 4.5 é带ï¼åºåºè®°å½å表 ââ `GET /stockOutRecord/listPage` |
| | | |
| | | åæ · `sor.*`ï¼åºåºä¾§æ°å¢å段èªå¨å¸¦åºï¼`tankNo`ã`tankId`ã`oilDepotId`ã`oilDepotName`ã`outCategory`ã`outDate`ã`outTonnage`ã`oilProduct`ã`customerId`ã`customerName`ã`contactPerson`ã`contactPhone`ã`loadingInspectionStatus`ã`loadingCranePosition`ã`loadingPhotos`ã`density`ã`grossWeight`ã`tareWeight`ã`netWeight`ã`lossQuantity`ã`actualVolume`ã`poundPhotos`ã`driverName`ã`driverPhone`ã`escortName`ã`escortPhone`ã`truckPlateNo`ã`trailerPlateNo` |
| | | |
| | | --- |
| | | |
| | | ## 5. æ°å¢æ¥å£ï¼ä»
å建油ååºåºè®°å½ |
| | | |
| | | ``` |
| | | POST /stockInventory/addOilOutRecordOnly |
| | | ``` |
| | | |
| | | 请æ±ä½ä¸º `StockOutRecordDto`ï¼åæ®µä¸ 4.5 ååºçåºåºä¾§å段ä¸è´ï¼æ°å¢å段å表ï¼ãè¡ä¸ºï¼ |
| | | |
| | | - `stockOutNum` ç± `outTonnage` åå¡«ï¼`approvalStatus` ç½® `0`ï¼å¾
审æ¹ï¼ |
| | | - `recordType` ç±å端åºå®ä¸ºèªå®ä¹åºåºç±»åï¼`recordId` åºå® `0`ï¼**å端ä¸è¦ä¼ ** |
| | | - **ä¸è°æ´åºå**ï¼åªè½ä¸æ¡åºåºè®°å½ |
| | | |
| | | --- |
| | | |
| | | ## 6. å·²ç¥éå¶ï¼èè°åéç¥æ
ï¼ |
| | | |
| | | 1. **åºå管çå表çå¨ç½å·æ¯ãè§æ ¼çº§ãèéãæ¹æ¬¡çº§ã**ã该页ä¸è¡ä¸ä¸ªè§æ ¼ï¼`batch_no` æ¯ `GROUP_CONCAT`ï¼æä»¥å¨ç½å·åªè½åè¯¥è§æ ¼æè¿ä¸æ¡å
¥åºè®°å½çå¼ã**åä¸è§æ ¼åå¸å¨å¤ä¸ªå¨ç½æ¶ï¼å表åªä¼æ¾ç¤ºæè¿å
¥åºçé£ä¸ªç½**ãè¦ææ¹æ¬¡çåç¡®çç½ï¼ç¨ 4.2 çæ¹å·æç»ã |
| | | 2. **ç°ææ°æ®å¤§å¤æ¯ç©ºç**ãå½ååºå
12 æ¡å
¥åºè®°å½éåªæ 3 æ¡æ `tank_no`ï¼åå²å
¥åºæªééï¼ãæä»¥èè°æ¶åºåå页大é¨åè¡çå¨ç½å·ä¼æ¯ç©ºââ**è¿æ¯æ°æ®ç°ç¶ï¼ä¸æ¯æ¥å£é®é¢**ãéè¦ä¸å¡è¡¥å½ï¼æéæ°èµ°ä¸é带å¨ç½çå
¥åºã |
| | | 3. 导åºçå¨ç½å·åä½ç½®å¨**æå**ï¼å¤æ³¨ä¹åï¼ï¼è¥å端/ä¸å¡æå顺åºçº¦å®é注æã |
| | | 4. `addstockInventory` ä¸éä¼ æ²¹å/å¨ç½å段ï¼è§ 3.1ï¼ï¼è¿æ¯æ¬æ¬¡æå®¹æè¸©çç¹ã |
| | | 5. å端çé¢å±æ æ³å¨æ¬å端ä»åºéªè¯ï¼æ `web/`ã`ui/`ï¼ï¼ä»¥ä¸æ¸
åéå端ä»åºé
åæ§è¡ã |
| | | |
| | | --- |
| | | |
| | | ## 7. èè°èªæ¥æ¸
å |
| | | |
| | | - [ ] èå 2353 æ²¹åºä¿¡æ¯ã2354 å¨ç½ä¿¡æ¯è½æå¼å¹¶å¢å æ¹æ¥ï¼æ¤åå端缺失ï¼ç¹å¼æ¥éï¼ |
| | | - [ ] å¨ç½ä¿¡æ¯è½ä¿å `tankNo`ã`category`ã`oilProduct`ã`capacity`ã`remaining` |
| | | - [ ] æ°å¢å
¥åºè¡¨åï¼æ²¹åº/å¨ç½åæä¸æï¼`/basic/oilDepot/all`ã`/basic/tankInfo/all`ï¼ï¼éå¨ç½å `tankNo` èªå¨å¸¦åº |
| | | - [ ] æ°å¢å
¥åºæäº¤åï¼å
¥åºç®¡çåè¡¨è¯¥è¡ `tankNo` æå¼ |
| | | - [ ] èµ°çæ¯ `addStockInRecordOnly`ï¼ç¨ `addstockInventory` æäº¤å `tankNo` 为空 ââ ç¨æ¥åå确认 3.1ï¼ |
| | | - [ ] åºå管çå表åºç°ãå¨ç½å·ãåï¼ä¸ä¸åè§æ ¼æè¿ä¸æ¬¡å
¥åºçç½ä¸è´ |
| | | - [ ] åºå详æ
/æ¹å·æç»åºç°ãå¨ç½å·ãï¼ä¸**åä¸è§æ ¼ä¸åæ¹æ¬¡è½æ¾ç¤ºä¸åç½** |
| | | - [ ] åºå详æ
æåºä¸ºæ´æ°æ¶é´ååº |
| | | - [ ] 导åºåºå Excel æ«å°¾æãå¨ç½å·ãåä¸æå¼ |
| | | - [ ] ä¸è½½å¯¼å
¥æ¨¡æ¿**ä¸å«**å¨ç½å·åï¼ç¨è¯¥æ¨¡æ¿å¯¼å
¥ä»è½æã产ååç§°|è§æ ¼ãå¹é
æå |
| | | - [ ] ç
§çåæ®µï¼ä¸ä¼ æ¶ä¼ æ°ç»ï¼åæ¾æ¶è½æ£ç¡®è§£æ JSON å符串ï¼å¾çå¯æå¼ |
| | | - [ ] åºåºè®°å½å表 `/stockOutRecord/listPage` è½åå° `tankNo` çåºåºä¾§æ°å段 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # åºåºå³åè´§ / 徿¥ä»æ¬¾å款 / å¤ä»¶æµæ°´ å端èè°ææ¡£ |
| | | |
| | | æ´æ°æ¶é´ï¼2026-09-20 |
| | | éç¨çæ¬ï¼æ¬æ¬¡åç«¯åæ´å |
| | | 对åºéæ±ï¼éæ±æ¸
å第 11ã13ã14ã15 æ¡ |
| | | |
| | | --- |
| | | |
| | | ## 1. åæ´èå´ |
| | | |
| | | | éæ± | å
容 | å½±åé¢ | |
| | | | --- | --- | --- | |
| | | | 13 | æ²¹å**éå®åºåºå³åè´§**ï¼åºåºæ¶èªå¨çæä¸å¼ ãå·²åè´§ãåè´§å°è´¦ï¼ä¸åèµ·åè´§å®¡æ¹ | åºåºè¡¨åãåºåºå°è´¦å表 | |
| | | | 11 | 客æ·/ä¾åºå徿¥å**æ°å¢ä¸ä¸ªä¸å¡å段**ï¼å®¢æ·ã仿¬¾ããä¾åºåã忬¾ãï¼å¹¶å¯æå·¥ç»´æ¤æµæ°´ | 客æ·å¾æ¥é¡µãä¾åºå徿¥é¡µ | |
| | | | 15 | å¤ä»¶**å
³è产åè§æ ¼**ï¼éè´å
¥åºèªå¨ç´¯å å¤ä»¶åºåï¼å¹¶æ°å¢å¤ä»¶åºå
¥åºæµæ°´ | å¤ä»¶ç»´æ¤é¡µãå¤ä»¶æµæ°´é¡µ | |
| | | | 14 | æ°å¢å
¥åºééè´è®¢åå**ç²¾ç¡®åæ¾æç»**ï¼ä¿®å¤å端 SQLï¼ | æ°å¢å
¥åºé¡µ | |
| | | |
| | | DDL å·²æ§è¡ï¼`doc/20260920_stock_out_shipping_link.sql`ã`doc/20260920_create_payment_record.sql`ã`doc/20260920_spare_parts_product_and_record.sql`ï¼ã |
| | | |
| | | --- |
| | | |
| | | ## 2. éæ± 13ï¼åºåºå³åè´§ |
| | | |
| | | ### 2.1 è§å说æ |
| | | |
| | | - ä»
**`type = 2`ï¼éå®åºåºï¼** 触åèªå¨åè´§ï¼`type = 1` éè´åºåºã`type = 3` èªå®ä¹åºåºä¸åå½±åã |
| | | - èªå¨çæçåè´§å°è´¦ `status` ç´æ¥ä¸º **`å·²åè´§`**ï¼ä¸è¿å
¥å®¡æ¹ï¼ä¹ä¸åºç°å¨ãå¾
å®¡æ ¸ãå表ã |
| | | - åè´§åå·ç±å端çæï¼æ ¼å¼ `SH` + `yyyyMMdd` + 彿¥ 3 使µæ°´ï¼å¦ `SH20260920001`ã |
| | | - **åä¸éå®äº§åå
è®¸åæ¹å¤æ¬¡åè´§**ï¼æ¯å¼ åºåºå对åºä¸å¼ æ°çåè´§åï¼åèªæ£å䏿¬¡åºåã |
| | | - åºåºåä¸åè´§åéè¿ `procurement_record_out.shipping_info_id` å
³èï¼**å é¤åºåºåä¼è¿å¸¦å²éåè´§å并忻已æ£åºå**ã |
| | | |
| | | ### 2.2 åºåºæ¥å£ï¼æ°å¢å¿
å¡« `batchNo` |
| | | |
| | | `POST /stockmanagement/stockout` |
| | | |
| | | | åæ®µ | ç±»å | å¿
å¡« | 说æ | |
| | | | --- | --- | --- | --- | |
| | | | `type` | Integer | æ¯ | `2` éå®åºåºæ¶æè§¦åèªå¨åè´§ | |
| | | | `batchNo` | String | **éå®åºåºå¿
å¡«** | åºåºæ¹æ¬¡ã为空æ¶å端æãè¯·éæ©åºåºæ¹æ¬¡ã | |
| | | | `salesLedgerProductId` | Long | éå®åºåºå¿
å¡« | éè½åæ¥å° `sales_ledger_product` ä¸ `type = 1`ï¼éå®ï¼ | |
| | | | `productModelId` | Long | æ¯ | è§æ ¼åå· id | |
| | | | `quantity` | String | æ¯ | åºåºæ°é | |
| | | | `id` | Long | æ¯ | 对åºç `procurement_record_storage` æç» id | |
| | | |
| | | **æ¹æ¬¡ä¸å
许ç空**ï¼ç³»ç»æ å
è¿å
åºï¼åºåææ¹æ¬¡ç®¡çï¼å端æ `productModelId + batchNo` æ£åï¼æ¹æ¬¡ä¸å¯¹ä¼æ¥ãåºåè®°å½ä¸åå¨ãã |
| | | |
| | | ### 2.3 æ°å¢ï¼æ¹æ¬¡å¯éå表 |
| | | |
| | | ``` |
| | | GET /stockmanagement/batchNoList?productModelId={è§æ ¼åå·id} |
| | | ``` |
| | | |
| | | ååºï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "data": [ |
| | | { "productModelId": 405, "batchNo": "20260915-001-001", "availableQuantity": 33.00 }, |
| | | { "productModelId": 405, "batchNo": "CG20260825001-192", "availableQuantity": 10000.00 } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | - `availableQuantity` = åºåé â é宿°éï¼å·²è¿æ»¤æ ⤠0 çæ¹æ¬¡ã |
| | | - å端å¨åºåºè¡¨åéæ©è§æ ¼åå·åè°ç¨ï¼æ `batchNo` åæä¸æï¼å¹¶æå¯ç¨éå±ç¤ºç»ç¨æ·ã |
| | | |
| | | ### 2.4 åºåºå°è´¦å表æ°å¢åè´§åå· |
| | | |
| | | `GET /stockmanagement/listPageByProduct` è¿åä½å¨åæå段åºç¡ä¸**æ°å¢**ï¼ |
| | | |
| | | | åæ®µ | 说æ | |
| | | | --- | --- | |
| | | | `shippingNo` | èªå¨çæçåè´§åå·ï¼å¦ `SH20260920001`ï¼ééå®åºåºä¸º `null` | |
| | | |
| | | > `GET /stockmanagement/listPage`ï¼éè´åºåº type=1ï¼**ä¸è¿å**è¯¥åæ®µï¼éè´åºåºä¸åè´§ã |
| | | |
| | | ### 2.5 å é¤åºåºå |
| | | |
| | | `POST /stockmanagement/del` è¡ä¸ºå·²åæ´ï¼è¥è¯¥åºåºåå·²èªå¨çæåè´§åï¼å端ä¼å
å é¤åè´§å䏿ç»ãåæ»åºåï¼åå é¤åºåºåãå端**æ éæ¹å¨è°ç¨æ¹å¼**ï¼ä½æç¤ºææ¡å¯è¯´æãä¼åæ¶å²éåè´§è®°å½ãã |
| | | |
| | | --- |
| | | |
| | | ## 3. éæ± 11ï¼å¾æ¥ä»æ¬¾ / 忬¾ |
| | | |
| | | ### 3.1 è¯ä¹ |
| | | |
| | | | 徿¥ | æ°å¢å段 | å弿¥æº | |
| | | | --- | --- | --- | |
| | | | 客æ·å¾æ¥ | `paymentAmount`ï¼**仿¬¾**ï¼ | `payment_record` ä¸ `party_type=1 and direction=1` çå计 | |
| | | | ä¾åºå徿¥ | `receiptAmount`ï¼**忬¾**ï¼ | `payment_record` ä¸ `party_type=2 and direction=2` çå计 | |
| | | |
| | | **åªæä¸ä¸ªæ¹åæ¯æå·¥æµæ°´**ï¼å®¢æ·ä¾§çãæ¶æ¬¾éé¢ã`receiptPaymentAmount`ãä¾åºåä¾§çã仿¬¾éé¢ã`paymentAmount` 仿¥èªåæçéåæ®è¡¨ï¼**计ç®å£å¾æªå**ï¼`receiptableAmount`ï¼åºæ¶ï¼ä¸ `payableAmount`ï¼åºä»ï¼å
¬å¼**ä¿æä¸å**ï¼æ°å段åªåå±ç¤ºï¼ä¸åä¸ä½é¢è®¡ç®ã |
| | | |
| | | ### 3.2 è¿ååæ®µæ°å¢ |
| | | |
| | | | æ¥å£ | æ°å¢è¿ååæ®µ | |
| | | | --- | --- | |
| | | | `GET /metricStatistics/customewTransactions` | `paymentAmount` | |
| | | | `GET /metricStatistics/customewTransactionsDetails` | `paymentAmount` | |
| | | | `GET /purchase/report/supplierTransactions` | `receiptAmount` | |
| | | | `GET /purchase/report/supplierTransactionsDetails` | `receiptAmount` | |
| | | |
| | | > æç»æ¥å£ç `paymentAmount` / `receiptAmount` æ¯**徿¥æ¹ç»´åº¦**çå计ï¼è¯¥å®¢æ·/ä¾åºåå
¨é¨æµæ°´å计ï¼ï¼æµæ°´æ¬èº«ä¸æå°åå¼ ååä¸ï¼å æ¤æç»åè¡è¯¥åå¼ç¸åãè¥åç«¯å¸æåªå¨å表页å±ç¤ºï¼æç»é¡µå¯éè该åã |
| | | |
| | | ### 3.3 æ°å¢ï¼ä»æ¬¾åæ¬¾æµæ°´åæ¥å£ |
| | | |
| | | åç¼ `/paymentRecord`ã |
| | | |
| | | | æ¥å£ | æ¹æ³ | 说æ | |
| | | | --- | --- | --- | |
| | | | `/paymentRecord/listPage` | GET | å页æ¥è¯¢ï¼æ¯æ `partyType`ã`partyId`ã`direction`ã`paymentMethod` | |
| | | | `/paymentRecord/add` | POST | æ°å¢ | |
| | | | `/paymentRecord/update` | POST | ä¿®æ¹ï¼å¿
须带 `id` | |
| | | | `/paymentRecord/delete` | DELETE | æ¹éå é¤ï¼body 为 id æ°ç» | |
| | | |
| | | 请æ±ä½åæ®µï¼ |
| | | |
| | | | åæ®µ | ç±»å | å¿
å¡« | 说æ | |
| | | | --- | --- | --- | --- | |
| | | | `id` | Long | ä¿®æ¹å¿
å¡« | ä¸»é® | |
| | | | `partyType` | Integer | æ¯ | `1` 客æ·ï¼`2` ä¾åºå | |
| | | | `partyId` | Long | æ¯ | å®¢æ· id æä¾åºå id | |
| | | | `direction` | Integer | æ¯ | `1` 仿¬¾ï¼`2` 忬¾ | |
| | | | `amount` | BigDecimal | æ¯ | éé¢ | |
| | | | `recordDate` | String | å¦ | åçæ¥æï¼æ ¼å¼ `yyyy-MM-dd` | |
| | | | `paymentMethod` | String | å¦ | 仿¬¾/忬¾æ¹å¼ | |
| | | | `remark` | String | å¦ | 夿³¨ | |
| | | |
| | | `tenantId` / `deptId` / `createUser` / `createTime` / `updateUser` / `updateTime` ç±å端èªå¨å¡«å
ï¼**å端ä¸è¦ä¼ **ã |
| | | |
| | | **æ¥è¯¢åæ°ç¤ºä¾**ï¼å®¢æ·å¾æ¥é¡µãæ°å¢ä»æ¬¾ã忥çè¯¥å®¢æ·æµæ°´ï¼ï¼ |
| | | |
| | | ``` |
| | | GET /paymentRecord/listPage?pageNum=1&pageSize=10&partyType=1&partyId=449&direction=1 |
| | | ``` |
| | | |
| | | `listPage` è¿åç»æä¸º MyBatis-Plus å页对象ï¼å端å `data.records`ã |
| | | |
| | | --- |
| | | |
| | | ## 4. éæ± 15ï¼å¤ä»¶å
³è产åä¸åºå
¥åºæµæ°´ |
| | | |
| | | ### 4.1 å¤ä»¶æ°å¢ä¸¤ä¸ªå段 |
| | | |
| | | `GET /spareParts/listPage`ã`POST /spareParts/add`ã`POST /spareParts/update` çå¤ä»¶å¯¹è±¡**æ°å¢**ï¼ |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | | --- | --- | --- | |
| | | | `productId` | Long | å
³è产å大类 id | |
| | | | `productModelId` | Long | å
³è产å**è§æ ¼åå·** id | |
| | | |
| | | **è¿æ¯æééè´çä¸å¡é©å**ï¼éè´å°è´¦æ°å¢æç»æ¶ï¼åç«¯ç¨æç»ç `productModelId` å»å¹é
`spare_parts.product_model_id`ãå¹é
ä¸åï¼ |
| | | |
| | | 1. `spare_parts.quantity` ç´¯å 该æç»æ°éï¼ |
| | | 2. å䏿¡å¤ä»¶å
¥åºæµæ°´ï¼`direction=1`ã`sourceType=1`ã`sourceId=éè´å°è´¦id`ã`sourceNo=éè´ååå·`ï¼ã |
| | | |
| | | æªç»´æ¤ `productModelId` çå¤ä»¶**ä¸ä¼**被å¹é
ï¼éé»è·³è¿ï¼ä¸å½±åéè´å°è´¦ä¿åã |
| | | |
| | | > ä»
å¨éè´å°è´¦**æ°å¢æç»**æ¶ååï¼ç¼è¾éè´å°è´¦èµ°æ´æ°åæ¯ï¼ä¸ä¼éå¤è®¡æ°ã |
| | | |
| | | ### 4.2 æ°å¢ï¼å¤ä»¶åºå
¥åºæµæ°´ |
| | | |
| | | åç¼ `/sparePartsRecord`ã |
| | | |
| | | | æ¥å£ | æ¹æ³ | 说æ | |
| | | | --- | --- | --- | |
| | | | `/sparePartsRecord/listPage` | GET | å页æ¥è¯¢ï¼æ¯æ `sparePartsId`ã`direction`ã`sourceType` | |
| | | | `/sparePartsRecord/delete` | DELETE | æ¹éå é¤ï¼body 为 id æ°ç» | |
| | | |
| | | è¿ååæ®µï¼ |
| | | |
| | | | åæ®µ | 说æ | |
| | | | --- | --- | |
| | | | `sparePartsId` | å¤ä»¶ id | |
| | | | `sparePartsName` | å¤ä»¶åç§°ï¼å端 join 带åºï¼ | |
| | | | `direction` | `1` å
¥åºï¼`2` åºåº | |
| | | | `quantity` | æ°é | |
| | | | `sourceType` | æ¥æºç±»åï¼è§ä¸è¡¨ | |
| | | | `sourceId` | æ¥æºåæ® id | |
| | | | `sourceNo` | æ¥æºåå· | |
| | | | `remark` | 夿³¨ | |
| | | | `createTime` | åçæ¶é´ | |
| | | |
| | | `sourceType` æä¸¾ï¼ |
| | | |
| | | | å¼ | å«ä¹ | 触åç¹ | |
| | | | --- | --- | --- | |
| | | | `1` | éè´å
¥åº | éè´å°è´¦æ°å¢å«è¯¥è§æ ¼çæç» | |
| | | | `2` | ç»´ä¿®é¢ç¨ | è®¾å¤æ¥ä¿®åæ´æ°æ¶é¢ç¨å¤ä»¶ | |
| | | | `3` | ä¿å
»é¢ç¨ | 设å¤ä¿å
»åæ´æ°æ¶é¢ç¨å¤ä»¶ | |
| | | |
| | | > ç»´ä¿®/ä¿å
»**é¢ç¨**仿²¿ç¨åæ `spare_parts_requisition_record`ï¼è®¾å¤ç»´åº¦ï¼å¦æé¡µé¢ï¼ï¼æ¬æ¬¡æ°å¢ç `spare_parts_record` æ¯**å¤ä»¶ç»´åº¦**çè¿åºæµæ°´ï¼ä¸¤è
å¹¶åï¼èè´£ä¸åã |
| | | |
| | | ### 4.3 å端页é¢å»ºè®® |
| | | |
| | | - å¤ä»¶ç»´æ¤è¡¨åï¼äº§å大类ãè§æ ¼åå·ä¸¤ä¸ªä¸æï¼å¤ç¨äº§åæ¥å£ï¼ã |
| | | - æ°å¢é¡µé¢ï¼å¤ä»¶åºå
¥åºæµæ°´ï¼æ¾å¨è®¾å¤ç®¡çæå¤ä»¶ç®¡çä¸ï¼ï¼å表å建议ï¼å¤ä»¶åç§°ãæ¹åãæ°éãæ¥æºç±»åãæ¥æºåå·ãæ¶é´ã |
| | | |
| | | --- |
| | | |
| | | ## 5. éæ± 14ï¼æ°å¢å
¥åºå
³è订ååæ¾ |
| | | |
| | | ### 5.1 å端修å¤è¯´æï¼å端æ¥å£å½¢æä¸åï¼ |
| | | |
| | | å `listProcurementBySalesLedgerId` ç join æ¡ä»¶åäº `slp.type = 2`ï¼ä½ `slp` æªå®ä¹ï¼å¯¼è´**ç±»åè¿æ»¤å®é
ä¸çæ**ï¼å¯è½è¿åééè´æç»ã已修æ£ä¸º `t2.type = 2`ã |
| | | |
| | | ### 5.2 æ°å¢å¯éåæ° |
| | | |
| | | `GET /stockin/productlist` æ°å¢å¯éåæ°ï¼ |
| | | |
| | | | åæ° | ç±»å | 说æ | |
| | | | --- | --- | --- | |
| | | | `purchaseLedgerId` | Integer | **æ¨è**ãæéè´å°è´¦ id ç²¾ç¡®åæ¾æç» | |
| | | | `purchaseContractNumber` | String | å
¼å®¹ä¿çï¼æååå·å¹é
| |
| | | |
| | | ä¸¤ä¸ªåæ°å¯åªä¼ å
¶ä¸ï¼`purchaseLedgerId` ä¼å
ãå端ä»éè´è®¢å䏿éä¸è®¢ååï¼ç´æ¥æè¯¥è®¢åç id ä½ä¸º `purchaseLedgerId` ä¼ å
¥ï¼æ¯ä¼ ååå·æ´å¯é ï¼ååå·å¯è½éå¤/为空ï¼ã |
| | | |
| | | åºåºä¾§åæ¾æ²¿ç¨å·²ææ¥å£ï¼**æ åæ´**ï¼`GET /sales/ledger/getSalesLedgerWithProducts`ã |
| | | |
| | | --- |
| | | |
| | | ## 6. èè°èªæ¥æ¸
å |
| | | |
| | | - [ ] åºåºè¡¨åï¼éè§æ ¼åè½æå°æ¹æ¬¡åè¡¨ï¼æ¹æ¬¡ä¸ºå¿
填项 |
| | | - [ ] åºåºï¼type=2ï¼åï¼åºåºå°è´¦ãåè´§åå·ãåæå¼ï¼æ ¼å¼ `SH+æ¥æ+æµæ°´` |
| | | - [ ] åè´§å°è´¦ä¸è½çå°è¯¥èªå¨çæçåï¼ç¶æä¸º `å·²åè´§` |
| | | - [ ] åä¸äº§å忬¡åºåºï¼çæ**å¦ä¸å¼ **åè´§åï¼ä¸æ¯è¢«æ¦æªï¼ |
| | | - [ ] å é¤åºåºååï¼åè´§å°è´¦ãåè´§æç»ãåºåæ£åè®°å½ä¸å¹¶æ¶å¤± |
| | | - [ ] 客æ·å¾æ¥å表/æç»åºç°ã仿¬¾ãåï¼æå
¥ä¸æ¡ `direction=1` æµæ°´åæ°å¼ååï¼ä¸ãåºæ¶ãä¸å |
| | | - [ ] ä¾åºå徿¥å表/æç»åºç°ã忬¾ãåï¼é»è¾åä¸ |
| | | - [ ] å¤ä»¶ç»´æ¤è½ä¿å产å大类 + è§æ ¼åå· |
| | | - [ ] æ°å¢ä¸å¼ å«è¯¥è§æ ¼çéè´å°è´¦ï¼å¤ä»¶æ°éå¢å ï¼å¤ä»¶æµæ°´åºç° `direction=1` è®°å½ |
| | | - [ ] è®¾å¤æ¥ä¿®/ä¿å
»é¢ç¨å¤ä»¶åï¼å¤ä»¶æµæ°´åºç° `direction=2` è®°å½ |
| | | - [ ] æ°å¢å
¥åºé订ååï¼æç»åªæ¾ç¤ºéè´ç±»ï¼type=2ï¼äº§å |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # éè´ç³è¯·æ¨¡åå端èè°ææ¡£ |
| | | |
| | | æ´æ°æ¶é´ï¼2026-09-20 |
| | | éç¨çæ¬ï¼æ¬æ¬¡åç«¯åæ´å |
| | | |
| | | ## 1. åæ´èå´ |
| | | |
| | | 1. èåãéè´ç®¡ç â **éè´å®¡æ ¸**ãæ¹å为ã**éè´ç®¡ç â éè´ç³è¯·**ãï¼å»æå®¡æ ¸ç¯èã |
| | | 2. æ°å¢éè´ç³è¯·å模åï¼ç¬ç«äºéè´å°è´¦ï¼ï¼æ¯æä¿åè稿ãç¼è¾ãå é¤ã**转订å**ã |
| | | 3. 转订åå¤ç¨éè´å°è´¦æ°å¢é»è¾ï¼èªå¨çæéè´ååå·ãåå
¥éè´å°è´¦ä¸äº§åæç»ï¼å¹¶**èªå¨æäº¤ OA éè´å®¡æ¹**ï¼å®¡æ¹æµç¨ä¸å¨æ¬æ¨¡åå
ï¼ä»å¨ã审æ¹ç®¡çãä¸å¤çï¼ã |
| | | 4. å端æ¥å£åç¼ï¼`/purchase/application`ã |
| | | |
| | | ### 1.1 èåæ¹å¨ï¼æ°æ®åºå·²æ§è¡ï¼ |
| | | |
| | | | 项 | åå¼ | æ°å¼ | |
| | | | --- | --- | --- | |
| | | | `sys_menu.menu_name`ï¼menu_id=2355ï¼ | éè´å®¡æ ¸ | éè´ç³è¯· | |
| | | | `path` | purchaseReview | purchaseApplication | |
| | | | `component` | procurementManagement/purchaseReview/index | procurementManagement/purchaseApplication/index | |
| | | |
| | | **åç«¯éæ°å¢é¡µé¢**ï¼`src/views/procurementManagement/purchaseApplication/index.vue`ï¼å `purchaseReview` 页é¢å·²ä¸å被èåå¼ç¨ï¼å¯å 餿ä¿çï¼ã |
| | | |
| | | --- |
| | | |
| | | ## 2. ç¶ææä¸¾ |
| | | |
| | | | å¼ | å«ä¹ | åç«¯å¯æä½é¡¹ | |
| | | | --- | --- | --- | |
| | | | `0` | è稿 | ç¼è¾ãå é¤ã转订å | |
| | | | `1` | å·²çæè®¢å | ä»
æ¥ç | |
| | | |
| | | 说æï¼ |
| | | |
| | | - æ°å¢çç³è¯·å**强å¶ä¸ºè稿**ï¼å端ä¸éè¦ä¹ä¸å
è®¸ä¼ `status`ã |
| | | - ç¼è¾ãå 餿¥å£é½ä¼æ ¡éªç¶æï¼éè稿ä¼è¿åé误ï¼è§ 4.6 常è§é误ï¼ã |
| | | - 转订åæååç¶æèªå¨å为 `1`ï¼å¹¶åå
¥ `purchaseLedgerId`ã`convertTime`ã |
| | | |
| | | --- |
| | | |
| | | ## 3. å
Œ
±å段说æï¼å端èªå¨ç»´æ¤ï¼å端åªè¯»ï¼ |
| | | |
| | | | åæ®µ | 说æ | |
| | | | --- | --- | |
| | | | `applicationNo` | ç³è¯·åå·ï¼æ°å¢æ¶å端çæï¼æ ¼å¼ `CGSQ` + æ¥æ + 彿¥æµæ°´ï¼å¦ `CGSQ20260920001`ã**å端ä¸è¦ä¼ **ï¼ä¼ äºä¹ä¼è¢«å¿½ç¥ã | |
| | | | `supplierName` | 便® `supplierId` 忥åå¡«ï¼å端ä¸å¿
ä¼ ï¼ä¼ äºä»¥åç«¯ç»æä¸ºåï¼ã | |
| | | | `applicantId` / `applicantName` | ä¸ä¼ æ¶é»è®¤åå½åç»å½ç¨æ·ï¼ä¹å¯æ¾å¼ä¼ `applicantId` æå®ç³è¯·äººã`applicantName` ç±åç«¯æ ¹æ® `applicantId` æ¥æµç§°åå¡«ã | |
| | | | `applyDate` | ä¸ä¼ æ¶é»è®¤å½å¤©ã | |
| | | | `productCategory` / `specificationModel` | **æç»è¡**ä¸çè¿ä¸¤ä¸ªå段ç±åç«¯æ ¹æ® `productId` / `productModelId` 忥åå
¥ï¼å端åªéä¼ idï¼ä¼ äºä¹ä¼è¢«è¦çã | |
| | | | `tenantId` / `deptId` / `createUser` / `createTime` / `updateTime` | å端èªå¨å¡«å
ï¼å端ä¸è¦ä¼ ã | |
| | | | `purchaseLedgerId` / `convertTime` | 转订åæååææå¼ã | |
| | | |
| | | --- |
| | | |
| | | ## 4. æ¥å£æ¸
å |
| | | |
| | | ### 4.1 æ¥è¯¢éè´ç³è¯·å表 |
| | | |
| | | `GET /purchase/application/list` |
| | | |
| | | **请æ±åæ°**ï¼å为å¯éï¼query å½¢å¼ï¼ |
| | | |
| | | | åæ° | ç±»å | 说æ | |
| | | | --- | --- | --- | |
| | | | `applicationNo` | string | ç³è¯·åå·ï¼æ¨¡ç³å¹é
| |
| | | | `projectName` | string | 项ç®åç§°ï¼æ¨¡ç³å¹é
| |
| | | | `supplierId` | number | ä¾åºåidï¼ç²¾ç¡®å¹é
| |
| | | | `status` | number | ç¶æï¼`0` è稿 / `1` å·²çæè®¢å | |
| | | | `startDate` | string | ç³è¯·æ¥æèµ·ï¼`yyyy-MM-dd` | |
| | | | `endDate` | string | ç³è¯·æ¥ææ¢ï¼`yyyy-MM-dd` | |
| | | | `pageNum` | number | 页ç ï¼å页忰 | |
| | | | `pageSize` | number | æ¯é¡µæ¡æ°ï¼å页忰 | |
| | | |
| | | æåºï¼æ `id` ååºï¼**䏿¯æä¼ å
¥æåºå段**ã |
| | | |
| | | **è¿å**ï¼RuoYi æ ååé¡µç»æ `{ total, rows, code, msg }`ï¼æ³¨ææ¯ `rows`ï¼ä¸æ¯ `records`ï¼ã |
| | | |
| | | ```json |
| | | { |
| | | "total": 1, |
| | | "rows": [ |
| | | { |
| | | "id": 3, |
| | | "applicationNo": "CGSQ20260920001", |
| | | "supplierId": 12, |
| | | "supplierName": "XXä¾åºå", |
| | | "projectName": "åéXX项ç®", |
| | | "salesContractNo": "XS20260901001", |
| | | "salesLedgerId": 88, |
| | | "applicantId": 1, |
| | | "applicantName": "å¼ ä¸", |
| | | "applyDate": "2026-09-20", |
| | | "expectedArrivalDate": "2026-09-30", |
| | | "contractAmount": 11300.00, |
| | | "paymentMethod": "çµæ±", |
| | | "remarks": "ç´§æ¥", |
| | | "status": 0, |
| | | "purchaseLedgerId": null, |
| | | "convertTime": null, |
| | | "createTime": "2026-09-20 10:12:33", |
| | | "updateTime": "2026-09-20 10:12:33" |
| | | } |
| | | ], |
| | | "code": 200, |
| | | "msg": "æ¥è¯¢æå" |
| | | } |
| | | ``` |
| | | |
| | | > å表æ¥å£**ä¸è¿å** `productData` æç»ï¼æç»è¯·åç¬è° 4.2 è·åã |
| | | |
| | | --- |
| | | |
| | | ### 4.2 æ¥è¯¢éè´ç³è¯·è¯¦æ
|
| | | |
| | | `GET /purchase/application/getById?id={id}` |
| | | |
| | | **è¿å**ï¼AjaxResultï¼`data` 为ç³è¯·å对象ï¼å段å 4.1ï¼å¦å« `productData` æç»æ°ç»ï¼ã |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "msg": "æä½æå", |
| | | "data": { |
| | | "id": 3, |
| | | "applicationNo": "CGSQ20260920001", |
| | | "supplierId": 12, |
| | | "supplierName": "XXä¾åºå", |
| | | "projectName": "åéXX项ç®", |
| | | "applyDate": "2026-09-20", |
| | | "contractAmount": 11300.00, |
| | | "status": 0, |
| | | "productData": [ |
| | | { |
| | | "id": 21, |
| | | "purchaseApplicationId": 3, |
| | | "productId": 5, |
| | | "productModelId": 17, |
| | | "productCategory": "éæ", |
| | | "specificationModel": "T2-30x3", |
| | | "unit": "ç±³", |
| | | "quantity": 100, |
| | | "taxRate": 13, |
| | | "taxInclusiveUnitPrice": 113.00, |
| | | "taxInclusiveTotalPrice": 11300.00, |
| | | "taxExclusiveTotalPrice": 10000.00, |
| | | "invoiceType": "å¢å¼ç¨ä¸ç¨å票", |
| | | "isChecked": true, |
| | | "remark": "" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ç³è¯·åä¸å卿¶è¿å `code=500`ã`msg="éè´ç³è¯·ä¸åå¨"`ã |
| | | |
| | | --- |
| | | |
| | | ### 4.3 æ°å¢éè´ç³è¯·ï¼èç¨¿ï¼ |
| | | |
| | | `POST /purchase/application/add` |
| | | |
| | | `Content-Type: application/json` |
| | | |
| | | **请æ±ä½**ï¼å 4.2 ç `data` ç»æï¼`id`ã`applicationNo`ã`status`ã`purchaseLedgerId`ã`convertTime` ä¸éè¦ä¼ ã |
| | | |
| | | **è¿å**ï¼`data` 为æ°ç³è¯·å idã |
| | | |
| | | ```json |
| | | { "code": 200, "msg": "æä½æå", "data": 3 } |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ### 4.4 ä¿®æ¹éè´ç³è¯· |
| | | |
| | | `POST /purchase/application/edit` |
| | | |
| | | `Content-Type: application/json` |
| | | |
| | | **请æ±ä½**ï¼å 4.3ï¼**å¿
须带 `id`**ï¼æç»éå
¨éæäº¤ï¼å端为ãå
å åæãï¼ã |
| | | |
| | | **è¿å**ï¼`{ "code": 200, "msg": "æä½æå" }` |
| | | |
| | | > ä»
èç¨¿ç¶æå¯ä¿®æ¹ãå·²çæè®¢åçç³è¯·åä¿®æ¹ä¼è¿åé误ã |
| | | |
| | | --- |
| | | |
| | | ### 4.5 å é¤éè´ç³è¯· |
| | | |
| | | `DELETE /purchase/application/delete` |
| | | |
| | | `Content-Type: application/json` |
| | | |
| | | **请æ±ä½**ï¼id æ°ç»ï¼æ¯ææ¹éã |
| | | |
| | | ```json |
| | | [3, 4] |
| | | ``` |
| | | |
| | | **è¿å**ï¼`{ "code": 200, "msg": "æä½æå" }` |
| | | |
| | | > ä»
èç¨¿ç¶æå¯å é¤ã请æ±ä½ä¸ºç©ºæ¶è¿å `code=500`ã`msg="è¯·éæ©è¦å é¤çéè´ç³è¯·"`ã |
| | | |
| | | --- |
| | | |
| | | ### 4.6 éè´ç³è¯·è½¬è®¢å |
| | | |
| | | `POST /purchase/application/convertToOrder?id={id}` |
| | | |
| | | > 注æï¼`id` æ¯ **query åæ°**ï¼ä¸æ¯è¯·æ±ä½ã |
| | | |
| | | **è¿å**ï¼`data` 为çæçéè´å°è´¦ idï¼å³ãéè´è®¢åãidï¼åç»å
¥åºãè´¨æ£ã仿¬¾çæµç¨é½ç¨å®ï¼ã |
| | | |
| | | ```json |
| | | { "code": 200, "msg": "æä½æå", "data": 1201 } |
| | | ``` |
| | | |
| | | **转订ååäºä»ä¹**ï¼å端äºè§£å³å¯ï¼æ éé¢å¤è°ç¨ï¼ï¼ |
| | | |
| | | 1. æ ¡éªï¼ä¾åºå已鿩ä¸åå¨ãåå¨äº§åæç»ï¼ |
| | | 2. æ¢å ç¶æï¼ä»¥æ¡ä»¶æ´æ°æç¶æä» `0` æ¹ä¸º `1`ï¼**å¹¶åéå¤ç¹å»åªæç¬¬ä¸æ¬¡ä¼æå**ï¼ |
| | | 3. çæéè´ååå·ï¼ç±éè´å°è´¦ä¾§è§åçæï¼ï¼ |
| | | 4. åå
¥ `purchase_ledger` 主表 + `sales_ledger_product` 产åæç»ï¼`type=2`ï¼ï¼ |
| | | 5. èªå¨æäº¤ OA éè´å®¡æ¹ï¼æµç¨è§ã审æ¹ç®¡çãï¼æ¬æ¨¡åä¸åæå®¡æ ¸æé®ï¼ï¼ |
| | | 6. åå¡« `purchaseLedgerId`ã`convertTime`ã |
| | | |
| | | 任䏿¥å¤±è´¥æ´ä¸ªäºå¡åæ»ï¼ç³è¯·åä»ä¿æèç¨¿ç¶æã |
| | | |
| | | --- |
| | | |
| | | ## 5. 常è§é误è¿å |
| | | |
| | | ç»ä¸ä¸º `{ "code": 500, "msg": "<é误信æ¯>" }`ï¼åç«¯ç´æ¥ toast `msg` å³å¯ã |
| | | |
| | | | msg | 触ååºæ¯ | |
| | | | --- | --- | |
| | | | `éè´ç³è¯·ä¸åå¨` | 详æ
/ç¼è¾/转订åä¼ å
¥ç id ä¸åå¨ | |
| | | | `éè´ç³è¯·idä¸è½ä¸ºç©º` | ç¼è¾ãè½¬è®¢åæªä¼ id | |
| | | | `å·²çæè®¢åçéè´ç³è¯·ä¸å
许修æ¹` | 对 `status=1` çåæ®è°ç¨ç¼è¾ | |
| | | | `å·²çæè®¢åçéè´ç³è¯·ä¸å
许å é¤ï¼<åå·>` | 对 `status=1` çåæ®è°ç¨å é¤ï¼ä¼åæ¾å
·ä½åå· | |
| | | | `è¯·éæ©è¦å é¤çéè´ç³è¯·` | å 餿¥å£è¯·æ±ä½ä¸ºç©ºæ°ç» | |
| | | | `请å
éæ©ä¾åºåå转订å` | è½¬è®¢åæ¶ `supplierId` 为空 | |
| | | | `ä¾åºåä¸åå¨ï¼è¯·éæ°éæ©` | `supplierId` å¨ä¾åºåè¡¨ä¸æ¥ä¸å° | |
| | | | `éè´ç³è¯·æ²¡æäº§åæç»ï¼æ æ³è½¬è®¢å` | ç³è¯·å䏿²¡ææç»è¡ | |
| | | | `该éè´ç³è¯·å·²çæè®¢åï¼è¯·å¿éå¤è½¬æ¢` | å¹¶å/éå¤ç¹å»è½¬è®¢å | |
| | | | `转订å失败ï¼<åå >` | éè´å°è´¦ä¾§å¤±è´¥ï¼å¦ `转订å失败ï¼è¯·å
é
ç½®éè´å®¡æ¹æ¨¡æ¿` | |
| | | |
| | | --- |
| | | |
| | | ## 6. 请æ±ç¤ºä¾ï¼curlï¼ |
| | | |
| | | ```bash |
| | | # å表 |
| | | curl -X GET "http://localhost:8080/purchase/application/list?status=0&pageNum=1&pageSize=10" \ |
| | | -H "Authorization: Bearer <token>" |
| | | |
| | | # 详æ
|
| | | curl -X GET "http://localhost:8080/purchase/application/getById?id=3" \ |
| | | -H "Authorization: Bearer <token>" |
| | | |
| | | # æ°å¢ |
| | | curl -X POST "http://localhost:8080/purchase/application/add" \ |
| | | -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \ |
| | | -d '{ |
| | | "supplierId": 12, |
| | | "projectName": "åéXX项ç®", |
| | | "salesContractNo": "XS20260901001", |
| | | "salesLedgerId": 88, |
| | | "expectedArrivalDate": "2026-09-30", |
| | | "contractAmount": 11300.00, |
| | | "paymentMethod": "çµæ±", |
| | | "remarks": "ç´§æ¥", |
| | | "productData": [ |
| | | { |
| | | "productId": 5, |
| | | "productModelId": 17, |
| | | "unit": "ç±³", |
| | | "quantity": 100, |
| | | "taxRate": 13, |
| | | "taxInclusiveUnitPrice": 113.00, |
| | | "taxInclusiveTotalPrice": 11300.00, |
| | | "taxExclusiveTotalPrice": 10000.00, |
| | | "invoiceType": "å¢å¼ç¨ä¸ç¨å票", |
| | | "isChecked": true |
| | | } |
| | | ] |
| | | }' |
| | | |
| | | # 转订å |
| | | curl -X POST "http://localhost:8080/purchase/application/convertToOrder?id=3" \ |
| | | -H "Authorization: Bearer <token>" |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## 7. å端æ¹é 建议 |
| | | |
| | | 1. æ°å»º `procurementManagement/purchaseApplication/index.vue`ï¼é¡µé¢ç»æå¯ç´æ¥æ²¿ç¨åéè´å®¡æ ¸é¡µé¢ï¼**å»æå®¡æ ¸ç¸å
³æé®å审æ¹ç¶æå**ã |
| | | 2. å表页æ°å¢ãç¶æãåï¼`0` æ¾ç¤ºãè稿ãï¼`1` æ¾ç¤ºãå·²çæè®¢åãï¼å»ºè®®ç¨ tag åºåé¢è²ã |
| | | 3. å表页æ°å¢ãç¶æãçé项ï¼å¼ `0` / `1`ï¼æ°å¢ãç³è¯·æ¥æãåºé´çé项ï¼å¯¹åº `startDate` / `endDate`ã |
| | | 4. ãç¼è¾ããå é¤ãã转订åãä¸ä¸ªæé®ä»
å¨ `status === 0` æ¶æ¾ç¤ºï¼è½¬è®¢å建议å äºæ¬¡ç¡®è®¤ã |
| | | 5. 转订åæååç¨è¿åç `data`ï¼éè´å°è´¦idï¼è·³è½¬éè´å°è´¦è¯¦æ
ï¼å¹¶å·æ°å表ã |
| | | 6. æ°å¢/ç¼è¾è¡¨åä¸çä¾åºåãéå®ååå·å»ºè®®å¤ç¨éè´å°è´¦çç°æä¸æ/éæ©é»è¾ï¼`/purchase/ledger/getSalesNo`ã`/purchase/ledger/getPurchaseNo` çï¼ã |
| | | 7. æç»è¡ç `productCategory`ï¼äº§å大类ï¼ã`specificationModel`ï¼è§æ ¼åå·ï¼ä¸ºå端åå¡«åæ®µï¼è¡¨åéåªåå±ç¤ºï¼æäº¤æ¶ä¼ `productId` / `productModelId` å³å¯ã |
| | | |
| | | --- |
| | | |
| | | ## 8. èè°æ£æ¥æ¸
å |
| | | |
| | | 1. èåå±ç¤ºä¸ºãéè´ç³è¯·ãï¼ç¹å»å¯è¿å
¥æ°é¡µé¢ï¼æ 404ã |
| | | 2. `/list` ä¸ä¼ 任使¡ä»¶ï¼è¿åå
¨é¨æ°æ®ï¼`rows` å« `status`ã`applicationNo`ã`supplierName` çåæ®µã |
| | | 3. `/list?status=0`ï¼åªè¿åè稿ï¼`/list?status=1`ï¼åªè¿åå·²çæè®¢åã |
| | | 4. `/list?startDate=2026-09-01&endDate=2026-09-30`ï¼æç³è¯·æ¥æè¿æ»¤ã |
| | | 5. `/add` åªä¼ `supplierId` + `productData`ï¼è½æ°å¢æåï¼è¿å idï¼å表è½çå°è稿ï¼`applicationNo` èªå¨çæã |
| | | 6. `/getById`ï¼è¿åå« `productData` ç宿´æç»ï¼`productCategory` / `specificationModel` å·²ç±å端åå¡«ã |
| | | 7. `/edit` ä¿®æ¹èç¨¿ï¼æç»å
¨éæ¿æ¢çæï¼æ¹æ°éãå¢å è¡é½æ£ç¡®ï¼ã |
| | | 8. `/edit` ä¿®æ¹ `status=1` çåæ®ï¼è¿åãå·²çæè®¢åçéè´ç³è¯·ä¸å
许修æ¹ãã |
| | | 9. `/delete` å é¤èç¨¿ï¼æåï¼`/delete` å é¤ `status=1`ï¼è¿å带åå·çé误æç¤ºã |
| | | 10. `/convertToOrder`ï¼æååç¶æå `1`ï¼è¿åéè´å°è´¦idï¼**æå¼éè´å°è´¦åè¡¨è½æ¥å°è¯¥éè´ååå·**ã |
| | | 11. `/convertToOrder` 对åä¸ id åç¹ä¸æ¬¡ï¼è¿åã该éè´ç³è¯·å·²çæè®¢åï¼è¯·å¿éå¤è½¬æ¢ãï¼ä¸**ä¸ä¼**çæç¬¬äºæ¡éè´å°è´¦ã |
| | | 12. 转订ååå»ã审æ¹ç®¡çãï¼è½çå°ä¸æ¡éè´å®¡æ¹ï¼æ é¢ä¸ºãéè´ååå· + 审æ¹ãï¼å¾
å¤çã |
| | | 13. æ `supplierId` æ¶ç¹è½¬è®¢åï¼è¿åã请å
éæ©ä¾åºåå转订åãï¼æ æç»æ¶è¿åãéè´ç³è¯·æ²¡æäº§åæç»ï¼æ æ³è½¬è®¢åãã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.sql.Connection; |
| | | import java.sql.DriverManager; |
| | | import java.sql.ResultSet; |
| | | import java.sql.ResultSetMetaData; |
| | | import java.sql.Statement; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Scanner; |
| | | |
| | | /** |
| | | * æ°æ®åºç´è¿å°å·¥å
·ãç¨æ³è§ printUsage()ã |
| | | * è¿è¡ï¼bash sql/db.sh "SELECT 1" |
| | | */ |
| | | public class DbTool { |
| | | |
| | | private static final String DEFAULT_URL = |
| | | "jdbc:mysql://localhost:3306/product-inventory-management-rbhb" |
| | | + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull" |
| | | + "&serverTimezone=GMT%2B8&sslMode=DISABLED&allowPublicKeyRetrieval=true"; |
| | | private static final String DEFAULT_USER = "root"; |
| | | private static final String DEFAULT_PASS = "123456"; |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | String url = DEFAULT_URL; |
| | | String user = DEFAULT_USER; |
| | | String pass = DEFAULT_PASS; |
| | | String sqlText = null; |
| | | Path scriptFile = null; |
| | | |
| | | List<String> positional = new ArrayList<>(); |
| | | for (int i = 0; i < args.length; i++) { |
| | | String arg = args[i]; |
| | | switch (arg) { |
| | | case "-url" -> url = args[++i]; |
| | | case "-user" -> user = args[++i]; |
| | | case "-pass" -> pass = args[++i]; |
| | | case "-f" -> scriptFile = Path.of(args[++i]); |
| | | case "-h", "--help" -> { |
| | | printUsage(); |
| | | return; |
| | | } |
| | | default -> positional.add(arg); |
| | | } |
| | | } |
| | | |
| | | if (scriptFile != null) { |
| | | sqlText = Files.readString(scriptFile, StandardCharsets.UTF_8); |
| | | } else if (!positional.isEmpty()) { |
| | | sqlText = String.join(" ", positional); |
| | | } else if (System.console() != null) { |
| | | printUsage(); |
| | | return; |
| | | } else { |
| | | Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8).useDelimiter("\\A"); |
| | | sqlText = scanner.hasNext() ? scanner.next() : null; |
| | | } |
| | | |
| | | if (sqlText == null || sqlText.isBlank()) { |
| | | printUsage(); |
| | | return; |
| | | } |
| | | |
| | | List<String> statements = splitStatements(sqlText); |
| | | if (statements.isEmpty()) { |
| | | printUsage(); |
| | | return; |
| | | } |
| | | |
| | | try (Connection conn = DriverManager.getConnection(url, user, pass)) { |
| | | for (String sql : statements) { |
| | | runOne(conn, sql); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static void runOne(Connection conn, String sql) throws Exception { |
| | | long start = System.currentTimeMillis(); |
| | | try (Statement stmt = conn.createStatement()) { |
| | | boolean hasResultSet = stmt.execute(sql); |
| | | long cost = System.currentTimeMillis() - start; |
| | | if (hasResultSet) { |
| | | try (ResultSet rs = stmt.getResultSet()) { |
| | | printResultSet(rs); |
| | | } |
| | | System.out.println("èæ¶ " + cost + " ms"); |
| | | } else { |
| | | System.out.println("åå½±åè¡æ°: " + stmt.getUpdateCount() + " èæ¶ " + cost + " ms"); |
| | | } |
| | | } catch (Exception e) { |
| | | System.out.println("æ§è¡å¤±è´¥: " + e.getMessage()); |
| | | System.out.println("SQL: " + sql); |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | private static void printResultSet(ResultSet rs) throws Exception { |
| | | ResultSetMetaData meta = rs.getMetaData(); |
| | | int columnCount = meta.getColumnCount(); |
| | | String[] headers = new String[columnCount]; |
| | | int[] widths = new int[columnCount]; |
| | | for (int i = 0; i < columnCount; i++) { |
| | | headers[i] = meta.getColumnLabel(i + 1); |
| | | widths[i] = displayWidth(headers[i]); |
| | | } |
| | | |
| | | List<String[]> rows = new ArrayList<>(); |
| | | while (rs.next()) { |
| | | String[] row = new String[columnCount]; |
| | | for (int i = 0; i < columnCount; i++) { |
| | | Object value = rs.getObject(i + 1); |
| | | row[i] = value == null ? "NULL" : String.valueOf(value); |
| | | widths[i] = Math.max(widths[i], displayWidth(row[i])); |
| | | } |
| | | rows.add(row); |
| | | } |
| | | |
| | | StringBuilder separator = new StringBuilder(); |
| | | for (int width : widths) { |
| | | separator.append('-').append("-".repeat(width)).append('-'); |
| | | } |
| | | System.out.println(separator); |
| | | System.out.println(joinRow(headers, widths)); |
| | | System.out.println(separator); |
| | | for (String[] row : rows) { |
| | | System.out.println(joinRow(row, widths)); |
| | | } |
| | | System.out.println(separator); |
| | | System.out.println("å
± " + rows.size() + " è¡"); |
| | | } |
| | | |
| | | private static String joinRow(String[] cells, int[] widths) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (int i = 0; i < cells.length; i++) { |
| | | sb.append("| ").append(cells[i]); |
| | | sb.append(" ".repeat(Math.max(0, widths[i] - displayWidth(cells[i]) + 1))); |
| | | } |
| | | return sb.append('|').toString(); |
| | | } |
| | | |
| | | /** |
| | | * å
¨è§å符å 两个ç»ç«¯å®½åº¦ï¼æ 2 计ç®ä»¥ä¿è¯è¡¨æ ¼å¯¹é½ã |
| | | */ |
| | | private static int displayWidth(String text) { |
| | | int width = 0; |
| | | for (int i = 0; i < text.length(); i++) { |
| | | width += text.charAt(i) > 0x2E80 ? 2 : 1; |
| | | } |
| | | return width; |
| | | } |
| | | |
| | | /** |
| | | * æåå·ååè¯å¥ï¼å¿½ç¥ç©ºè¯å¥ä¸çº¯æ³¨éè¡ã |
| | | * ç®åå®ç°ï¼ä¸æ¯æå符串åé¢éä¸å
å«åå·çæç«¯åºæ¯ã |
| | | */ |
| | | private static List<String> splitStatements(String sqlText) { |
| | | List<String> statements = new ArrayList<>(); |
| | | for (String part : sqlText.split(";")) { |
| | | String trimmed = part.trim(); |
| | | if (trimmed.isEmpty() || isCommentOnly(trimmed)) { |
| | | continue; |
| | | } |
| | | statements.add(trimmed); |
| | | } |
| | | return statements; |
| | | } |
| | | |
| | | private static boolean isCommentOnly(String sql) { |
| | | for (String line : sql.split("\\R")) { |
| | | String stripped = line.trim(); |
| | | if (!stripped.isEmpty() && !stripped.startsWith("--") && !stripped.startsWith("#")) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | private static void printUsage() { |
| | | System.out.println(""" |
| | | æ°æ®åºç´è¿å·¥å
· |
| | | |
| | | ç¨æ³: |
| | | bash sql/db.sh "SQLè¯å¥" |
| | | bash sql/db.sh -f èæ¬.sql |
| | | echo "SQLè¯å¥" | bash sql/db.sh |
| | | |
| | | å¯è¦çè¿æ¥åæ°: |
| | | -url jdbc:mysql://host:3306/db?... -user root -pass 123456 |
| | | """); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #!/usr/bin/env bash |
| | | # æ°æ®åºç´è¿å·¥å
·å
è£
èæ¬ï¼èªå¨å®ä½ MySQL JDBC 驱å¨å¹¶è°ç¨ sql/DbTool.java |
| | | set -euo pipefail |
| | | |
| | | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| | | |
| | | JAR="$(ls "$HOME"/.m2/repository/com/mysql/mysql-connector-j/*/mysql-connector-j-*.jar 2>/dev/null | grep -v sources | tail -1 || true)" |
| | | if [ -z "$JAR" ]; then |
| | | JAR="$(ls "$HOME"/.m2/repository/mysql/mysql-connector-java/*/mysql-connector-java-*.jar 2>/dev/null | grep -v sources | tail -1 || true)" |
| | | fi |
| | | if [ -z "$JAR" ]; then |
| | | echo "æªæ¾å° MySQL JDBC 驱å¨ï¼è¯·ç¡®è®¤ ~/.m2 ä¸åå¨ mysql-connector-j" >&2 |
| | | exit 1 |
| | | fi |
| | | |
| | | if command -v cygpath >/dev/null 2>&1; then |
| | | JAR="$(cygpath -m "$JAR")" |
| | | SOURCE="$(cygpath -m "$SCRIPT_DIR/DbTool.java")" |
| | | else |
| | | SOURCE="$SCRIPT_DIR/DbTool.java" |
| | | fi |
| | | |
| | | exec java -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 --class-path "$JAR" "$SOURCE" "$@" |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.account.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.account.pojo.PaymentRecord; |
| | | import com.ruoyi.account.service.PaymentRecordService; |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Log; |
| | | import com.ruoyi.framework.aspectj.lang.enums.BusinessType; |
| | | import com.ruoyi.framework.web.controller.BaseController; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 客æ·/ä¾åºå徿¥ä»æ¬¾åæ¬¾æµæ°´ |
| | | * |
| | | * @author :yys |
| | | */ |
| | | @RestController |
| | | @Tag(name = "徿¥ä»æ¬¾å款") |
| | | @RequestMapping("/paymentRecord") |
| | | @AllArgsConstructor |
| | | public class PaymentRecordController extends BaseController { |
| | | |
| | | private PaymentRecordService paymentRecordService; |
| | | |
| | | @GetMapping("/listPage") |
| | | @Log(title = "徿¥ä»æ¬¾å款-å页æ¥è¯¢", businessType = BusinessType.OTHER) |
| | | public AjaxResult listPage(Page page, PaymentRecord paymentRecord) { |
| | | IPage<PaymentRecord> listPage = paymentRecordService.listPage(page, paymentRecord); |
| | | return AjaxResult.success(listPage); |
| | | } |
| | | |
| | | @PostMapping("/add") |
| | | @Log(title = "徿¥ä»æ¬¾å款-æ°å¢", businessType = BusinessType.INSERT) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult add(@RequestBody PaymentRecord paymentRecord) { |
| | | validate(paymentRecord); |
| | | boolean save = paymentRecordService.save(paymentRecord); |
| | | return save ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | | @PostMapping("/update") |
| | | @Log(title = "徿¥ä»æ¬¾å款-ä¿®æ¹", businessType = BusinessType.UPDATE) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult update(@RequestBody PaymentRecord paymentRecord) { |
| | | if (paymentRecord.getId() == null) { |
| | | return AjaxResult.error("缺å°ä¸»é®id"); |
| | | } |
| | | validate(paymentRecord); |
| | | boolean update = paymentRecordService.updateById(paymentRecord); |
| | | return update ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Log(title = "徿¥ä»æ¬¾å款-å é¤", businessType = BusinessType.DELETE) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult delete(@RequestBody List<Long> ids) { |
| | | if (CollectionUtils.isEmpty(ids)) { |
| | | return AjaxResult.error("è¯·éæ©è³å°ä¸æ¡æ°æ®"); |
| | | } |
| | | boolean delete = paymentRecordService.removeBatchByIds(ids); |
| | | return delete ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | | private void validate(PaymentRecord paymentRecord) { |
| | | if (paymentRecord.getPartyType() == null || paymentRecord.getPartyId() == null) { |
| | | throw new RuntimeException("è¯·éæ©å¾æ¥æ¹"); |
| | | } |
| | | if (paymentRecord.getDirection() == null) { |
| | | throw new RuntimeException("è¯·éæ©æ¹åï¼ä»æ¬¾/忬¾ï¼"); |
| | | } |
| | | if (paymentRecord.getAmount() == null) { |
| | | throw new RuntimeException("请填åéé¢"); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.account.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.account.pojo.PaymentRecord; |
| | | |
| | | /** |
| | | * @author :yys |
| | | */ |
| | | public interface PaymentRecordMapper extends BaseMapper<PaymentRecord> { |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.account.pojo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * 客æ·/ä¾åºå徿¥ä»æ¬¾åæ¬¾æµæ°´ |
| | | * |
| | | * @author :yys |
| | | */ |
| | | @Data |
| | | @TableName("payment_record") |
| | | @Schema(name = "PaymentRecord", description = "徿¥ä»æ¬¾åæ¬¾æµæ°´") |
| | | public class PaymentRecord implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | @Schema(description = "主é®id") |
| | | private Long id; |
| | | |
| | | @Schema(description = "徿¥æ¹ç±»å 1å®¢æ· 2ä¾åºå") |
| | | private Integer partyType; |
| | | |
| | | @Schema(description = "客æ·idæä¾åºåid") |
| | | private Long partyId; |
| | | |
| | | @Schema(description = "æ¹å 1仿¬¾ 2忬¾") |
| | | private Integer direction; |
| | | |
| | | @Schema(description = "éé¢") |
| | | private BigDecimal amount; |
| | | |
| | | @Schema(description = "åçæ¥æ") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private LocalDate recordDate; |
| | | |
| | | @Schema(description = "仿¬¾/忬¾æ¹å¼") |
| | | private String paymentMethod; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private LocalDateTime createTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Integer updateUser; |
| | | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.account.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.account.pojo.PaymentRecord; |
| | | |
| | | /** |
| | | * @author :yys |
| | | */ |
| | | public interface PaymentRecordService extends IService<PaymentRecord> { |
| | | |
| | | IPage<PaymentRecord> listPage(Page page, PaymentRecord req); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.account.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.mapper.PaymentRecordMapper; |
| | | import com.ruoyi.account.pojo.PaymentRecord; |
| | | import com.ruoyi.account.service.PaymentRecordService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * @author :yys |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class PaymentRecordServiceImpl extends ServiceImpl<PaymentRecordMapper, PaymentRecord> implements PaymentRecordService { |
| | | |
| | | private final PaymentRecordMapper paymentRecordMapper; |
| | | |
| | | @Override |
| | | public IPage<PaymentRecord> listPage(Page page, PaymentRecord req) { |
| | | LambdaQueryWrapper<PaymentRecord> wrapper = new LambdaQueryWrapper<PaymentRecord>() |
| | | .eq(req.getPartyType() != null, PaymentRecord::getPartyType, req.getPartyType()) |
| | | .eq(req.getPartyId() != null, PaymentRecord::getPartyId, req.getPartyId()) |
| | | .eq(req.getDirection() != null, PaymentRecord::getDirection, req.getDirection()) |
| | | .like(StringUtils.isNotBlank(req.getPaymentMethod()), PaymentRecord::getPaymentMethod, req.getPaymentMethod()) |
| | | .orderByDesc(PaymentRecord::getRecordDate) |
| | | .orderByDesc(PaymentRecord::getId); |
| | | return paymentRecordMapper.selectPage(page, wrapper); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * æ´æ°æ¶é´ |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | /** |
| | | * æ´æ°äºº |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Long updateUser; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * æ´æ°æ¶é´ |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | /** |
| | | * æ´æ°äºº |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Long updateUser; |
| | | |
| | | /** |
| | |
| | | import com.ruoyi.collaborativeApproval.pojo.RulesRegulationsManagement; |
| | | import com.ruoyi.collaborativeApproval.pojo.SealApplicationManagement; |
| | | import com.ruoyi.collaborativeApproval.service.RulesRegulationsManagementService; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | |
| | | @PostMapping("/update") |
| | | @Operation(summary = "ä¿®æ¹") |
| | | public AjaxResult update(@RequestBody RulesRegulationsManagement rulesRegulationsManagement){ |
| | | // å端åä¼ æ´è¡ä¼å¸¦ä¸æ§ç updateTime/updateUserï¼å¯¼è´èªå¨å¡«å
被跳è¿ï¼éæ¾å¼åæ¥ä¸ºå½åæä½äººä¸æ¶é´ |
| | | rulesRegulationsManagement.setUpdateTime(LocalDateTime.now()); |
| | | rulesRegulationsManagement.setUpdateUser(SecurityUtils.getUserId().intValue()); |
| | | return AjaxResult.success(rulesRegulationsManagementService.updateById(rulesRegulationsManagement)); |
| | | } |
| | | |
| | |
| | | //åä¼äººåid(人åå°è´¦åç¨æ·è¡¨éè¿äººåç¼å·åç¨æ·åç§°(ç»å½è´¦å·)åå¹é
) |
| | | if (Integer.valueOf(1).equals(meetApplication.getPublishStatus())) { |
| | | MeetApplication application = meetApplicationMapper.selectById(meetApplication.getId()); |
| | | |
| | | String cleanStr = application.getParticipants() |
| | | .replaceAll("^\\[|\\]$", "") |
| | | .trim(); |
| | | |
| | | List<Long> userIds = Arrays.stream(cleanStr.split(",")) |
| | | .map(String::trim) |
| | | .filter(s -> !s.isEmpty()) |
| | | .map(Long::valueOf) |
| | | .map(staffId -> { |
| | | StaffOnJob record = staffOnJobMapper.selectById(staffId); |
| | | if (record == null) { |
| | | return null; |
| | | } |
| | | return userMapper.selectOne( |
| | | Wrappers.<SysUser>lambdaQuery() |
| | | .eq(SysUser::getUserName, record.getStaffNo()) |
| | | ); |
| | | }) |
| | | .filter(Objects::nonNull) |
| | | .map(SysUser::getUserId) |
| | | .collect(Collectors.toList()); |
| | | List<Long> userIds = resolveParticipantUserIds(application.getParticipants()); |
| | | |
| | | if (!userIds.isEmpty()) { |
| | | sysNoticeService.simpleNoticeByUser( |
| | |
| | | return R.ok(); |
| | | } |
| | | |
| | | // åä¼äººåå°è´¦id -> ç»å½ç¨æ·idï¼åä¸ç»å½è´¦å·å¨ sys_user åå¨å¤æ¡åå²è®°å½æ¶ï¼ææªå é¤ä¼å
å䏿¡ï¼é¿å
selectOne æ TooManyResultsException |
| | | private List<Long> resolveParticipantUserIds(String participants) { |
| | | if (StrUtil.isBlank(participants)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | String cleanStr = participants.replaceAll("^\\[|\\]$", "").trim(); |
| | | if (cleanStr.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<Long> staffIds = Arrays.stream(cleanStr.split(",")) |
| | | .map(String::trim) |
| | | .filter(s -> !s.isEmpty()) |
| | | .map(Long::valueOf) |
| | | .collect(Collectors.toList()); |
| | | if (staffIds.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<String> loginNames = staffOnJobMapper.selectBatchIds(staffIds).stream() |
| | | .map(StaffOnJob::getStaffNo) |
| | | .filter(StrUtil::isNotBlank) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | if (loginNames.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return userMapper.selectList(Wrappers.<SysUser>lambdaQuery() |
| | | .in(SysUser::getUserName, loginNames) |
| | | .orderByAsc(SysUser::getDelFlag) |
| | | .orderByAsc(SysUser::getUserId)) |
| | | .stream() |
| | | .collect(Collectors.toMap(SysUser::getUserName, SysUser::getUserId, |
| | | (first, ignored) -> first, LinkedHashMap::new)) |
| | | .values() |
| | | .stream() |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<MeetApplication> getMeetingApplicationList(SearchMeetingApplicationVo vo) { |
| | | LambdaQueryWrapper<MeetApplication> queryWrapper = new LambdaQueryWrapper<>(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.common.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * éè´ç³è¯·ç¶ææä¸¾ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum PurchaseApplicationStatusEnum implements BaseEnum<Integer> { |
| | | |
| | | DRAFT(0, "è稿"), |
| | | ORDER_GENERATED(1, "å·²çæè®¢å"); |
| | | |
| | | private final Integer value; |
| | | private final String label; |
| | | |
| | | @Override |
| | | public Integer getCode() { |
| | | return value; |
| | | } |
| | | |
| | | @Override |
| | | public String getValue() { |
| | | return label; |
| | | } |
| | | |
| | | public static String getLabelByValue(Integer value) { |
| | | if (value == null) { |
| | | return "æªç¥ç¶æ"; |
| | | } |
| | | for (PurchaseApplicationStatusEnum status : values()) { |
| | | if (status.getCode().equals(value)) { |
| | | return status.getValue(); |
| | | } |
| | | } |
| | | return "æªç¥ç¶æ"; |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SpareParts; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRecordService; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | |
| | | private final DeviceMaintenanceMapper deviceMaintenanceMapper; |
| | | private final SparePartsMapper sparePartsMapper; |
| | | private final SparePartsRequisitionRecordService sparePartsRequisitionRecordService; |
| | | private final SparePartsRecordService sparePartsRecordService; |
| | | private final FileUtil fileUtil; |
| | | |
| | | @Override |
| | |
| | | record.setSparePartsId(sparePartUse.getId()); |
| | | record.setQuantity(sparePartUse.getQuantity()); |
| | | sparePartsRequisitionRecordService.save(record); |
| | | |
| | | // 追å å¤ä»¶åºåºæµæ°´ï¼3 ä¿å
»é¢ç¨ï¼ |
| | | SparePartsRecord outRecord = new SparePartsRecord(); |
| | | outRecord.setSparePartsId(sparePartUse.getId()); |
| | | outRecord.setDirection(2); |
| | | outRecord.setQuantity(new BigDecimal(sparePartUse.getQuantity())); |
| | | outRecord.setSourceType(3); |
| | | outRecord.setSourceId(deviceMaintenance.getId()); |
| | | sparePartsRecordService.save(outRecord); |
| | | } else { |
| | | return AjaxResult.error("å¤ä»¶ " + spareParts.getName() + " æ°éä¸è¶³"); |
| | | } |
| | |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SpareParts; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRecordService; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | |
| | | private final IDeviceLedgerService deviceLedgerService; |
| | | private final SparePartsMapper sparePartsMapper; |
| | | private final SparePartsRequisitionRecordService sparePartsRequisitionRecordService; |
| | | private final SparePartsRecordService sparePartsRecordService; |
| | | private final FileUtil fileUtil; |
| | | |
| | | private static final int STATUS_PENDING_REPAIR = 0; |
| | |
| | | record.setSparePartsId(sparePartUse.getId()); |
| | | record.setQuantity(sparePartUse.getQuantity()); |
| | | sparePartsRequisitionRecordService.save(record); |
| | | |
| | | // 追å å¤ä»¶åºåºæµæ°´ï¼2 ç»´ä¿®é¢ç¨ï¼ |
| | | SparePartsRecord outRecord = new SparePartsRecord(); |
| | | outRecord.setSparePartsId(sparePartUse.getId()); |
| | | outRecord.setDirection(2); |
| | | outRecord.setQuantity(new BigDecimal(sparePartUse.getQuantity())); |
| | | outRecord.setSourceType(2); |
| | | outRecord.setSourceId(deviceRepairDto.getId()); |
| | | sparePartsRecordService.save(outRecord); |
| | | } else { |
| | | return AjaxResult.error("å¤ä»¶ " + spareParts.getName() + " æ°éä¸è¶³"); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.measuringinstrumentledger.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Log; |
| | | import com.ruoyi.framework.aspectj.lang.enums.BusinessType; |
| | | import com.ruoyi.framework.web.controller.BaseController; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRecordService; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å¤ä»¶åºå
¥åºæµæ°´ |
| | | * |
| | | * @author :yys |
| | | */ |
| | | @RestController |
| | | @Tag(name = "å¤ä»¶åºå
¥åºæµæ°´") |
| | | @RequestMapping("/sparePartsRecord") |
| | | @AllArgsConstructor |
| | | public class SparePartsRecordController extends BaseController { |
| | | |
| | | private SparePartsRecordService sparePartsRecordService; |
| | | |
| | | @GetMapping("/listPage") |
| | | @Log(title = "å¤ä»¶åºå
¥åºæµæ°´-å页æ¥è¯¢", businessType = BusinessType.OTHER) |
| | | public AjaxResult listPage(Page page, SparePartsRecord sparePartsRecord) { |
| | | IPage<SparePartsRecord> listPage = sparePartsRecordService.listPage(page, sparePartsRecord); |
| | | return AjaxResult.success(listPage); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Log(title = "å¤ä»¶åºå
¥åºæµæ°´-å é¤", businessType = BusinessType.DELETE) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult delete(@RequestBody List<Long> ids) { |
| | | if (CollectionUtils.isEmpty(ids)) { |
| | | return AjaxResult.error("è¯·éæ©è³å°ä¸æ¡æ°æ®"); |
| | | } |
| | | boolean delete = sparePartsRecordService.removeBatchByIds(ids); |
| | | return delete ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.measuringinstrumentledger.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | /** |
| | | * @author :yys |
| | | */ |
| | | public interface SparePartsRecordMapper extends BaseMapper<SparePartsRecord> { |
| | | |
| | | IPage<SparePartsRecord> listPage(Page page, @Param("req") SparePartsRecord req); |
| | | } |
| | |
| | | */ |
| | | private Long parentId; |
| | | /** |
| | | * å
³è产å大类id |
| | | */ |
| | | private Long productId; |
| | | /** |
| | | * å
³è产åè§æ ¼idï¼éè´å°è´¦æç»ææ¤å¹é
å¤ä»¶ï¼ |
| | | */ |
| | | private Long productModelId; |
| | | /** |
| | | * å¤ä»¶ç¶æ |
| | | */ |
| | | private String status; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.measuringinstrumentledger.pojo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å¤ä»¶åºå
¥åºæµæ°´ |
| | | * |
| | | * @author :yys |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | @TableName("spare_parts_record") |
| | | @Schema(name = "SparePartsRecord对象", description = "å¤ä»¶åºå
¥åºæµæ°´") |
| | | public class SparePartsRecord implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @Schema(description = "å¤ä»¶id") |
| | | private Long sparePartsId; |
| | | |
| | | @Schema(description = "æ¹å 1å
¥åº 2åºåº") |
| | | private Integer direction; |
| | | |
| | | @Schema(description = "æ°é") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "æ¥æºç±»å 1éè´å
¥åº 2ç»´ä¿®é¢ç¨ 3ä¿å
»é¢ç¨") |
| | | private Integer sourceType; |
| | | |
| | | @Schema(description = "æ¥æºåæ®id") |
| | | private Long sourceId; |
| | | |
| | | @Schema(description = "æ¥æºåå·") |
| | | private String sourceNo; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å¤ä»¶åç§°") |
| | | @TableField(exist = false) |
| | | private String sparePartsName; |
| | | |
| | | @Schema(description = "ç§æ·id") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | @Schema(description = "å建人") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | | |
| | | @Schema(description = "å½å
¥æ¶é´") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "æ´æ°æ¶é´") |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Integer updateUser; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.measuringinstrumentledger.service; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | |
| | | /** |
| | | * @author :yys |
| | | */ |
| | | public interface SparePartsRecordService extends IService<SparePartsRecord> { |
| | | |
| | | IPage<SparePartsRecord> listPage(Page page, SparePartsRecord req); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.measuringinstrumentledger.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.measuringinstrumentledger.mapper.SparePartsRecordMapper; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRecordService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * @author :yys |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class SparePartsRecordServiceImpl extends ServiceImpl<SparePartsRecordMapper, SparePartsRecord> implements SparePartsRecordService { |
| | | |
| | | private final SparePartsRecordMapper sparePartsRecordMapper; |
| | | |
| | | @Override |
| | | public IPage<SparePartsRecord> listPage(Page page, SparePartsRecord req) { |
| | | return sparePartsRecordMapper.listPage(page, req); |
| | | } |
| | | } |
| | |
| | | |
| | | private String purchaseContractNumber; |
| | | |
| | | /** |
| | | * éè´å°è´¦idï¼æ°å¢å
¥åºé订ååç²¾ç¡®åæ¾æç»ç¨ï¼ä¼äºæååå·æ¨¡ç³å¹é
ï¼ |
| | | */ |
| | | private Integer purchaseLedgerId; |
| | | |
| | | private Integer id; |
| | | |
| | | private Integer recordId; |
| | |
| | | |
| | | private Long productModelId;// åºç¡äº§åID |
| | | |
| | | /** |
| | | * åºåºæ¹æ¬¡ï¼éå®åºåºå¿
å¡«ï¼æ£åºåææ¹æ¬¡æ£ï¼ |
| | | */ |
| | | private String batchNo; |
| | | |
| | | } |
| | |
| | | @Excel(name = "åºåºç¼å·") |
| | | private String code; |
| | | |
| | | /** |
| | | * åºåºæ¹æ¬¡ |
| | | */ |
| | | private String batchNo; |
| | | |
| | | /** |
| | | * èªå¨çæçåè´§åå·ï¼éå®åºåºæç®åè´§ï¼ |
| | | */ |
| | | @Excel(name = "åè´§åå·") |
| | | private String shippingNo; |
| | | |
| | | private Integer id; |
| | | |
| | | private BigDecimal warnNum; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.procurementrecord.bean.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * åºåºå¯éæ¹æ¬¡ï¼æ¹æ¬¡å· + å½åå¯ç¨é |
| | | * |
| | | * @author :yys |
| | | */ |
| | | @Data |
| | | @Schema(name = "BatchNoOptionVo", description = "åºåºå¯éæ¹æ¬¡") |
| | | public class BatchNoOptionVo { |
| | | |
| | | @Schema(description = "è§æ ¼åå·id") |
| | | private Long productModelId; |
| | | |
| | | @Schema(description = "æ¹å·") |
| | | private String batchNo; |
| | | |
| | | @Schema(description = "å¯ç¨éï¼åºåé - é宿°éï¼") |
| | | private BigDecimal availableQuantity; |
| | | } |
| | |
| | | return AjaxResult.success(result); |
| | | } |
| | | |
| | | /** |
| | | * éå®åºåºéæ¹æ¬¡ï¼æè§æ ¼åå·æ¥å¯éæ¹æ¬¡ä¸å¯ç¨é |
| | | */ |
| | | @GetMapping("/batchNoList") |
| | | @Log(title = "éè´åºåº-åºåºç®¡ç-æ¹æ¬¡å表", businessType = BusinessType.OTHER) |
| | | public AjaxResult batchNoList(@RequestParam("productModelId") Long productModelId) { |
| | | return AjaxResult.success(procurementRecordOutService.listBatchNoByProductModelId(productModelId)); |
| | | } |
| | | |
| | | @GetMapping("/listPageByProduct") |
| | | @Log(title = "ç产åºåº-åºåºå°è´¦-åºåºæ¥è¯¢", businessType = BusinessType.OTHER) |
| | | public AjaxResult listPageByProduct(Page page, ProcurementRecordOutPageDto procurementDto) { |
| | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementRecordOutPageDto; |
| | | import com.ruoyi.procurementrecord.bean.vo.BatchNoOptionVo; |
| | | import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | |
| | | ProcurementRecordOut selectCode(@Param("format") String format); |
| | | |
| | | IPage<ProcurementRecordOutPageDto> listPageBySemiProduct(Page page,@Param("req") ProcurementRecordOutPageDto procurementDto); |
| | | |
| | | /** |
| | | * æ¥è¯¢æè§æ ¼åå·ä¸å¯éæ¹æ¬¡åå¯ç¨éï¼éå®åºåºéæ¹æ¬¡ç¨ï¼ |
| | | */ |
| | | List<BatchNoOptionVo> listBatchNoByProductModelId(@Param("productModelId") Long productModelId); |
| | | } |
| | |
| | | */ |
| | | private Long productModelId; |
| | | |
| | | /** |
| | | * åºåºæ¹æ¬¡ï¼æ£åºåç¨ï¼ |
| | | */ |
| | | private String batchNo; |
| | | |
| | | /** |
| | | * éå®åºåºæ¶èªå¨çæçåè´§å°è´¦id |
| | | */ |
| | | private Long shippingInfoId; |
| | | |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementRecordOutAdd; |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementRecordOutPageDto; |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementUpdateDto; |
| | | import com.ruoyi.procurementrecord.bean.vo.BatchNoOptionVo; |
| | | import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author :yys |
| | |
| | | IPage<ProcurementRecordOutPageDto> listPageByCustom(Page page, ProcurementRecordOutPageDto procurementDto); |
| | | |
| | | IPage<ProcurementRecordOutPageDto> listPageBySemiProduct(Page page, ProcurementRecordOutPageDto procurementDto); |
| | | |
| | | /** |
| | | * éå®åºåºéæ¹æ¬¡ï¼è¿åè¯¥è§æ ¼åå·ä¸çå¯éæ¹æ¬¡ä¸å¯ç¨é |
| | | */ |
| | | List<BatchNoOptionVo> listBatchNoByProductModelId(Long productModelId); |
| | | } |
| | |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementRecordOutAdd; |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementRecordOutPageDto; |
| | | import com.ruoyi.procurementrecord.bean.dto.ProcurementUpdateDto; |
| | | import com.ruoyi.procurementrecord.bean.vo.BatchNoOptionVo; |
| | | import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper; |
| | | import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut; |
| | | import com.ruoyi.procurementrecord.service.ProcurementRecordOutService; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | | import com.ruoyi.project.system.mapper.SysUserMapper; |
| | | import com.ruoyi.sales.dto.ShippingInfoDto; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import com.ruoyi.sales.pojo.ShippingProductDetail; |
| | | import com.ruoyi.sales.service.ShippingInfoService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | @Slf4j |
| | | public class ProcurementRecordOutServiceImpl extends ServiceImpl<ProcurementRecordOutMapper, ProcurementRecordOut> implements ProcurementRecordOutService { |
| | | |
| | | /** |
| | | * åºåºç±»åï¼éå®åºåºãæ²¹åéå®åºåºå³åè´§ |
| | | */ |
| | | private static final Integer TYPE_SALE_OUT = 2; |
| | | |
| | | /** |
| | | * éå®äº§åæç»ç±»åï¼1éå®ï¼sales_ledger_product.typeï¼ä¸åºåº type è¯ä¹ä¸åï¼ |
| | | */ |
| | | private static final Integer LEDGER_PRODUCT_TYPE_SALE = 1; |
| | | |
| | | public final ProcurementRecordOutMapper procurementRecordOutMapper; |
| | | |
| | | public final SysUserMapper sysUserMapper; |
| | | |
| | | public final ShippingInfoService shippingInfoService; |
| | | |
| | | public final SalesLedgerProductMapper salesLedgerProductMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int stockout(ProcurementRecordOutAdd procurementRecordOutAdd) { |
| | | SysUser sysUser = sysUserMapper.selectUserById(Long.valueOf(procurementRecordOutAdd.getUserId().toString())); |
| | | if(sysUser == null){ |
| | |
| | | .createBy(sysUser.getNickName()) |
| | | .updateUser(Long.valueOf(procurementRecordOutAdd.getUserId())) |
| | | .updateTime(LocalDateTime.now()) |
| | | .productModelId(procurementRecordOutAdd.getProductModelId()); |
| | | this.save(procurementRecordOut.build()); |
| | | .productModelId(procurementRecordOutAdd.getProductModelId()) |
| | | .batchNo(procurementRecordOutAdd.getBatchNo()); |
| | | ProcurementRecordOut record = procurementRecordOut.build(); |
| | | this.save(record); |
| | | |
| | | // æ²¹åéå®åºåºå³åè´§ï¼èªå¨çæä¸æ¡å·²åè´§çåè´§å°è´¦å¹¶ååå
³è |
| | | if (TYPE_SALE_OUT.equals(record.getType())) { |
| | | record.setShippingInfoId(createShippingForOutbound(record)); |
| | | this.updateById(record); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * æåºåºè®°å½çæåè´§å°è´¦ï¼æ¹æ¬¡å¿
å¡«ï¼åºåç±åè´§ä¾§æ£å |
| | | */ |
| | | private Long createShippingForOutbound(ProcurementRecordOut record) { |
| | | if (StringUtils.isBlank(record.getBatchNo())) { |
| | | throw new RuntimeException("è¯·éæ©åºåºæ¹æ¬¡"); |
| | | } |
| | | SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(record.getSalesLedgerProductId()); |
| | | if (salesLedgerProduct == null || !LEDGER_PRODUCT_TYPE_SALE.equals(salesLedgerProduct.getType())) { |
| | | throw new RuntimeException("éå®åºåºæªå
³èå°ææçéå®äº§åæç»"); |
| | | } |
| | | ShippingProductDetail detail = new ShippingProductDetail(); |
| | | detail.setProductModelId(record.getProductModelId()); |
| | | detail.setQuantity(record.getInboundNum()); |
| | | detail.setBatchNo(record.getBatchNo()); |
| | | |
| | | ShippingInfoDto shippingInfoDto = new ShippingInfoDto(); |
| | | shippingInfoDto.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId()); |
| | | shippingInfoDto.setSalesLedgerProductId(record.getSalesLedgerProductId()); |
| | | shippingInfoDto.setBatchNoDetailList(Collections.singletonList(detail)); |
| | | return shippingInfoService.addShippedFromOutbound(shippingInfoDto); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int deletePro(ProcurementUpdateDto procurementDto) { |
| | | List<ProcurementRecordOut> procurementRecordOutByIds = getProcurementRecordOutByIds(procurementDto.getIds()); |
| | | if(CollectionUtils.isEmpty(procurementRecordOutByIds)){ |
| | | throw new RuntimeException("æªæ¥è¯¢å°éä¸ç人"); |
| | | } |
| | | // éå®åºåºå·²çæåè´§åï¼å é¤åºåºååå
å²éåè´§åå¹¶å½è¿å·²æ£åºå |
| | | for (ProcurementRecordOut record : procurementRecordOutByIds) { |
| | | if (record.getShippingInfoId() != null) { |
| | | shippingInfoService.cancelByOutbound(record.getShippingInfoId()); |
| | | } |
| | | } |
| | | procurementRecordOutMapper.deleteBatchIds(procurementRecordOutByIds.stream().map(ProcurementRecordOut::getId).collect(Collectors.toList())); |
| | | return 0; |
| | |
| | | public IPage<ProcurementRecordOutPageDto> listPageBySemiProduct(Page page, ProcurementRecordOutPageDto procurementDto) { |
| | | return procurementRecordOutMapper.listPageBySemiProduct(page, procurementDto); |
| | | } |
| | | |
| | | @Override |
| | | public List<BatchNoOptionVo> listBatchNoByProductModelId(Long productModelId) { |
| | | if (productModelId == null) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return procurementRecordOutMapper.listBatchNoByProductModelId(productModelId); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.controller; |
| | | |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Log; |
| | | import com.ruoyi.framework.aspectj.lang.enums.BusinessType; |
| | | import com.ruoyi.framework.web.controller.BaseController; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.framework.web.page.TableDataInfo; |
| | | import com.ruoyi.purchase.dto.PurchaseApplicationDto; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplication; |
| | | import com.ruoyi.purchase.service.PurchaseApplicationService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.DeleteMapping; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éè´ç³è¯·å Controller |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/purchase/application") |
| | | @AllArgsConstructor |
| | | @Tag(name = "éè´ç³è¯·") |
| | | public class PurchaseApplicationController extends BaseController { |
| | | |
| | | private final PurchaseApplicationService purchaseApplicationService; |
| | | |
| | | /** |
| | | * æ¥è¯¢éè´ç³è¯·å表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo list(PurchaseApplicationDto purchaseApplicationDto) { |
| | | startPage(); |
| | | List<PurchaseApplication> list = purchaseApplicationService.selectApplicationList(purchaseApplicationDto); |
| | | return getDataTable(list); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢éè´ç³è¯·è¯¦æ
ï¼å«äº§åæç»ï¼ |
| | | */ |
| | | @GetMapping("/getById") |
| | | public AjaxResult getById(@RequestParam Long id) { |
| | | return AjaxResult.success(purchaseApplicationService.getDetail(id)); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢éè´ç³è¯·ï¼èç¨¿ï¼ |
| | | */ |
| | | @Log(title = "éè´ç³è¯·", businessType = BusinessType.INSERT) |
| | | @PostMapping("/add") |
| | | public AjaxResult add(@RequestBody PurchaseApplicationDto purchaseApplicationDto) { |
| | | return AjaxResult.success(purchaseApplicationService.saveApplication(purchaseApplicationDto)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹éè´ç³è¯·ï¼ä»
èç¨¿ç¶æå
è®¸ä¿®æ¹ |
| | | */ |
| | | @Log(title = "éè´ç³è¯·", businessType = BusinessType.UPDATE) |
| | | @PostMapping("/edit") |
| | | public AjaxResult edit(@RequestBody PurchaseApplicationDto purchaseApplicationDto) { |
| | | return toAjax(purchaseApplicationService.updateApplication(purchaseApplicationDto)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éè´ç³è¯·ï¼ä»
èç¨¿ç¶æå
许å é¤ |
| | | */ |
| | | @Log(title = "éè´ç³è¯·", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/delete") |
| | | public AjaxResult delete(@RequestBody Long[] ids) { |
| | | return toAjax(purchaseApplicationService.deleteApplications( |
| | | ids == null ? List.of() : List.of(ids))); |
| | | } |
| | | |
| | | /** |
| | | * éè´ç³è¯·è½¬è®¢åï¼çæéè´å°è´¦å¹¶æäº¤ OA éè´å®¡æ¹ |
| | | */ |
| | | @Operation(summary = "éè´ç³è¯·è½¬è®¢å") |
| | | @Log(title = "éè´ç³è¯·è½¬è®¢å", businessType = BusinessType.OTHER) |
| | | @PostMapping("/convertToOrder") |
| | | public AjaxResult convertToOrder(@RequestParam Long id) { |
| | | return AjaxResult.success(purchaseApplicationService.convertToOrder(id)); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.dto; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplicationProduct; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éè´ç³è¯·å DTO |
| | | */ |
| | | @Data |
| | | public class PurchaseApplicationDto { |
| | | |
| | | @Schema(description = "ç³è¯·å主é®") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç³è¯·åå·") |
| | | private String applicationNo; |
| | | |
| | | @Schema(description = "ä¾åºåid") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "ä¾åºååç§°") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "项ç®åç§°") |
| | | private String projectName; |
| | | |
| | | @Schema(description = "éå®ååå·") |
| | | private String salesContractNo; |
| | | |
| | | @Schema(description = "å
³èéå®å°è´¦ä¸»è¡¨ä¸»é®") |
| | | private Long salesLedgerId; |
| | | |
| | | @Schema(description = "ç³è¯·äººid") |
| | | private Long applicantId; |
| | | |
| | | @Schema(description = "ç³è¯·äººå§å") |
| | | private String applicantName; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥æ") |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private LocalDate applyDate; |
| | | |
| | | @Schema(description = "ææå°è´§æ¥æ") |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private LocalDate expectedArrivalDate; |
| | | |
| | | @Schema(description = "ç³è¯·éé¢ï¼å«ç¨æ»ä»·ï¼") |
| | | private BigDecimal contractAmount; |
| | | |
| | | @Schema(description = "仿¬¾æ¹å¼") |
| | | private String paymentMethod; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remarks; |
| | | |
| | | @Schema(description = "ç¶æ 0è稿 1å·²çæè®¢å") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "转订ååçæçéè´å°è´¦id") |
| | | private Long purchaseLedgerId; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥ææ¥è¯¢å¼å§ï¼yyyy-MM-ddï¼") |
| | | private String startDate; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥ææ¥è¯¢ç»æï¼yyyy-MM-ddï¼") |
| | | private String endDate; |
| | | |
| | | @Schema(description = "éè´ç³è¯·äº§åæç»") |
| | | private List<PurchaseApplicationProduct> productData; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplication; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * éè´ç³è¯·å Mapper æ¥å£ |
| | | */ |
| | | @Mapper |
| | | public interface PurchaseApplicationMapper extends BaseMapper<PurchaseApplication> { |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplicationProduct; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * éè´ç³è¯·äº§åæç» Mapper æ¥å£ |
| | | */ |
| | | @Mapper |
| | | public interface PurchaseApplicationProductMapper extends BaseMapper<PurchaseApplicationProduct> { |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.pojo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éè´ç³è¯·å对象 purchase_application |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | @TableName("purchase_application") |
| | | @Schema(name = "PurchaseApplication对象", description = "éè´ç³è¯·å") |
| | | public class PurchaseApplication implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç³è¯·åå·") |
| | | private String applicationNo; |
| | | |
| | | @Schema(description = "ä¾åºåid") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "ä¾åºååç§°") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "项ç®åç§°") |
| | | private String projectName; |
| | | |
| | | @Schema(description = "éå®ååå·") |
| | | private String salesContractNo; |
| | | |
| | | @Schema(description = "å
³èéå®å°è´¦ä¸»è¡¨ä¸»é®") |
| | | private Long salesLedgerId; |
| | | |
| | | @Schema(description = "ç³è¯·äººid") |
| | | private Long applicantId; |
| | | |
| | | @Schema(description = "ç³è¯·äººå§å") |
| | | private String applicantName; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥æ") |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private LocalDate applyDate; |
| | | |
| | | @Schema(description = "ææå°è´§æ¥æ") |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd") |
| | | private LocalDate expectedArrivalDate; |
| | | |
| | | @Schema(description = "ç³è¯·éé¢ï¼å«ç¨æ»ä»·ï¼") |
| | | private BigDecimal contractAmount; |
| | | |
| | | @Schema(description = "仿¬¾æ¹å¼") |
| | | private String paymentMethod; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remarks; |
| | | |
| | | @Schema(description = "ç¶æ 0è稿 1å·²çæè®¢å") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "转订ååçæçéè´å°è´¦id") |
| | | private Long purchaseLedgerId; |
| | | |
| | | @Schema(description = "è½¬è®¢åæ¶é´") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime convertTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @TableField(exist = false) |
| | | @Schema(description = "éè´ç³è¯·äº§åæç»") |
| | | private List<PurchaseApplicationProduct> productData; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.pojo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * éè´ç³è¯·äº§åæç»å¯¹è±¡ purchase_application_product |
| | | */ |
| | | @Getter |
| | | @Setter |
| | | @TableName("purchase_application_product") |
| | | @Schema(name = "PurchaseApplicationProduct对象", description = "éè´ç³è¯·äº§åæç»") |
| | | public class PurchaseApplicationProduct implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´ç³è¯·åid") |
| | | private Long purchaseApplicationId; |
| | | |
| | | @Schema(description = "产åid") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产åè§æ ¼id") |
| | | private Long productModelId; |
| | | |
| | | @Schema(description = "产å大类") |
| | | private String productCategory; |
| | | |
| | | @Schema(description = "è§æ ¼åå·") |
| | | private String specificationModel; |
| | | |
| | | @Schema(description = "åä½") |
| | | private String unit; |
| | | |
| | | @Schema(description = "æ°é") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "ç¨ç") |
| | | private BigDecimal taxRate; |
| | | |
| | | @Schema(description = "å«ç¨åä»·") |
| | | private BigDecimal taxInclusiveUnitPrice; |
| | | |
| | | @Schema(description = "å«ç¨æ»ä»·") |
| | | private BigDecimal taxInclusiveTotalPrice; |
| | | |
| | | @Schema(description = "ä¸å«ç¨æ»ä»·") |
| | | private BigDecimal taxExclusiveTotalPrice; |
| | | |
| | | @Schema(description = "å票类å") |
| | | private String invoiceType; |
| | | |
| | | @Schema(description = "æ¯å¦æ¨éè´¨æ£") |
| | | private Boolean isChecked; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime updateTime; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.purchase.dto.PurchaseApplicationDto; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplication; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * éè´ç³è¯·å Service æ¥å£ |
| | | */ |
| | | public interface PurchaseApplicationService extends IService<PurchaseApplication> { |
| | | |
| | | /** |
| | | * æ¥è¯¢éè´ç³è¯·å表 |
| | | */ |
| | | List<PurchaseApplication> selectApplicationList(PurchaseApplicationDto purchaseApplicationDto); |
| | | |
| | | /** |
| | | * æ¥è¯¢éè´ç³è¯·è¯¦æ
ï¼å«äº§åæç»ï¼ |
| | | */ |
| | | PurchaseApplicationDto getDetail(Long id); |
| | | |
| | | /** |
| | | * æ°å¢éè´ç³è¯·ï¼èç¨¿ï¼ |
| | | */ |
| | | Long saveApplication(PurchaseApplicationDto purchaseApplicationDto); |
| | | |
| | | /** |
| | | * ç¼è¾éè´ç³è¯·ï¼ä»
èç¨¿ç¶æå
许ç¼è¾ |
| | | */ |
| | | boolean updateApplication(PurchaseApplicationDto purchaseApplicationDto); |
| | | |
| | | /** |
| | | * å é¤éè´ç³è¯·ï¼ä»
èç¨¿ç¶æå
许å é¤ |
| | | */ |
| | | boolean deleteApplications(List<Long> ids); |
| | | |
| | | /** |
| | | * éè´ç³è¯·è½¬è®¢åï¼çæéè´å°è´¦å¹¶æäº¤ OA éè´å®¡æ¹ï¼è¿åéè´å°è´¦id |
| | | */ |
| | | Long convertToOrder(Long id); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.purchase.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.mapper.ProductMapper; |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | | import com.ruoyi.basic.mapper.SupplierManageMapper; |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.basic.pojo.SupplierManage; |
| | | import com.ruoyi.common.enums.PurchaseApplicationStatusEnum; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import com.ruoyi.common.utils.OrderUtils; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | | import com.ruoyi.project.system.mapper.SysUserMapper; |
| | | import com.ruoyi.purchase.dto.PurchaseApplicationDto; |
| | | import com.ruoyi.purchase.dto.PurchaseLedgerDto; |
| | | import com.ruoyi.purchase.mapper.PurchaseApplicationMapper; |
| | | import com.ruoyi.purchase.mapper.PurchaseApplicationProductMapper; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplication; |
| | | import com.ruoyi.purchase.pojo.PurchaseApplicationProduct; |
| | | import com.ruoyi.purchase.service.IPurchaseLedgerService; |
| | | import com.ruoyi.purchase.service.PurchaseApplicationService; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * éè´ç³è¯·å Service ä¸å¡å±å¤ç |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class PurchaseApplicationServiceImpl extends ServiceImpl<PurchaseApplicationMapper, PurchaseApplication> |
| | | implements PurchaseApplicationService { |
| | | |
| | | private static final String APPLICATION_NO_PREFIX = "CGSQ"; |
| | | |
| | | private final PurchaseApplicationMapper purchaseApplicationMapper; |
| | | private final PurchaseApplicationProductMapper purchaseApplicationProductMapper; |
| | | private final IPurchaseLedgerService purchaseLedgerService; |
| | | private final SupplierManageMapper supplierManageMapper; |
| | | private final SysUserMapper sysUserMapper; |
| | | private final ProductMapper productMapper; |
| | | private final ProductModelMapper productModelMapper; |
| | | |
| | | @Override |
| | | public List<PurchaseApplication> selectApplicationList(PurchaseApplicationDto purchaseApplicationDto) { |
| | | LambdaQueryWrapper<PurchaseApplication> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.like(StringUtils.isNotBlank(purchaseApplicationDto.getApplicationNo()), |
| | | PurchaseApplication::getApplicationNo, purchaseApplicationDto.getApplicationNo()) |
| | | .like(StringUtils.isNotBlank(purchaseApplicationDto.getProjectName()), |
| | | PurchaseApplication::getProjectName, purchaseApplicationDto.getProjectName()) |
| | | .eq(purchaseApplicationDto.getSupplierId() != null, |
| | | PurchaseApplication::getSupplierId, purchaseApplicationDto.getSupplierId()) |
| | | .eq(purchaseApplicationDto.getStatus() != null, |
| | | PurchaseApplication::getStatus, purchaseApplicationDto.getStatus()) |
| | | .ge(StringUtils.isNotBlank(purchaseApplicationDto.getStartDate()), |
| | | PurchaseApplication::getApplyDate, purchaseApplicationDto.getStartDate()) |
| | | .le(StringUtils.isNotBlank(purchaseApplicationDto.getEndDate()), |
| | | PurchaseApplication::getApplyDate, purchaseApplicationDto.getEndDate()) |
| | | .orderByDesc(PurchaseApplication::getId); |
| | | return this.list(queryWrapper); |
| | | } |
| | | |
| | | @Override |
| | | public PurchaseApplicationDto getDetail(Long id) { |
| | | PurchaseApplication application = this.getById(id); |
| | | if (application == null) { |
| | | throw new ServiceException("éè´ç³è¯·ä¸åå¨"); |
| | | } |
| | | PurchaseApplicationDto resultDto = new PurchaseApplicationDto(); |
| | | BeanUtils.copyProperties(application, resultDto); |
| | | resultDto.setProductData(listProducts(id)); |
| | | return resultDto; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long saveApplication(PurchaseApplicationDto purchaseApplicationDto) { |
| | | PurchaseApplication application = new PurchaseApplication(); |
| | | BeanUtils.copyProperties(purchaseApplicationDto, application); |
| | | application.setId(null); |
| | | application.setStatus(PurchaseApplicationStatusEnum.DRAFT.getCode()); |
| | | application.setPurchaseLedgerId(null); |
| | | application.setConvertTime(null); |
| | | application.setApplicationNo(OrderUtils.countTodayByCreateTime( |
| | | purchaseApplicationMapper, APPLICATION_NO_PREFIX, "application_no", LocalDateTime.now())); |
| | | fillSupplierName(application); |
| | | fillApplicant(application, purchaseApplicationDto); |
| | | this.save(application); |
| | | |
| | | saveProducts(application.getId(), purchaseApplicationDto.getProductData()); |
| | | return application.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean updateApplication(PurchaseApplicationDto purchaseApplicationDto) { |
| | | if (purchaseApplicationDto.getId() == null) { |
| | | throw new ServiceException("éè´ç³è¯·idä¸è½ä¸ºç©º"); |
| | | } |
| | | PurchaseApplication existing = this.getById(purchaseApplicationDto.getId()); |
| | | if (existing == null) { |
| | | throw new ServiceException("éè´ç³è¯·ä¸åå¨"); |
| | | } |
| | | if (!PurchaseApplicationStatusEnum.DRAFT.getCode().equals(existing.getStatus())) { |
| | | throw new ServiceException("å·²çæè®¢åçéè´ç³è¯·ä¸å
许修æ¹"); |
| | | } |
| | | |
| | | PurchaseApplication application = new PurchaseApplication(); |
| | | BeanUtils.copyProperties(purchaseApplicationDto, application); |
| | | // åå·ãç¶æã订åå
³èç±ç³»ç»ç»´æ¤ï¼ä¸å
许å端æ¹å¨ï¼ç½®ç©ºå MyBatis-Plus ä¸ä¼æ´æ°è¿äºå |
| | | application.setApplicationNo(null); |
| | | application.setStatus(null); |
| | | application.setPurchaseLedgerId(null); |
| | | application.setConvertTime(null); |
| | | application.setTenantId(null); |
| | | application.setCreateUser(null); |
| | | application.setCreateTime(null); |
| | | fillSupplierName(application); |
| | | boolean updated = this.updateById(application); |
| | | |
| | | if (updated) { |
| | | purchaseApplicationProductMapper.delete(Wrappers.<PurchaseApplicationProduct>lambdaQuery() |
| | | .eq(PurchaseApplicationProduct::getPurchaseApplicationId, purchaseApplicationDto.getId())); |
| | | saveProducts(purchaseApplicationDto.getId(), purchaseApplicationDto.getProductData()); |
| | | } |
| | | return updated; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteApplications(List<Long> ids) { |
| | | if (ids == null || ids.isEmpty()) { |
| | | throw new ServiceException("è¯·éæ©è¦å é¤çéè´ç³è¯·"); |
| | | } |
| | | List<String> orderedNos = this.listByIds(ids).stream() |
| | | .filter(application -> !PurchaseApplicationStatusEnum.DRAFT.getCode().equals(application.getStatus())) |
| | | .map(PurchaseApplication::getApplicationNo) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | if (!orderedNos.isEmpty()) { |
| | | throw new ServiceException("å·²çæè®¢åçéè´ç³è¯·ä¸å
许å é¤ï¼" + String.join("ã", orderedNos)); |
| | | } |
| | | |
| | | purchaseApplicationProductMapper.delete(Wrappers.<PurchaseApplicationProduct>lambdaQuery() |
| | | .in(PurchaseApplicationProduct::getPurchaseApplicationId, ids)); |
| | | return this.removeByIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long convertToOrder(Long id) { |
| | | if (id == null) { |
| | | throw new ServiceException("éè´ç³è¯·idä¸è½ä¸ºç©º"); |
| | | } |
| | | PurchaseApplication application = this.getById(id); |
| | | if (application == null) { |
| | | throw new ServiceException("éè´ç³è¯·ä¸åå¨"); |
| | | } |
| | | if (application.getSupplierId() == null) { |
| | | throw new ServiceException("请å
éæ©ä¾åºåå转订å"); |
| | | } |
| | | SupplierManage supplierManage = supplierManageMapper.selectById(application.getSupplierId()); |
| | | if (supplierManage == null) { |
| | | throw new ServiceException("ä¾åºåä¸åå¨ï¼è¯·éæ°éæ©"); |
| | | } |
| | | List<PurchaseApplicationProduct> products = listProducts(id); |
| | | if (products.isEmpty()) { |
| | | throw new ServiceException("éè´ç³è¯·æ²¡æäº§åæç»ï¼æ æ³è½¬è®¢å"); |
| | | } |
| | | |
| | | // æ¡ä»¶æ´æ°æ¢å èç¨¿ç¶æï¼é¿å
å¹¶åä¸éå¤çæè®¢å |
| | | boolean converted = this.update(Wrappers.<PurchaseApplication>lambdaUpdate() |
| | | .eq(PurchaseApplication::getId, id) |
| | | .eq(PurchaseApplication::getStatus, PurchaseApplicationStatusEnum.DRAFT.getCode()) |
| | | .set(PurchaseApplication::getStatus, PurchaseApplicationStatusEnum.ORDER_GENERATED.getCode())); |
| | | if (!converted) { |
| | | throw new ServiceException("该éè´ç³è¯·å·²çæè®¢åï¼è¯·å¿éå¤è½¬æ¢"); |
| | | } |
| | | |
| | | PurchaseLedgerDto purchaseLedgerDto = buildPurchaseLedgerDto(application, supplierManage, products); |
| | | try { |
| | | // å¤ç¨éè´å°è´¦æ°å¢é»è¾ï¼çæéè´ååå·ãä¿åå°è´¦ä¸äº§åæç»ãæäº¤ OA éè´å®¡æ¹ |
| | | purchaseLedgerService.addOrEditPurchase(purchaseLedgerDto); |
| | | } catch (Exception e) { |
| | | log.error("éè´ç³è¯·è½¬è®¢å失败, applicationId={}, applicationNo={}", |
| | | id, application.getApplicationNo(), e); |
| | | throw new ServiceException("转订å失败ï¼" + e.getMessage()); |
| | | } |
| | | |
| | | Long purchaseLedgerId = purchaseLedgerDto.getId(); |
| | | if (purchaseLedgerId == null) { |
| | | throw new ServiceException("转订åå¤±è´¥ï¼æªçæéè´è®¢å"); |
| | | } |
| | | this.update(Wrappers.<PurchaseApplication>lambdaUpdate() |
| | | .eq(PurchaseApplication::getId, id) |
| | | .set(PurchaseApplication::getPurchaseLedgerId, purchaseLedgerId) |
| | | .set(PurchaseApplication::getConvertTime, LocalDateTime.now())); |
| | | return purchaseLedgerId; |
| | | } |
| | | |
| | | private List<PurchaseApplicationProduct> listProducts(Long applicationId) { |
| | | return purchaseApplicationProductMapper.selectList(Wrappers.<PurchaseApplicationProduct>lambdaQuery() |
| | | .eq(PurchaseApplicationProduct::getPurchaseApplicationId, applicationId) |
| | | .orderByAsc(PurchaseApplicationProduct::getId)); |
| | | } |
| | | |
| | | private void saveProducts(Long applicationId, List<PurchaseApplicationProduct> products) { |
| | | if (products == null || products.isEmpty()) { |
| | | return; |
| | | } |
| | | fillProductNames(products); |
| | | for (PurchaseApplicationProduct product : products) { |
| | | product.setId(null); |
| | | product.setPurchaseApplicationId(applicationId); |
| | | product.setTenantId(null); |
| | | product.setCreateUser(null); |
| | | product.setCreateTime(null); |
| | | purchaseApplicationProductMapper.insert(product); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è¡¥å
¨äº§å大类ä¸è§æ ¼åå·ï¼ä¾¿äºç³è¯·åç´æ¥å±ç¤ºäº§ååç§° |
| | | */ |
| | | private void fillProductNames(List<PurchaseApplicationProduct> products) { |
| | | Set<Long> productIds = products.stream() |
| | | .map(PurchaseApplicationProduct::getProductId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | Set<Long> modelIds = products.stream() |
| | | .map(PurchaseApplicationProduct::getProductModelId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | Map<Long, String> productMap = new HashMap<>(); |
| | | if (!productIds.isEmpty()) { |
| | | for (Product product : productMapper.selectBatchIds(productIds)) { |
| | | productMap.put(product.getId(), product.getProductName()); |
| | | } |
| | | } |
| | | Map<Long, String> modelMap = new HashMap<>(); |
| | | if (!modelIds.isEmpty()) { |
| | | for (ProductModel model : productModelMapper.selectBatchIds(modelIds)) { |
| | | modelMap.put(model.getId(), model.getModel()); |
| | | } |
| | | } |
| | | |
| | | for (PurchaseApplicationProduct product : products) { |
| | | String productName = productMap.get(product.getProductId()); |
| | | if (productName != null) { |
| | | product.setProductCategory(productName); |
| | | } |
| | | String model = modelMap.get(product.getProductModelId()); |
| | | if (model != null) { |
| | | product.setSpecificationModel(model); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void fillSupplierName(PurchaseApplication application) { |
| | | if (application.getSupplierId() == null) { |
| | | return; |
| | | } |
| | | SupplierManage supplierManage = supplierManageMapper.selectById(application.getSupplierId()); |
| | | if (supplierManage != null) { |
| | | application.setSupplierName(supplierManage.getSupplierName()); |
| | | } |
| | | } |
| | | |
| | | private void fillApplicant(PurchaseApplication application, PurchaseApplicationDto purchaseApplicationDto) { |
| | | Long applicantId = purchaseApplicationDto.getApplicantId() != null |
| | | ? purchaseApplicationDto.getApplicantId() |
| | | : SecurityUtils.getUserId(); |
| | | application.setApplicantId(applicantId); |
| | | |
| | | if (StringUtils.isBlank(purchaseApplicationDto.getApplicantName())) { |
| | | SysUser applicant = sysUserMapper.selectUserById(applicantId); |
| | | application.setApplicantName(applicant != null ? applicant.getNickName() : SecurityUtils.getUsername()); |
| | | } |
| | | if (application.getApplyDate() == null) { |
| | | application.setApplyDate(LocalDate.now()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç»è£
éè´å°è´¦å
¥åï¼ä¾åºåãéå®ååã产åæç»çï¼éè´ååå·ç±éè´å°è´¦ä¾§çæ |
| | | */ |
| | | private PurchaseLedgerDto buildPurchaseLedgerDto(PurchaseApplication application, |
| | | SupplierManage supplierManage, |
| | | List<PurchaseApplicationProduct> products) { |
| | | PurchaseLedgerDto purchaseLedgerDto = new PurchaseLedgerDto(); |
| | | purchaseLedgerDto.setSupplierId(application.getSupplierId()); |
| | | purchaseLedgerDto.setSupplierName(supplierManage.getSupplierName()); |
| | | purchaseLedgerDto.setRecorderId(application.getApplicantId()); |
| | | purchaseLedgerDto.setRecorderName(application.getApplicantName()); |
| | | purchaseLedgerDto.setSalesContractNo(application.getSalesContractNo()); |
| | | purchaseLedgerDto.setSalesLedgerId(application.getSalesLedgerId()); |
| | | purchaseLedgerDto.setProjectName(application.getProjectName()); |
| | | purchaseLedgerDto.setRemarks(application.getRemarks()); |
| | | purchaseLedgerDto.setPaymentMethod(application.getPaymentMethod()); |
| | | purchaseLedgerDto.setContractAmount(application.getContractAmount()); |
| | | LocalDate entryDate = application.getApplyDate() != null ? application.getApplyDate() : LocalDate.now(); |
| | | purchaseLedgerDto.setEntryDate(DateUtils.toDate(entryDate)); |
| | | purchaseLedgerDto.setProductData(products.stream() |
| | | .map(this::toSalesLedgerProduct) |
| | | .collect(Collectors.toList())); |
| | | return purchaseLedgerDto; |
| | | } |
| | | |
| | | private SalesLedgerProduct toSalesLedgerProduct(PurchaseApplicationProduct source) { |
| | | SalesLedgerProduct target = new SalesLedgerProduct(); |
| | | target.setProductId(source.getProductId()); |
| | | target.setProductModelId(source.getProductModelId()); |
| | | target.setProductCategory(source.getProductCategory()); |
| | | target.setSpecificationModel(source.getSpecificationModel()); |
| | | target.setUnit(source.getUnit()); |
| | | target.setQuantity(source.getQuantity()); |
| | | target.setTaxRate(source.getTaxRate()); |
| | | target.setTaxInclusiveUnitPrice(source.getTaxInclusiveUnitPrice()); |
| | | target.setTaxInclusiveTotalPrice(source.getTaxInclusiveTotalPrice()); |
| | | target.setTaxExclusiveTotalPrice(source.getTaxExclusiveTotalPrice()); |
| | | target.setInvoiceType(source.getInvoiceType()); |
| | | target.setIsChecked(source.getIsChecked()); |
| | | return target; |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.framework.security.LoginUser; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.framework.web.domain.R; |
| | | import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SpareParts; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord; |
| | | import com.ruoyi.measuringinstrumentledger.service.SparePartsRecordService; |
| | | import com.ruoyi.other.mapper.TempFileMapper; |
| | | import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper; |
| | | import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage; |
| | |
| | | @RequiredArgsConstructor |
| | | public class PurchaseLedgerServiceImpl extends ServiceImpl<PurchaseLedgerMapper, PurchaseLedger> implements IPurchaseLedgerService { |
| | | |
| | | /** |
| | | * æç»ç±»åï¼éè´ï¼sales_ledger_product.typeï¼ãä»
éè´æç»æååå¤ä»¶åºå |
| | | */ |
| | | private static final Integer LEDGER_TYPE_PURCHASE = 2; |
| | | |
| | | private final PurchaseLedgerMapper purchaseLedgerMapper; |
| | | private final SalesLedgerMapper salesLedgerMapper; |
| | | private final SalesLedgerProductMapper salesLedgerProductMapper; |
| | |
| | | private final StockUtils stockUtils; |
| | | private final ApprovalTemplateMapper approvalTemplateMapper; |
| | | private final OilDepotMapper oilDepotMapper; |
| | | private final SparePartsMapper sparePartsMapper; |
| | | private final SparePartsRecordService sparePartsRecordService; |
| | | |
| | | @Override |
| | | public List<PurchaseLedger> selectPurchaseLedgerList(PurchaseLedger purchaseLedger) { |
| | |
| | | purchaseLedger.setPurchaseContractNumber(generatePurchaseContractNo(purchaseLedger.getEntryDate())); |
| | | } |
| | | this.saveOrUpdate(purchaseLedger); |
| | | // åå主é®ï¼ä¾è°ç¨æ¹ï¼å¦éè´ç³è¯·è½¬è®¢åï¼è·åæ°çæçéè´å°è´¦id |
| | | purchaseLedgerDto.setId(purchaseLedger.getId()); |
| | | |
| | | // 4. å¤çåè¡¨æ°æ® |
| | | List<SalesLedgerProduct> productList = purchaseLedgerDto.getProductData(); |
| | |
| | | salesLedgerProduct.setRegisterDate(localDateTime); |
| | | salesLedgerProductMapper.insert(salesLedgerProduct); |
| | | } |
| | | // ä»
æ°å¢æç»ååå¤ä»¶ï¼ç¼è¾èµ° update 忝天ç¶ä¸éå¤è®¡æ° |
| | | if (LEDGER_TYPE_PURCHASE.equals(ledgerType)) { |
| | | recordSparePartsInbound(insertList, purchaseLedger); |
| | | } |
| | | } |
| | | |
| | | // è®¡ç®æ»å«ç¨éé¢ |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè´å°è´¦æ°å¢æç»æè§æ ¼å¹é
å¤ä»¶ï¼ç´¯å å¤ä»¶åºåå¹¶è®°ä¸æ¡å
¥åºæµæ°´ã |
| | | * æªç»´æ¤è§æ ¼çå¤ä»¶ä¸åä¸ï¼éé»è·³è¿ã |
| | | */ |
| | | private void recordSparePartsInbound(List<SalesLedgerProduct> insertList, PurchaseLedger purchaseLedger) { |
| | | List<Long> modelIds = insertList.stream() |
| | | .map(SalesLedgerProduct::getProductModelId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | if (modelIds.isEmpty()) { |
| | | return; |
| | | } |
| | | List<SpareParts> sparePartsList = sparePartsMapper.selectList(new LambdaQueryWrapper<SpareParts>() |
| | | .in(SpareParts::getProductModelId, modelIds)); |
| | | if (CollectionUtils.isEmpty(sparePartsList)) { |
| | | return; |
| | | } |
| | | Map<Long, SpareParts> sparePartsByModelId = sparePartsList.stream() |
| | | .collect(Collectors.toMap(SpareParts::getProductModelId, s -> s, (a, b) -> a)); |
| | | for (SalesLedgerProduct product : insertList) { |
| | | SpareParts spareParts = sparePartsByModelId.get(product.getProductModelId()); |
| | | if (spareParts == null || product.getQuantity() == null |
| | | || product.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | BigDecimal quantity = product.getQuantity(); |
| | | spareParts.setQuantity((spareParts.getQuantity() == null ? BigDecimal.ZERO : spareParts.getQuantity()).add(quantity)); |
| | | sparePartsMapper.updateById(spareParts); |
| | | |
| | | SparePartsRecord record = new SparePartsRecord(); |
| | | record.setSparePartsId(spareParts.getId()); |
| | | record.setDirection(1); |
| | | record.setQuantity(quantity); |
| | | record.setSourceType(1); |
| | | record.setSourceId(purchaseLedger.getId()); |
| | | record.setSourceNo(purchaseLedger.getPurchaseContractNumber()); |
| | | sparePartsRecordService.save(record); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int deletePurchaseLedgerByIds(Long[] ids) { |
| | |
| | | @Schema(description = "仿¬¾éé¢") |
| | | private BigDecimal paymentAmount; |
| | | |
| | | @Schema(description = "忬¾éé¢") |
| | | private BigDecimal receiptAmount; |
| | | |
| | | @Schema(description = "åºä»éé¢") |
| | | private BigDecimal payableAmount; |
| | | |
| | |
| | | //该ä¾åºåéè´ä»æ¬¾ç´¯è®¡éé¢ |
| | | private BigDecimal paymentAmount; |
| | | |
| | | @Schema(description = "忬¾éé¢") |
| | | //该ä¾åºå徿¥å款累计éé¢ï¼payment_record æå·¥æµæ°´ï¼ |
| | | private BigDecimal receiptAmount; |
| | | |
| | | @Schema(description = "åºä»éé¢") |
| | | //该ä¾åºåéè´åºä»ç´¯è®¡éé¢=åå§éé¢-仿¬¾-鿬¾ |
| | | private BigDecimal payableAmount; |
| | |
| | | ShippingApproveDto getDateilByShippingNo(String shippingNo); |
| | | |
| | | boolean addReq(ShippingInfoDto req); |
| | | |
| | | /** |
| | | * ä»å¨ç©æµåºåºèªå¨çæåè´§åï¼ç´æ¥ç½®ä¸ºå·²åè´§ï¼ä¸åèµ·å货审æ¹ï¼å
鍿£ååºå |
| | | * |
| | | * @return çæçåè´§å°è´¦id |
| | | */ |
| | | Long addShippedFromOutbound(ShippingInfoDto req); |
| | | |
| | | /** |
| | | * åºåºå被å 餿¶å²éåè´§åï¼å é¤åè´§å䏿ç»ï¼å¹¶åæ»å·²æ£åçåºå |
| | | */ |
| | | void cancelByOutbound(Long shippingInfoId); |
| | | } |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | |
| | | @Override |
| | | public boolean addReq(ShippingInfoDto req) { |
| | | |
| | | // æ ¡éªè¯¥äº§åæ¯å¦å·²æå¾
å®¡æ ¸/å®¡æ ¸ä¸çåè´§è®°å½ï¼é²æ¢éå¤æäº¤ |
| | | Long salesLedgerProductId = req.getSalesLedgerProductId(); |
| | | if (salesLedgerProductId != null) { |
| | |
| | | this.updateById(req); |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long addShippedFromOutbound(ShippingInfoDto req) { |
| | | // ä»å¨ç©æµåºåºå³åè´§ï¼ä¸åèµ·å货审æ¹ï¼ç´æ¥è½ä¸ºå·²åè´§ï¼åºåç± add å
鍿£å |
| | | req.setShippingNo(OrderUtils.countTodayByCreateTime( |
| | | shippingInfoMapper, "SH", "shipping_no", LocalDateTime.now())); |
| | | req.setStatus("å·²åè´§"); |
| | | if (req.getShippingDate() == null) { |
| | | req.setShippingDate(new Date()); |
| | | } |
| | | this.add(req); |
| | | return req.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelByOutbound(Long shippingInfoId) { |
| | | if (shippingInfoId == null) { |
| | | return; |
| | | } |
| | | // åæ»è¯¥åè´§åå ç¨çåºå |
| | | stockUtils.deleteStockOutRecord(shippingInfoId, StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode()); |
| | | shippingProductDetailMapper.delete(new LambdaQueryWrapper<ShippingProductDetail>() |
| | | .eq(ShippingProductDetail::getShippingInfoId, shippingInfoId)); |
| | | this.removeById(shippingInfoId); |
| | | } |
| | | } |
| | |
| | | @Schema(description = "æ¶æ¬¾éé¢") |
| | | private BigDecimal receiptPaymentAmount; |
| | | |
| | | @Schema(description = "仿¬¾éé¢") |
| | | private BigDecimal paymentAmount; |
| | | |
| | | @Schema(description = "åºæ¶éé¢") |
| | | private BigDecimal receiptableAmount; |
| | | |
| | |
| | | //该客æ·é宿¶æ¬¾ç´¯è®¡éé¢ |
| | | private BigDecimal receiptPaymentAmount; |
| | | |
| | | @Schema(description = "仿¬¾éé¢") |
| | | //该客æ·å¾æ¥ä»æ¬¾ç´¯è®¡éé¢ï¼payment_record æå·¥æµæ°´ï¼ |
| | | private BigDecimal paymentAmount; |
| | | |
| | | @Schema(description = "åºæ¶éé¢") |
| | | //该客æ·éå®åºæ¶ç´¯è®¡éé¢=åå§éé¢-忬¾-鿬¾ |
| | | private BigDecimal receiptableAmount; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @Log(title = "ä¸è½½åºå导å
¥æ¨¡æ¿", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/downloadStockInventory") |
| | | public void downloadStockInventory(HttpServletResponse response) { |
| | | List<StockInventoryExportData> list = new ArrayList<>(); |
| | | ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class); |
| | | util.exportExcel(response, list, "åºå模æ¿"); |
| | | util.importTemplateExcel(response, "åºå模æ¿"); |
| | | } |
| | | |
| | | @PostMapping("/exportStockInventory") |
| | |
| | | package com.ruoyi.stock.execl; |
| | | |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Excel; |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Excel.Type; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | |
| | | |
| | | @Excel(name = "夿³¨") |
| | | private String remark; |
| | | |
| | | /** |
| | | * å¨ç½å·ï¼å¨ç½åç±»ï¼ãéå® EXPORTï¼é¿å
污æå¯¼å
¥æ¨¡æ¿ |
| | | */ |
| | | @Excel(name = "å¨ç½å·", type = Type.EXPORT) |
| | | private String tankNo; |
| | | // |
| | | // @Excel(name = "ææ°æ´æ°æ¶é´") |
| | | // @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | |
| | | c.customer_name, |
| | | T1.contractAmounts AS contractAmounts, |
| | | IFNULL(T2.receiptPaymentAmount, 0) AS receiptPaymentAmount, |
| | | IFNULL(T5.paymentAmount, 0) AS paymentAmount, |
| | | T1.contractAmounts - IFNULL(T2.receiptPaymentAmount, 0) - IFNULL(T4.returnAmount, 0) AS receiptableAmount, |
| | | IFNULL(T4.returnAmount, 0) AS returnAmount |
| | | from (select customer_id, sum(contract_amount) as contractAmounts from sales_ledger group by customer_id) T1 |
| | | left join (select customer_id, sum(collection_amount) as receiptPaymentAmount from account_sales_collection group by customer_id) T2 on T1.customer_id = T2.customer_id |
| | | left join (select party_id, sum(amount) as paymentAmount from payment_record where party_type = 1 and direction = 1 group by party_id) T5 on T5.party_id = T1.customer_id |
| | | left join ( |
| | | select |
| | | sl.customer_id, |
| | |
| | | sl.execution_date, |
| | | sl.contract_amount AS contract_amount, |
| | | IFNULL(T1.receiptPaymentAmount, 0) AS receiptPaymentAmount, |
| | | IFNULL(T5.paymentAmount, 0) AS paymentAmount, |
| | | sl.contract_amount - IFNULL(T1.receiptPaymentAmount, 0) - IFNULL(T3.returnAmount, 0) AS receiptableAmount, |
| | | IFNULL(T3.returnAmount, 0) AS returnAmount |
| | | from sales_ledger sl |
| | |
| | | where rm.status=1 |
| | | group by sl.id |
| | | )T3 on T3.id = sl.id |
| | | left join ( |
| | | select party_id, sum(amount) as paymentAmount |
| | | from payment_record |
| | | where party_type = 1 and direction = 1 |
| | | group by party_id |
| | | )T5 on T5.party_id = sl.customer_id |
| | | where sl.customer_id = #{customerId} |
| | | order by sl.id desc |
| | | </select> |
| | |
| | | sm.supplier_name, |
| | | T1.contractAmounts, |
| | | IFNULL(T2.paymentAmount, 0) AS paymentAmount, |
| | | IFNULL(T5.receiptAmount, 0) AS receiptAmount, |
| | | T1.contractAmounts - IFNULL(T2.paymentAmount, 0) - IFNULL(T4.returnAmount, 0) AS payableAmount, |
| | | IFNULL(T4.returnAmount, 0) AS returnAmount |
| | | from (select supplier_id, sum(contract_amount) as contractAmounts from purchase_ledger group by supplier_id) T1 |
| | | left join (select supplier_id, sum(payment_amount) as paymentAmount from account_purchase_payment group by supplier_id) T2 on T1.supplier_id = T2.supplier_id |
| | | left join (select party_id, sum(amount) as receiptAmount from payment_record where party_type = 2 and direction = 2 group by party_id) T5 on T5.party_id = T1.supplier_id |
| | | left join ( |
| | | select |
| | | supplier_id, |
| | |
| | | pl.execution_date, |
| | | pl.contract_amount AS contract_amount, |
| | | IFNULL(T1.paymentAmount, 0) AS paymentAmount, |
| | | IFNULL(T5.receiptAmount, 0) AS receiptAmount, |
| | | pl.contract_amount - IFNULL(T1.paymentAmount, 0) - IFNULL(T3.returnAmount, 0) AS payableAmount, |
| | | IFNULL(T3.returnAmount, 0) AS returnAmount |
| | | from purchase_ledger pl |
| | |
| | | left join purchase_ledger pl on pro.purchase_ledger_id = pl.id |
| | | group by pl.id |
| | | )T3 on T3.id = pl.id |
| | | left join ( |
| | | select party_id, sum(amount) as receiptAmount |
| | | from payment_record |
| | | where party_type = 2 and direction = 2 |
| | | group by party_id |
| | | )T5 on T5.party_id = pl.supplier_id |
| | | where pl.supplier_id = #{supplierId} |
| | | order by pl.id desc |
| | | </select> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.ruoyi.measuringinstrumentledger.mapper.SparePartsRecordMapper"> |
| | | |
| | | <select id="listPage" resultType="com.ruoyi.measuringinstrumentledger.pojo.SparePartsRecord"> |
| | | select t1.id, |
| | | t1.spare_parts_id, |
| | | t2.name as sparePartsName, |
| | | t1.direction, |
| | | t1.quantity, |
| | | t1.source_type, |
| | | t1.source_id, |
| | | t1.source_no, |
| | | t1.remark, |
| | | t1.create_user, |
| | | t1.create_time |
| | | from spare_parts_record t1 |
| | | left join spare_parts t2 on t2.id = t1.spare_parts_id |
| | | <where> |
| | | <if test="req.sparePartsId != null"> |
| | | and t1.spare_parts_id = #{req.sparePartsId} |
| | | </if> |
| | | <if test="req.direction != null"> |
| | | and t1.direction = #{req.direction} |
| | | </if> |
| | | <if test="req.sourceType != null"> |
| | | and t1.source_type = #{req.sourceType} |
| | | </if> |
| | | </where> |
| | | order by t1.id desc |
| | | </select> |
| | | </mapper> |
| | |
| | | t2.tax_exclusive_total_price, |
| | | t3.inbound_num as quantityStock |
| | | from purchase_ledger t1 |
| | | left join sales_ledger_product t2 on t1.id = t2.sales_ledger_id and slp.type = 2 |
| | | left join sales_ledger_product t2 on t1.id = t2.sales_ledger_id and t2.type = 2 |
| | | left join procurement_record_storage t3 on t2.id = t3.sales_ledger_product_id |
| | | where t1.purchase_contract_number = #{req.purchaseContractNumber} |
| | | <if test="req.id != null and req.id != ''"> |
| | | and t3.id = #{req.id} |
| | | </if> |
| | | <where> |
| | | <if test="req.purchaseLedgerId != null"> |
| | | and t1.id = #{req.purchaseLedgerId} |
| | | </if> |
| | | <if test="req.purchaseContractNumber != null and req.purchaseContractNumber != ''"> |
| | | and t1.purchase_contract_number = #{req.purchaseContractNumber} |
| | | </if> |
| | | <if test="req.id != null and req.id != ''"> |
| | | and t3.id = #{req.id} |
| | | </if> |
| | | </where> |
| | | group by t2.id |
| | | </select> |
| | | <select id="listPage" resultType="com.ruoyi.procurementrecord.bean.dto.ProcurementPageDto"> |
| | |
| | | t2.product_category, |
| | | t1.id, |
| | | t1.code, |
| | | t1.batch_no, |
| | | t5.shipping_no, |
| | | t2.specification_model, |
| | | t2.unit, |
| | | t2.tax_rate, |
| | |
| | | left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id and t2.type = 1 |
| | | left join sales_ledger t3 on t3.id = t2.sales_ledger_id |
| | | left join procurement_record_storage t4 on t4.id = t1.procurement_record_storage_id |
| | | left join shipping_info t5 on t5.id = t1.shipping_info_id |
| | | <where> |
| | | and t1.type = 2 |
| | | <if test="req.customerName != null and req.customerName != ''"> |
| | |
| | | order by id desc |
| | | limit 1 |
| | | </select> |
| | | <select id="listBatchNoByProductModelId" resultType="com.ruoyi.procurementrecord.bean.vo.BatchNoOptionVo"> |
| | | select si.product_model_id, |
| | | si.batch_no, |
| | | (si.qualitity - ifnull(si.locked_quantity, 0)) as availableQuantity |
| | | from stock_inventory si |
| | | where si.product_model_id = #{productModelId} |
| | | and si.batch_no is not null |
| | | and si.batch_no != '' |
| | | and (si.qualitity - ifnull(si.locked_quantity, 0)) > 0 |
| | | order by si.batch_no |
| | | </select> |
| | | |
| | | <select id="listPageBySemiProduct" resultType="com.ruoyi.procurementrecord.bean.dto.ProcurementRecordOutPageDto"> |
| | | select |
| | | t1.id, |
| | |
| | | product_id, |
| | | 'combined' as stockType, |
| | | ( |
| | | select sir.tank_no |
| | | from stock_in_record sir |
| | | where sir.product_model_id = combined.product_model_id |
| | | order by sir.id desc |
| | | limit 1 |
| | | ) as tank_no, |
| | | ( |
| | | select sir.oil_product |
| | | from stock_in_record sir |
| | | where sir.product_model_id = combined.product_model_id |
| | |
| | | unit, |
| | | product_name, |
| | | product_id, |
| | | 'combined' as stockType |
| | | 'combined' as stockType, |
| | | ( |
| | | select sir.tank_no |
| | | from stock_in_record sir |
| | | where sir.product_model_id = combined.product_model_id |
| | | and (sir.batch_no = combined.batch_no or (combined.batch_no is null and sir.batch_no is null)) |
| | | order by sir.id desc |
| | | limit 1 |
| | | ) as tank_no |
| | | from ( |
| | | select |
| | | si.batch_no, |
| | |
| | | product_name, |
| | | product_id |
| | | order by |
| | | batch_no |
| | | MAX(update_time) desc |
| | | </select> |
| | | |
| | | </mapper> |