LikeShop 二开最常改的 5 个文件(附改前改后对比)

做 LikeShop 二开的人都有一个共同的痛点:拿到源码后觉得哪里都能改,结果改完一处,升级时冲突一片。根据 LikeShop 官方二开规范和多份实践文档,核心原则只有一条------核心链路文件尽量不动,扩展逻辑新建文件承载。但现实是,有些文件你绕不开,它们就是二开需求最集中的地方。

下面梳理出二开中修改频率最高的 5 个文件,每个都给出现场级的改前/改后对比,并说明为什么这样改能兼顾功能实现与升级兼容。

1. `style/variables.scss` ------ 主题色一改,全站生效

为什么最常改:客户第一句话往往是"把主题色换成我们的品牌色"。如果颜色硬编码在几十个页面里,全局搜索替换就是灾难。LikeShop 的 UniApp 端已经内置了 SCSS 变量机制,正确做法是只改变量文件,不动页面。

改前(页面里硬编码):

```scss

/ pages/index/index.vue 或 goods-card.vue 里 /

.price {

color: #E63946; // 每个用到价格色的地方都写一遍

}

.btn-primary {

background: #FF6B35; // 主题色散落各处

}

```

改后(统一引用变量):

```scss

/ style/variables.scss /

$primary-color: #1A73E8; // 改成客户品牌蓝

$price-color: #E63946;

$border-radius-base: 12rpx;

/组件或页面中 /

.price {

color: $price-color;

}

.btn-primary {

background: $primary-color;

}

```

要点:`uni.scss` 中已全局引入变量文件,页面和组件直接使用即可,无需逐文件 import。换主题时只动 `variables.scss` 一个文件,所有引用 `$primary-color` 的按钮、高亮文字、选中状态同步变化。

2. `components/business/goods-card/goods-card.vue` ------ 商品卡片是复用之王

为什么最常改:商品卡片出现在首页瀑布流、分类页、搜索结果页、活动页。如果每个页面各写一遍,改一次样式要改四五处。LikeShop 标准版已经提供了业务组件层,但客户往往需要调整展示字段(比如加上"销量"或"标签"),改动集中在这个文件里,影响面可控。

改前(Props 较少,展示形态单一):

```vue

<!-- components/business/goods-card/goods-card.vue -->

<template>

<view class="goods-card" @click="goDetail">

<image :src="goods.image" class="goods-img" />

<view class="goods-info">

<text class="goods-name">{{ goods.name }}</text>

<text class="price">{{ goods.price }}</text>

</view>

</view>

</template>

<script>

export default {

props: {

goods: { type: Object, default: () => ({}) }

},

methods: {

goDetail() {

uni.navigateTo({ url: `/pages/goods/detail?id=${this.goods.id}` });

}

}

};

</script>

```

改后(新增 Props,扩展展示字段,不改原有逻辑):

```vue

<template>

<view class="goods-card" @click="goDetail">

<image :src="goods.image" class="goods-img" />

<view class="goods-info">

<text class="goods-name">{{ goods.name }}</text>

<!-- 新增:销量展示,由 showSales 控制 -->

<text v-if="showSales" class="goods-sales">已售 {{ goods.sales_sum }}</text>

<view class="price-row">

<text class="price">{{ goods.price }}</text>

<!-- 新增:标签位 -->

<text v-if="goods.tag" class="goods-tag">{{ goods.tag }}</text>

</view>

</view>

</view>

</template>

<script>

export default {

props: {

goods: { type: Object, default: () => ({}) },

// 新增 Props,默认 false,不影响旧页面

showSales: { type: Boolean, default: false }

},

// methods 不变

};

</script>

```

要点:新增展示需求优先加 Props,不要直接改组件内部已有逻辑。旧页面不传 `showSales` 时表现与之前完全一致,新页面按需开启。

3. `app/shopapi/logic/OrderLogic.php` ------ 订单扩展的"雷区"

为什么最常改:订单支付成功后的附加动作(发短信、推企业微信、同步 ERP)是二开高频需求。很多人的第一反应是在 `paySuccess()` 末尾塞几行代码。功能能跑,但官方一升级,这个文件就没法直接合并了。

改前(直接修改核心 Logic,植入扩展逻辑):

