CRMEB Pro 商品字段二开:为什么加一个字段会牵动 SKU、缓存和前端展示?

摘要

很多 CRMEB Pro 二开需求看起来很小:给商品加一个业务字段,比如商品卖点、渠道标识、适用场景、内部备注、采购属性、展示标签。真正动手时才会发现,商品字段不是只改一张表那么简单。

商品保存会经过后台表单、Controller 参数收集、Services 数据整理、Dao/Model 入库、规格库存同步、列表搜索、移动端展示和缓存清理。字段如果只加在前端,保存时会丢;只加在后端,列表不显示;只改主表,不考虑 SKU 和缓存,移动端可能还是旧数据。

这篇结合 CRMEB Pro 当前商品模块实现,整理一套商品字段二开的检查链路。

一、先看商品保存的真实入口

后台商品模块的核心路由在 crmeb_pro/route/admin.phpproduct 分组中,和商品新增、编辑、列表、规格、库存有关的入口包括:

text 复制代码
GET  product/product                 商品列表
POST product/product/:id             新建或修改商品
GET  product/product/:id             商品编辑详情
GET  product/product/type_header     商品列表头部数据
GET  product/product/attrs/:id       获取商品规格
PUT  product/product/saveStocks/:id  快速批量修改库存
POST generate_attr/:id/:type         生成商品规格列表

后台前端对应接口封装在 crmeb_pro_admin/src/api/product.js

text 复制代码
getGoods             商品列表
productInfoApi       商品编辑详情
productAddApi        商品提交
getGoodHeade         商品头部统计
productAttrsApi      商品规格
productSaveStocksApi 提交规格库存

所以商品字段二开不要只盯一个页面,要先确认这个字段属于:

text 复制代码
商品主表字段
商品 SKU 字段
商品分类/品牌/标签关系
商品详情 description
列表筛选字段
移动端展示字段

字段归属不同,改动位置完全不同。

二、Controller 里要先接住字段

后台商品保存入口是 StoreProduct::save()。它并不直接读取所有请求参数,而是通过 getProductSaveFields() 定义允许接收的字段。

当前商品保存字段里已经包含很多业务项,例如:

text 复制代码
product_type      商品类型
cate_id           商品分类
store_name        商品名称
store_info        商品简介
keyword           关键字
slider_image      商品轮播图
spec_type         单规格/多规格
items             SKU 明细
attrs             多规格规则
label_id          用户标签
store_label_id    商品标签
brand_id          品牌
delivery_type     配送方式
temp_id           运费模板
is_vip_product    付费会员商品
product_clear     商品适用群体
custom_form       自定义表单
system_form_id    系统表单

如果新增字段没有放进这个参数白名单,前端传了也会被过滤,后续 Services 根本拿不到。

二开建议:

text 复制代码
1. 新增商品主字段:先补 getProductSaveFields()
2. 新增列表筛选字段:再补 index() 和 type_header() 的 getMore()
3. 新增快速编辑字段:检查 set_product 或批量操作入口
4. 新增移动端字段:再检查 API 输出字段

Controller 只做参数接收和调用,不要在这里写查询或业务判断。

三、Services 才是商品字段落库前的核心整理层

商品保存真正的业务编排在 StoreProductServices::saveData(),它会先调用 prepareProductSaveData() 整理数据,然后进入事务保存。

这个链路里会做很多事情:

text 复制代码
1. 校验商品基础数据
2. 处理运费和配送方式
3. 区分普通商品、供应商商品、门店商品
4. 整理单规格/多规格数据
5. 处理分类、标签、轮播图、主图
6. 保存商品详情 description
7. 校验并保存 SKU
8. 汇总商品库存、会员价、售罄状态
9. 触发商品创建事件和库存流水事件
10. 清理商品和规格缓存

这也是为什么"加一个字段"会牵动这么多地方。比如你加的是主表字段,至少要确认:

