feat(erp): 采购计划/采购审核/到货跟踪 + 供应商管理

- 采购计划:选合同自动带出明细、合同/供应商表格选择器、批量填充(可生成N行)、卷号/数量列、送审/重新送审流程
- 采购审核:通过/驳回 + 申请意见,每次审核留痕(erp_purchase_plan_audit_log),计划详情展示审核历史/驳回理由
- 到货跟踪:上传到货Excel按牌号+规格回填明细到货量与状态,列校验/kg→t纠正,满额自动归档
- 供应商管理页(复用既有 erp_supplier 后端)
- 综合搜索(计划号/供货商/合同号)、左右分栏工作台、全局表单按钮对齐修复
- 清理无用旧 erp 页面(看板/需求/订单/收货/退货/汇总)
- DDL 与菜单脚本:docs/purchase-plan-ddl.sql(按 path 解析父目录、可重复执行)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 16:53:21 +08:00
parent 47931b75ae
commit ce3998db74
38 changed files with 3559 additions and 2842 deletions

View File

@@ -0,0 +1,80 @@
<?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.klp.erp.mapper.ErpPurchasePlanMapper">
<select id="selectOrderCodes" resultType="java.lang.String">
SELECT order_code FROM crm_order
WHERE del_flag = 0 AND order_id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 选合同自动带出明细crm_order_item -> 采购计划明细VO公差空值给 '0' -->
<select id="selectItemsByOrderIds" resultType="com.klp.erp.domain.vo.ErpPurchasePlanItemVo">
SELECT
product_type AS productType,
material AS material,
grade AS grade,
width AS width,
thickness AS thickness,
COALESCE(NULLIF(TRIM(width_tolerance), ''), '0') AS widthTolerance,
COALESCE(NULLIF(TRIM(thickness_tolerance), ''), '0') AS thicknessTolerance,
weight AS weight,
product_num AS quantity
FROM crm_order_item
WHERE del_flag = 0 AND order_id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
ORDER BY order_id, item_id
</select>
<!-- 合同列表 + 该合同已挂接的采购计划数 -->
<select id="selectContractPage" resultType="com.klp.erp.domain.vo.ErpContractOptionVo">
SELECT
o.order_id AS orderId,
o.order_code AS orderCode,
o.contract_code AS contractCode,
o.contract_name AS contractName,
o.customer AS customer,
o.supplier AS supplier,
o.order_amount AS orderAmount,
o.salesman AS salesman,
(SELECT COUNT(*) FROM erp_purchase_plan_contract_rel r
JOIN erp_purchase_plan p ON p.plan_id = r.plan_id AND p.del_flag = '0'
WHERE r.del_flag = '0' AND r.order_id = o.order_id) AS planCount
FROM crm_order o
WHERE o.del_flag = 0
<if test="kw != null and kw != ''">
AND (o.order_code LIKE CONCAT('%', #{kw}, '%')
OR o.contract_name LIKE CONCAT('%', #{kw}, '%')
OR o.contract_code LIKE CONCAT('%', #{kw}, '%')
OR o.customer LIKE CONCAT('%', #{kw}, '%'))
</if>
ORDER BY o.is_top DESC, o.order_id DESC
</select>
<!-- 某合同下的所有采购计划 -->
<select id="selectPlansByContract" resultType="com.klp.erp.domain.vo.ErpPurchasePlanVo">
SELECT p.*
FROM erp_purchase_plan p
JOIN erp_purchase_plan_contract_rel r ON r.plan_id = p.plan_id AND r.del_flag = '0'
WHERE p.del_flag = '0' AND r.order_id = #{orderId}
ORDER BY p.plan_id DESC
</select>
<!-- 按合同关键字查关联的采购计划ID订单编号/合同号/合同名称) -->
<select id="selectPlanIdsByContractKeyword" resultType="java.lang.Long">
SELECT DISTINCT r.plan_id
FROM erp_purchase_plan_contract_rel r
JOIN crm_order o ON o.order_id = r.order_id AND o.del_flag = 0
WHERE r.del_flag = '0'
AND (o.order_code LIKE CONCAT('%', #{kw}, '%')
OR o.contract_code LIKE CONCAT('%', #{kw}, '%')
OR o.contract_name LIKE CONCAT('%', #{kw}, '%'))
</select>
</mapper>