```php

// app/shopapi/logic/OrderLogic.php

public static function paySuccess($orderId)

{

// ... 原有核心逻辑:更新订单状态、记录支付日志、触发库存扣减 ...

// ❌ 直接塞入二开逻辑

order = OrderModel::get(orderId);

user = UserModel::get(order'user_id');

self::sendEnterpriseWechatNotify(user\['nickname'\], order'order_sn');

return true;

}

```

改后(核心文件只加一行调用,扩展逻辑独立成类):

```php

// app/shopapi/logic/OrderLogic.php

public static function paySuccess($orderId)

{

// ... 原有核心逻辑保持不变 ...

// ✅ 只加一行调用,扩展逻辑在独立文件中

\app\extra\logic\OrderExtendLogic::afterPaySuccess($orderId);

return true;

}

```

```php

// app/extra/logic/OrderExtendLogic.php (新建文件,物理隔离)

namespace app\extra\logic;

class OrderExtendLogic

{

public static function afterPaySuccess(int $orderId): void

{

try {

order = \\app\\common\\model\\Order::get(orderId);

user = \\app\\common\\model\\User::get(order'user_id');

// 企业微信推送逻辑

self::pushWechat(user\['nickname'\], order'order_sn');

} catch (\Exception $e) {

// 扩展失败不影响支付主流程

\think\facade\Log::error("支付后扩展失败:{$e->getMessage()}");

}

}

}

```

要点:官方升级时 `OrderLogic.php` 的合并冲突只有一行调用需要处理;扩展逻辑全部在 `app/extra/` 下,完全不受升级影响。同时扩展逻辑必须 try-catch 包裹,不能因为推送失败导致支付流程异常。

4. `app/shopapi/logic/GoodsLogic.php` ------ SKU 与库存联动的实际落点

为什么最常改:客户常提"库存要和小程序、H5、线下门店打通"或"增加库存预警"。商品详情的 SKU 计算和库存校验逻辑集中在 `GoodsLogic` 中,二开时需要在读取 SKU 和扣减库存的关键节点插入渠道判断或预警检查。

改前(库存扣减直接走原逻辑,无渠道区分):

```php

// app/shopapi/logic/GoodsLogic.php 中库存扣减相关方法

public static function deductStock(skuId, num)

{

sku = GoodsSkuModel::where('id', skuId)->lock(true)->find();

if (sku\['stock'\] \< num) {

throw new \Exception('库存不足');

}

sku-\>stock = sku->stock - $num;

$sku->save();

return true;

}

```

改后(保留原逻辑,在扣减前插入渠道库存检查):

```php

public static function deductStock(skuId, num, $channel = 'default')

{

sku = GoodsSkuModel::where('id', skuId)->lock(true)->find();

if (sku\['stock'\] \< num) {

throw new \Exception('库存不足');

}

// ✅ 新增:多渠道库存检查(扩展逻辑独立方法,不破坏原有扣减)

if ($channel !== 'default') {

channelStock = \\app\\extra\\service\\ChannelStockService::check(skuId, channel, num);

if (!$channelStock) {

throw new \Exception('该渠道库存不足');

}

\app\extra\service\ChannelStockService::deduct(skuId, channel, $num);

}

// 原有扣减逻辑保持不变

sku-\>stock = sku->stock - $num;

$sku->save();

return true;

}

```

要点:方法签名增加了可选参数 `$channel`,默认值保证旧调用方不受影响。真正的多渠道库存逻辑放在 `app/extra/service/` 下,`GoodsLogic` 只负责在正确的时机调用。

5. `uniapp/pages/user/user.vue`(个人中心页)------ 菜单项增删改的集中地

为什么最常改:几乎每个二开项目都会动个人中心:加一个"我的推广"入口、改菜单图标、调整订单状态栏、隐藏某些客户不需要的模块。这个文件是页面层,本来就可以自由改,但问题在于**不要把它改成上千行的意大利面**。

改前(菜单项写死在页面模板里,状态判断也堆在页面中):

