feat(bid): 完成甲方报价模块全量功能开发

1.  新增甲方报价业务实体,继承基础实体类
2.  新增供应商报价明细查询接口,支持按供应商ID展开物料明细
3.  重构甲方报价关联逻辑,通过material_id精确关联物料表
4.  新增甲方报价历史统计、月度趋势、快速新建等服务功能
5.  完善菜单配置,修正甲方报价菜单结构,添加完整权限控制
6.  新增物料搜索自动补全功能,优化报价单详情页面
7.  在供应商详情页新增报价历史Tab页签,展示该供应商的所有报价物料明细
8.  在物料详情页新增甲方报价记录Tab页签,展示该物料的所有甲方报价历史
9.  新增数据库优化脚本,添加索引并修复历史数据关联
This commit is contained in:
2026-06-01 19:05:04 +08:00
parent 18a71526dc
commit a75589018f
23 changed files with 1758 additions and 144 deletions

View File

@@ -3,31 +3,48 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.bid.BizClientQuoteMapper">
<!-- ========== 甲方报价主表操作 ========== -->
<sql id="quoteColumns">
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,
status, validity_date AS validityDate, total_amount AS totalAmount,
currency, remark, create_by AS createBy, create_time AS createTime
</sql>
<select id="selectClientQuoteList" resultType="com.ruoyi.system.domain.bid.BizClientQuote">
SELECT 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,
status, validity_date AS validityDate, total_amount AS totalAmount,
currency, remark, create_by AS createBy, create_time AS createTime
SELECT <include refid="quoteColumns"/>
FROM biz_client_quote
<where>
<if test="q.clientName != null and q.clientName != ''">AND client_name LIKE CONCAT('%',#{q.clientName},'%')</if>
<if test="q.status != null and q.status != ''">AND status = #{q.status}</if>
<if test="q.quoteNo != null and q.quoteNo != ''">AND quote_no LIKE CONCAT('%',#{q.quoteNo},'%')</if>
<if test="q.params.beginTime != null and q.params.beginTime != ''">
AND create_time &gt;= #{q.params.beginTime}
</if>
<if test="q.params.endTime != null and q.params.endTime != ''">
AND create_time &lt;= #{q.params.endTime}
</if>
</where>
ORDER BY create_time DESC
</select>
<select id="selectClientQuoteById" resultType="com.ruoyi.system.domain.bid.BizClientQuote">
SELECT 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,
status, validity_date AS validityDate, total_amount AS totalAmount,
currency, remark, create_by AS createBy, create_time AS createTime
SELECT <include refid="quoteColumns"/>
FROM biz_client_quote WHERE quote_id = #{quoteId}
</select>
<!-- ========== 甲方报价明细操作 ========== -->
<sql id="itemColumns">
item_id AS itemId, quote_id AS quoteId, material_id AS materialId,
material_name AS materialName, spec, model_no AS modelNo, unit, quantity,
cost_price AS costPrice, unit_price AS unitPrice, total_price AS totalPrice,
delivery_days AS deliveryDays, remark
</sql>
<select id="selectItemsByQuoteId" resultType="com.ruoyi.system.domain.bid.BizClientQuoteItem">
SELECT item_id AS itemId, quote_id AS quoteId, material_name AS materialName,
spec, model_no AS modelNo, unit, quantity, cost_price AS costPrice,
unit_price AS unitPrice, total_price AS totalPrice, delivery_days AS deliveryDays, remark
SELECT <include refid="itemColumns"/>
FROM biz_client_quote_item WHERE quote_id = #{quoteId} ORDER BY item_id
</select>
@@ -44,9 +61,9 @@
</insert>
<insert id="insertClientQuoteItem" useGeneratedKeys="true" keyProperty="itemId">
INSERT INTO biz_client_quote_item (quote_id,material_name,spec,model_no,unit,quantity,
INSERT INTO biz_client_quote_item (quote_id,material_id,material_name,spec,model_no,unit,quantity,
cost_price,unit_price,total_price,delivery_days,remark)
VALUES (#{quoteId},#{materialName},#{spec},#{modelNo},#{unit},#{quantity},
VALUES (#{quoteId},#{materialId},#{materialName},#{spec},#{modelNo},#{unit},#{quantity},
#{costPrice},#{unitPrice},#{totalPrice},#{deliveryDays},#{remark})
</insert>
@@ -59,4 +76,63 @@
<delete id="deleteClientQuoteById">DELETE FROM biz_client_quote WHERE quote_id=#{quoteId}</delete>
<delete id="deleteItemsByQuoteId">DELETE FROM biz_client_quote_item WHERE quote_id=#{quoteId}</delete>
<!-- ========== 甲方报价历史 - 统计查询 ========== -->
<select id="selectClientQuoteStatistics" resultType="java.util.Map">
SELECT
COUNT(*) AS total_count,
COUNT(DISTINCT client_name) AS client_count,
COALESCE(SUM(total_amount), 0) AS total_amount_sum,
MAX(total_amount) AS max_amount,
AVG(total_amount) AS avg_amount
FROM biz_client_quote
<where>
<if test="q.clientName != null and q.clientName != ''">AND client_name LIKE CONCAT('%',#{q.clientName},'%')</if>
<if test="q.status != null and q.status != ''">AND status = #{q.status}</if>
<if test="q.params.beginTime != null and q.params.beginTime != ''">
AND create_time &gt;= #{q.params.beginTime}
</if>
<if test="q.params.endTime != null and q.params.endTime != ''">
AND create_time &lt;= #{q.params.endTime}
</if>
</where>
</select>
<!-- ========== 按物料ID查询甲方报价历史使用material_id精确关联 ========== -->
<select id="selectClientQuotesByMaterialId" resultType="java.util.Map">
SELECT cqi.item_id AS itemId, cqi.spec, cqi.model_no AS modelNo, cqi.unit, cqi.quantity,
cqi.cost_price AS costPrice, cqi.unit_price AS unitPrice, cqi.total_price AS totalPrice,
cqi.delivery_days AS deliveryDays, cqi.material_id AS materialId,
cqi.material_name AS materialName,
cq.quote_id AS quoteId, cq.quote_no AS quoteNo, cq.client_name AS clientName,
cq.status AS quoteStatus, cq.create_time AS createTime
FROM biz_client_quote_item cqi
JOIN biz_client_quote cq ON cqi.quote_id = cq.quote_id
WHERE cqi.material_id = #{materialId}
ORDER BY cq.create_time DESC
</select>
<!-- ========== 快速创建 - 复制历史报价单的明细按报价单ID ========== -->
<select id="selectItemsByQuoteIdForCopy" resultType="com.ruoyi.system.domain.bid.BizClientQuoteItem">
SELECT <include refid="itemColumns"/>
FROM biz_client_quote_item WHERE quote_id = #{quoteId}
ORDER BY item_id
</select>
<!-- ========== 甲方报价历史 - 按日期统计趋势 ========== -->
<select id="selectMonthlyTrend" resultType="java.util.Map">
SELECT
DATE_FORMAT(create_time, '%Y-%m') AS month,
COUNT(*) AS quote_count,
COALESCE(SUM(total_amount), 0) AS amount_sum
FROM biz_client_quote
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 12 MONTH)
GROUP BY DATE_FORMAT(create_time, '%Y-%m')
ORDER BY month
</select>
</mapper>