text 复制代码
prepareProductSaveData() 中不会被 unset 掉
normalizeProductBaseData() 或相关整理方法是否需要处理格式
fillProductPriceData() 是否会影响价格字段
saveData() 事务里是否需要和 SKU 一起更新
event('product.create') 后续监听是否需要这个字段

如果字段和 SKU 没关系,不要放到 itemsattrs 里;如果字段是 SKU 维度,比如规格独立编码、规格成本、规格外部库存,就应该放到 SKU 保存链路,而不是商品主表。

四、SKU 和库存不能顺手乱改

商品保存时,StoreProductServices::saveData() 会调用:

text 复制代码
StoreProductAttrServices::validateProductAttr()
StoreProductAttrServices::saveProductAttr()

规格保存完成后,还会根据所有 SKU 的库存汇总更新商品主表:

text 复制代码
商品 stock = 所有 SKU stock 求和
商品 is_sold = SKU 最小库存判断
商品 vip_price = SKU 会员价最小值

这意味着,如果你的字段和库存、价格、会员价、佣金、成本价有关,就不能只改商品主表。

例如新增"规格外部编码"时,应该考虑:

text 复制代码
store_product_attr_value 是否新增字段
StoreProductAttrServices::validateProductAttr() 是否允许该字段
StoreProductAttrServices::saveProductAttr() 是否保存该字段
StoreProductAttrValueServices::updateAttrs() 是否快速编辑同步
前端规格表格是否显示和提交该字段
导入/导出是否需要支持该字段

否则后台新增商品时字段能保存,列表快速改库存时又可能把它漏掉。

五、列表展示和搜索也要一起补

后台商品列表在 StoreProduct::index() 接收筛选条件,再调用 StoreProductServices::getList(),最后走 StoreProductDao::getList() 和 Model 搜索器。

当前列表筛选已经支持很多条件:

text 复制代码
商品名称/ID/关键字/条码
商品类型
分类、品牌、配送方式
单规格/多规格
商品标签
供应商
销量区间、价格区间、库存区间
创建时间区间
付费会员价
等级会员价格
是否参与返佣
活动类型
适用群体

如果新增字段需要搜索,不要在 Services 拼 SQL。更稳的方式是:

text 复制代码
Controller 增加筛选参数
Dao search() 传入 where
Model 增加搜索器
前端 tableForm/artFrom 增加字段
列表导出字段同步更新

例如适用群体 product_clear 最终对应 Model 搜索器,会转换成 is_general_productis_channel_productis_vip_product 等字段判断。类似字段最好也按搜索器封装,避免列表页和导出页各写一份查询逻辑。

六、缓存和草稿也容易被忽略

商品新增编辑页有临时保存能力:

text 复制代码
GET    product/cache     获取退出未保存的数据
POST   product/cache     保存还未提交数据
DELETE product/cache     删除退出未保存数据

Controller 中 saveCacheData() 会把商品编辑中的大量字段写到缓存里。如果新增字段只加正式保存,不加草稿保存,运营编辑一半离开页面后再回来,这个字段可能丢失。

商品保存成功后,系统会清理:

text 复制代码
商品缓存 tag
规格缓存 tag

涉及移动端商品详情、商品列表、SKU 展示的字段,发布后还要确认缓存是否清掉,否则会出现后台已保存、前端仍展示旧值。

七、前端需要同步三类位置

后台前端至少要看这些位置:

text 复制代码
crmeb_pro_admin/src/api/product.js
crmeb_pro_admin/src/pages/product/productAdd/index.vue
crmeb_pro_admin/src/pages/product/productAdd/components/productBaseSet.vue
crmeb_pro_admin/src/pages/product/productAdd/components/vipPriceSet.vue
crmeb_pro_admin/src/pages/product/productList/index.vue

一般字段改造分三类:

text 复制代码
编辑页字段:表单展示、校验、提交
列表字段:表格展示、搜索、导出
SKU 字段:规格表格列、单规格默认值、多规格批量填充

移动端如果要展示,还要看:

text 复制代码
crmeb_pro_uniapp/api/store.js
product/detail/:id
products
product/hot
v2/get_attr/:id/:type

