feat: 路由跳转重构 + 甲方报价单 + 物料分类 + 比价选择方案 + 规格型号拆分

- 比价页改为列表→路由跳转到 comparison/detail,支持勾选物料行生成采购方案PDF
- 新增甲方报价单模块(clientquote):列表+详情路由,含成本价/报价/毛利率,导出PDF
- 新增物料分类管理(category):树形结构,CRUD,物料页面关联分类筛选
- BizMaterial 拆分 spec(规格) + modelNo(型号) 两个字段
- Logo 修复:新PNG + 内联样式确保完整显示
- sys_menu 新增 2012(物料分类)、2013(甲方报价单)、2014(报价单详情)、2015(比价详情)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 13:49:11 +08:00
parent 608ee0ed61
commit 54a421aa36
25 changed files with 1614 additions and 502 deletions

View File

@@ -0,0 +1,62 @@
<?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.system.mapper.bid.BizClientQuoteMapper">
<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
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>
</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
FROM biz_client_quote WHERE quote_id = #{quoteId}
</select>
<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
FROM biz_client_quote_item WHERE quote_id = #{quoteId} ORDER BY item_id
</select>
<select id="selectNextQuoteNo" resultType="String">
SELECT CONCAT('CQ-', DATE_FORMAT(NOW(),'%Y%m'), '-', LPAD(IFNULL(MAX(CAST(SUBSTRING_INDEX(quote_no,'-',-1) AS UNSIGNED)),0)+1,3,'0'))
FROM biz_client_quote WHERE quote_no LIKE CONCAT('CQ-', DATE_FORMAT(NOW(),'%Y%m'), '%')
</select>
<insert id="insertClientQuote" useGeneratedKeys="true" keyProperty="quoteId">
INSERT INTO biz_client_quote (tenant_id,quote_no,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},
#{status},#{validityDate},#{totalAmount},#{currency},#{remark},#{createBy},NOW())
</insert>
<insert id="insertClientQuoteItem" useGeneratedKeys="true" keyProperty="itemId">
INSERT INTO biz_client_quote_item (quote_id,material_name,spec,model_no,unit,quantity,
cost_price,unit_price,total_price,delivery_days,remark)
VALUES (#{quoteId},#{materialName},#{spec},#{modelNo},#{unit},#{quantity},
#{costPrice},#{unitPrice},#{totalPrice},#{deliveryDays},#{remark})
</insert>
<update id="updateClientQuote">
UPDATE biz_client_quote SET client_name=#{clientName},status=#{status},
validity_date=#{validityDate},total_amount=#{totalAmount},
currency=#{currency},remark=#{remark},update_time=NOW()
WHERE quote_id=#{quoteId}
</update>
<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>
</mapper>

View File

@@ -0,0 +1,34 @@
<?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.system.mapper.bid.BizMaterialCategoryMapper">
<select id="selectCategoryList" resultType="com.ruoyi.system.domain.bid.BizMaterialCategory">
SELECT category_id AS categoryId, tenant_id AS tenantId,
category_name AS categoryName, parent_id AS parentId,
ancestors, sort, status, create_by AS createBy, create_time AS createTime
FROM biz_material_category ORDER BY sort, category_id
</select>
<select id="selectCategoryById" resultType="com.ruoyi.system.domain.bid.BizMaterialCategory">
SELECT category_id AS categoryId, category_name AS categoryName,
parent_id AS parentId, ancestors, sort, status
FROM biz_material_category WHERE category_id = #{categoryId}
</select>
<insert id="insertCategory" useGeneratedKeys="true" keyProperty="categoryId">
INSERT INTO biz_material_category (tenant_id,category_name,parent_id,ancestors,sort,status,create_by,create_time)
VALUES (1,#{categoryName},#{parentId},#{ancestors},#{sort},#{status},#{createBy},NOW())
</insert>
<update id="updateCategory">
UPDATE biz_material_category
SET category_name=#{categoryName},parent_id=#{parentId},ancestors=#{ancestors},
sort=#{sort},status=#{status}
WHERE category_id=#{categoryId}
</update>
<delete id="deleteCategory">
DELETE FROM biz_material_category WHERE category_id=#{categoryId}
</delete>
</mapper>

View File

@@ -9,6 +9,7 @@
<result property="materialCode" column="material_code"/>
<result property="materialName" column="material_name"/>
<result property="spec" column="spec"/>
<result property="modelNo" column="model_no"/>
<result property="unit" column="unit"/>
<result property="brand" column="brand"/>
<result property="description" column="description"/>
@@ -23,9 +24,10 @@
SELECT m.* FROM biz_material m
<where>
<if test="tenantId != null"> AND m.tenant_id = #{tenantId}</if>
<if test="materialCode != null and materialCode != ''"> AND m.material_code LIKE CONCAT('%',#{materialCode},'%')</if>
<if test="materialName != null and materialName != ''"> AND m.material_name LIKE CONCAT('%',#{materialName},'%')</if>
<if test="status != null and status != ''"> AND m.status = #{status}</if>
<if test="categoryId != null"> AND m.category_id = #{categoryId}</if>
<if test="materialCode != null and materialCode != &apos;&apos;"> AND m.material_code LIKE CONCAT(&apos;%&apos;,#{materialCode},&apos;%&apos;)</if>
<if test="materialName != null and materialName != &apos;&apos;"> AND m.material_name LIKE CONCAT(&apos;%&apos;,#{materialName},&apos;%&apos;)</if>
<if test="status != null and status != &apos;&apos;"> AND m.status = #{status}</if>
</where>
ORDER BY m.material_id DESC
</select>
@@ -35,8 +37,8 @@
</select>
<insert id="insertBizMaterial" useGeneratedKeys="true" keyProperty="materialId">
INSERT INTO biz_material(tenant_id,category_id,material_code,material_name,spec,unit,brand,description,status,create_by,create_time)
VALUES(#{tenantId},#{categoryId},#{materialCode},#{materialName},#{spec},#{unit},#{brand},#{description},#{status},#{createBy},NOW())
INSERT INTO biz_material(tenant_id,category_id,material_code,material_name,spec,model_no,unit,brand,description,status,create_by,create_time)
VALUES(#{tenantId},#{categoryId},#{materialCode},#{materialName},#{spec},#{modelNo},#{unit},#{brand},#{description},#{status},#{createBy},NOW())
</insert>
<update id="updateBizMaterial">
@@ -45,6 +47,7 @@
<if test="materialName != null">material_name=#{materialName},</if>
<if test="materialCode != null">material_code=#{materialCode},</if>
<if test="spec != null">spec=#{spec},</if>
<if test="modelNo != null">model_no=#{modelNo},</if>
<if test="unit != null">unit=#{unit},</if>
<if test="brand != null">brand=#{brand},</if>
<if test="description != null">description=#{description},</if>