```vue

<!-- pages/user/user.vue -->

<template>

<view class="user-page">

<!-- 订单状态栏,四个图标写死 -->

<view class="order-nav">

<view class="nav-item" @click="goOrder(0)">待付款</view>

<view class="nav-item" @click="goOrder(1)">待发货</view>

<view class="nav-item" @click="goOrder(2)">待收货</view>

<view class="nav-item" @click="goOrder(3)">待评价</view>

</view>

<!-- 菜单列表,每一项手写 -->

<view class="menu-list">

<view class="menu-item" @click="goPage('/pages/user/address')">收货地址</view>

<view class="menu-item" @click="goPage('/pages/user/coupon')">优惠券</view>

<view class="menu-item" @click="goPage('/pages/user/collect')">我的收藏</view>

</view>

</view>

</template>

```

改后(菜单数据抽到 data 中,用循环渲染,新增入口只加一行数据):

```vue

<template>

<view class="user-page">

<view class="order-nav">

<view

v-for="item in orderNav"

:key="item.status"

class="nav-item"

@click="goOrder(item.status)"

>

{{ item.label }}

</view>

</view>

<view class="menu-list">

<view

v-for="item in menuList"

:key="item.path"

class="menu-item"

@click="goPage(item.path)"

>

{{ item.label }}

</view>

</view>

</view>

</template>

<script>

export default {

data() {

return {

orderNav: [

{ label: '待付款', status: 0 },

{ label: '待发货', status: 1 },

{ label: '待收货', status: 2 },

{ label: '待评价', status: 3 }

],

menuList: [

{ label: '收货地址', path: '/pages/user/address' },

{ label: '优惠券', path: '/pages/user/coupon' },

{ label: '我的收藏', path: '/pages/user/collect' },

// ✅ 新增入口只需加这一行

{ label: '我的推广', path: '/pages/user/promotion' }

]

};

},

methods: {

goOrder(status) {

uni.navigateTo({ url: `/pages/order/list?status=${status}` });

},

goPage(path) {

uni.navigateTo({ url: path });

}

}

};

</script>

```

要点:页面层可以改,但用数据驱动代替手写模板。以后加菜单项只改 `menuList` 数组,不需要在 template 里复制粘贴一堆 `<view>`。如果某个菜单模块逻辑复杂(比如分销中心有自己的数据请求),应该抽成独立的页面区块组件,而不是全堆在 `user.vue` 里。

改文件不如改"位置"

这 5 个文件之所以最常被改,是因为它们分别对应了二开中最普遍的五类需求:换皮、商品展示、订单钩子、库存扩展、个人中心入口。

但真正让二开项目能持续维护的,不是"改得少",而是改对位置:

| 文件 | 正确改法 | 错误改法 |

| `variables.scss` | 只改变量值 | 页面里硬编码颜色 |

| `goods-card.vue` | 加 Props,旧行为不变 | 直接改组件内部逻辑 |

| `OrderLogic.php` | 加一行调用,扩展独立成类 | 在方法体里塞业务代码 |

| `GoodsLogic.php` | 加可选参数,扩展逻辑外置 | 重写整个扣减方法 |

| `user.vue` | 数据驱动菜单 | 模板里手写每一项 |

按照 LikeShop 官方二开白皮书的说法:新增能力 > 修改原逻辑,组合扩展 > 覆盖替换。做到这一点,官方发新版本时你才敢点"合并"。

"本文基于 LikeShop 单商户标准版 v3.5编写,多商户版逻辑类似但需注意 shop_id 隔离"。

相关推荐
时间的情敌8 分钟前
Cesium 流动管线、管道动画、管线流向仿真,管网、油气、水利孪生高频需求
前端·交互·cesium
wangxiaoxuan2172 小时前
SLAM 的基本结构:前端、后端、回环与地图优化
前端·机器人·科沃斯八界
Agent世界5 小时前
用 CDP 做发布自动化:四道机器闸门与产物验收
前端·javascript
FungLeo5 小时前
成为全栈·Vue 管理后台篇·编辑器图片上传:从文件选择到文章附件关联
前端·vue.js·编辑器·markdown·文件上传·formdata·附件管理
某哈压力大5 小时前
SSH 突然 Connection reset?不是密钥坏了,是 OpenSSL 把 sshd 干趴了
前端·node.js·命令行
笑容掩饰我的失落5 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
程序员大阳5 小时前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半5 小时前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳6 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
deli0076 小时前
写满 200GB 后 SSD 为什么掉到 95MB/s?SLC 缓存模型实测
前端