不要只改后台保存,忘了移动端读取。

八、推荐二开步骤

text 复制代码
1. 先判断字段归属:主表、SKU、详情、关系表还是筛选字段
2. 涉及数据库时,同步维护完整安装 SQL 和升级 SQL
3. Controller 参数白名单接住字段
4. Services 中整理格式、校验边界、避免被 unset
5. Dao/Model 搜索器补查询,不在业务层写 SQL
6. 前端编辑页、列表页、导出和移动端展示一起同步
7. 保存后确认缓存 tag 清理
8. 测试新增、编辑、复制商品、批量操作、导入导出、移动端详情

如果字段影响价格、库存、佣金、会员价,一定要额外测试下单、退款、库存扣减和分销结算,不要只看商品页保存成功。

九、关键目录说明

text 复制代码
crmeb_pro/route/admin.php
后台商品路由入口,能看到商品列表、保存、规格、库存等接口。

crmeb_pro/app/controller/admin/v1/product/StoreProduct.php
商品后台控制器,负责接收参数、调用 Services、返回统一响应。

crmeb_pro/app/services/product/product/StoreProductServices.php
商品主业务服务,负责保存编排、字段整理、库存汇总、缓存清理和事件触发。

crmeb_pro/app/services/product/sku/StoreProductAttrServices.php
商品规格服务,负责规格校验、SKU 生成和 SKU 保存。

crmeb_pro/app/services/product/sku/StoreProductAttrValueServices.php
规格值服务,负责 SKU 库存、价格、库存流水和快速库存修改。

crmeb_pro/app/dao/product/product/StoreProductDao.php
商品查询 Dao,列表、搜索、分页、统计都应优先从这里扩展。

crmeb_pro/app/model/product/product/StoreProduct.php
商品模型,包含关联和搜索器。

crmeb_pro_admin/src/api/product.js
后台前端商品接口封装。

crmeb_pro_admin/src/pages/product/productAdd
商品新增编辑页面和组件。

crmeb_pro_admin/src/pages/product/productList/index.vue
商品列表、筛选、批量操作和库存入口。

十、注意事项

  • 不要在 Controller 或 Services 中直接写临时 SQL。
  • 新增查询条件优先放到 Dao 和 Model 搜索器。
  • 新增字段涉及数据库时,安装 SQL 和升级 SQL 都要维护。
  • SKU 字段不要混到商品主表字段里。
  • 价格、库存、会员价、佣金字段必须额外测试下单和退款链路。
  • 商品编辑草稿、复制商品、导入商品、导出商品都要检查字段是否丢失。
  • 发布后要确认商品缓存和规格缓存被清理。

十一、标签建议

text 复制代码
CRMEB
CRMEB Pro
二次开发
商品模块
SKU
ThinkPHP
商城系统
源码解析
相关推荐
IT_陈寒1 小时前
Python的pickle让我半夜加班,这破玩意儿太坑了
前端·人工智能·后端
qq_422152572 小时前
图片格式转换工具怎么选?JPEG、PNG、WebP、AVIF 格式对比与在线转换方案实测
前端
xiaofeichaichai2 小时前
ES 新特性九年速览:从 ES2016 到 ES2024
前端·javascript·es6
2401_834636992 小时前
Keepalived + LVS (DR) + Nginx + NFS 高可用 Web 集群部署实战手册
前端·nginx·lvs
和你看星星2 小时前
我把代码排查流程做成了一个 Codex Skill
前端
excel2 小时前
AI 冲击下的前端发展指引:从工具到价值的重塑
前端
文心快码BaiduComate2 小时前
提升组织级AI Coding质量:电商搜索项目实践
前端·后端·程序员
excel2 小时前
AI 时代前端转型:模型训练才是未来的核心竞争力
前端
放下华子我只抽RuiKe53 小时前
FastAPI 全栈后端(四):认证与授权
开发语言·前端·javascript·python·深度学习·react.js·fastapi