CRMEB 商城运维技能
环境变量
| 变量名 | 说明 |
|---|---|
$CRMEB_SSH_PASS |
服务器 SSH 密码 |
$CRMEB_MYSQL_PASS |
MySQL 数据库密码 |
$CRMEB_BT_USER |
宝塔面板用户名 |
$CRMEB_BT_PASS |
宝塔面板密码 |
$CRMEB_ADMIN_USER |
CRMEB 后台用户名 |
$CRMEB_ADMIN_PASS |
CRMEB 后台密码 |
服务器与数据库
- 服务器:
root@43.142.157.212,密码:$CRMEB_SSH_PASS - 数据库:
mysql -u crmeb_yunjinhong -p$CRMEB_MYSQL_PASS crmeb_yunjinhong - 表前缀:
eb_ - 项目路径:
/www/wwwroot/crmeb.yunjinhong.cn - Swoole 端口:
8324(非 PHP-FPM,是 Swoole HTTP 服务) - 宝塔面板:
http://43.142.157.212:58801/tencentcloud(用户名:$CRMEB_BT_USER/ 密码:$CRMEB_BT_PASS) - CRMEB 后台:
https://crmeb.yunjinhong.cn/admin(用户名:$CRMEB_ADMIN_USER/ 密码:$CRMEB_ADMIN_PASS)
SSH 连接模板:
sshpass -p "$CRMEB_SSH_PASS" ssh -o StrictHostKeyChecking=no root@43.142.157.212 '<命令>'
MySQL 模板(heredoc 避免转义问题):
sshpass -p "$CRMEB_SSH_PASS" ssh -o StrictHostKeyChecking=no root@43.142.157.212 "mysql -u crmeb_yunjinhong -p$CRMEB_MYSQL_PASS crmeb_yunjinhong << 'EOSQL'
<SQL语句>
EOSQL
"
⚠️ 不在同一个 mysql 调用中混用 INSERT 和 SELECT(会导致语法错误)。
⚠️ MySQL UPDATE 不能在 FROM 子句中引用目标表(用 JOIN 替代)。
核心数据结构
详细表结构参考 references/schema.md。
商品(eb_store_product)
- 主键:
product_id,分类字段:cate_id(二级分类ID) - 关键字段:
mer_id(商户ID,当前=10)、status(1上架)、is_show(1显示)、is_del(0未删)、is_best/is_hot/is_new/is_benefit(推荐标记) product_type=0为普通商品
SPU(eb_store_spu)⚠️ 重要
- CRMEB 前端 API 通过 SPU 表关联商品,直接插入 product 不够,必须同步创建 SPU 记录
- 字段:
mer_id,product_id,status(1),store_name,price,image等
SKU(eb_store_product_attr_value)
- 每个商品必须至少一条 SKU 记录(含
stock/price/cost/image)
分类(eb_store_category)
- 主键:
store_category_id,父级:pid - path 格式必须为斜杠分隔: 一级
/72/,二级/72/73/(❌ 不能用逗号0,72,73) - 前端
findChildrenId用LIKE '%/72/%'匹配子分类
分类与商品关联(eb_store_product_cate)
- 字段:
product_id,mer_cate_id,mer_id
内容详情(eb_store_product_content)
- 每商品一条 HTML 详情,字段:
product_id,content
常见运维操作
1. 添加新商品
- INSERT
eb_store_product(主记录) - INSERT
eb_store_spu(SPU 关联,前端必需) - INSERT
eb_store_product_attr_value(SKU,库存/价格) - INSERT
eb_store_product_cate(分类关联) - INSERT
eb_store_product_content(详情 HTML,可选) - 刷新缓存
2. 添加/修改分类
- path 必须用
/ID/格式 - 一级:
path = CONCAT('/', store_category_id, '/') - 二级:
path = CONCAT(parent_path, store_category_id, '/')
3. 刷新缓存(数据修改后必须执行)
sshpass -p "$CRMEB_SSH_PASS" ssh -o StrictHostKeyChecking=no root@43.142.157.212 '
redis-cli FLUSHALL
cd /www/wwwroot/crmeb.yunjinhong.cn
rm -rf runtime/cache/*
php think swoole stop
sleep 2
php think swoole start &
sleep 6
'
⚠️ php think swoole stop 有时会无法停止,需 kill -9 清理:
ps aux | grep swoole | grep -v grep | awk '{print $2}' | xargs kill -9
4. 验证前端 API
# 分类商品列表
curl -s "http://127.0.0.1:8324/api/product/spu/lst?cate_pid=72&page=1&limit=10"
# 推荐商品
curl -s "http://127.0.0.1:8324/api/product/spu/recommend?page=1&limit=10"
# 热卖排行
curl -s "http://127.0.0.1:8324/api/product/spu/get_hot_ranking?cate_pid=72"
小程序相关
- 小程序 appId:
wxf18cea80f436912e - 客服类型必须选"小程序客服"(系统客服仅适用于PC/H5端)
- 小程序端实际调用的接口(从 Nginx 日志确认):
/api/product/spu/recommend— 首页推荐/api/product/spu/lst?cate_pid=XX— 分类商品/api/product/spu/get_hot_ranking?cate_pid=XX— 热卖排行/api/store/product/category/hotranking— 分类热卖- ❌
/api/category/lst不存在(404)
Nginx 配置
- 主配置:
/www/server/panel/vhost/nginx/crmeb.yunjinhong.cn.conf - 代理配置:
/www/server/panel/vhost/nginx/proxy/crmeb.yunjinhong.cn/fb56cb2de41f7fe35fef4744de3bd4e3_crmeb.yunjinhong.cn.conf - Rewrite:
/www/server/panel/vhost/rewrite/crmeb.yunjinhong.cn.conf(必须存在但可为空,删除会导致 nginx -t 失败) - Nginx 通过反向代理
proxy_pass http://127.0.0.1:8324转发请求,不需要 URL rewrite 规则
踩坑记录
- 分类 path 格式: 必须用
/ID/ID/斜杠格式,逗号格式会导致前端 API 查不到子分类下的商品 - SPU 记录: 直接插入 store_product 不够,前端通过 SPU 表查询,缺少 SPU 记录商品不可见
- Swoole 缓存: 数据库修改后必须重启 Swoole + 清 Redis + 清 runtime/cache
- Nginx rewrite 文件: 不能删除,否则 nginx -t 报错;保持空文件即可
- MySQL 保留字:
unique是保留字,需用反引号 - SSH heredoc: 批量 SQL 用
<< 'EOSQL'传递,避免引号转义 - CNB 云环境: 64核128G 适合浏览器自动化,但 SSH 频繁断连,批量数据操作改用 SSH 直连数据库
现有分类结构
参考 references/categories.md。