Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/seth-shi/monday-shop

网上在线商城、综合网上购物平台
https://github.com/seth-shi/monday-shop

b2c e-shop e-shopping laravel monday-shop shop shopping

Last synced: 6 days ago
JSON representation

网上在线商城、综合网上购物平台

Awesome Lists containing this project

README

        

# seth-shi/monday-shop

* !!! 非`Docker`运行请使用`v1`[https://github.com/seth-shi/monday-shop/tree/1.0](https://github.com/seth-shi/monday-shop/tree/1.0)

## QQ 群
* `584453488`

## 部署(新新新)
1. 下载源码(也可直接下载压缩包, 然后解压)
* `git clone https://github.com/seth-shi/monday-shop.git`
2. 修改配置
* `cp .env.example .env`
* 修改`.env`文件中数据库,域名等配置信息
3. 构建镜像
* `docker build . -t monday-shop`
4. 运行
* `docker run -d --net=host --name monday-shop-service monday-shop`
5. 执行安装命令
* `docker exec monday-shop-service php artisan moon:install`

## 目录说明
* [演示地址](#演示地址)
* [页面展示](#页面展示)
* [特色](#Feature)
* [安装](#Installation)
* [命令行功能](#Commands)
* [秒杀处理逻辑](#秒杀处理逻辑)
* [API文档(新)](#API)
* [依赖的 Packages](#Packages)
* [文章引用](#Reference)
* [错误/注意点](#Notice)
* [协议](#License)

## 演示地址
[演示地址:http://shop.shiguopeng.cn](http://shop.shiguopeng.cn)

[后台地址:http://shop.shiguopeng.cn/admin](http://shop.shiguopeng.cn/admin)
* 账号:`admin`
* 密码:`admin`
****
* 测试支付功能
* 下载[支付宝沙箱](https://sandbox.alipaydev.com/user/downloadApp.htm)
* 账号:`[email protected]`
* 密码:`111111`
* 支付密码:`111111`
* 当前账户余额:`9999999.99`
* 余额不足,请联系我及时充值

## 页面展示
![PC首页](public/media/pc_index.png)
![支付](public/media/pay.gif)
![个人设置](public/media/map_center.png)
![个人中心](public/media/center.png)
![积分详情](public/media/score_detail.png)
![后台仪表盘](public/media/admin/dash_board.png)
![后台订单列表](public/media/admin/orders.png)
![用户喜好数据](public/media/admin/user_like.png)

## Feature
- [x] **库存问题**
* [x] 普通订单使用乐观锁防止超卖
* [X] 秒杀订单使用`Redis`队列防止超卖
- [x] **首页数据全走缓存(推荐使用`Redis`驱动)**
* [x] 未登录的首页,零数据库查询,通过缓存驱动
* [x] 计划任务每分钟会更新一次首页数据
* [x] 开启秒杀模块,零数据库查询,通过`Redis`驱动
* [x] 登录之后首页零数据库查询,`Session`驱动数据
- [x] **积分功能**
* [x] 每日首次登录(访问网站)得到积分(bitmap 计算)
* [x] 连续登录 n 天得到积分(bitmap 计算)
* [x] 当天浏览商品数量 n 个得到积分(bitmap 计算)
* [x] 后台可新增 n+ 积分种类
* [x] 完成订单可获得金钱等比例积分
- [x] **优惠券功能**
* [x] 满减优惠
* [x] 积分兑换满减优惠券
* [x] 发放兑换码,兑换优惠券
- [x] **物流功能**
* [x] 运费设置
* [x] 快递物流
- [x] **秒杀功能**
* 秒杀过期,自动回退库存
* 使用延时队列,当订单超过三十分钟(可配置)未付款,自动取消订单
* 秒杀商品,如果用户收藏,发送邮件提醒活动
* 后台秒杀模块的开启关闭
* 秒杀的商品数量,皆通过`Redis`读取
- [x] **第三方授权登录 + 登录回跳**
* `Github`
* `QQ`
* 微博
- [x] **第三方支付(支持自动适应手机,web 支付)**
- [x] 支付宝支付,退款
- [ ] 微信支付
- [x] **购物车**
* 使用`H5`本地存储
* 登录之后同时显示本地购物车和数据库购物车数量
* 用户登录之后会询问是否需要持久化到数据库
- [x] **商品搜索**
* 使用**ElasticSearch**全文索引
* 支持拼音首字母
* `AJAX`无刷新显示
- [x] **订阅模块**
* 每周定时推送一封邮件包含最受欢迎,最新,最火卖商品
- [x] **分类排序**
* 后台使用拖动排序,可以设置在商城首页优先展示的分类
- [x] **订单模块**
* 订单下单
* 买家支付
* 后台发货 / 卖家申请退款
* 买确认收货 / 后台确认收货
* 买家确认订单获取积分
* 用户下订单之后可以评论
- [x] **站内消息**
* 消息通知
* 多模板类型通知, 兑换码通知、文章通知等等
* 轮询通知消息,一点即达
- [x] **数据统计**
* 每天晚上一点进行站点数据统计
- [x] 全文搜索
- [x] **响应式网站**

## Commands
| 命令 | 一句话描述 |
| ----- | --- |
|`php artisan moon:install`|安装应用程序|
|`php artisan add:shop-to-search`|生成全文索引|
|`php artisan moon:uninstall`|卸载网站(清空数据库,缓存,路由)|
|`php artisan moon:cache`|执行缓存(缓存配置,路由,类映射)|
|`php artisan moon:clear`|清除缓存|
|`php artisan moon:copy`|复制项目内置的静态资源|
|`php artisan moon:delete`|删除项目及上传的基本静态资源|
|`php artisan moon:export`|导出用户数据到json文件|
|`php artisan moon:count-site`|统计站点任务(每天夜里一点执行)|
|`php artisan moon:del-seckills`|删除秒杀数据 (每小时自动执行一次)|
|`php artisan moon:moon:del-score-data`|删除积分缓存数据 (每天夜里 0 点执行)|
|`php artisan moon:update-home`|更新首页数据 (每分钟自动执行一次)|
|`php artisan moon:send-subscribes`|发送订阅邮件 (每个礼拜六早上八点)|
|`php artisan queue:work --tries=3`|监听队列(邮件发送,处理过期的秒杀数据 !!!|

## 秒杀处理逻辑
```php

## 初始化抢购数据
number, 9));

?>

## 抢购
id();

// 判断是否已经开始了秒杀

// 返回 0,代表当前用户已经抢购过了
if (0 == Redis::hset("seckills:{$id}:users:{$userId}", 'id', $userId)) {

return responseJson(403, '你已经抢购过了');
}

// 如果从队列中读取到了 null,代表已经没有库存
if (is_null(Redis::lpop("seckills:{$id}:queue"))) {

return responseJson(403, '已经抢购完了');
}

// 这里就可以开始入库订单

?>

## 利用 crontab 定时扫描过期数据,回滚库存,删除过期 redis (可选)
where('end_at', '<', date('Y-m-d H:i:s'))
->get()
->map(function (Seckill $seckill) {

// 先模糊查找到所有用户 key
$ids = Redis::keys("seckills:{$seckill->id}:*");
Redis::del($ids);

// 回滚库存
// 做更多的事
};

?>

```

## API
* 接口响应数据说明
* 响应的数据格式总是保证拥有基本元素(`code`, `msg`, `data`)
* `code` 请参考接口全局状态码说明
* `msg` 此次请求消息,如果返回状态码为非成功,可直接展示`msg`
* `data` 如果为列表页将会一个数组类型(如商品列表),否则为一个对象类型(商品详情)
* 如有额外扩展字段, 将于基本元素平级, 如分页的`count`
```json
{
"code": 401,
"msg": "无效的token",
"data": []
}
```
* 刷新`token`说明
* 为了保证安全性,`token`的有效时间为`60`分钟
* 当旧的`token`失效时,服务器会主动刷新,并在响应头加入`Authorization`
* 这时候旧的`token`将会加入黑名单不能再使用, 请将在响应头中新的`token`保存使用
* 当服务器主动刷新之后,会有一个期限(`2`周).服务器将无法再刷新,将返回`402`状态码,请重新登录账户
* `token`使用流程说明
```javascript
// 全局请求类
function request(_method, _url, _param, _func) {

$.ajax({
method: _method,
url: _url,
data: _param,
beforeSend: function (xhr) {
console.log(xhr);
xhr.setRequestHeader('Authorization', localStorage.getItem('api_token'))
},
complete: function (xhr, a, b) {

if (xhr.getResponseHeader('Authorization')) {
localStorage.setItem('api_token', xhr.getResponseHeader('Authorization'))
}
},
success: function (res) {

// token 永久过期
if (res.code === 402) {
// 跳去登录页面
return false;
}
// 更多状态码判断
}
});
}

// 第一次登录保存 token, 之后使用全局类请求数据即可

```

* 接口全局状态码说明(建议封装一个全局请求类或者中间件,统一处理全局状态码)
* `200`
* 请求数据成功
* `401`
* 身份验证出错(未登录就请求数据)
* 非法无效的`token`
* `token`已被加入黑名单(一般不会出现这个问题,出现这个问题那么就是你刷新 token 的逻辑有问题)
* `402`
* `token`已完全失效,后台暂设为 2 周,再也无法刷新,请重新登录账户
* `500`
* 服务器出错,具体请参考响应的消息
* __接口文档__(重要的事情说三遍)

[接口文档](http://shop.shiguopeng.cn/docs.html)

[接口文档](http://shop.shiguopeng.cn/docs.html)

[接口文档](http://shop.shiguopeng.cn/docs.html)
![](public/media/api_example.gif)

## Packages
| 扩展包 | 一句话描述 | 在本项目中的使用案例 |
| --- | --- | --- |
|[z-song/laravel-admin](https://github.com/z-song/laravel-admin)|后台|快速搭建后台系统|
|[mews/captcha](https://github.com/mewebstudio/captcha)|验证码|登录注册功能使用验证码验证|
|[overtrue/laravel-socialite](https://github.com/overtrue/laravel-socialite)|第三方登录|用户登录可以使用Github,QQ,新浪微博|
|[intervention/image](https://github.com/Intervention/image)|图片处理|是为 Laravel 定制的图片处理工具,加水印|
|[webpatser/laravel-uuid](https://github.com/webpatser/laravel-uuid)|uuid生成|商品添加增加一个uuid,订单号|
|[renatomarinho/laravel-page-speed](https://github.com/renatomarinho/laravel-page-speed)|压缩页面DOM|打包优化您的网站自动导致35%以上的优化(已移除使用)|
|[overtrue/laravel-pinyin](https://github.com/overtrue/laravel-pinyin)|汉语拼音翻译|分类首字母查询|
|[acelaya/doctrine-enum-type](https://github.com/acelaya/doctrine-enum-type)|枚举|优化代码中的映射|

## Reference
* [Laravel 的中大型專案架構](https://old-oomusou.goodjack.tw/laravel/architecture/)
* [十个 Laravel 5 程序优化技巧](https://laravel-china.org/articles/2020/ten-laravel-5-program-optimization-techniques)
* [十个 Laravel 5 程序优化技巧](http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html)
* [服务器做了两个优化 CPU 使用率减低 40%(使用缓存优化访问量不写数据库)](https://learnku.com/articles/13366/the-server-has-made-two-optimization-and-the-cpu-utilization-rate-has-been-reduced-by-40)

## Notice
* 建议开启`bcmath`扩展保证字符串数字运算正确
* 监听队列如果长时间没反应,或者一直重复任务
* 数据库没配置好,导致队列任务表连接不上
* 邮件配置出错,导致发送邮件一直失败
* `composer install`安装不上依赖
* 请删除`composer.lock`文件,重新运行`composer install`
* `SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint`
* 数据库引擎切换到`InnoDB`
* `composer install` 安装依赖错误
* `composer.lock`锁定了镜像源,删除`composer.lock`再执行即可
## License
The MIT License (MIT)