From 93785be50580ed5530aad93a59761085bea80460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E6=98=8A?= Date: Wed, 10 Jun 2026 20:47:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(bid):=20=E5=AE=8C=E6=88=90=E6=8B=9B?= =?UTF-8?q?=E6=8A=95=E6=A0=87=E4=B8=9A=E5=8A=A1=E6=A8=A1=E5=9D=97=E5=A4=9A?= =?UTF-8?q?=E9=9C=80=E6=B1=82=E8=BF=AD=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本次提交包含多项功能改进与业务优化: 1. 全局主题色替换为#4A6FA5,统一前端UI风格 2. 新增客户报价单clientId字段,完善客户报价数据结构 3. 实现发货单状态流转功能,支持发货、完成、撤回、设置结单日期操作 4. 新增物料发货记录多表关联查询功能 5. 优化客户管理页面UI布局与交互体验 6. 修复客户报价表单自动补全逻辑,关联clientId与clientName 7. 补充租户ID自动填充逻辑,完善多租户数据隔离 --- .../controller/bid/BizClientController.java | 5 + .../bid/BizDeliveryOrderController.java | 45 ++ .../system/domain/bid/BizClientQuote.java | 3 + .../mapper/bid/BizDeliveryOrderMapper.java | 13 + .../service/bid/IBizDeliveryOrderService.java | 10 + .../bid/impl/BizDeliveryOrderServiceImpl.java | 54 ++ .../mapper/bid/BizClientQuoteMapper.xml | 9 +- .../mapper/bid/BizDeliveryOrderMapper.xml | 32 + .../src/assets/styles/element-variables.scss | 2 +- ruoyi-ui/src/assets/styles/ruoyi.scss | 34 + ruoyi-ui/src/assets/styles/variables.scss | 8 +- ruoyi-ui/src/views/bid/client/index.vue | 378 +++++----- ruoyi-ui/src/views/bid/clientquote/detail.vue | 21 +- ruoyi-ui/src/views/bid/clientquote/index.vue | 679 +++++------------- ruoyi-ui/src/views/bid/material/index.vue | 44 +- ruoyi-ui/src/views/bid/quotation/index.vue | 61 +- 16 files changed, 671 insertions(+), 727 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizClientController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizClientController.java index b71c2a35..af182a83 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizClientController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizClientController.java @@ -37,6 +37,11 @@ public class BizClientController extends BaseController { @PostMapping public AjaxResult add(@RequestBody BizClient record) { record.setCreateBy(getUsername()); + Long tenantId = getDeptId(); + if (tenantId == null) { + tenantId = 1L; + } + record.setTenantId(tenantId); return toAjax(service.insertBizClient(record)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizDeliveryOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizDeliveryOrderController.java index 515bd259..0f36063d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizDeliveryOrderController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/bid/BizDeliveryOrderController.java @@ -37,6 +37,9 @@ public class BizDeliveryOrderController extends BaseController { @PostMapping public AjaxResult add(@RequestBody BizDeliveryOrder record) { record.setCreateBy(getUsername()); + Long tenantId = getDeptId(); + if (tenantId == null) tenantId = 1L; + record.setTenantId(tenantId); return toAjax(service.insertBizDeliveryOrder(record)); } @@ -54,4 +57,46 @@ public class BizDeliveryOrderController extends BaseController { public AjaxResult remove(@PathVariable Long[] doIds) { return toAjax(service.deleteBizDeliveryOrderByIds(doIds)); } + + // ════════════════════════════════════════ + // 状态流转 + // ════════════════════════════════════════════ + + @PreAuthorize("@ss.hasPermi('bid:order:status')") + @Log(title = "发货管理", businessType = BusinessType.UPDATE) + @PutMapping("/{id}/ship") + public AjaxResult ship(@PathVariable Long id) { + return toAjax(service.ship(id)); + } + + @PreAuthorize("@ss.hasPermi('bid:order:status')") + @Log(title = "发货管理", businessType = BusinessType.UPDATE) + @PutMapping("/{id}/complete") + public AjaxResult complete(@PathVariable Long id) { + return toAjax(service.complete(id, getUsername())); + } + + @PreAuthorize("@ss.hasPermi('bid:order:status')") + @Log(title = "发货管理", businessType = BusinessType.UPDATE) + @PutMapping("/{id}/recall") + public AjaxResult recall(@PathVariable Long id) { + return toAjax(service.recall(id)); + } + + @PreAuthorize("@ss.hasPermi('bid:order:closeDate:edit')") + @Log(title = "结单时间", businessType = BusinessType.UPDATE) + @PutMapping("/{id}/closeDate") + public AjaxResult setCloseDate(@PathVariable Long id, @RequestParam String closeDate) { + return toAjax(service.setCloseDate(id, closeDate, getUsername())); + } + + // ════════════════════════════════════════ + // 物料发货记录 + // ════════════════════════════════════════════ + + @PreAuthorize("@ss.hasPermi('bid:material:query')") + @GetMapping("/materialRecords/{materialId}") + public AjaxResult materialRecords(@PathVariable Long materialId) { + return success(service.selectMaterialRecords(materialId)); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizClientQuote.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizClientQuote.java index 01cda00a..c5df9361 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizClientQuote.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizClientQuote.java @@ -9,6 +9,7 @@ public class BizClientQuote extends BaseEntity { private Long quoteId; private Long tenantId; private String quoteNo; + private Long clientId; private String clientName; private Long rfqId; private String rfqNo; @@ -29,6 +30,8 @@ public class BizClientQuote extends BaseEntity { public void setTenantId(Long v){tenantId=v;} public String getQuoteNo(){return quoteNo;} public void setQuoteNo(String v){quoteNo=v;} + public Long getClientId(){return clientId;} + public void setClientId(Long v){clientId=v;} public String getClientName(){return clientName;} public void setClientName(String v){clientName=v;} public Long getRfqId(){return rfqId;} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/bid/BizDeliveryOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/bid/BizDeliveryOrderMapper.java index 61104d19..bed6b1c0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/bid/BizDeliveryOrderMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/bid/BizDeliveryOrderMapper.java @@ -1,7 +1,10 @@ package com.ruoyi.system.mapper.bid; import com.ruoyi.system.domain.bid.BizDeliveryOrder; +import org.apache.ibatis.annotations.Param; +import java.util.Date; import java.util.List; +import java.util.Map; public interface BizDeliveryOrderMapper { List selectBizDeliveryOrderList(BizDeliveryOrder query); @@ -10,4 +13,14 @@ public interface BizDeliveryOrderMapper { int updateBizDeliveryOrder(BizDeliveryOrder record); int deleteBizDeliveryOrderById(Long id); int deleteBizDeliveryOrderByIds(Long[] ids); + + // 状态流转(直接更新,不受动态SQL null判断影响) + int updateDeliveryStatus(@Param("doId") Long doId, + @Param("deliveryStatus") String deliveryStatus, + @Param("delayDate") Date delayDate, + @Param("actualCloseDate") Date actualCloseDate, + @Param("closeDateSetBy") String closeDateSetBy); + + // 物料发货记录 + List> selectMaterialRecords(@Param("materialId") Long materialId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/IBizDeliveryOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/IBizDeliveryOrderService.java index 133e82ac..898891ec 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/IBizDeliveryOrderService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/IBizDeliveryOrderService.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service.bid; import com.ruoyi.system.domain.bid.BizDeliveryOrder; import java.util.List; +import java.util.Map; public interface IBizDeliveryOrderService { List selectBizDeliveryOrderList(BizDeliveryOrder query); @@ -10,4 +11,13 @@ public interface IBizDeliveryOrderService { int updateBizDeliveryOrder(BizDeliveryOrder record); int deleteBizDeliveryOrderById(Long id); int deleteBizDeliveryOrderByIds(Long[] ids); + + // 状态流转 + int ship(Long id); + int complete(Long id, String username); + int recall(Long id); + int setCloseDate(Long id, String closeDate, String username); + + // 物料发货记录 + List> selectMaterialRecords(Long materialId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java index 458861e5..293ff788 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java @@ -12,6 +12,7 @@ import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.Map; @Service public class BizDeliveryOrderServiceImpl implements IBizDeliveryOrderService { @@ -86,4 +87,57 @@ public class BizDeliveryOrderServiceImpl implements IBizDeliveryOrderService { public int deleteBizDeliveryOrderByIds(Long[] ids) { return mapper.deleteBizDeliveryOrderByIds(ids); } + + // ═══════════════════════════════════════════════ + // 状态流转 + // ═══════════════════════════════════════════════ + + @Override + @Transactional + public int ship(Long id) { + BizDeliveryOrder d = mapper.selectBizDeliveryOrderById(id); + if (d == null) throw new RuntimeException("发货单不存在"); + if (!"pending".equals(d.getDeliveryStatus())) + throw new RuntimeException("当前状态不允许发货确认"); + return mapper.updateDeliveryStatus(id, "transit", null, null, ""); + } + + @Override + @Transactional + public int complete(Long id, String username) { + BizDeliveryOrder d = mapper.selectBizDeliveryOrderById(id); + if (d == null) throw new RuntimeException("发货单不存在"); + if (!"transit".equals(d.getDeliveryStatus())) + throw new RuntimeException("当前状态不允许收货完成"); + return mapper.updateDeliveryStatus(id, "history", null, new java.sql.Date(System.currentTimeMillis()), username); + } + + @Override + @Transactional + public int recall(Long id) { + BizDeliveryOrder d = mapper.selectBizDeliveryOrderById(id); + if (d == null) throw new RuntimeException("发货单不存在"); + if (!"transit".equals(d.getDeliveryStatus()) && !"history".equals(d.getDeliveryStatus())) + throw new RuntimeException("当前状态不允许撤回"); + return mapper.updateDeliveryStatus(id, "pending", null, null, ""); + } + + @Override + @Transactional + public int setCloseDate(Long id, String closeDate, String username) { + if (closeDate == null || closeDate.isEmpty()) { + return mapper.updateDeliveryStatus(id, null, null, null, ""); + } else { + return mapper.updateDeliveryStatus(id, null, null, java.sql.Date.valueOf(closeDate), username); + } + } + + // ═══════════════════════════════════════════════ + // 物料发货记录 + // ═══════════════════════════════════════════════ + + @Override + public List> selectMaterialRecords(Long materialId) { + return mapper.selectMaterialRecords(materialId); + } } diff --git a/ruoyi-system/src/main/resources/mapper/bid/BizClientQuoteMapper.xml b/ruoyi-system/src/main/resources/mapper/bid/BizClientQuoteMapper.xml index e9262d9b..e62585ad 100644 --- a/ruoyi-system/src/main/resources/mapper/bid/BizClientQuoteMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/bid/BizClientQuoteMapper.xml @@ -7,7 +7,8 @@ quote_id AS quoteId, tenant_id AS tenantId, quote_no AS quoteNo, - client_name AS clientName, rfq_id AS rfqId, rfq_no AS rfqNo, rfq_title AS rfqTitle, + client_id AS clientId, client_name AS clientName, + rfq_id AS rfqId, rfq_no AS rfqNo, rfq_title AS rfqTitle, status, validity_date AS validityDate, total_amount AS totalAmount, currency, remark, create_by AS createBy, create_time AS createTime @@ -54,9 +55,9 @@ - INSERT INTO biz_client_quote (tenant_id,quote_no,client_name,rfq_id,rfq_no,rfq_title, + INSERT INTO biz_client_quote (tenant_id,quote_no,client_id,client_name,rfq_id,rfq_no,rfq_title, status,validity_date,total_amount,currency,remark,create_by,create_time) - VALUES (1,#{quoteNo},#{clientName},#{rfqId},#{rfqNo},#{rfqTitle}, + VALUES (1,#{quoteNo},#{clientId},#{clientName},#{rfqId},#{rfqNo},#{rfqTitle}, #{status},#{validityDate},#{totalAmount},#{currency},#{remark},#{createBy},NOW()) @@ -68,7 +69,7 @@ - UPDATE biz_client_quote SET client_name=#{clientName},status=#{status}, + UPDATE biz_client_quote SET client_id=#{clientId},client_name=#{clientName},status=#{status}, validity_date=#{validityDate},total_amount=#{totalAmount}, currency=#{currency},remark=#{remark},update_time=NOW() WHERE quote_id=#{quoteId} diff --git a/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml index e6982300..80cd2010 100644 --- a/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml @@ -73,4 +73,36 @@ DELETE FROM biz_delivery_order WHERE do_id IN #{id} + + + + UPDATE biz_delivery_order + SET delivery_status=#{deliveryStatus}, + delay_date=#{delayDate}, + actual_close_date=#{actualCloseDate}, + close_date_set_by=#{closeDateSetBy}, + update_time=NOW() + WHERE do_id=#{doId} + + + + diff --git a/ruoyi-ui/src/assets/styles/element-variables.scss b/ruoyi-ui/src/assets/styles/element-variables.scss index 5bf2fbb1..c5fb0d13 100644 --- a/ruoyi-ui/src/assets/styles/element-variables.scss +++ b/ruoyi-ui/src/assets/styles/element-variables.scss @@ -4,7 +4,7 @@ **/ /* theme color */ -$--color-primary: #1890ff; +$--color-primary: #4A6FA5; $--color-success: #13ce66; $--color-warning: #ffba00; $--color-danger: #ff4949; diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss index cb1314d5..d3a6e837 100644 --- a/ruoyi-ui/src/assets/styles/ruoyi.scss +++ b/ruoyi-ui/src/assets/styles/ruoyi.scss @@ -482,3 +482,37 @@ position: relative; float: right; } + +/* ═══════ 全局按钮统一样式 ═══════ */ +.el-button--primary { + background: #4A6FA5; + border-color: #4A6FA5; + border-radius: 4px; +} +.el-button--primary:hover, +.el-button--primary:focus { + background: #5a80b5; + border-color: #5a80b5; +} +.el-button--primary.is-disabled { + background: #8aa3c5; + border-color: #8aa3c5; +} +.el-button--danger { + border-radius: 4px; +} +.el-button--default { + border-radius: 4px; +} + +/* 搜索按钮特殊色(浅蓝) */ +.search-btn { + background: #409EFF; + border-color: #409EFF; + border-radius: 4px; + color: #fff; +} +.search-btn:hover { + background: #66b1ff; + border-color: #66b1ff; +} diff --git a/ruoyi-ui/src/assets/styles/variables.scss b/ruoyi-ui/src/assets/styles/variables.scss index d34e6bc4..5fb5eea7 100644 --- a/ruoyi-ui/src/assets/styles/variables.scss +++ b/ruoyi-ui/src/assets/styles/variables.scss @@ -1,6 +1,6 @@ // base color - ERPNext inspired palette -$blue:#1171c4; -$light-blue:#409EFF; +$blue:#4A6FA5; +$light-blue:#6B8FB5; $red:#C03639; $pink: #E65D6E; $green: #30B08F; @@ -10,13 +10,13 @@ $panGreen: #30B08F; // 默认菜单主题风格(ERPNext风格:白色边栏,蓝色主色) $base-menu-color: #555c70; -$base-menu-color-active: #1171c4; +$base-menu-color-active: #4A6FA5; $base-menu-background: #1a2332; $base-logo-title-color: #ffffff; $base-menu-light-color: rgba(0,0,0,.65); $base-menu-light-background: #ffffff; -$base-logo-light-title-color: #1171c4; +$base-logo-light-title-color: #4A6FA5; $base-sub-menu-background: #111a27; $base-sub-menu-hover: rgba(17,113,196,.08); diff --git a/ruoyi-ui/src/views/bid/client/index.vue b/ruoyi-ui/src/views/bid/client/index.vue index 6d81cd71..94d83915 100644 --- a/ruoyi-ui/src/views/bid/client/index.vue +++ b/ruoyi-ui/src/views/bid/client/index.vue @@ -1,31 +1,33 @@