Browse Source

部署

master
wanghongjun 2 years ago
parent
commit
ae026989fb
  1. 116
      README.md
  2. 1
      app/.htaccess
  3. 160
      app/admin/controller/Controller.php
  4. 60
      app/admin/controller/Passport.php
  5. 97
      app/admin/controller/Store.php
  6. 60
      app/admin/controller/admin/User.php
  7. 40
      app/admin/controller/setting/Cache.php
  8. 264
      app/admin/controller/setting/Science.php
  9. 90
      app/admin/controller/store/Api.php
  10. 124
      app/admin/controller/store/Menu.php
  11. 48
      app/admin/model/Store.php
  12. 25
      app/admin/model/UploadFile.php
  13. 110
      app/admin/model/admin/User.php
  14. 129
      app/admin/model/store/Api.php
  15. 116
      app/admin/model/store/Menu.php
  16. 63
      app/admin/model/store/MenuApi.php
  17. 60
      app/admin/model/store/User.php
  18. 94
      app/admin/service/Cache.php
  19. 120
      app/admin/service/admin/User.php
  20. 25
      app/admin/service/store/User.php
  21. 29
      app/api/common.php
  22. 31
      app/api/config/captcha.php
  23. 124
      app/api/controller/Address.php
  24. 48
      app/api/controller/Article.php
  25. 49
      app/api/controller/Captcha.php
  26. 118
      app/api/controller/Cart.php
  27. 37
      app/api/controller/Category.php
  28. 202
      app/api/controller/Checkout.php
  29. 76
      app/api/controller/Comment.php
  30. 101
      app/api/controller/Controller.php
  31. 39
      app/api/controller/Coupon.php
  32. 37
      app/api/controller/Express.php
  33. 98
      app/api/controller/Goods.php
  34. 36
      app/api/controller/Help.php
  35. 16
      app/api/controller/Index.php
  36. 53
      app/api/controller/MyCoupon.php
  37. 36
      app/api/controller/Notify.php
  38. 159
      app/api/controller/Order.php
  39. 40
      app/api/controller/Page.php
  40. 97
      app/api/controller/Passport.php
  41. 58
      app/api/controller/Recharge.php
  42. 96
      app/api/controller/Refund.php
  43. 50
      app/api/controller/Region.php
  44. 37
      app/api/controller/Setting.php
  45. 77
      app/api/controller/Upload.php
  46. 92
      app/api/controller/User.php
  47. 39
      app/api/controller/article/Category.php
  48. 38
      app/api/controller/balance/Log.php
  49. 40
      app/api/controller/goods/Service.php
  50. 83
      app/api/controller/order/Comment.php
  51. 37
      app/api/controller/points/Log.php
  52. 39
      app/api/controller/recharge/Order.php
  53. 36
      app/api/controller/recharge/Plan.php
  54. 20
      app/api/event.php
  55. 101
      app/api/listener/order/PaySuccess.php
  56. 97
      app/api/model/Article.php
  57. 166
      app/api/model/Cart.php
  58. 46
      app/api/model/Category.php
  59. 274
      app/api/model/Comment.php
  60. 42
      app/api/model/CommentImage.php
  61. 86
      app/api/model/Coupon.php
  62. 34
      app/api/model/Delivery.php
  63. 34
      app/api/model/DeliveryRule.php
  64. 36
      app/api/model/Express.php
  65. 265
      app/api/model/Goods.php
  66. 33
      app/api/model/GoodsImage.php
  67. 43
      app/api/model/GoodsSku.php
  68. 24
      app/api/model/GoodsSpecRel.php
  69. 32
      app/api/model/Help.php
  70. 400
      app/api/model/Order.php
  71. 33
      app/api/model/OrderAddress.php
  72. 51
      app/api/model/OrderGoods.php
  73. 234
      app/api/model/OrderRefund.php
  74. 33
      app/api/model/OrderRefundAddress.php
  75. 25
      app/api/model/OrderRefundImage.php
  76. 161
      app/api/model/Page.php
  77. 25
      app/api/model/Region.php
  78. 33
      app/api/model/Setting.php
  79. 24
      app/api/model/Spec.php
  80. 24
      app/api/model/SpecValue.php
  81. 55
      app/api/model/Store.php
  82. 56
      app/api/model/UploadFile.php
  83. 129
      app/api/model/User.php
  84. 180
      app/api/model/UserAddress.php
  85. 206
      app/api/model/UserCoupon.php
  86. 44
      app/api/model/UserOauth.php
  87. 36
      app/api/model/article/Category.php
  88. 54
      app/api/model/goods/Service.php
  89. 24
      app/api/model/goods/ServiceRel.php
  90. 35
      app/api/model/h5/Setting.php
  91. 251
      app/api/model/recharge/Order.php
  92. 42
      app/api/model/recharge/OrderPlan.php
  93. 67
      app/api/model/recharge/Plan.php
  94. 49
      app/api/model/user/BalanceLog.php
  95. 25
      app/api/model/user/Grade.php
  96. 25
      app/api/model/user/GradeLog.php
  97. 41
      app/api/model/user/PointsLog.php
  98. 25
      app/api/model/wxapp/Setting.php
  99. 171
      app/api/service/Cart.php
  100. 39
      app/api/service/Goods.php

116
README.md

@ -0,0 +1,116 @@
# 萤火商城V2.0开源版
#### 项目介绍
萤火商城V2.0,是全新推出的一款轻量级、高性能、前后端分离的电商系统,支持微信小程序 + H5+ 公众号 + APP,前后端源码完全开源,看见及所得,完美支持二次开发,可学习可商用,让您快速搭建个性化独立商城。
如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,获取第一时间更新,谢谢!
#### 技术特点
* 前后端完全分离 (互不依赖 开发效率高)
* 采用PHP7.4 (强类型严格模式)
* Thinkphp6.0.5(轻量级PHP开发框架)
* Uni-APP(开发跨平台应用的前端框架)
* Ant Design Vue(企业级中后台产品UI组件库)
* RBAC(基于角色的权限控制管理)
* Composer一键引入三方扩展
* 部署运行的项目体积仅30多MB(真正的轻量化)
* 所有端代码开源 (服务端PHP、后台vue端、uniapp端)
* 简约高效的编码风格 (可能是最适合二开的源码)
* 源码中清晰中文注释 (小白也能看懂的代码)
#### 页面展示
![前端展示](https://images.gitee.com/uploads/images/2021/0316/215102_7bcb0802_2166072.png "前端展示.png")
![后台-首页](https://images.gitee.com/uploads/images/2021/0316/215827_7df5251c_2166072.png "后台-首页.png")
![后台-页面设计](https://images.gitee.com/uploads/images/2021/0316/215839_2d4ebccc_2166072.png "后台-页面设计.png")
![后台-编辑商品](https://images.gitee.com/uploads/images/2021/0316/215848_9d54adff_2166072.png "后台-编辑商品.png")
![后台-订单详情](https://images.gitee.com/uploads/images/2021/0316/215855_8606fce3_2166072.png "后台-订单详情.png")
#### 系统演示
- 商城后台演示:https://shop2.yiovo.com/admin/
- 用户名和密码:admin yinghuo
![前端演示二维码](https://images.gitee.com/uploads/images/2021/0316/104516_3778337e_2166072.png "111.png")
- QQ交流群 806461900
#### 源码下载
1. 主商城端(又称后端、服务端,PHP开发 用于管理后台和提供api接口)
下载地址:https://gitee.com/xany/yoshop2.0
2. 用户端(也叫客户端、前端,uniapp开发 用于生成H5和微信小程序)
下载地址:https://gitee.com/xany/yoshop2.0-uniapp
2. 后台VUE端(指的是商城后台的前端代码,使用vue2编写,分store模块和admin模块)
下载地址:https://gitee.com/xany/yoshop2.0-store
下载地址:https://gitee.com/xany/yoshop2.0-admin
#### 代码风格
* PHP7强类型严格模式
* 严格遵守MVC设计模式 同时具有service层和枚举类enum支持
* 简约整洁的编码风格 绝不冗余一行代码
* 代码注释完整易读性高 尽量保障初级程序员也可读懂 极大提升二开效率
* 不允许直接调用和使用DB类(破坏封装性)
* 不允许使用原生SQL语句 全部使用链式操作(可维护性强)
* 不允许存在复杂SQL查询语句(可维护性强)
* 所有的CURD操作均通过ORM模型类 并封装方法(扩展性强)
* 数据库设计满足第三范式
* 前端JS编码均采用ES6标准
#### 环境要求
- CentOS 7.0+
- Nginx 1.10+
- PHP 7.4
- MySQL 5.6+
#### 如何安装
##### 一、自动安装(推荐)
1. 将后端源码上传至服务器站点,并且将站点运行目录设置为/public
2. 在浏览器中输入站点域名 + /install,例如:https://www.你的域名.com/install
3. 根据页面提示,自动完成安装即可
##### 二、手动安装(不推荐)
1. 将后端源码上传至服务器站点,并且将站点运行目录设置为/public
2. 创建一个数据库,例如:yoshop2_db
3. 导入数据库表结构文件,路径:/public/install/data/install_struct.sql
4. 导入数据库默认数据文件,路径:/public/install/data/install_data.sql
5. 修改数据库连接文件,将数据库用户名密码等信息填写完整,路径/.env
#### 后台地址
- 超管后台:https://www.你的域名.com/admin
- 商户后台:https://www.你的域名.com/store
- 默认的账户密码:admin yinghuo
#### 定时任务
用于自动处理订单状态、优惠券状态、会员等级等
```sh
php think timer start
```
#### 安全&缺陷
如果您碰到安装和使用问题可以查阅[Issue](https://gitee.com/xany/yoshop2.0/issues?state=all),或者将操作流程和截图详细发出来,我们看到后会给出解决方案。
如果有BUG或者安全问题,我们会第一时间修复。
#### 版权须知
1. 允许个人学习研究使用,支持二次开发,允许商业用途(仅限自运营)。
2. 允许商业用途,但仅限自运营,如果商用必须保留版权信息,望自觉遵守。
3. 不允许对程序代码以任何形式任何目的的再发行或出售,否则将追究侵权者法律责任。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2017-2023 By 萤火科技 (https://www.yiovo.com) All rights reserved。

1
app/.htaccess

@ -0,0 +1 @@
deny from all

160
app/admin/controller/Controller.php

@ -0,0 +1,160 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller;
use cores\BaseController;
use cores\exception\BaseException;
use app\admin\service\admin\User as AdminUserService;
use think\response\Json;
/**
* 超管后台控制器基类
* Class Controller
* @package app\admin\controller
*/
class Controller extends BaseController
{
// 商家登录信息
protected $admin;
// 当前控制器名称
protected $controller = '';
// 当前方法名称
protected $action = '';
// 当前路由uri
protected $routeUri = '';
// 当前路由:分组名称
protected $group = '';
// 登录验证白名单
protected $allowAllAction = [
// 登录页面
'passport/login',
];
// 无需全局layout
protected $notLayoutAction = [];
/**
* 强制验证当前访问的控制器方法method
* 例: [ 'login' => 'POST' ]
* @var array
*/
protected $methodRules = [];
/**
* 后台初始化
* @throws \Exception
*/
public function initialize()
{
// 设置管理员登录信息
$this->setAdminInfo();
// 当前路由信息
$this->getRouteInfo();
// 验证登录
$this->checkLogin();
// 强制验证当前访问的控制器方法method
$this->checkMethodRules();
}
/**
* 设置管理员登录信息
*/
private function setAdminInfo()
{
$this->admin = AdminUserService::getLoginInfo();
}
/**
* 解析当前路由参数 (分组名称、控制器名称、方法名)
*/
protected function getRouteInfo()
{
// 控制器名称
$this->controller = uncamelize($this->request->controller());
// 方法名称
$this->action = $this->request->action();
// 控制器分组 (用于定义所属模块)
$group = strstr($this->controller, '.', true);
$this->group = $group !== false ? $group : $this->controller;
// 当前uri
$this->routeUri = "{$this->controller}/$this->action";
}
/**
* 后台菜单配置
* @return array
*/
private function menus(): array
{
// 获取后台菜单内容 [app/admin/config/menus.php]
$menus = \think\facade\Config::get('menus');
foreach ($menus as $group => &$first) {
$first['active'] = $group === $this->group;
// 遍历:二级菜单
if (isset($first['submenu'])) {
foreach ($first['submenu'] as $secondKey => &$second) {
// 二级菜单所有uri
$secondUris = $second['uris'] ?? [$second['index']];
// 二级菜单:active
!isset($second['active']) && $second['active'] = in_array($this->routeUri, $secondUris);
}
}
}
return $menus;
}
/**
* 验证登录状态
* @return void
* @throws BaseException
*/
private function checkLogin(): void
{
// 验证当前请求是否在白名单
if (in_array($this->routeUri, $this->allowAllAction)) {
return;
}
// 验证登录状态
if (empty($this->admin) || (int)$this->admin['is_login'] !== 1) {
throwError('请先登录后再访问', config('status.not_logged'));
}
}
/**
* 强制验证当前访问的控制器方法method
* @throws BaseException
*/
private function checkMethodRules(): void
{
if (!isset($this->methodRules[$this->action])) {
return;
}
$methodRule = $this->methodRules[$this->action];
$currentMethod = $this->request->method();
if (empty($methodRule)) {
return;
}
if (is_array($methodRule) && in_array($currentMethod, $methodRule)) {
return;
}
if (is_string($methodRule) && $methodRule == $currentMethod) {
return;
}
throwError('illegal request method');
}
}

60
app/admin/controller/Passport.php

@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller;
use app\admin\model\admin\User as UserModel;
/**
* 超管后台认证
* Class Passport
* @package app\store\controller
*/
class Passport extends Controller
{
/**
* 强制验证当前访问的控制器方法method
* @var array
*/
protected $methodRules = [
'login' => 'POST',
];
/**
* 超管后台登录
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \Exception
*/
public function login()
{
// 超管后台用户登录
$model = new UserModel;
if (($userInfo = $model->login($this->postData())) === false) {
return $this->renderError($model->getError() ?: '登录失败');
}
return $this->renderSuccess([
'userId' => $userInfo['admin_user_id'],
'token' => $model->getToken()
], '登录成功');
}
/**
* 退出登录
*/
public function logout()
{
return $this->renderSuccess('操作成功');
}
}

97
app/admin/controller/Store.php

@ -0,0 +1,97 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller;
use app\admin\model\Store as StoreModel;
/**
* 小程序商城管理
* Class Store
* @package app\admin\controller
*/
class Store extends Controller
{
/**
* 强制验证当前访问的控制器方法method
* @var array
*/
protected $methodRules = [
'index' => 'GET',
'recycle' => 'GET',
'add' => 'POST',
'move' => 'POST',
'delete' => 'POST',
];
/**
* 小程序商城列表
* @return array
* @throws \think\db\exception\DbException
*/
public function index()
{
// 商城列表
$model = new StoreModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
/**
* 回收站列表
* @return array
* @throws \think\db\exception\DbException
*/
public function recycle()
{
// 商城列表
$model = new StoreModel;
$list = $model->getList(true);
return $this->renderSuccess(compact('list'));
}
/**
* 回收小程序
* @param int $storeId
* @return array
*/
public function recovery(int $storeId)
{
// 小程序详情
$model = StoreModel::detail($storeId);
if (!$model->recycle()) {
return $this->renderError($model->getError() ?: '操作失败');
}
return $this->renderSuccess('操作成功');
}
/**
* 移出回收站
* @param int $storeId
* @return array
*/
public function move(int $storeId)
{
// 小程序详情
$model = StoreModel::detail($storeId);
if (!$model->recycle(false)) {
return $this->renderError($model->getError() ?: '操作失败');
}
return $this->renderSuccess('操作成功');
}
public function add()
{
return $this->renderError('很抱歉,免费版暂不支持多开商城');
}
}

60
app/admin/controller/admin/User.php

@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller\admin;
use app\admin\controller\Controller;
use app\admin\model\admin\User as AdminUserModel;
/**
* 超管后台管理员控制器
* Class User
* @package app\store\controller
*/
class User extends Controller
{
/**
* 强制验证当前访问的控制器方法method
* 例: [ 'login' => 'POST' ]
* @var array
*/
protected $methodRules = [
'detail' => 'GET',
'renew' => 'POST',
];
/**
* 获取当前用户信息
* @return array
*/
public function detail()
{
$userInfo = AdminUserModel::detail($this->admin['user']['admin_user_id']);
return $this->renderSuccess(['userInfo' => $userInfo]);
}
/**
* 更新当前管理员信息
* @return array|string
* @throws \Exception
*/
public function renew()
{
// 获取当前用户信息
$model = AdminUserModel::detail($this->admin['user']['admin_user_id']);
// 更新用户信息
if ($model->renew($this->postForm())) {
return $this->renderSuccess('更新成功');
}
return $this->renderError($model->getError() ?: '更新失败');
}
}

40
app/admin/controller/setting/Cache.php

@ -0,0 +1,40 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller\setting;
use app\admin\controller\Controller;
use app\admin\service\Cache as CacheService;
/**
* 清理缓存
* Class Index
* @package app\admin\controller
*/
class Cache extends Controller
{
/**
* 清理缓存
* @return array|string
* @throws \Exception
*/
public function clear()
{
// 清理缓存
$CacheService = new CacheService;
if (!$CacheService->rmCache($this->postForm())) {
return $this->renderError($CacheService->getError() ?: '操作失败');
}
return $this->renderSuccess('操作成功');
}
}

264
app/admin/controller/setting/Science.php

@ -0,0 +1,264 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller\setting;
use think\response\Json;
use app\admin\controller\Controller;
use app\common\library\helper;
/**
* 环境检测
* Class Science
* @package app\admin\controller\setting
*/
class Science extends Controller
{
/**
* 环境检测
* @return Json
*/
public function info(): Json
{
return $this->renderSuccess([
'scienceInfo' => [
'server' => $this->server(), // 服务器信息
'phpinfo' => $this->phpinfo(), // PHP环境要求
'writeable' => $this->writeable(), // 目录权限监测
]
]);
}
/**
* 服务器信息
* @return array
*/
private function server(): array
{
return [
[
'name' => '服务器操作系统',
'key' => 'system',
'value' => PHP_OS,
'status' => PHP_SHLIB_SUFFIX === 'dll' ? 'warning' : 'normal',
'remark' => '建议使用 Linux 系统以提升程序性能'
],
[
'name' => 'Web服务器环境',
'key' => 'webserver',
'value' => $this->request->server('SERVER_SOFTWARE'),
'status' => PHP_SAPI === 'isapi' ? 'warning' : 'normal',
'remark' => '建议使用 Apache 或 Nginx 以提升程序性能'
],
[
'name' => 'PHP版本',
'key' => 'php',
'value' => PHP_VERSION,
'status' => version_compare(PHP_VERSION, '7.4.0') === -1 ? 'danger' : 'normal',
'remark' => 'PHP版本必须为 7.4.0 及以上'
],
[
'name' => 'PHP运行位数',
'key' => 'system',
'value' => (PHP_INT_SIZE === 4 ? '32' : '64') . '位',
'status' => PHP_INT_SIZE === 4 ? 'warning' : 'normal',
'remark' => '建议使用 64位 PHP以提升程序性能'
],
// [
// 'name' => '文件上传功能',
// 'key' => 'file_uploads',
// 'value' => !ini_get('file_uploads') ? '关闭' : '开启',
// 'status' => !ini_get('file_uploads') ? 'danger' : 'normal',
// 'remark' => '文件上传必须开启 file_uploads'
// ],
[
'name' => '文件上传最大值',
'key' => 'upload_max_filesize',
'value' => ini_get('upload_max_filesize'),
'status' => $this->compareBytes(ini_get('upload_max_filesize'), '30m') ? 'danger' : 'normal',
'remark' => '不能小于30MB;请修改php.ini中upload_max_filesize'
],
[
'name' => 'POST数据最大值',
'key' => 'post_max_size',
'value' => ini_get('post_max_size'),
'status' => $this->compareBytes(ini_get('post_max_size'), '30m') ? 'danger' : 'normal',
'remark' => '不能小于30MB;请修改php.ini中post_max_size'
],
[
'name' => '程序运行目录',
'key' => 'root_path',
'value' => str_replace('\\', '/', root_path()),
'status' => 'normal',
'remark' => ''
],
];
}
/**
* PHP环境要求
* @return string[][]
*/
private function phpinfo(): array
{
return [
[
'name' => 'PHP版本',
'key' => 'php_version',
'value' => '7.4.0及以上',
'status' => version_compare(PHP_VERSION, '7.4.0') === -1 ? 'danger' : 'normal',
'remark' => 'PHP版本必须为 7.4.0及以上'
],
[
'name' => 'Mysqlnd',
'key' => 'mysqlnd',
'value' => '支持',
'status' => extension_loaded('mysqlnd') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持mysqlnd, 系统无法正常运行'
],
// [
// 'name' => 'Redis',
// 'key' => 'redis',
// 'value' => '支持',
// 'status' => extension_loaded('redis') ? 'normal' : 'warning',
// 'remark' => '您的PHP环境不支持redis, 系统无法使用队列服务'
// ],
[
'name' => 'ZIP',
'key' => 'zip',
'value' => '支持',
'status' => extension_loaded('zip') ? 'normal' : 'warning',
'remark' => '您的PHP环境不支持zip, 系统无法使用zip压缩文件'
],
[
'name' => 'CURL',
'key' => 'curl',
'value' => '支持',
'status' => extension_loaded('curl') && function_exists('curl_init') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持CURL, 系统无法正常运行'
],
[
'name' => 'JSON',
'key' => 'json',
'value' => '支持',
'status' => extension_loaded('json') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持JSON, 系统无法正常运行'
],
[
'name' => 'Fileinfo',
'key' => 'fileinfo',
'value' => '支持',
'status' => extension_loaded('fileinfo') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持fileinfo, 系统无法上传文件'
],
[
'name' => 'OpenSSL',
'key' => 'openssl',
'value' => '支持',
'status' => extension_loaded('openssl') ? 'normal' : 'danger',
'remark' => '没有启用OpenSSL, 将无法访问微信平台的接口'
],
[
'name' => 'PDO',
'key' => 'pdo',
'value' => '支持',
'status' => extension_loaded('PDO') && extension_loaded('pdo_mysql') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持PDO, 系统无法正常运行'
],
[
'name' => 'GD',
'key' => 'gd',
'value' => '支持',
'status' => extension_loaded('gd') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持GD, 系统无法正常生成图片'
],
[
'name' => 'BCMath',
'key' => 'bcmath',
'value' => '支持',
'status' => extension_loaded('bcmath') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持BCMath, 系统无法正常运行'
],
[
'name' => 'Mbstring',
'key' => 'mbstring',
'value' => '支持',
'status' => extension_loaded('mbstring') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持mbstring, 系统无法正常运行'
],
[
'name' => 'SimpleXML',
'key' => 'simplexML',
'value' => '支持',
'status' => extension_loaded('SimpleXML') ? 'normal' : 'danger',
'remark' => '您的PHP环境不支持SimpleXML, 系统无法解析xml 无法使用微信支付'
],
];
}
/**
* 目录权限监测
* @return array[]
*/
private function writeable(): array
{
$paths = [
'data' => realpath(data_path()) . '/',
'uploads' => realpath(web_path()) . '/uploads/',
'downloads' => realpath(web_path()) . '/downloads/',
'temp' => realpath(web_path()) . '/temp/',
];
return [
[
'name' => '系统数据目录',
'key' => 'data',
'value' => str_replace('\\', '/', $paths['data']),
'status' => helper::checkWriteable($paths['data']) ? 'normal' : 'danger',
'remark' => '目录不可写,系统将无法正常写入文件'
],
[
'name' => '文件上传目录',
'key' => 'uploads',
'value' => str_replace('\\', '/', $paths['uploads']),
'status' => helper::checkWriteable($paths['uploads']) ? 'normal' : 'danger',
'remark' => '目录不可写,系统将无法正常上传文件'
],
[
'name' => '文件下载目录',
'key' => 'downloads',
'value' => str_replace('\\', '/', $paths['downloads']),
'status' => helper::checkWriteable($paths['downloads']) ? 'normal' : 'danger',
'remark' => '目录不可写,系统将无法正常上传文件'
],
[
'name' => '临时文件目录',
'key' => 'temp',
'value' => str_replace('\\', '/', $paths['temp']),
'status' => helper::checkWriteable($paths['temp']) ? 'normal' : 'danger',
'remark' => '目录不可写,系统将无法正常写入文件'
],
];
}
/**
* 比较数据大小
* @param string $size1
* @param string $size2
* @return bool
*/
private function compareBytes(string $size1, string $size2): bool
{
$size1 = helper::convertToBytes($size1);
$size2 = helper::convertToBytes($size2);
return $size1 < $size2;
}
}

90
app/admin/controller/store/Api.php

@ -0,0 +1,90 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller\store;
use app\admin\controller\Controller;
use app\admin\model\store\Api as ApiModel;
/**
* 商家后台API权限控制器
* Class Api
* @package app\store\controller
*/
class Api extends Controller
{
/**
* 权限列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$model = new ApiModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
/**
* 添加权限
* @return array
*/
public function add()
{
// 新增记录
$model = new ApiModel;
if ($model->add($this->postForm())) {
return $this->renderSuccess('添加成功');
}
return $this->renderError($model->getError() ?: '添加失败');
}
/**
* 更新权限
* @param $apiId
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit(int $apiId)
{
// 权限详情
$model = ApiModel::detail($apiId);
// 更新记录
if ($model->edit($this->postForm())) {
return $this->renderSuccess('更新成功');
}
return $this->renderError($model->getError() ?: '更新失败');
}
/**
* 删除权限
* @param $apiId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function delete(int $apiId)
{
// 权限详情
$model = ApiModel::detail($apiId);
if (!$model->remove()) {
return $this->renderError($model->getError() ?: '删除失败');
}
return $this->renderSuccess('删除成功');
}
}

124
app/admin/controller/store/Menu.php

@ -0,0 +1,124 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\controller\store;
use app\admin\controller\Controller;
use app\admin\model\store\Menu as MenuModel;
/**
* 商家后台菜单控制器
* Class Menu
* @package app\store\controller
*/
class Menu extends Controller
{
/**
* 菜单列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index()
{
$model = new MenuModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
/**
* 菜单详情
* @param int $menuId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function info(int $menuId)
{
// 菜单详情
$model = MenuModel::detail($menuId);
return $this->renderSuccess(['info' => $model]);
}
/**
* 添加菜单
* @return array
*/
public function add()
{
// 新增记录
$model = new MenuModel;
if ($model->add($this->postForm())) {
return $this->renderSuccess('添加成功');
}
return $this->renderError($model->getError() ?: '添加失败');
}
/**
* 更新菜单
* @param $menuId
* @return array|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit(int $menuId)
{
// 菜单详情
$model = MenuModel::detail($menuId);
// 更新记录
if ($model->edit($this->postForm())) {
return $this->renderSuccess('更新成功');
}
return $this->renderError($model->getError() ?: '更新失败');
}
/**
* 设置菜单绑定的Api
* @param int $menuId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function setApis(int $menuId)
{
// 菜单详情
$model = MenuModel::detail($menuId);
// 更新记录
if ($model->setApis($this->postForm())) {
return $this->renderSuccess('操作成功');
}
return $this->renderError($model->getError() ?: '操作失败');
}
/**
* 删除菜单
* @param $menuId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function delete(int $menuId)
{
// 菜单详情
$model = MenuModel::detail($menuId);
if (!$model->remove()) {
return $this->renderError($model->getError() ?: '删除失败');
}
return $this->renderSuccess('删除成功');
}
}

48
app/admin/model/Store.php

@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model;
use app\common\model\Store as StoreModel;
/**
* 商家记录表模型
* Class Store
* @package app\admin\model
*/
class Store extends StoreModel
{
/**
* 获取列表数据
* @param bool $isRecycle
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList(bool $isRecycle = false): \think\Paginator
{
return $this->where('is_recycle', '=', (int)$isRecycle)
->where('is_delete', '=', 0)
->order(['create_time' => 'desc'])
->paginate(15);
}
/**
* 移入移出回收站
* @param bool $isRecycle
* @return false|int
*/
public function recycle($isRecycle = true)
{
return $this->save(['is_recycle' => (int)$isRecycle]);
}
}

25
app/admin/model/UploadFile.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model;
use app\common\model\UploadFile as UploadFileModel;
/**
* 文件库模型
* Class UploadFile
* @package app\admin\model
*/
class UploadFile extends UploadFileModel
{
}

110
app/admin/model/admin/User.php

@ -0,0 +1,110 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model\admin;
use app\common\model\admin\User as UserModel;
use app\admin\service\admin\User as AdminUserService;
/**
* 超管后台用户模型
* Class User
* @package app\admin\model\admin
*/
class User extends UserModel
{
/**
* 隐藏的字段
* @var array
*/
protected $hidden = [
'password',
];
// 用户登录token
private $token;
/**
* 超管后台用户登录
* @param array $data
* @return array|bool|null|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function login(array $data)
{
// 验证用户名密码是否正确
if (!$user = $this->getUserInfoByLogin($data)) {
$this->error = '登录失败, 用户名或密码错误';
return false;
}
// 记录登录状态, 并记录token
$this->token = AdminUserService::login($user->toArray());
return $user;
}
/**
* 返回生成的token
* @return mixed
*/
public function getToken()
{
return $this->token;
}
/**
* 获取登录的用户信息
* @param $data
* @return array|false|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getUserInfoByLogin(array $data)
{
// 用户信息
$useInfo = static::withoutGlobalScope()
->where(['user_name' => $data['username']])
->find();
if (empty($useInfo)) return false;
// 验证密码是否正确
if (!password_verify($data['password'], $useInfo['password'])) {
return false;
}
return $useInfo;
}
/**
* 更新当前管理员信息
* @param $data
* @return bool
*/
public function renew(array $data)
{
if ($data['password'] !== $data['password_confirm']) {
$this->error = '确认密码不正确';
return false;
}
// 更新管理员信息
if ($this->save([
'user_name' => $data['user_name'],
'password' => encryption_hash($data['password']),
]) === false) {
return false;
}
// 更新登录信息
AdminUserService::update($this->toArray());
return true;
}
}

129
app/admin/model/store/Api.php

@ -0,0 +1,129 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model\store;
use app\common\model\store\Api as ApiModel;
/**
* 商家后台API权限模型
* Class Api
* @package app\admin\model\store
*/
class Api extends ApiModel
{
/**
* 获取权限列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getList()
{
$all = static::getAll();
return $this->getTreeData($all);
}
/**
* 新增记录
* @param $data
* @return false|int
*/
public function add(array $data)
{
return $this->allowField(['name', 'parent_id', 'url', 'sort'])->save($data);
}
/**
* 更新记录
* @param $data
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit($data)
{
// 判断上级角色是否为当前子级
if ($data['parent_id'] > 0) {
// 获取所有上级id集
$parentIds = $this->getTopApiIds($data['parent_id']);
if (in_array($this['api_id'], $parentIds)) {
$this->error = '上级权限不允许设置为当前子权限';
return false;
}
}
return $this->allowField(['name', 'parent_id', 'url', 'sort'])->save($data) !== false;
}
/**
* 删除权限
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \Exception
*/
public function remove()
{
// 判断是否存在下级权限
if (self::detail(['parent_id' => $this['api_id']])) {
$this->error = '当前权限下存在子权限,请先删除';
return false;
}
return $this->delete();
}
/**
* 获取所有上级id集
* @param int $apiId
* @param null $all
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getTopApiIds(int $apiId, $all = null)
{
static $ids = [];
is_null($all) && $all = $this->getAll();
foreach ($all as $item) {
if ($item['api_id'] == $apiId && $item['parent_id'] > 0) {
$ids[] = $item['parent_id'];
$this->getTopApiIds($item['parent_id'], $all);
}
}
return $ids;
}
/**
* 获取树状列表
* @param array $list
* @param int $parentId
* @return array
*/
private function getTreeData(array &$list, int $parentId = 0)
{
$data = [];
foreach ($list as $key => $item) {
if ($item['parent_id'] == $parentId) {
$children = $this->getTreeData($list, (int)$item['api_id']);
!empty($children) && $item['children'] = $children;
$data[] = $item;
unset($list[$key]);
}
}
return $data;
}
}

116
app/admin/model/store/Menu.php

@ -0,0 +1,116 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model\store;
use app\common\model\store\Menu as MenuModel;
use app\admin\model\store\MenuApi as MenuApiModel;
/**
* 商家后台菜单模型
* Class Menu
* @package app\admin\model\store
*/
class Menu extends MenuModel
{
/**
* 新增记录
* @param $data
* @return false|int
*/
public function add(array $data)
{
return $this->save($data);
}
/**
* 更新记录
* @param array $data
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function edit(array $data)
{
// 判断上级角色是否为当前子级
if (isset($data['parent_id']) && $data['parent_id'] > 0) {
// 获取所有上级id集
$parentIds = $this->getTopMenuIds($data['parent_id']);
if (in_array($this['menu_id'], $parentIds)) {
$this->error = '上级菜单不允许设置为当前子菜单';
return false;
}
}
// 如果模块是操作, 不允许修改上级菜单id
if ($this['module'] == 20 && isset($data['parent_id'])) {
unset($data['parent_id']);
}
return $this->save($data) !== false;
}
/**
* 设置菜单的API权限
* @param array $data
* @return bool|int
*/
public function setApis(array $data)
{
if (!isset($data['apiIds']) || empty($data['apiIds'])) {
$this->error = 'API权限不能为空';
return false;
}
// 根据菜单id批量更新API关联记录
return (new MenuApiModel)->updateByMenuId($this['menu_id'], $data['apiIds']);
}
/**
* 删除菜单
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \Exception
*/
public function remove()
{
// 判断是否存在下级菜单
if (self::detail(['parent_id' => $this['menu_id']])) {
$this->error = '当前菜单下存在子菜单或操作,请先删除';
return false;
}
return $this->delete();
}
/**
* 获取所有上级id集
* @param int $menuId
* @param null $menuList
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getTopMenuIds(int $menuId, $menuList = null)
{
static $ids = [];
is_null($menuList) && $menuList = $this->getAll();
foreach ($menuList as $item) {
if ($item['menu_id'] == $menuId && $item['parent_id'] > 0) {
$ids[] = $item['parent_id'];
$this->getTopMenuIds($item['parent_id'], $menuList);
}
}
return $ids;
}
}

63
app/admin/model/store/MenuApi.php

@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model\store;
use app\common\model\store\MenuApi as MenuApiModel;
/**
* 商家后台用户角色与菜单权限关系表模型
* Class MenuApi
* @package app\admin\model\store
*/
class MenuApi extends MenuApiModel
{
/**
* 根据菜单id批量更新记录
* @param int $menuId
* @param array $apiIds
* @return int
*/
public function updateByMenuId(int $menuId, array $apiIds)
{
return $this->transaction(function () use ($menuId, $apiIds) {
$this->removeByMenuId($menuId);
return $this->insertByMenuId($menuId, $apiIds);
});
}
/**
* 根据菜单id批量删除记录
* @param int $menuId
* @return void
*/
private function removeByMenuId(int $menuId): void
{
static::deleteAll(['menu_id' => $menuId]);
}
/**
* 根据菜单id批量新增记录
* @param int $menuId
* @param array $apiIds
* @return bool
*/
private function insertByMenuId(int $menuId, array $apiIds)
{
$data = [];
foreach ($apiIds as $api) {
$data[] = ['menu_id' => $menuId, 'api_id' => $api];
}
return (bool)$this->addAll($data);
}
}

60
app/admin/model/store/User.php

@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\model\store;
use cores\exception\BaseException;
use app\common\model\store\User as StoreUserModel;
/**
* 商家用户模型
* Class StoreUser
* @package app\admin\model
*/
class User extends StoreUserModel
{
/**
* 商家用户登录
* @param int $storeId
* @throws BaseException
* @throws \think\Exception
*/
public function login(int $storeId)
{
// 获取该商户管理员用户信息
$userInfo = $this->getSuperStoreUser($storeId);
if (empty($userInfo)) {
throwError('超级管理员用户信息不存在');
}
}
/**
* 获取该商户管理员用户信息
* @param int $storeId
* @return static|null
*/
private function getSuperStoreUser(int $storeId)
{
return static::detail(['store_id' => $storeId, 'is_super' => 1], ['wxapp']);
}
/**
* 删除小程序下的商家用户
* @param $storeId
* @return false|int
*/
public static function setDelete(int $storeId)
{
static::update(['is_delete' => '1'], ['store_id' => $storeId]);
return true;
}
}

94
app/admin/service/Cache.php

@ -0,0 +1,94 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\service;
use app\common\service\BaseService;
use think\facade\Cache as CacheDriver;
/**
* 清理缓存
* Class Cache
*/
class Cache extends BaseService
{
// 缓存驱动句柄
/** @var $CacheDriver \think\Cache */
private $cache;
/**
* 构造方法
* Cache constructor.
*/
public function initialize()
{
// 实例化缓存驱动
$this->cache = CacheDriver::instance();
}
/**
* 删除缓存
* @param $data
* @return bool
*/
public function rmCache($data)
{
// 数据缓存
if (in_array('data', $data['item'])) {
// 强制模式
$isForce = isset($data['isForce']) && $data['isForce'];
// 清除缓存
$isForce ? $this->cache->clear() : $this->cache->tag('cache')->clear();
}
// 临时文件
if (in_array('temp', $data['item'])) {
$paths = [
'temp' => web_path() . 'temp/',
'runtime-image' => runtime_root_path() . 'image/',
'runtime-local' => runtime_root_path() . 'local/',
];
foreach ($paths as $path) {
$this->deleteFolder($path);
}
}
return true;
}
/**
* 递归删除指定目录下所有文件
* @param $path
* @return bool
*/
private function deleteFolder($path)
{
if (!is_dir($path))
return false;
// 扫描一个文件夹内的所有文件夹和文件
foreach (scandir($path) as $val) {
// 排除目录中的.和..
if (!in_array($val, ['.', '..', '.gitignore'])) {
// 如果是目录则递归子目录,继续操作
if (is_dir($path . $val)) {
// 子目录中操作删除文件夹和文件
$this->deleteFolder($path . $val . '/');
// 目录清空后删除空文件夹
rmdir($path . $val . '/');
} else {
// 如果是文件直接删除
unlink($path . $val);
}
}
}
return true;
}
}

120
app/admin/service/admin/User.php

@ -0,0 +1,120 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\service\admin;
use think\facade\Cache;
use app\common\service\BaseService;
/**
* 超管用户服务类
* Class User
*/
class User extends BaseService
{
// 用于生成token的自定义盐
const TOKEN_SALT = '_admin_user_salt_';
/**
* 获取登录的信息
* @return mixed
*/
public static function getLoginInfo()
{
if (($token = self::getToken()) !== false) {
return Cache::get($token);
}
return false;
}
/**
* 记录登录信息
* @param array $userInfo
* @return string
*/
public static function login(array $userInfo)
{
// 生成token
$token = self::makeToken((int)$userInfo['admin_user_id']);
// 记录缓存, 7天
Cache::set($token, [
'user' => [
'admin_user_id' => (int)$userInfo['admin_user_id'],
'user_name' => $userInfo['user_name'],
],
'is_login' => true,
], 86400 * 7);
return $token;
}
/**
* 清空登录状态
* @return bool
*/
public static function logout()
{
Cache::delete(self::getToken());
return true;
}
/**
* 更新登录信息
* @param array $userInfo
* @return mixed
*/
public static function update(array $userInfo)
{
return Cache::set(self::getToken(), [
'user' => [
'admin_user_id' => $userInfo['admin_user_id'],
'user_name' => $userInfo['user_name'],
],
'is_login' => true,
], 86400 * 7);
}
/**
* 生成用户认证的token
* @param int $userId
* @return string
*/
private static function makeToken(int $userId)
{
// 生成一个不会重复的随机字符串
$guid = get_guid_v4();
// 当前时间戳 (精确到毫秒)
$timeStamp = microtime(true);
// 自定义一个盐
$salt = self::TOKEN_SALT;
return md5("{$timeStamp}_{$userId}_{$guid}_{$salt}");
}
/**
* 获取用户认证Token
* @return bool|string
*/
private static function getToken()
{
// 获取请求中的token
$token = request()->header('Access-Token');
// 调试模式下可通过param
if (empty($token) && is_debug()) {
$token = request()->param('Access-Token');
}
// 不存在token报错
if (empty($token)) {
return false;
}
return $token;
}
}

25
app/admin/service/store/User.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\admin\service\store;
use app\common\service\store\User as Basics;
use app\admin\model\store\User as StoreUserModel;
/**
* 超管用户服务类
* Class User
*/
class User extends Basics
{
}

29
app/api/common.php

@ -0,0 +1,29 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
// 应用公共函数库文件
/**
* 获取当前访问的渠道(微信小程序、H5、APP等)
* @return string|null
*/
function getPlatform()
{
static $value = null;
// 从header中获取 channel
empty($value) && $value = request()->header('platform');
// 调试模式下可通过param中获取
if (is_debug() && empty($value)) {
$value = request()->param('platform');
}
return $value;
}

31
app/api/config/captcha.php

@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
return [
// 验证码图片宽度
'imageW' => 0,
// 验证码图片高度
'imageH' => 0,
// 验证码位数
'length' => 4,
// 是否画混淆曲线
'useCurve' => false,
// 是否添加杂点
'useNoise' => true,
// 验证码字体大小(px)
'fontSize' => 26,
// 验证码字符集合
// 复杂版:2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY
'codeSet' => '23456ACEFHJKLMNPRTUVWXY',
// 验证码可重复验证的次数
'checkTimes' => 5,
];

124
app/api/controller/Address.php

@ -0,0 +1,124 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\service\User as UserService;
use app\api\model\UserAddress as UserAddressModel;
use cores\exception\BaseException;
/**
* 收货地址管理
* Class Address
* @package app\api\controller
*/
class Address extends Controller
{
/**
* 收货地址列表
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list(): Json
{
// 获取收货地址列表
$model = new UserAddressModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
/**
* 获取当前用户默认收货地址
* @return Json
* @throws BaseException
*/
public function defaultId(): Json
{
$useInfo = UserService::getCurrentLoginUser(true);
return $this->renderSuccess(['defaultId' => $useInfo['address_id']]);
}
/**
* 收货地址详情
* @param int $addressId 地址ID
* @return Json
* @throws BaseException
*/
public function detail(int $addressId): Json
{
$detail = UserAddressModel::detail($addressId);
return $this->renderSuccess(compact('detail'));
}
/**
* 添加收货地址
* @return Json
* @throws BaseException
*/
public function add(): Json
{
$model = new UserAddressModel;
if ($model->add($this->postForm())) {
return $this->renderSuccess([], '添加成功');
}
return $this->renderError($model->getError() ?: '添加失败');
}
/**
* 编辑收货地址
* @param int $addressId 地址ID
* @return Json
* @throws BaseException
*/
public function edit(int $addressId): Json
{
$model = UserAddressModel::detail($addressId);
if ($model->edit($this->postForm())) {
return $this->renderSuccess([], '更新成功');
}
return $this->renderError($model->getError() ?: '更新失败');
}
/**
* 设为默认地址
* @param int $addressId 地址ID
* @return Json
* @throws BaseException
*/
public function setDefault(int $addressId): Json
{
$model = UserAddressModel::detail($addressId);
if ($model->setDefault((int)$model['address_id'])) {
return $this->renderSuccess([], '设置成功');
}
return $this->renderError($model->getError() ?: '设置失败');
}
/**
* 删除收货地址
* @param int $addressId 地址ID
* @return Json
* @throws BaseException
*/
public function remove(int $addressId): Json
{
$model = UserAddressModel::detail($addressId);
if ($model->remove()) {
return $this->renderSuccess([], '删除成功');
}
return $this->renderError($model->getError() ?: '删除失败');
}
}

48
app/api/controller/Article.php

@ -0,0 +1,48 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Article as ArticleModel;
/**
* 文章控制器
* Class Article
* @package app\api\controller
*/
class Article extends Controller
{
/**
* 文章列表
* @param int $categoryId
* @return \think\response\Json
* @throws \think\db\exception\DbException
*/
public function list(int $categoryId = 0)
{
$model = new ArticleModel;
$list = $model->getList($categoryId);
return $this->renderSuccess(compact('list'));
}
/**
* 文章详情
* @param int $articleId
* @return \think\response\Json
* @throws \cores\exception\BaseException
*/
public function detail(int $articleId)
{
$detail = ArticleModel::getDetail($articleId);
return $this->renderSuccess(compact('detail'));
}
}

49
app/api/controller/Captcha.php

@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\service\passport\{Captcha as CaptchaService, SmsCaptcha as SmsCaptchaService};
use cores\exception\BaseException;
/**
* 验证码管理
* Class Cart
* @package app\api\controller
*/
class Captcha extends Controller
{
/**
* 图形验证码
* @return Json
*/
public function image(): Json
{
$CaptchaService = new CaptchaService;
return $this->renderSuccess($CaptchaService->create());
}
/**
* 发送短信验证码
* @return Json
* @throws BaseException
*/
public function sendSmsCaptcha(): Json
{
$SmsCaptchaService = new SmsCaptchaService;
if ($SmsCaptchaService->handle($this->postForm())) {
return $this->renderSuccess('发送成功,请注意查收');
}
return $this->renderError($SmsCaptchaService->getError() ?: '短信发送失败');
}
}

118
app/api/controller/Cart.php

@ -0,0 +1,118 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\model\Cart as CartModel;
use app\api\service\Cart as CartService;
use cores\exception\BaseException;
/**
* 购物车管理
* Class Cart
* @package app\api\controller
*/
class Cart extends Controller
{
/**
* 购物车商品列表
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \cores\exception\BaseException
*/
public function list(): Json
{
// 购物车商品列表
$service = new CartService;
$list = $service->getList();
// 购物车商品总数量
$cartTotal = (new CartModel)->getCartTotal();
return $this->renderSuccess(compact('cartTotal', 'list'));
}
/**
* 购物车商品总数量
* @return Json
* @throws BaseException
*/
public function total(): Json
{
$model = new CartModel;
$cartTotal = $model->getCartTotal();
return $this->renderSuccess(compact('cartTotal'));
}
/**
* 加入购物车
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku索引
* @param int $goodsNum 商品数量
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add(int $goodsId, string $goodsSkuId, int $goodsNum): Json
{
$model = new CartModel;
if (!$model->add($goodsId, $goodsSkuId, $goodsNum)) {
return $this->renderError($model->getError() ?: '加入购物车失败');
}
// 购物车商品总数量
$cartTotal = $model->getCartTotal();
return $this->renderSuccess(compact('cartTotal'), '加入购物车成功');
}
/**
* 更新购物车商品数量
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku索引
* @param int $goodsNum 商品数量
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function update(int $goodsId, string $goodsSkuId, int $goodsNum): Json
{
$model = new CartModel;
if (!$model->sUpdate($goodsId, $goodsSkuId, $goodsNum)) {
return $this->renderError($model->getError() ?: '更新失败');
}
// 购物车商品总数量
$cartTotal = $model->getCartTotal();
return $this->renderSuccess(compact('cartTotal'), '更新成功');
}
/**
* 删除购物车中指定记录
* @param array $cartIds 购物车ID集, 如果为空删除所有
* @return Json
* @throws BaseException
*/
public function clear(array $cartIds = []): Json
{
$model = new CartModel;
if (!$model->clear($cartIds)) {
return $this->renderError($model->getError() ?: '操作失败');
}
// 购物车商品总数量
$cartTotal = $model->getCartTotal();
return $this->renderSuccess(compact('cartTotal'), '操作成功');
}
}

37
app/api/controller/Category.php

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Category as CategoryModel;
/**
* 商品分类控制器
* Class Category
* @package app\api\controller
*/
class Category extends Controller
{
/**
* 分类列表
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list()
{
$model = new CategoryModel;
$list = $model->getListPublic($this->request->param());
return $this->renderSuccess(compact('list'));
}
}

202
app/api/controller/Checkout.php

@ -0,0 +1,202 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Order as OrderModel;
use app\api\service\User as UserService;
use app\api\service\Cart as CartService;
use app\api\service\order\Checkout as CheckoutService;
use app\api\validate\order\Checkout as CheckoutValidate;
use cores\exception\BaseException;
use think\response\Json;
/**
* 订单结算控制器
* Class Checkout
* @package app\api\controller
*/
class Checkout extends Controller
{
// 结算台验证器
private ?CheckoutValidate $validate = null;
/**
* 结算台订单信息
* @param string $mode
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function order(string $mode = 'buyNow'): Json
{
if ($mode === 'buyNow') {
return $this->buyNow();
} elseif ($mode === 'cart') {
return $this->cart();
}
return $this->renderError('结算模式不合法');
}
/**
* 订单提交
* @param string $mode
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function submit(string $mode = 'buyNow'): Json
{
return $this->order($mode);
}
/**
* 订单确认-立即购买
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function buyNow(): Json
{
// 实例化结算台服务
$Checkout = new CheckoutService;
// 订单结算api参数
$params = $Checkout->setParam($this->getParam([
'goodsId' => 0,
'goodsSkuId' => '',
'goodsNum' => 0,
]));
// 表单验证
if (!$this->getValidate()->scene('buyNow')->check($params)) {
return $this->renderError($this->getValidate()->getError(), ['isCreated' => false]);
}
// 立即购买:获取订单商品列表
$model = new OrderModel;
$goodsList = $model->getOrderGoodsListByNow(
(int)$params['goodsId'],
(string)$params['goodsSkuId'],
(int)$params['goodsNum']
);
// 获取订单确认信息
$orderInfo = $Checkout->onCheckout($goodsList);
if ($this->request->isGet()) {
return $this->renderSuccess([
'order' => $orderInfo,
'personal' => $Checkout->getPersonal(),
'setting' => $Checkout->getSetting(),
]);
}
// 验证订单是否存在错误
if ($Checkout->hasError()) {
return $this->renderError($Checkout->getError(), ['is_created' => false]);
}
// 创建订单
if (!$Checkout->createOrder($orderInfo)) {
return $this->renderError($Checkout->getError() ?: '订单创建失败', ['is_created' => false]);
}
// 构建微信支付请求
$payment = $model->onOrderPayment($Checkout->model, $params['payType']);
// 返回结算信息
return $this->renderSuccess([
'orderId' => $Checkout->model['order_id'], // 订单id
'payType' => $params['payType'], // 支付方式
'payment' => $payment // 微信支付参数
]);
}
/**
* 订单确认-购物车结算
* @return Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function cart(): Json
{
// 实例化结算台服务
$Checkout = new CheckoutService;
// 订单结算api参数
$params = $Checkout->setParam($this->getParam());
// 购物车ID集
$cartIds = $this->getCartIds();
// 商品结算信息
$CartModel = new CartService;
// 购物车商品列表
$goodsList = $CartModel->getOrderGoodsList($cartIds);
// 获取订单结算信息
$orderInfo = $Checkout->onCheckout($goodsList);
if ($this->request->isGet()) {
return $this->renderSuccess([
'order' => $orderInfo,
'personal' => $Checkout->getPersonal(),
'setting' => $Checkout->getSetting(),
]);
}
// 验证订单是否存在错误
if ($Checkout->hasError()) {
return $this->renderError($Checkout->getError(), ['is_created' => false]);
}
// 创建订单
if (!$Checkout->createOrder($orderInfo)) {
return $this->renderError($Checkout->getError() ?: '订单创建失败');
}
// 移出购物车中已下单的商品
$CartModel->clear($cartIds);
// 构建微信支付请求
$payment = $Checkout->onOrderPayment();
// 返回状态
return $this->renderSuccess([
'orderId' => $Checkout->model['order_id'], // 订单id
'payType' => $params['payType'], // 支付方式
'payment' => $payment // 微信支付参数
]);
}
/**
* 获取结算台验证器
* @return CheckoutValidate
*/
private function getValidate(): CheckoutValidate
{
if (is_null($this->validate)) {
$this->validate = new CheckoutValidate;
}
return $this->validate;
}
/**
* 获取购物车ID集
* @return false|string[]
*/
private function getCartIds()
{
$cartIds = $this->request->param('cartIds');
return explode(',', $cartIds);
}
/**
* 订单结算提交的参数
* @param array $define
* @return array
*/
private function getParam(array $define = []): array
{
return array_merge($define, $this->request->param());
}
}

76
app/api/controller/Comment.php

@ -0,0 +1,76 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Comment as CommentModel;
/**
* 商品评价控制器
* Class Comment
* @package app\api\controller
*/
class Comment extends Controller
{
/**
* 商品评价列表
* @param int $goodsId 商品ID
* @param int|null $scoreType 评价评分
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list(int $goodsId, int $scoreType = null)
{
// 评价列表
$model = new CommentModel;
$list = $model->getCommentList($goodsId, $scoreType);
return $this->renderSuccess(compact('list'));
}
/**
* 商品评分总数
* @param int $goodsId
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function total(int $goodsId)
{
// 指定评分总数
$model = new CommentModel;
$total = $model->getTotal($goodsId);
return $this->renderSuccess(compact('total'));
}
/**
* 商品评价列表 (限制数量, 用于商品详情页展示)
* @param int $goodsId
* @param int $limit
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function listRows(int $goodsId, int $limit = 5)
{
// 评价列表
$model = new CommentModel;
$list = $model->listRows($goodsId, $limit);
// 评价总数量
$total = $model->rowsTotal($goodsId);
return $this->renderSuccess(compact('list', 'total'));
}
}

101
app/api/controller/Controller.php

@ -0,0 +1,101 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use cores\BaseController;
use app\api\model\User as UserModel;
use app\api\model\Store as StoreModel;
use app\api\service\User as UserService;
use cores\exception\BaseException;
/**
* API控制器基类
* Class Controller
* @package app\store\controller
*/
class Controller extends BaseController
{
// 当前商城ID
protected $storeId;
/**
* API基类初始化
* @throws BaseException
*/
public function initialize()
{
// 当前商城id
$this->storeId = $this->getStoreId();
// 验证当前商城状态
$this->checkStore();
// 验证当前客户端状态
$this->checkClient();
}
/**
* 获取当前商城ID
* @return int|null
* @throws BaseException
*/
protected function getStoreId(): ?int
{
$storeId = getStoreId(); // app/api/common.php
empty($storeId) && throwError('缺少必要的参数:storeId');
return $storeId;
}
/**
* 验证当前商城状态
* @return void
* @throws BaseException
*/
private function checkStore(): void
{
// 获取当前商城信息
$store = StoreModel::detail($this->storeId);
if (empty($store)) {
throwError('当前商城信息不存在');
}
if ($store['is_recycle'] || $store['is_delete']) {
throwError('当前商城已删除');
}
}
/**
* 验证当前客户端是否允许访问
* @throws BaseException
*/
private function checkClient()
{
$client = getPlatform();
$settingClass = [
'H5' => [\app\api\model\h5\Setting::class, 'checkStatus', 'H5端']
];
if (!isset($settingClass[$client])) {
return;
}
$status = call_user_func([$settingClass[$client][0], $settingClass[$client][1]]);
$status === false && throwError('很抱歉,当前' . $settingClass[$client][2] . '端暂不支持访问');
}
/**
* 获取当前用户信息
* @param bool $isForce 强制验证登录
* @return UserModel|bool|null
* @throws BaseException
*/
protected function getLoginUser(bool $isForce = true)
{
return UserService::getCurrentLoginUser($isForce);
}
}

39
app/api/controller/Coupon.php

@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\model\Coupon as CouponModel;
/**
* 优惠券中心
* Class Coupon
* @package app\api\controller
*/
class Coupon extends Controller
{
/**
* 优惠券列表
* @return Json
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list(): Json
{
$model = new CouponModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

37
app/api/controller/Express.php

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Express as ExpressModel;
/**
* 物流公司管理
* Class Express
* @package app\api\controller
*/
class Express extends Controller
{
/**
* 物流公司列表
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list()
{
$model = new ExpressModel;
$list = $model->getAll();
return $this->renderSuccess(compact('list'));
}
}

98
app/api/controller/Goods.php

@ -0,0 +1,98 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\model\{Goods as GoodsModel};
use app\api\service\{Goods as GoodsService};
/**
* 商品控制器
* Class Goods
* @package app\api\controller
*/
class Goods extends Controller
{
/**
* 商品列表
* @return \think\response\Json
* @throws \think\db\exception\DbException
*/
public function list(): \think\response\Json
{
// 获取列表数据
$model = new GoodsModel;
$list = $model->getList($this->request->param());
return $this->renderSuccess(compact('list'));
}
/**
* 获取商品详情
* @param int $goodsId
* @return \think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function detail(int $goodsId): \think\response\Json
{
// 商品详情
$model = new GoodsModel;
$goodsInfo = $model->getDetails($goodsId);
return $this->renderSuccess(['detail' => $goodsInfo]);
}
/**
* 获取商品详情(基础信息)
* @param int $goodsId
* @param bool $verifyStatus
* @return \think\response\Json
* @throws \cores\exception\BaseException
*/
public function basic(int $goodsId, bool $verifyStatus = true): \think\response\Json
{
// 获取商品详情
$model = new GoodsModel;
$detail = $model->getBasic($goodsId, $verifyStatus);
return $this->renderSuccess(compact('detail'));
}
/**
* 获取商品规格数据
* @param int $goodsId 商品ID
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function specData(int $goodsId): \think\response\Json
{
// 获取商品详情
$model = new GoodsModel;
$specData = $model->getSpecData($goodsId);
return $this->renderSuccess(compact('specData'));
}
/**
* 获取商品的指定SKU信息
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品SKU标识
* @return Json
*/
public function skuInfo(int $goodsId, string $goodsSkuId): Json
{
$skuInfo = GoodsService::getSkuInfo($goodsId, $goodsSkuId);
return $this->renderSuccess(compact('skuInfo'));
}
}

36
app/api/controller/Help.php

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Help as HelpModel;
/**
* 帮助中心
* Class help
* @package app\store\controller\wxapp
*/
class Help extends Controller
{
/**
* 获取列表记录
* @return array
* @throws \think\db\exception\DbException
*/
public function list()
{
$model = new HelpModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

16
app/api/controller/Index.php

@ -0,0 +1,16 @@
<?php
namespace app\api\controller;
/**
* 默认控制器
* Class Index
* @package app\api\controller
*/
class Index
{
public function index()
{
echo '当前访问的index.php,请将index.html设为默认站点入口';
}
}

53
app/api/controller/MyCoupon.php

@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\UserCoupon as UserCouponModel;
use app\api\service\User as UserService;
/**
* 用户优惠券
* Class Coupon
* @package app\api\controller
*/
class MyCoupon extends Controller
{
/**
* 用户优惠券列表
* @return \think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DbException
*/
public function list(): \think\response\Json
{
$userId = UserService::getCurrentLoginUserId();
$model = new UserCouponModel;
$list = $model->getList($userId, $this->request->param());
return $this->renderSuccess(compact('list'));
}
/**
* 领取优惠券
* @param int $couponId
* @return \think\response\Json
* @throws \cores\exception\BaseException
*/
public function receive(int $couponId): \think\response\Json
{
$model = new UserCouponModel;
if ($model->receive($couponId)) {
return $this->renderSuccess([], '领取成功');
}
return $this->renderError($model->getError() ?: '领取失败');
}
}

36
app/api/controller/Notify.php

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\common\library\wechat\WxPay;
/**
* 支付成功异步通知接口
* Class Notify
* @package app\api\controller
*/
class Notify
{
/**
* 支付成功异步通知(微信小程序-微信支付)
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function wxpay()
{
// 微信支付组件:验证异步通知
$WxPay = new WxPay();
$WxPay->notify();
}
}

159
app/api/controller/Order.php

@ -0,0 +1,159 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Order as OrderModel;
use app\api\model\Setting as SettingModel;
use app\store\model\Express as ExpressModel;
use app\common\enum\order\PayType as OrderPayTypeEnum;
use cores\exception\BaseException;
use think\response\Json;
/**
* 我的订单控制器
* Class Order
* @package app\api\controller
*/
class Order extends Controller
{
/**
* 获取当前用户待处理的订单数量
* @return Json
* @throws BaseException
*/
public function todoCounts(): Json
{
$model = new OrderModel;
$counts = $model->getTodoCounts();
return $this->renderSuccess(compact('counts'));
}
/**
* 我的订单列表
* @param string $dataType 订单类型 (all全部 payment待付款 received待发货 deliver待收货 comment待评价)
* @return Json
* @throws \think\db\exception\DbException
* @throws BaseException
*/
public function list(string $dataType): Json
{
$model = new OrderModel;
$list = $model->getList($dataType);
return $this->renderSuccess(compact('list'));
}
/**
* 订单详情信息
* @param int $orderId 订单ID
* @return Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws BaseException
*/
public function detail(int $orderId): Json
{
// 订单详情
$model = OrderModel::getUserOrderDetail($orderId);
return $this->renderSuccess([
'order' => $model, // 订单详情
'setting' => [
// 积分名称
'points_name' => SettingModel::getPointsName(),
],
]);
}
/**
* 获取物流信息
* @param int $orderId 订单ID
* @return Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws BaseException
*/
public function express(int $orderId): Json
{
// 订单信息
$order = OrderModel::getDetail($orderId);
if (!$order['express_no']) {
return $this->renderError('没有物流信息');
}
// 获取物流信息
$model = ExpressModel::detail($order['express_id']);
$express = $model->dynamic($model['express_name'], $model['kuaidi100_code'], $order['express_no']);
if ($express === false) {
return $this->renderError($model->getError());
}
return $this->renderSuccess(compact('express'));
}
/**
* 取消订单
* @param int $orderId
* @return Json
* @throws BaseException
*/
public function cancel(int $orderId): Json
{
$model = OrderModel::getDetail($orderId);
if ($model->cancel()) {
return $this->renderSuccess('订单取消成功');
}
return $this->renderError($model->getError() ?: '订单取消失败');
}
/**
* 确认收货
* @param int $orderId
* @return Json
* @throws BaseException
*/
public function receipt(int $orderId): Json
{
$model = OrderModel::getDetail($orderId);
if ($model->receipt()) {
return $this->renderSuccess('确认收货成功');
}
return $this->renderError($model->getError());
}
/**
* 立即支付
* @param int $orderId 订单ID
* @param int $payType 支付方式
* @return Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws BaseException
*/
public function pay(int $orderId, int $payType = OrderPayTypeEnum::WECHAT): Json
{
// 获取订单详情
$model = OrderModel::getUserOrderDetail($orderId);
// 订单支付事件
if (!$model->onPay($payType)) {
return $this->renderError($model->getError() ?: '订单支付失败');
}
// 构建微信支付请求
$payment = $model->onOrderPayment($model, $payType);
// 支付状态提醒
return $this->renderSuccess([
'order_id' => $model['order_id'], // 订单id
'pay_type' => $payType, // 支付方式
'payment' => $payment // 微信支付参数
]);
}
}

40
app/api/controller/Page.php

@ -0,0 +1,40 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Page as PageModel;
/**
* 页面控制器
* Class Index
* @package app\api\controller
*/
class Page extends Controller
{
/**
* 页面数据
* @param int|null $pageId 页面ID, 不传的话默认为首页
* @return array|\think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function detail(int $pageId = null)
{
// 页面数据
$model = new PageModel;
$pageData = $model->getPageData($pageId);
return $this->renderSuccess(compact('pageData'));
}
}

97
app/api/controller/Passport.php

@ -0,0 +1,97 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\service\passport\Login as LoginService;
/**
* 用户认证模块
* Class Passport
* @package app\api\controller
*/
class Passport extends Controller
{
/**
* 登录接口 (需提交手机号、短信验证码、第三方用户信息)
* @return array|\think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function login()
{
// 执行登录
$LoginService = new LoginService;
if (!$LoginService->login($this->postForm())) {
return $this->renderError($LoginService->getError());
}
// 用户信息
$userInfo = $LoginService->getUserInfo();
return $this->renderSuccess([
'userId' => (int)$userInfo['user_id'],
'token' => $LoginService->getToken((int)$userInfo['user_id'])
], '登录成功');
}
/**
* 微信小程序快捷登录 (需提交wx.login接口返回的code、微信用户公开信息)
* 业务流程:判断openid是否存在 -> 存在: 更新用户登录信息 -> 返回userId和token
* -> 不存在: 返回false, 跳转到注册页面
* @return array|\think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function loginMpWx()
{
// 微信小程序一键登录
$LoginService = new LoginService;
if (!$LoginService->loginMpWx($this->postForm())) {
return $this->renderError($LoginService->getError());
}
// 获取登录成功后的用户信息
$userInfo = $LoginService->getUserInfo();
return $this->renderSuccess([
'userId' => (int)$userInfo['user_id'],
'token' => $LoginService->getToken((int)$userInfo['user_id'])
], '登录成功');
}
/**
* 快捷登录: 微信小程序授权手机号登录
* @return array|\think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function loginMpWxMobile()
{
// 微信小程序一键登录
$LoginService = new LoginService;
if (!$LoginService->loginMpWxMobile($this->postForm())) {
return $this->renderError($LoginService->getError());
}
// 获取登录成功后的用户信息
$userInfo = $LoginService->getUserInfo();
return $this->renderSuccess([
'userId' => (int)$userInfo['user_id'],
'token' => $LoginService->getToken((int)$userInfo['user_id'])
], '登录成功');
}
}

58
app/api/controller/Recharge.php

@ -0,0 +1,58 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\recharge\Order as OrderModel;
use app\api\service\Payment as PaymentService;
use app\common\enum\OrderType as OrderTypeEnum;
use cores\exception\BaseException;
/**
* 用户充值管理
* Class Recharge
* @package app\api\controller
*/
class Recharge extends Controller
{
/**
* 确认充值
* @param int|null $planId 方案ID
* @param float|string|null $customMoney 自定义金额
* @return array|\think\response\Json
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function submit(int $planId = null, $customMoney = null)
{
if (getPlatform() !== 'MP-WEIXIN') {
return $this->renderError('很抱歉,余额充值暂时仅支持微信小程序端');
}
// 生成充值订单
$model = new OrderModel;
if (!$model->createOrder($planId, (float)$customMoney)) {
return $this->renderError($model->getError() ?: '充值失败');
}
// 构建微信支付
$payment = PaymentService::wechat(
$model['order_id'],
$model['order_no'],
$model['pay_price'],
OrderTypeEnum::RECHARGE
);
// 充值状态提醒
$message = ['success' => '充值成功', 'error' => '订单未支付'];
return $this->renderSuccess(compact('payment', 'message'));
}
}

96
app/api/controller/Refund.php

@ -0,0 +1,96 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\OrderRefund as OrderRefundModel;
use cores\exception\BaseException;
/**
* 订单售后服务
* Class service
* @package app\api\controller\user\order
*/
class Refund extends Controller
{
/**
* 售后单列表
* @param int $state
* @return array|\think\response\Json
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function list(int $state = -1)
{
$model = new OrderRefundModel;
$list = $model->getList($state);
return $this->renderSuccess(compact('list'));
}
/**
* 订单商品详情
* @param int $orderGoodsId 订单商品ID
* @return array|\think\response\Json
* @throws BaseException
*/
public function goods(int $orderGoodsId)
{
$model = new OrderRefundModel;
$goods = $model->getRefundGoods($orderGoodsId);
return $this->renderSuccess(compact('goods'));
}
/**
* 申请售后
* @param int $orderGoodsId 订单商品ID
* @return array|\think\response\Json
* @throws BaseException
*/
public function apply(int $orderGoodsId)
{
// 新增售后单记录
$model = new OrderRefundModel;
if ($model->apply($orderGoodsId, $this->postForm())) {
return $this->renderSuccess([], '提交成功');
}
return $this->renderError($model->getError() ?: '提交失败');
}
/**
* 售后单详情
* @param int $orderRefundId 售后单ID
* @return array|\think\response\Json
* @throws BaseException
*/
public function detail(int $orderRefundId)
{
$detail = OrderRefundModel::getDetail($orderRefundId, true);
return $this->renderSuccess(compact('detail'));
}
/**
* 用户发货
* @param int $orderRefundId 售后单ID
* @return array|\think\response\Json
* @throws BaseException
*/
public function delivery(int $orderRefundId)
{
// 售后单详情
$model = OrderRefundModel::getDetail($orderRefundId, false);
if ($model->delivery($this->postForm())) {
return $this->renderSuccess([], '操作成功');
}
return $this->renderError($model->getError() ?: '提交失败');
}
}

50
app/api/controller/Region.php

@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Region as RegionModel;
/**
* 地区管理
* Class Region
* @package app\api\controller
*/
class Region extends Controller
{
/**
* 获取所有地区
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function all()
{
$list = RegionModel::getCacheAll();
return $this->renderSuccess(compact('list'));
}
/**
* 获取所有地区(树状)
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function tree()
{
$list = RegionModel::getCacheTree();
return $this->renderSuccess(compact('list'));
}
}

37
app/api/controller/Setting.php

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\service\Setting as SettingService;
/**
* 商城设置控制器
* Class Setting
* @package app\store\controller
*/
class Setting extends Controller
{
/**
* 商城公共设置(仅展示可公开的信息)
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function data()
{
$service = new SettingService;
$setting = $service->getPublic();
return $this->renderSuccess(compact('setting'));
}
}

77
app/api/controller/Upload.php

@ -0,0 +1,77 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use app\api\model\Setting as SettingModel;
use app\api\model\UploadFile as UploadFileModel;
use app\api\service\User as UserService;
use app\common\enum\Setting as SettingEnum;
use app\common\enum\file\FileType as FileTypeEnum;
use app\common\library\storage\Driver as StorageDriver;
use cores\exception\BaseException;
/**
* 文件库管理
* Class Upload
* @package app\api\controller
*/
class Upload extends Controller
{
// 当前商城的上传设置
private $config;
/**
* 构造方法
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function initialize()
{
parent::initialize();
// 验证登录
UserService::isLogin(true);
// 存储配置信息
$this->config = SettingModel::getItem(SettingEnum::STORAGE);
}
/**
* 图片上传接口
* @return array|\think\response\Json
* @throws BaseException
* @throws \think\Exception
*/
public function image()
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 实例化存储驱动
$storage = new StorageDriver($this->config);
// 设置上传文件的信息
$storage->setUploadFile('file')
->setRootDirName((string)$this->storeId)
->setValidationScene('image');
// 执行文件上传
if (!$storage->upload()) {
return $this->renderError('图片上传失败:' . $storage->getError());
}
// 文件信息
$fileInfo = $storage->getSaveFileInfo();
// 添加文件库记录
$model = new UploadFileModel;
$model->add($fileInfo, FileTypeEnum::IMAGE, $userId);
// 图片上传成功
return $this->renderSuccess(['fileInfo' => $model->toArray()], '图片上传成功');
}
}

92
app/api/controller/User.php

@ -0,0 +1,92 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\model\User as UserModel;
use app\api\model\UserCoupon as UserCouponModel;
use app\api\service\User as UserService;
use cores\exception\BaseException;
/**
* 用户管理
* Class User
* @package app\api
*/
class User extends Controller
{
/**
* 当前用户详情
* @return Json
* @throws BaseException
*/
public function info(): Json
{
// 当前用户信息
$userInfo = UserService::getCurrentLoginUser(true);
// 获取用户头像
$userInfo['avatar'];
// 获取会员等级
$userInfo['grade'];
return $this->renderSuccess(compact('userInfo'));
}
/**
* 账户资产
* @return Json
* @throws BaseException
*/
public function assets(): Json
{
// 当前用户信息
$userInfo = UserService::getCurrentLoginUser(true);
// 用户优惠券模型
$model = new UserCouponModel;
// 返回数据
return $this->renderSuccess([
'assets' => [
'balance' => $userInfo['balance'], // 账户余额
'points' => $userInfo['points'], // 会员积分
'coupon' => $model->getCount($userInfo['user_id']), // 优惠券数量(可用)
]
]);
}
/**
* 手机号绑定
* @return Json
* @throws \cores\exception\BaseException
*/
public function bindMobile(): Json
{
$model = new UserModel;
if (!$model->bindMobile($this->postForm())) {
return $this->renderSuccess($model->getError() ?: '操作失败');
}
return $this->renderSuccess('恭喜您,手机号绑定成功');
}
/**
* 修改个人信息(头像昵称)
* @return Json
* @throws \cores\exception\BaseException
*/
public function personal(): Json
{
$model = new UserModel;
if (!$model->personal($this->postForm())) {
return $this->renderSuccess($model->getError() ?: '操作失败');
}
return $this->renderSuccess('恭喜您,信息修改成功');
}
}

39
app/api/controller/article/Category.php

@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\article;
use app\api\controller\Controller;
use app\api\model\article\Category as CategoryModel;
/**
* 文章分类
* Class Category
* @package app\api\controller\article
*/
class Category extends Controller
{
/**
* 文章分类列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list()
{
$model = new CategoryModel;
$list = $model->getShowList();
return $this->renderSuccess(compact('list'));
}
}

38
app/api/controller/balance/Log.php

@ -0,0 +1,38 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\balance;
use think\response\Json;
use app\api\controller\Controller;
use app\api\model\user\BalanceLog as BalanceLogModel;
/**
* 余额账单明细
* Class Log
* @package app\api\controller\balance
*/
class Log extends Controller
{
/**
* 余额账单明细列表
* @return Json
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DbException
*/
public function list(): Json
{
$model = new BalanceLogModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

40
app/api/controller/goods/Service.php

@ -0,0 +1,40 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\goods;
use app\api\controller\Controller;
use app\api\model\goods\Service as ServiceModel;
/**
* 商品服务与承诺管理
* Class Service
* @package app\store\controller\goods
*/
class Service extends Controller
{
/**
* 获取指定商品的服务与承诺
* @param int $goodsId
* @return array|\think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function list(int $goodsId)
{
$model = new ServiceModel;
$list = $model->getListByGoods($goodsId);
return $this->renderSuccess(compact('list'));
}
}

83
app/api/controller/order/Comment.php

@ -0,0 +1,83 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\order;
use app\api\controller\Controller;
use app\api\model\Order as OrderModel;
use app\api\model\Comment as CommentModel;
use app\api\model\OrderGoods as OrderGoodsModel;
/**
* 订单评价管理
* Class Comment
* @package app\api\controller\order
*/
class Comment extends Controller
{
/**
* 待评价订单商品列表
* @param int $orderId
* @return array
* @throws \Exception
* @throws \cores\exception\BaseException
* @throws \think\exception\DbException
*/
public function list(int $orderId)
{
// 订单信息
$orderInfo = OrderModel::getDetail($orderId);
// 验证订单是否已完成
$model = new CommentModel;
if (!$model->checkOrderAllowComment($orderInfo)) {
return $this->renderError($model->getError());
}
// 待评价商品列表
$goodsList = OrderGoodsModel::getNotCommentGoodsList($orderId);
if ($goodsList->isEmpty()) {
return $this->renderError('该订单没有可评价的商品');
}
return $this->renderSuccess(compact('goodsList'));
}
/**
* 创建商品评价
* @param int $orderId
* @return array|\think\response\Json
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function submit(int $orderId)
{
// 订单信息
$orderInfo = OrderModel::getDetail($orderId);
// 验证订单是否已完成
$model = new CommentModel;
if (!$model->checkOrderAllowComment($orderInfo)) {
return $this->renderError($model->getError());
}
// 待评价商品列表
$goodsList = OrderGoodsModel::getNotCommentGoodsList($orderId);
if ($goodsList->isEmpty()) {
return $this->renderError('该订单没有可评价的商品');
}
// 提交商品评价
$model = new CommentModel;
if ($model->increased($orderInfo, $goodsList, $this->postForm())) {
return $this->renderSuccess([], '评价发表成功');
}
return $this->renderError($model->getError() ?: '评价发表失败');
}
}

37
app/api/controller/points/Log.php

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\points;
use app\api\controller\Controller;
use app\api\model\user\PointsLog as PointsLogModel;
/**
* 积分明细
* Class Log
* @package app\api\controller\balance
*/
class Log extends Controller
{
/**
* 积分明细列表
* @return array
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DbException
*/
public function list()
{
$model = new PointsLogModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

39
app/api/controller/recharge/Order.php

@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\recharge;
use app\api\controller\Controller;
use app\api\model\recharge\Order as OrderModel;
use cores\exception\BaseException;
/**
* 充值记录管理
* Class Order
* @package app\api\controller\recharge
*/
class Order extends Controller
{
/**
* 我的充值记录列表
* @return array
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function list()
{
$model = new OrderModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

36
app/api/controller/recharge/Plan.php

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller\recharge;
use app\api\controller\Controller;
use app\api\model\recharge\Plan as PlanModel;
/**
* 充值套餐管理
* Class Plan
* @package app\api\controller\recharge
*/
class Plan extends Controller
{
/**
* 充值套餐列表
* @return array
* @throws \think\db\exception\DbException
*/
public function list()
{
$model = new PlanModel;
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
}

20
app/api/event.php

@ -0,0 +1,20 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
// 应用行为扩展定义文件
return [
'listen' => [
'OrderPaySuccess' => [
\app\api\listener\order\PaySuccess::class
]
]
];

101
app/api/listener/order/PaySuccess.php

@ -0,0 +1,101 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\listener\order;
use app\common\service\Message as MessageService;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\order\OrderSource as OrderSourceEnum;
/**
* 订单支付成功后扩展类
* Class PaySuccess
* @package app\api\behavior\order
*/
class PaySuccess
{
// 订单信息
private $order;
// 订单类型
private $orderType;
// 当前商城ID
private $storeId;
/**
* 订单来源回调业务映射类
* @var array
*/
protected $sourceCallbackClass = [
OrderSourceEnum::MAIN => \app\api\service\main\order\PaySuccess::class,
];
/**
* 执行句柄
* @param array $params
* @return bool
*/
public function handle(array $params)
{
// 解构赋值: 订单模型、订单类型
['order' => $order, 'orderType' => $orderType] = $params;
// 设置当前类的属性
$this->setAttribute($order, $orderType);
// 订单公共事件
$this->onCommonEvent();
// 订单来源回调业务
$this->onSourceCallback();
return true;
}
/**
* 设置当前类的属性
* @param $order
* @param int $orderType
*/
private function setAttribute($order, $orderType = OrderTypeEnum::ORDER)
{
$this->order = $order;
$this->storeId = $this->order['store_id'];
$this->orderType = $orderType;
}
/**
* 订单公共业务
*/
private function onCommonEvent()
{
// 发送消息通知
MessageService::send('order.payment', [
'order' => $this->order,
'order_type' => $this->orderType,
], $this->storeId);
}
/**
* 订单来源回调业务
* @return bool
*/
private function onSourceCallback()
{
if (!isset($this->order['order_source'])) {
return false;
}
if (!isset($this->sourceCallbackClass[$this->order['order_source']])) {
return false;
}
$class = $this->sourceCallbackClass[$this->order['order_source']];
return !is_null($class) ? (new $class)->onPaySuccess($this->order) : false;
}
}

97
app/api/model/Article.php

@ -0,0 +1,97 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use cores\exception\BaseException;
use app\common\model\Article as ArticleModel;
/**
* 商品评价模型
* Class Article
* @package app\api\model
*/
class Article extends ArticleModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'is_delete',
'store_id',
'create_time',
'update_time'
];
/**
* 获取器:文章详情HTML实体转换回普通字符
* @param $value
* @return string
*/
public function getArticleContentAttr($value)
{
return htmlspecialchars_decode($value);
}
/**
* 获取文章详情并累计阅读次数
* @param int $articleId 文章ID
* @return static|null
* @throws BaseException
*/
public static function getDetail(int $articleId)
{
// 获取文章详情
$detail = parent::detail($articleId, ['image']);
if (empty($detail) || $detail['is_delete']) {
throwError('很抱歉,当前文章不存在');
}
// 累积文章实际阅读数
static::setIncActualViews($articleId);
return $detail;
}
/**
* 累积文章实际阅读数
* @param int $articleId 文章ID
* @param int $num 递增的数量
* @return mixed
*/
private static function setIncActualViews(int $articleId, int $num = 1)
{
return (new static)->setInc($articleId, 'actual_views', $num);
}
/**
* 获取文章列表
* @param int $categoryId
* @param int $limit
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList(int $categoryId = 0, int $limit = 15)
{
// 检索查询条件
$filter = [];
$categoryId > 0 && $filter[] = ['category_id', '=', $categoryId];
// 获取列表数据
return $this->withoutField(['content'])
->with(['image', 'category'])
->where($filter)
->where('status', '=', 1)
->where('is_delete', '=', 0)
->order(['sort' => 'asc', 'create_time' => 'desc'])
->paginate($limit);
}
}

166
app/api/model/Cart.php

@ -0,0 +1,166 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\model\Goods as GoodsModel;
use app\api\model\GoodsSku as GoodsSkuModel;
use app\api\service\User as UserService;
use app\common\model\Cart as CartModel;
use app\common\enum\goods\Status as GoodsStatusEnum;
use app\common\exception\BaseException;
/**
* 购物车管理
* Class Cart
* @package app\api\model
*/
class Cart extends CartModel
{
/**
* 加入购物车
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku唯一标识
* @param int $goodsNum 商品数量
* @return bool
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function add(int $goodsId, string $goodsSkuId, int $goodsNum)
{
// 判断是否已存在购物车记录
$detail = $this->getInfo($goodsId, $goodsSkuId, false);
// 如果已存在购物车记录, 则累计商品数量
!empty($detail) && $goodsNum += $detail['goods_num'];
// 验证商品的状态
$this->checkGoodsStatus($goodsId, $goodsSkuId, $goodsNum);
// 获取当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 实例化模型
$model = $detail ?: (new static);
return $model->save([
'goods_id' => $goodsId,
'goods_sku_id' => $goodsSkuId,
'goods_num' => $goodsNum,
'user_id' => $userId,
'store_id' => self::$storeId,
]);
}
/**
* 更新购物车记录
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku唯一标识
* @param int $goodsNum 商品数量
* @return bool
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function sUpdate(int $goodsId, string $goodsSkuId, int $goodsNum)
{
// 验证商品的状态
$this->checkGoodsStatus($goodsId, $goodsSkuId, $goodsNum);
// 获取购物车记录
$model = $this->getInfo($goodsId, $goodsSkuId, true);
// 更新记录
return $model->save(['goods_num' => $goodsNum]);
}
/**
* 验证商品的状态
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku唯一标识
* @param int $goodsNum 商品数量
* @return bool
* @throws BaseException
*/
private function checkGoodsStatus(int $goodsId, string $goodsSkuId, int $goodsNum)
{
// 获取商品详情
$goods = GoodsModel::detail($goodsId);
// 商品不存在
if (empty($goods) || $goods['is_delete']) {
throwError('很抱歉, 商品信息不存在');
}
// 商品已下架
if ($goods['status'] == GoodsStatusEnum::OFF_SALE) {
throwError('很抱歉, 该商品已经下架');
}
// 获取SKU信息
$skuInfo = GoodsSkuModel::detail($goodsId, $goodsSkuId);
if ($skuInfo['stock_num'] < $goodsNum) {
throwError('很抱歉, 该商品库存数量不足');
}
return true;
}
/**
* 获取购物车记录
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品sku唯一标识
* @param bool $isForce
* @return static|bool
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getInfo(int $goodsId, string $goodsSkuId, bool $isForce = true)
{
// 获取当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 获取购物车记录
$model = static::detail($userId, $goodsId, $goodsSkuId);
if (empty($model)) {
$isForce && throwError('购物车中没有该记录');
return false;
}
return $model;
}
/**
* 删除购物车中指定记录
* @param array $cartIds 购物车ID集, 如果为空删除所有
* @return bool
* @throws BaseException
*/
public function clear(array $cartIds = [])
{
// 获取当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 设置更新条件
$where = [['user_id', '=', $userId]];
// 购物车ID集
!empty($cartIds) && $where[] = ['id', 'in', $cartIds];
// 更新记录
return $this->updateBase(['is_delete' => 1], $where);
}
/**
* 获取当前用户购物车商品总数量
* @return float
* @throws BaseException
*/
public function getCartTotal()
{
if (!UserService::isLogin()) return 0;
$userId = UserService::getCurrentLoginUserId();
return $this->where('user_id', '=', $userId)
->where('is_delete', '=', 0)
->sum('goods_num');
}
}

46
app/api/model/Category.php

@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Category as CategoryModel;
/**
* 商品分类模型
* Class Category
* @package app\common\model
*/
class Category extends CategoryModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
'update_time'
];
/**
* 获取列表记录
* @param array $param
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getListPublic(array $param = []): array
{
return parent::getList(array_merge($param, ['status' => 1]));
}
}

274
app/api/model/Comment.php

@ -0,0 +1,274 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\model\Order as OrderModel;
use app\common\model\Comment as CommentModel;
use app\api\model\OrderGoods as OrderGoodsModel;
use app\api\service\User as UserService;
use app\common\library\helper;
use app\common\exception\BaseException;
/**
* 商品评价模型
* Class Comment
* @package app\api\model
*/
class Comment extends CommentModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'status',
'sort',
'order_id',
'goods_id',
'order_goods_id',
'is_delete',
'update_time'
];
/**
* 获取指定商品评价列表
* @param int $goodsId 商品ID
* @param int|null $scoreType 评分 (10好评 20中评 30差评)
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getCommentList(int $goodsId, int $scoreType = null)
{
$filter = $this->getFilter($goodsId, $scoreType);
return $this->with(['user.avatar', 'orderGoods', 'images.file'])
->where($filter)
->order(['sort' => 'asc', 'create_time' => 'desc'])
->paginate(15);
}
/**
* 获取指定商品评价列表 (限制数量, 不分页)
* @param int $goodsId 商品ID
* @param int $limit 限制的数量
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function listRows(int $goodsId, int $limit = 5)
{
$filter = $this->getFilter($goodsId);
return $this->with(['user.avatar'])
->where($filter)
->order(['sort' => 'asc', $this->getPk()])
->limit($limit)
->select();
}
/**
* 获取指定商品评价总数量
* @param int $goodsId
* @return int
*/
public function rowsTotal(int $goodsId)
{
$filter = $this->getFilter($goodsId);
return $this->where($filter)->count();
}
/**
* 获取查询条件
* @param int $goodsId 商品ID
* @param int|null $scoreType 评分 (10好评 20中评 30差评)
* @return array[]
*/
private function getFilter(int $goodsId, int $scoreType = null)
{
// 筛选条件
$filter = [
['goods_id', '=', $goodsId],
['status', '=', 1],
['is_delete', '=', 0],
];
// 评分
$scoreType > 0 && $filter[] = ['score', '=', $scoreType];
return $filter;
}
/**
* 获取指定评分总数
* @param int $goodsId
* @return array|null|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getTotal(int $goodsId)
{
return $this->field([
'count(comment_id) AS `all`',
'count(score = 10 OR NULL) AS `praise`',
'count(score = 20 OR NULL) AS `review`',
'count(score = 30 OR NULL) AS `negative`',
])->where([
'goods_id' => $goodsId,
'is_delete' => 0,
'status' => 1
])->find();
}
/**
* 验证订单是否允许评价
* @param OrderModel $order
* @return boolean
*/
public function checkOrderAllowComment(OrderModel $order)
{
// 验证订单是否已完成
if ($order['order_status'] != 30) {
$this->error = '该订单未完成,无法评价';
return false;
}
// 验证订单是否已评价
if ($order['is_comment'] == 1) {
$this->error = '该订单已完成评价';
return false;
}
return true;
}
/**
* 根据已完成订单商品 添加评价
* @param OrderModel $order
* @param $goodsList
* @param array $data
* @return boolean
* @throws BaseException
*/
public function increased(OrderModel $order, $goodsList, array $data)
{
// 生成 formData
$formData = $this->formatFormData($data);
// 生成评价数据
$data = $this->createCommentData($order['order_id'], $goodsList, $formData);
if (empty($data)) {
$this->error = '没有输入评价内容';
return false;
}
return $this->transaction(function () use ($order, $goodsList, $formData, $data) {
// 记录评价内容
$result = $this->addAll($data);
// 记录评价图片`
$this->saveAllImages($result, $formData);
// 更新订单评价状态
$isComment = count($goodsList) === count($data);
$this->updateOrderIsComment($order, $isComment, $result);
return true;
});
}
/**
* 更新订单评价状态
* @param OrderModel $order
* @param $isComment
* @param $commentList
* @return array|false
* @throws \Exception
*/
private function updateOrderIsComment(OrderModel $order, $isComment, $commentList)
{
// 更新订单商品
$orderGoodsData = [];
foreach ($commentList as $comment) {
$orderGoodsData[] = [
'where' => [
'order_goods_id' => $comment['order_goods_id'],
],
'data' => [
'is_comment' => 1
]
];
}
// 更新订单
$isComment && $order->save(['is_comment' => 1]);
return (new OrderGoods)->updateAll($orderGoodsData);
}
/**
* 生成评价数据
* @param int $orderId
* @param $goodsList
* @param array $formData
* @return array
* @throws BaseException
*/
private function createCommentData(int $orderId, $goodsList, array $formData)
{
$data = [];
foreach ($goodsList as $goods) {
if (!isset($formData[$goods['order_goods_id']])) {
throwError('提交的数据不合法');
}
$commentItem = $formData[$goods['order_goods_id']];
$commentItem['content'] = trim($commentItem['content']);
!empty($commentItem['content']) && $data[$goods['order_goods_id']] = [
'score' => $commentItem['score'],
'content' => $commentItem['content'],
'is_picture' => !empty($commentItem['uploaded']),
'sort' => 100,
'status' => 1,
'user_id' => UserService::getCurrentLoginUserId(),
'order_id' => $orderId,
'goods_id' => $commentItem['goods_id'],
'order_goods_id' => $commentItem['order_goods_id'],
'store_id' => self::$storeId
];
}
return $data;
}
/**
* 格式化 formData
* @param array $data
* @return array
*/
private function formatFormData(array $data)
{
return helper::arrayColumn2Key($data, 'order_goods_id');
}
/**
* 记录评价图片
* @param $commentList
* @param $formData
* @return bool
*/
private function saveAllImages($commentList, $formData)
{
// 生成评价图片数据
$imageData = [];
foreach ($commentList as $comment) {
$item = $formData[$comment['order_goods_id']];
foreach ($item['uploaded'] as $imageId) {
$imageData[] = [
'comment_id' => $comment['comment_id'],
'image_id' => $imageId,
'store_id' => self::$storeId
];
}
}
$model = new CommentImage;
return !empty($imageData) && $model->addAll($imageData) !== false;
}
}

42
app/api/model/CommentImage.php

@ -0,0 +1,42 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\CommentImage as CommentImageModel;
/**
* 商品图片模型
* Class GoodsImage
* @package app\api\model
*/
class CommentImage extends CommentImageModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
];
/**
* 关联文件库
* @return \think\model\relation\BelongsTo
*/
public function file()
{
return parent::file()->bind(['image_url' => 'preview_url']);
}
}

86
app/api/model/Coupon.php

@ -0,0 +1,86 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\service\User as UserService;
use app\common\model\Coupon as CouponModel;
use cores\exception\BaseException;
/**
* 优惠券模型
* Class Coupon
* @package app\api\model
*/
class Coupon extends CouponModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'receive_num',
'is_delete',
'create_time',
'update_time',
];
/**
* 获取优惠券列表
* @param int|null $limit 获取的数量
* @param bool $onlyReceive 只显示可领取
* @return mixed
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getList(int $limit = null, bool $onlyReceive = false)
{
// 查询构造器
$query = $this->getNewQuery();
// 只显示可领取(未过期,未发完)的优惠券
if ($onlyReceive) {
$query->where('IF ( `total_num` > - 1, `receive_num` < `total_num`, 1 = 1 )')
->where('IF ( `expire_type` = 20, (`end_time` + 86400) >= ' . time() . ', 1 = 1 )');
}
// 查询数量
$limit > 0 && $query->limit($limit);
// 优惠券列表
$couponList = $query->where('status', '=', 1)
->where('is_delete', '=', 0)
->order(['sort', 'create_time' => 'desc'])
->select();
// 获取用户已领取的优惠券
return $this->setIsReceive($couponList);
}
/**
* 获取用户已领取的优惠券
* @param mixed $couponList
* @return mixed
* @throws BaseException
*/
private function setIsReceive($couponList)
{
// 获取用户已领取的优惠券
$userInfo = UserService::getCurrentLoginUser();
if ($userInfo !== false) {
$UserCouponModel = new UserCoupon;
$userCouponIds = $UserCouponModel->getUserCouponIds($userInfo['user_id']);
foreach ($couponList as $key => $item) {
$couponList[$key]['is_receive'] = in_array($item['coupon_id'], $userCouponIds);
}
}
return $couponList;
}
}

34
app/api/model/Delivery.php

@ -0,0 +1,34 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Delivery as DeliveryModel;
/**
* 配送模板模型
* Class Delivery
* @package app\api\model
*/
class Delivery extends DeliveryModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
'update_time'
];
}

34
app/api/model/DeliveryRule.php

@ -0,0 +1,34 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\DeliveryRule as DeliveryRuleModel;
/**
* 配送模板区域及运费模型
* Class DeliveryRule
* @package app\api\model
*/
class DeliveryRule extends DeliveryRuleModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
'update_time'
];
}

36
app/api/model/Express.php

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Express as ExpressModel;
/**
* 物流公司模型
* Class Express
* @package app\api\model
*/
class Express extends ExpressModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'kuaidi100_code',
'sort',
'store_id',
'create_time',
'update_time'
];
}

265
app/api/model/Goods.php

@ -0,0 +1,265 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\service\Goods as GoodsService;
use app\api\service\user\Grade as UserGradeService;
use app\api\model\GoodsSku as GoodsSkuModel;
use app\api\model\GoodsSpecRel as GoodsSpecRelModel;
use app\common\model\Goods as GoodsModel;
use app\common\enum\goods\Status as GoodsStatusEnum;
use cores\exception\BaseException;
/**
* 商品模型
* Class Goods
* @package app\api\model
*/
class Goods extends GoodsModel
{
/**
* 隐藏字段
* @var array
*/
public $hidden = [
'images',
'delivery',
'deduct_stock_type',
'sales_initial',
'sales_actual',
'sort',
'is_delete',
'store_id',
'create_time',
'update_time'
];
// 是否设置会员折扣价
private $isGoodsGradeMoney = true;
/**
* 商品详情:HTML实体转换回普通字符
* @param $value
* @return string
*/
public function getContentAttr($value): string
{
return htmlspecialchars_decode((string)$value);
}
/**
* 是否设置会员折扣价
* @param bool $value
* @return $this
*/
public function isGoodsGradeMoney(bool $value): Goods
{
$this->isGoodsGradeMoney = $value;
return $this;
}
/**
* 获取商品列表
* @param array $param 查询条件
* @param int $listRows 分页数量
* @return mixed|\think\model\Collection|\think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList(array $param = [], int $listRows = 15)
{
// 整理查询参数
$params = array_merge($param, ['status' => GoodsStatusEnum::ON_SALE]);
// 获取商品列表
$list = parent::getList($params, $listRows);
if ($list->isEmpty()) {
return $list;
}
// 隐藏冗余的属性
$list->hidden(static::getHidden(['content', 'goods_images', 'images']));
// 整理列表数据并返回
return $this->setGoodsListDataFromApi($list);
}
/**
* 获取商品详情 (详细数据用于页面展示)
* @param int $goodsId 商品ID
* @param bool $verifyStatus 是否验证商品状态(上架)
* @return mixed
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getDetails(int $goodsId, bool $verifyStatus = true)
{
// 关联查询(商品图片、sku列表)
$with = ['images.file', 'skuList.image', 'video', 'videoCover'];
// 获取商品记录
$goodsInfo = $this->getGoodsMain($goodsId, $with, $verifyStatus);
// 商品规格列表
$goodsInfo['specList'] = GoodsSpecRelModel::getSpecList($goodsInfo['goods_id']);
return $goodsInfo->hidden(static::getHidden(['images']));
}
/**
* 获取商品详情 (仅包含主商品信息和商品图片)
* @param int $goodsId 商品ID
* @param bool $verifyStatus 是否验证商品状态(上架)
* @return mixed
* @throws BaseException
*/
public function getBasic(int $goodsId, bool $verifyStatus = true)
{
// 关联查询(商品图片)
$with = ['images.file'];
// 获取商品记录
return $this->getGoodsMain($goodsId, $with, $verifyStatus);
}
/**
* 获取商品规格数据
* @param int $goodsId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getSpecData(int $goodsId): array
{
$data = [];
// 商品SKU列表
$data['skuList'] = GoodsSkuModel::getSkuList($goodsId);
// 商品规格列表
$data['specList'] = GoodsSpecRelModel::getSpecList($goodsId);
return $data;
}
/**
* 获取商品主体信息
* @param int $goodsId 商品ID
* @param array $with 关联查询
* @param bool $verifyStatus 是否验证商品状态(上架)
* @return mixed
* @throws BaseException
*/
private function getGoodsMain(int $goodsId, array $with = [], bool $verifyStatus = true)
{
// 获取商品记录
$goodsInfo = static::detail($goodsId, $with);
// 判断商品是否存在
if (empty($goodsInfo) || $goodsInfo['is_delete']) {
throwError('很抱歉,商品信息不存在');
}
// 判断商品状态(上架)
if ($verifyStatus && $goodsInfo['status'] == GoodsStatusEnum::OFF_SALE) {
throwError('很抱歉,当前商品已下架');
}
// 整理商品数据并返回
return $this->setGoodsDataFromApi($goodsInfo);
}
/**
* 根据商品id集获取商品列表
* @param array $goodsIds
* @return mixed
*/
public function getListByIdsFromApi(array $goodsIds)
{
// 获取商品列表
$data = $this->getListByIds($goodsIds, GoodsStatusEnum::ON_SALE);
// 整理列表数据并返回
return $this->setGoodsListDataFromApi($data);
}
/**
* 获取商品指定的sku信息并且设置商品的会员价
* @param mixed $goodsInfo 商品信息
* @param string $goodsSkuId 商品SKUID
* @param bool $isGoodsGradeMoney 是否设置会员折扣价
* @return \app\common\model\GoodsSku|array|null
* @throws BaseException
*/
public static function getSkuInfo($goodsInfo, string $goodsSkuId, bool $isGoodsGradeMoney = true)
{
$goodsInfo['skuInfo'] = GoodsService::getSkuInfo($goodsInfo['goods_id'], $goodsSkuId);
$isGoodsGradeMoney && (new static)->setGoodsGradeMoney($goodsInfo);
return $goodsInfo['skuInfo'];
}
/**
* 设置商品展示的数据 api模块
* @param $data
* @return mixed
*/
private function setGoodsListDataFromApi($data)
{
return $this->setGoodsListData($data, function ($goods) {
// 整理商品数据 api模块
$this->setGoodsDataFromApi($goods);
});
}
/**
* 整理商品数据 api模块
* @param $goodsInfo
* @return mixed
*/
private function setGoodsDataFromApi($goodsInfo)
{
return $this->setGoodsData($goodsInfo, function ($goods) {
// 计算并设置商品会员价
$this->isGoodsGradeMoney && $this->setGoodsGradeMoney($goods);
});
}
/**
* 设置商品的会员价
* @param Goods $goods
* @throws BaseException
*/
private function setGoodsGradeMoney(self $goods)
{
// 设置当前商品是否使用会员等级折扣价
$goods['is_user_grade'] = false;
// 获取当前登录用户的会员等级信息
$gradeInfo = UserGradeService::getCurrentGradeInfo();
// 判断商品是否参与会员折扣
if (empty($gradeInfo) || !$goods['is_enable_grade']) {
return;
}
// 默认的折扣比例
$discountRatio = $gradeInfo['equity']['discount'];
// 商品单独设置了会员折扣
if ($goods['is_alone_grade'] && isset($goods['alone_grade_equity'][$gradeInfo['grade_id']])) {
$discountRatio = $goods['alone_grade_equity'][$gradeInfo['grade_id']];
}
if (empty($discountRatio)) {
return;
}
// 标记参与会员折扣
$goods['is_user_grade'] = true;
// 会员折扣价: 商品基础价格
$goods['goods_price_min'] = UserGradeService::getDiscountPrice($goods['goods_price_min'], $discountRatio);
$goods['goods_price_max'] = UserGradeService::getDiscountPrice($goods['goods_price_max'], $discountRatio);
// 会员折扣价: 商品sku列表
if ($goods->getRelation('skuList')) {
foreach ($goods['skuList'] as &$skuItem) {
$skuItem['goods_price'] = UserGradeService::getDiscountPrice($skuItem['goods_price'], $discountRatio);
}
}
// 会员折扣价: 已选择的商品sku(用于购物车)
if ($goods->getAttr('skuInfo')) {
$goods['skuInfo']['goods_price'] = UserGradeService::getDiscountPrice($goods['skuInfo']['goods_price'], $discountRatio);
}
}
}

33
app/api/model/GoodsImage.php

@ -0,0 +1,33 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\GoodsImage as GoodsImageModel;
/**
* 商品图片模型
* Class GoodsImage
* @package app\api\model
*/
class GoodsImage extends GoodsImageModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
];
}

43
app/api/model/GoodsSku.php

@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\GoodsSku as GoodsSkuModel;
/**
* 商品规格模型
* Class GoodsSku
* @package app\api\model
*/
class GoodsSku extends GoodsSkuModel
{
/**
* 关联模型:规格图片
* @return \think\model\relation\HasOne
*/
public function image(): \think\model\relation\HasOne
{
return parent::image()->bind(['image_url' => 'preview_url']);
}
/**
* 隐藏字段
* @var array
*/
public $hidden = [
'image',
'store_id',
'create_time',
'update_time'
];
}

24
app/api/model/GoodsSpecRel.php

@ -0,0 +1,24 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\GoodsSpecRel as GoodsSpecRelModel;
/**
* 商品规格关系模型
* Class GoodsSpecRel
* @package app\api\model
*/
class GoodsSpecRel extends GoodsSpecRelModel
{
}

32
app/api/model/Help.php

@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Help as HelpModel;
/**
* 模型类:帮助中心
* Class Help
* @package app\api\model
*/
class Help extends HelpModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'create_time',
'update_time',
];
}

400
app/api/model/Order.php

@ -0,0 +1,400 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\model\{Goods as GoodsModel, OrderRefund as OrderRefundModel, Setting as SettingModel};
use app\api\service\{User as UserService, Payment as PaymentService};
use app\api\service\order\{PaySuccess as OrderPaySuccesService, source\Factory as OrderSourceFactory};
use app\common\model\Order as OrderModel;
use app\common\service\{Order as OrderService, order\Complete as OrderCompleteService};
use app\common\enum\{
Setting as SettingEnum,
OrderType as OrderTypeEnum,
order\PayType as OrderPayTypeEnum,
order\PayStatus as PayStatusEnum,
order\OrderStatus as OrderStatusEnum,
// order\DeliveryType as DeliveryTypeEnum,
order\ReceiptStatus as ReceiptStatusEnum,
order\DeliveryStatus as DeliveryStatusEnum
};
use app\common\library\helper;
use cores\exception\BaseException;
/**
* 订单模型
* Class Order
* @package app\api\model
*/
class Order extends OrderModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'update_time'
];
// 信息提示
private $message = '';
/**
* 待支付订单详情
* @param string $orderNo 订单号
* @return null|static
*/
public static function getPayDetail(string $orderNo): ?Order
{
return self::detail(['order_no' => $orderNo, 'pay_status' => PayStatusEnum::PENDING, 'is_delete' => 0], ['goods', 'user']);
}
/**
* 订单支付事件
* @param int $payType
* @return bool
*/
public function onPay(int $payType = OrderPayTypeEnum::WECHAT): bool
{
// 判断订单状态
$orderSource = OrderSourceFactory::getFactory($this['order_source']);
if (!$orderSource->checkOrderStatusOnPay($this)) {
$this->error = $orderSource->getError();
return false;
}
// 余额支付
if ($payType == OrderPayTypeEnum::BALANCE) {
return $this->onPaymentByBalance($this['order_no']);
}
return true;
}
/**
* 构建支付请求的参数
* @param self $order 订单信息
* @param int $payType 订单支付方式
* @return array
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function onOrderPayment(self $order, int $payType): array
{
if ($payType == OrderPayTypeEnum::WECHAT) {
return $this->onPaymentByWechat($order);
}
return [];
}
/**
* 构建微信支付请求
* @param self $order 订单详情
* @return array
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
protected function onPaymentByWechat(self $order): array
{
return PaymentService::wechat(
$order['order_id'],
$order['order_no'],
$order['pay_price'],
OrderTypeEnum::ORDER
);
}
/**
* 立即购买:获取订单商品列表
* @param int $goodsId 商品ID
* @param string $goodsSkuId 商品SKU
* @param int $goodsNum 购买数量
* @return mixed
* @throws BaseException
*/
public function getOrderGoodsListByNow(int $goodsId, string $goodsSkuId, int $goodsNum)
{
// 获取商品列表
$model = new GoodsModel;
$goodsList = $model->isGoodsGradeMoney(false)->getListByIdsFromApi([$goodsId]);
if ($goodsList->isEmpty()) {
throwError('未找到商品信息');
}
// 隐藏冗余的属性
$goodsList->hidden(GoodsModel::getHidden(['content', 'goods_images', 'images']));
foreach ($goodsList as &$item) {
// 商品sku信息
$goodsInfo['skuInfo'] = GoodsModel::getSkuInfo($item, $goodsSkuId, false);
// 商品封面 (优先sku封面)
$item['goods_image'] = $item['skuInfo']['goods_image'] ?: $item['goods_image'];
// 商品单价
$item['goods_price'] = $item['skuInfo']['goods_price'];
// 商品购买数量
$item['total_num'] = $goodsNum;
// 商品SKU索引
$item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
// 商品购买总金额
$item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
}
return $goodsList;
}
/**
* 余额支付标记订单已支付
* @param string $orderNo 订单号
* @return bool
*/
public function onPaymentByBalance(string $orderNo): bool
{
// 获取订单详情
$service = new OrderPaySuccesService($orderNo);
// 发起余额支付
$status = $service->onPaySuccess(OrderPayTypeEnum::BALANCE);
if (!$status) {
$this->error = $service->getError();
}
return $status;
}
/**
* 获取用户订单列表
* @param string $type 订单类型 (all全部 payment待付款 received待发货 deliver待收货 comment待评价)
* @return \think\Paginator
* @throws \think\db\exception\DbException
* @throws BaseException
*/
public function getList(string $type = 'all'): \think\Paginator
{
// 筛选条件
$filter = [];
// 订单数据类型
switch ($type) {
case 'all':
break;
case 'payment':
$filter['pay_status'] = PayStatusEnum::PENDING;
$filter['order_status'] = OrderStatusEnum::NORMAL;
break;
case 'delivery':
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = DeliveryStatusEnum::NOT_DELIVERED;
$filter['order_status'] = OrderStatusEnum::NORMAL;
break;
case 'received':
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = DeliveryStatusEnum::DELIVERED;
$filter['receipt_status'] = ReceiptStatusEnum::NOT_RECEIVED;
$filter['order_status'] = OrderStatusEnum::NORMAL;
break;
case 'comment':
$filter['is_comment'] = 0;
$filter['order_status'] = OrderStatusEnum::COMPLETED;
break;
}
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 查询列表数据
return $this->with(['goods.image'])
->where($filter)
->where('user_id', '=', $userId)
->where('is_delete', '=', 0)
->order(['create_time' => 'desc'])
->paginate(15);
}
/**
* 取消订单
* @return bool|mixed
*/
public function cancel()
{
if ($this['delivery_status'] == DeliveryStatusEnum::DELIVERED) {
$this->error = '已发货订单不可取消';
return false;
}
// 订单是否已支付
$isPay = $this['pay_status'] == PayStatusEnum::SUCCESS;
// 提示信息
$this->message = $isPay ? '订单已申请取消,需等待后台审核' : '订单已取消成功';
// 订单取消事件
return $this->transaction(function () use ($isPay) {
// 订单取消事件
$isPay == false && OrderService::cancelEvent($this);
// 更新订单状态: 已付款的订单设置为"待取消", 等待后台审核
return $this->save(['order_status' => $isPay ? OrderStatusEnum::APPLY_CANCEL : OrderStatusEnum::CANCELLED]);
});
}
/**
* 确认收货
* @return bool|mixed
*/
public function receipt()
{
// 验证订单是否合法
// 条件1: 订单必须已发货
// 条件2: 订单必须未收货
if ($this['delivery_status'] != 20 || $this['receipt_status'] != 10) {
$this->error = '该订单不合法';
return false;
}
return $this->transaction(function () {
// 更新订单状态
$status = $this->save([
'receipt_status' => 20,
'receipt_time' => time(),
'order_status' => 30
]);
// 执行订单完成后的操作
$OrderCompleteService = new OrderCompleteService();
$OrderCompleteService->complete([$this], static::$storeId);
return $status;
});
}
/**
* 获取当前用户订单数量
* @param string $type 订单类型 (all全部 payment待付款 received待发货 deliver待收货 comment待评价)
* @return int
* @throws BaseException
*/
public function getCount(string $type = 'all'): int
{
// 筛选条件
$filter = [];
// 订单数据类型
switch ($type) {
case 'all':
break;
case 'payment':
$filter['pay_status'] = PayStatusEnum::PENDING;
break;
case 'received':
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = DeliveryStatusEnum::DELIVERED;
$filter['receipt_status'] = ReceiptStatusEnum::NOT_RECEIVED;
break;
case 'delivery':
$filter['pay_status'] = PayStatusEnum::SUCCESS;
$filter['delivery_status'] = DeliveryStatusEnum::NOT_DELIVERED;
$filter['order_status'] = OrderStatusEnum::NORMAL;
break;
case 'comment':
$filter['is_comment'] = 0;
$filter['order_status'] = OrderStatusEnum::COMPLETED;
break;
}
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 查询数据
return $this->where('user_id', '=', $userId)
->where('order_status', '<>', 20)
->where($filter)
->where('is_delete', '=', 0)
->count();
}
/**
* 获取用户订单详情(含关联数据)
* @param int $orderId 订单ID
* @return Order|array|null
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getUserOrderDetail(int $orderId)
{
// 关联查询
$with = [
'goods' => ['image', 'goods', 'refund'],
'address', 'express'
];
// 查询订单记录
$order = static::getDetail($orderId, $with);
// 该订单是否允许申请售后
$order['isAllowRefund'] = static::isAllowRefund($order);
return $order;
}
/**
* 获取用户订单详情(仅订单记录)
* @param int $orderId
* @param array $with
* @return Order|array|null
* @throws BaseException
*/
public static function getDetail(int $orderId, array $with = [])
{
// 查询订单记录
$order = static::detail([
'order_id' => $orderId,
'user_id' => UserService::getCurrentLoginUserId(),
], $with);
empty($order) && throwError('订单不存在');
return $order;
}
/**
* 获取当前用户待处理的订单数量
* @return array
* @throws BaseException
*/
public function getTodoCounts(): array
{
return [
'payment' => $this->getCount('payment'), // 待付款的订单
'delivery' => $this->getCount('delivery'), // 待发货的订单
'received' => $this->getCount('received'), // 待收货的订单
'refund' => OrderRefundModel::getCountByUnderway(), // 进行中的售后单
];
}
// 返回提示信息
public function getMessage(): string
{
return $this->message;
}
/**
* 当前订单是否允许申请售后
* @param Order $order
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private static function isAllowRefund(self $order): bool
{
// 必须是已发货的订单
if ($order['delivery_status'] != DeliveryStatusEnum::DELIVERED) {
return false;
}
// 允许申请售后期限(天)
$refundDays = SettingModel::getItem(SettingEnum::TRADE)['order']['refund_days'];
// 不允许售后
if ($refundDays == 0) {
return false;
}
// 当前时间超出允许申请售后期限
if (
$order['receipt_status'] == ReceiptStatusEnum::RECEIVED
&& time() > ($order->getData('receipt_time') + ((int)$refundDays * 86400))
) {
return false;
}
return true;
}
}

33
app/api/model/OrderAddress.php

@ -0,0 +1,33 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\OrderAddress as OrderAddressModel;
/**
* 订单收货地址模型
* Class OrderAddress
* @package app\api\model
*/
class OrderAddress extends OrderAddressModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
];
}

51
app/api/model/OrderGoods.php

@ -0,0 +1,51 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\OrderGoods as OrderGoodsModel;
/**
* 订单商品模型
* Class OrderGoods
* @package app\api\model
*/
class OrderGoods extends OrderGoodsModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'image',
'content',
'store_id',
'create_time',
];
/**
* 获取未评价的商品
* @param int $orderId 订单ID
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getNotCommentGoodsList(int $orderId)
{
return (new static)->with(['image'])
->where('order_id', '=', $orderId)
->where('is_comment', '=', 0)
->select();
}
}

234
app/api/model/OrderRefund.php

@ -0,0 +1,234 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\service\User as UserService;
use app\api\model\OrderGoods as OrderGoodsModel;
use app\common\model\OrderRefund as OrderRefundModel;
use app\common\enum\order\refund\RefundType as RefundTypeEnum;
use app\common\enum\order\refund\AuditStatus as AuditStatusEnum;
use app\common\enum\order\refund\RefundStatus as RefundStatusEnum;
use cores\exception\BaseException;
/**
* 售后单模型
* Class OrderRefund
* @package app\api\model
*/
class OrderRefund extends OrderRefundModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'update_time'
];
/**
* 追加字段
* @var array
*/
protected $append = [
'state_text', // 售后单状态文字描述
];
/**
* 售后单状态文字描述
* @param $value
* @param $data
* @return string
*/
public function getStateTextAttr($value, $data): string
{
// 已完成
if ($data['status'] == RefundStatusEnum::COMPLETED) {
$text = [RefundTypeEnum::RETURN => '已同意退货并已退款', RefundTypeEnum::EXCHANGE => '已同意换货'];
return $text[$data['type']];
}
// 已取消
if ($data['status'] == RefundStatusEnum::CANCELLED) {
return '已取消';
}
// 已拒绝
if ($data['status'] == RefundStatusEnum::REJECTED) {
// return '已拒绝';
return $data['type'] == RefundTypeEnum::RETURN ? '已拒绝退货退款' : '已拒绝换货';
}
// 进行中
if ($data['status'] == RefundStatusEnum::NORMAL) {
if ($data['audit_status'] == AuditStatusEnum::WAIT) {
return '等待审核中';
}
if ($data['type'] == RefundTypeEnum::RETURN) {
return $data['is_user_send'] ? '已发货,待平台确认' : '已同意退货,请及时发货';
}
}
return $value;
}
/**
* 获取用户售后单列表
* @param int $state 售后单状态 -1为全部
* @return \think\Paginator
* @throws \app\common\exception\BaseException
* @throws \think\db\exception\DbException
* @throws BaseException
*/
public function getList(int $state = -1): \think\Paginator
{
// 检索查询条件
$filter = [];
// 售后单状态
$state > -1 && $filter[] = ['status', '=', $state];
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 查询列表记录
return $this->with(['orderGoods.image'])
->where($filter)
->where('user_id', '=', $userId)
->order(['create_time' => 'desc'])
->paginate(15);
}
/**
* 获取当前用户的售后单详情
* @param int $orderRefundId 售后单ID
* @param bool $isWith 是否关联
* @return static|null
* @throws BaseException
*/
public static function getDetail(int $orderRefundId, bool $isWith = false): ?OrderRefund
{
// 关联查询
$with = $isWith ? ['orderGoods' => ['image'], 'images.file', 'address', 'express'] : [];
// 获取记录
$detail = static::detail([
'user_id' => UserService::getCurrentLoginUserId(),
'order_refund_id' => $orderRefundId
], $with);
if (empty($detail)) throwError('未找到该售后单');
return $detail;
}
/**
* 获取当前用户的售后单数量(进行中的)
* @return int
* @throws BaseException
*/
public static function getCountByUnderway(): int
{
$userId = UserService::getCurrentLoginUserId();
return (new static)->where('user_id', '=', $userId)
->where('status', '=', 0)
->count();
}
/**
* 订单商品详情
* @param int $orderGoodsId 订单商品ID
* @return \app\common\model\OrderGoods|null
* @throws BaseException
*/
public function getRefundGoods(int $orderGoodsId)
{
$goods = OrderGoodsModel::detail($orderGoodsId);
if (isset($goods['refund']) && !empty($goods['refund'])) {
throwError('当前商品已申请售后');
}
return $goods;
}
/**
* 用户发货
* @param $data
* @return false|int
*/
public function delivery(array $data)
{
if (
$this['type'] != RefundTypeEnum::RETURN
|| $this['audit_status'] != AuditStatusEnum::REVIEWED
|| $this['is_user_send'] != 0
) {
$this->error = '当前售后单不合法,不允许该操作';
return false;
}
if ($data['expressId'] <= 0) {
$this->error = '请选择物流公司';
return false;
}
if (empty($data['expressNo'])) {
$this->error = '请填写物流单号';
return false;
}
return $this->save([
'is_user_send' => 1,
'send_time' => time(),
'express_id' => (int)$data['expressId'],
'express_no' => $data['expressNo'],
]);
}
/**
* 新增售后单记录
* @param int $orderGoodsId 订单商品ID
* @param array $data 用户提交的表单数据
* @return mixed
* @throws BaseException
*/
public function apply(int $orderGoodsId, array $data)
{
// 订单商品详情
$goods = $this->getRefundGoods($orderGoodsId);
return $this->transaction(function () use ($orderGoodsId, $data, $goods) {
// 新增售后单记录
$this->save([
'order_goods_id' => $orderGoodsId,
'order_id' => $goods['order_id'],
'user_id' => UserService::getCurrentLoginUserId(),
'type' => $data['type'],
'apply_desc' => $data['content'],
'audit_status' => AuditStatusEnum::WAIT,
'status' => 0,
'store_id' => self::$storeId
]);
// 记录凭证图片关系
if (isset($data['images']) && !empty($data['images'])) {
$this->saveImages((int)$this['order_refund_id'], $data['images']);
}
return true;
});
}
/**
* 记录售后单图片
* @param int $orderRefundId 售后单ID
* @param array $images 图片列表
* @return bool
*/
private function saveImages(int $orderRefundId, array $images)
{
// 生成评价图片数据
$data = [];
foreach ($images as $imageId) {
$data[] = [
'order_refund_id' => $orderRefundId,
'image_id' => $imageId,
'store_id' => self::$storeId
];
}
return !empty($data) && (new OrderRefundImage)->addAll($data) !== false;
}
}

33
app/api/model/OrderRefundAddress.php

@ -0,0 +1,33 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\OrderRefundAddress as OrderRefundAddressModel;
/**
* 售后单退货地址模型
* Class OrderRefundAddress
* @package app\api\model
*/
class OrderRefundAddress extends OrderRefundAddressModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time'
];
}

25
app/api/model/OrderRefundImage.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\OrderRefundImage as OrderRefundImageModel;
/**
* 售后单图片模型
* Class OrderRefundImage
* @package app\api\model
*/
class OrderRefundImage extends OrderRefundImageModel
{
}

161
app/api/model/Page.php

@ -0,0 +1,161 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\model\Goods as GoodsModel;
use app\api\model\Coupon as CouponModel;
use app\common\model\Page as PageModel;
use app\common\library\helper;
use cores\exception\BaseException;
/**
* 页面模型
* Class Page
* @package app\api\model
*/
class Page extends PageModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
'update_time'
];
/**
* DIY页面详情
* @param int|null $pageId 页面ID
* @return array
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getPageData(int $pageId = null)
{
// 页面详情
$detail = $pageId > 0 ? parent::detail($pageId) : parent::getHomePage();
if (empty($detail)) {
throwError('很抱歉,未找到该页面');
}
// 页面diy元素
$pageData = $detail['page_data'];
// 获取动态数据
foreach ($pageData['items'] as &$item) {
// 移出默认数据
if (array_key_exists('defaultData', $item)) {
unset($item['defaultData']);
}
if ($item['type'] === 'window') {
$item['data'] = array_values($item['data']);
} else if ($item['type'] === 'goods') {
$item['data'] = $this->getGoodsList($item);
} else if ($item['type'] === 'coupon') {
$item['data'] = $this->getCouponList($item);
} else if ($item['type'] === 'article') {
$item['data'] = $this->getArticleList($item);
} else if ($item['type'] === 'special') {
$item['data'] = $this->getSpecialList($item);
}
}
return $pageData;
}
/**
* 商品组件:获取商品列表
* @param $item
* @return array
* @throws \think\db\exception\DbException
*/
private function getGoodsList($item)
{
// 获取商品数据
$model = new GoodsModel;
if ($item['params']['source'] === 'choice') {
// 数据来源:手动
$goodsIds = helper::getArrayColumn($item['data'], 'goods_id');
if (empty($goodsIds)) return [];
$goodsList = $model->getListByIdsFromApi($goodsIds);
} else {
// 数据来源:自动
$goodsList = $model->getList([
'status' => 10,
'categoryId' => $item['params']['auto']['category'],
'sortType' => $item['params']['auto']['goodsSort'],
], $item['params']['auto']['showNum']);
}
if ($goodsList->isEmpty()) return [];
// 格式化商品列表
$data = [];
foreach ($goodsList as $goods) {
$data[] = [
'goods_id' => $goods['goods_id'],
'goods_name' => $goods['goods_name'],
'selling_point' => $goods['selling_point'],
'goods_image' => $goods['goods_images'][0]['preview_url'],
'goods_price_min' => $goods['goods_price_min'],
'goods_price_max' => $goods['goods_price_max'],
'line_price_min' => $goods['line_price_min'],
'line_price_max' => $goods['line_price_max'],
'goods_sales' => $goods['goods_sales'],
];
}
return $data;
}
/**
* 优惠券组件:获取优惠券列表
* @param $item
* @return array|mixed
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getCouponList($item)
{
// 获取优惠券数据
return (new CouponModel)->getList($item['params']['limit'], true);
}
/**
* 文章组件:获取文章列表
* @param $item
* @return array
* @throws \think\db\exception\DbException
*/
private function getArticleList($item)
{
// 获取文章数据
$model = new Article;
$articleList = $model->getList($item['params']['auto']['category'], $item['params']['auto']['showNum']);
return $articleList->isEmpty() ? [] : $articleList->toArray()['data'];
}
/**
* 头条快报:获取头条列表
* @param $item
* @return array
* @throws \think\db\exception\DbException
*/
private function getSpecialList($item)
{
// 获取头条数据
$model = new Article;
$articleList = $model->getList($item['params']['auto']['category'], $item['params']['auto']['showNum']);
return $articleList->isEmpty() ? [] : $articleList->toArray()['data'];
}
}

25
app/api/model/Region.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Region as RegionModel;
/**
* 地区模型
* Class Region
* @package app\api\model
*/
class Region extends RegionModel
{
}

33
app/api/model/Setting.php

@ -0,0 +1,33 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\store\Setting as SettingModel;
/**
* 系统设置模型
* Class Setting
* @package app\api\model
*/
class Setting extends SettingModel
{
/**
* 获取积分名称
* @return string
*/
public static function getPointsName()
{
return static::getItem('points')['points_name'];
}
}

24
app/api/model/Spec.php

@ -0,0 +1,24 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Spec as SpecModel;
/**
* 规格/属性(组)模型
* Class Spec
* @package app\api\model
*/
class Spec extends SpecModel
{
}

24
app/api/model/SpecValue.php

@ -0,0 +1,24 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\SpecValue as SpecValueModel;
/**
* 规格/属性(值)模型
* Class SpecValue
* @package app\api\model
*/
class SpecValue extends SpecValueModel
{
}

55
app/api/model/Store.php

@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Store as StoreModel;
use think\model\relation\HasOne;
/**
* 商家记录表模型
* Class Store
* @package app\store\model
*/
class Store extends StoreModel
{
/**
* 隐藏的字段
* @var string[]
*/
protected $hidden = [
'sort',
'is_recycle',
'is_delete',
'create_time',
'update_time'
];
/**
* 关联logo图片
* @return HasOne
*/
public function logoImage(): HasOne
{
return $this->hasOne('UploadFile', 'file_id', 'logo_image_id')
->bind(['image_url' => 'preview_url']);
}
/**
* 获取当前商城的基本信息
* @return Store|array|null
*/
public static function getInfo()
{
return static::detail(static::$storeId);
}
}

56
app/api/model/UploadFile.php

@ -0,0 +1,56 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\UploadFile as UploadFileModel;
/**
* 文件库模型
* Class UploadFile
* @package app\api\model
*/
class UploadFile extends UploadFileModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'create_time',
];
/**
* 添加新记录
* @param array $data 文件信息
* @param int $fileType 文件类型
* @param int $userId 用户ID
* @return bool
*/
public function add(array $data, int $fileType, int $userId)
{
return $this->save([
'channel' => 20,
'storage' => $data['storage'],
'domain' => $data['domain'],
'file_name' => $data['file_name'],
'file_path' => $data['file_path'],
'file_size' => $data['file_size'],
'file_ext' => $data['file_ext'],
'file_type' => $fileType,
'uploader_id' => $userId,
'store_id' => self::$storeId
]);
}
}

129
app/api/model/User.php

@ -0,0 +1,129 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use think\facade\Cache;
use app\api\service\User as UserService;
use app\api\model\UserOauth as UserOauthModel;
use app\common\model\User as UserModel;
use cores\exception\BaseException;
use yiovo\captcha\facade\CaptchaApi;
/**
* 用户模型类
* Class User
* @package app\api\model
*/
class User extends UserModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'open_id',
'is_delete',
'store_id',
'create_time',
'update_time'
];
/**
* 获取器:隐藏手机号中间四位
* @param string $value
* @return string
*/
public function getMobileAttr(string $value): string
{
return strlen($value) === 11 ? hide_mobile($value) : $value;
}
/**
* 获取用户信息
* @param string $token
* @return User|array|false|null
* @throws BaseException
*/
public static function getUserByToken(string $token)
{
// 检查登录态是否存在
if (!Cache::has($token)) {
return false;
}
// 用户的ID
$userId = (int)Cache::get($token)['user']['user_id'];
// 用户基本信息
$userInfo = self::detail($userId);
if (empty($userInfo) || $userInfo['is_delete']) {
throwError('很抱歉,用户信息不存在或已删除', config('status.not_logged'));
}
// 获取用户关联的第三方用户信息(当前客户端)
try {
$userInfo['currentOauth'] = UserOauthModel::getOauth($userId, getPlatform());
} catch (\Throwable $e) {
throwError($e->getMessage());
}
return $userInfo;
}
/**
* 绑定手机号(当前登录用户)
* @param array $data
* @return bool
* @throws BaseException
*/
public function bindMobile(array $data): bool
{
// 当前登录的用户信息
$userInfo = UserService::getCurrentLoginUser(true);
// 验证绑定的手机号
$this->checkBindMobile($data);
// 更新手机号记录
return $userInfo->save(['mobile' => $data['mobile']]);
}
/**
* 修改个人信息(头像昵称)
* @param array $form
* @return bool
* @throws BaseException
*/
public function personal(array $form): bool
{
// 当前登录的用户信息
$userInfo = UserService::getCurrentLoginUser(true);
// 默认数据
$data['avatar_id'] = $form['avatarId'] ?: $userInfo['avatar_id'];
$data['nick_name'] = $form['nickName'] ?: $userInfo['nick_name'];
// 更新用户记录
return $userInfo->save($data);
}
/**
* 验证绑定的手机号
* @param array $data
* @return void
* @throws BaseException
*/
private function checkBindMobile(array $data): void
{
// 验证短信验证码是否匹配
if (!CaptchaApi::checkSms($data['smsCode'], $data['mobile'])) {
throwError('短信验证码不正确');
}
// 判断手机号是否已存在
if (static::checkExistByMobile($data['mobile'])) {
throwError('很抱歉,该手机号已绑定其他账户');
}
}
}

180
app/api/model/UserAddress.php

@ -0,0 +1,180 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\model\User as UserModel;
use app\api\service\User as UserService;
use app\common\model\UserAddress as UserAddressModel;
use cores\exception\BaseException;
/**
* 用户收货地址模型
* Class UserAddress
* @package app\common\model
*/
class UserAddress extends UserAddressModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'is_delete',
'store_id',
'create_time',
'update_time'
];
// /**
// * 地区名称
// * @param $value
// * @param $data
// * @return array
// */
// public function getRegionAttr($value, $data)
// {
// return array_values(parent::getRegionAttr($value, $data));
// }
/**
* 获取收货地址列表
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws BaseException
*/
public function getList()
{
$userId = UserService::getCurrentLoginUserId();
return $this->where('user_id', '=', $userId)
->where('is_delete', '=', 0)
->select();
}
/**
* 新增收货地址
* @param array $data
* @return mixed
* @throws BaseException
*/
public function add(array $data)
{
// 当前用户信息
$user = UserService::getCurrentLoginUser(true);
// 省市区ID
[$data['province_id'], $data['city_id'], $data['region_id']] = $this->getRegionId($data);
// 添加收货地址
return $this->transaction(function () use ($user, $data) {
$this->save([
'name' => $data['name'],
'phone' => $data['phone'],
'province_id' => $data['province_id'],
'city_id' => $data['city_id'],
'region_id' => $data['region_id'],
'detail' => $data['detail'],
'user_id' => $user['user_id'],
'store_id' => self::$storeId
]);
// 设为默认收货地址
!$user['address_id'] && $this->setDefault((int)$this['address_id']);
return true;
});
}
/**
* 格式化用户上传的省市区数据
* @param array $data
* @return array
* @throws BaseException
*/
private function getRegionId(array $data)
{
if (!isset($data['region'])) {
throwError('省市区不能为空');
}
if (count($data['region']) != 3) {
throwError('省市区数据不合法');
}
return array_map(function ($item) {
return $item['value'];
}, $data['region']);
}
/**
* 编辑收货地址
* @param array $data
* @return bool
* @throws BaseException
*/
public function edit(array $data)
{
// 省市区ID
[$data['province_id'], $data['city_id'], $data['region_id']] = $this->getRegionId($data);
// 更新收货地址
return $this->save([
'name' => $data['name'],
'phone' => $data['phone'],
'province_id' => $data['province_id'],
'city_id' => $data['city_id'],
'region_id' => $data['region_id'],
'detail' => $data['detail']
]) !== false;
}
/**
* 设为默认收货地址
* @param int $addressIid
* @return bool
* @throws BaseException
*/
public function setDefault(int $addressIid)
{
// 设为默认地址
$userId = UserService::getCurrentLoginUserId();
return UserModel::updateBase(['address_id' => $addressIid], ['user_id' => $userId]);
}
/**
* 删除收货地址
* @return bool
* @throws BaseException
*/
public function remove()
{
// 查询当前是否为默认地址
$user = UserService::getCurrentLoginUser(true);
// 清空默认地址
if ($user['address_id'] == $this['address_id']) {
UserModel::updateBase(['address_id' => 0], ['user_id' => $this['user_id']]);
}
// 标记为已删除
return $this->save(['is_delete' => 1]);
}
/**
* 收货地址详情
* @param int $addressId
* @return UserAddress|array|null
* @throws BaseException
*/
public static function detail(int $addressId)
{
$userId = UserService::getCurrentLoginUserId();
$detail = self::get(['user_id' => $userId, 'address_id' => $addressId]);
if (empty($detail)) {
throwError('未找到该收货地址');
}
return $detail;
}
}

206
app/api/model/UserCoupon.php

@ -0,0 +1,206 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\api\service\User as UserService;
use app\api\model\Coupon as CouponModel;
use app\common\model\UserCoupon as UserCouponModel;
use app\common\enum\coupon\CouponType as CouponTypeEnum;
use app\common\enum\coupon\ApplyRange as ApplyRangeEnum;
use app\common\library\helper;
use cores\exception\BaseException;
/**
* 用户优惠券模型
* Class UserCoupon
* @package app\api\model
*/
class UserCoupon extends UserCouponModel
{
/**
* 获取用户优惠券列表
* @param int $userId
* @param array $param
* @return \think\Paginator
* @throws \think\db\exception\DbException
*/
public function getList(int $userId, array $param): \think\Paginator
{
$filter = $this->getFilter($param);
return $this->where($filter)
->where('user_id', '=', $userId)
->paginate();
}
/**
* 检索查询条件
* @param array $param
* @return array
*/
private function getFilter(array $param = []): array
{
// 设置默认查询参数
$params = $this->setQueryDefaultValue($param, [
'dataType' => 'all', // all:全部 isUsable:可用的 isExpire:已过期 isUse:已使用
'amount' => null, // 订单消费金额
]);
// 检索列表类型
$filter = [];
// 可用的优惠券
if ($params['dataType'] === 'isUsable') {
$filter[] = ['is_use', '=', 0];
$filter[] = ['is_expire', '=', 0];
$filter[] = ['start_time', '<=', time()];
$filter[] = ['end_time', '>', time()];
}
// 未使用的优惠券
if ($params['dataType'] === 'isUnused') {
$filter[] = ['is_use', '=', 0];
$filter[] = ['is_expire', '=', 0];
$filter[] = ['end_time', '>', time()];
}
// 已过期的优惠券
if ($params['dataType'] === 'isExpire') {
$filter[] = ['is_expire', '=', 1];
}
// 已使用的优惠券
if ($params['dataType'] === 'isUse') {
$filter[] = ['is_use', '=', 1];
}
// 订单消费金额
$params['amount'] > 0 && $filter[] = ['min_price', '<=', $params['amount']];
return $filter;
}
/**
* 获取用户优惠券总数量(可用)
* @param int $userId
* @return int
*/
public function getCount(int $userId): int
{
return $this->where('user_id', '=', $userId)
->where('is_use', '=', 0)
->where('is_expire', '=', 0)
->where('end_time', '>', time())
->count();
}
/**
* 获取用户优惠券ID集
* @param int $userId
* @return array
*/
public function getUserCouponIds(int $userId): array
{
return $this->where('user_id', '=', $userId)->column('coupon_id');
}
/**
* 领取优惠券
* @param int $couponId 优惠券ID
* @return bool
* @throws BaseException
*/
public function receive(int $couponId): bool
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId(true);
// 获取优惠券信息
$couponInfo = Coupon::detail($couponId);
// 验证优惠券是否可领取
if (!$this->checkReceive($userId, $couponInfo)) {
return false;
}
// 添加领取记录
return $this->add($userId, $couponInfo);
}
/**
* 验证优惠券是否可领取
* @param int $userId 当前用户ID
* @param CouponModel $couponInfo 优惠券详情
* @return bool
*/
private function checkReceive(int $userId, CouponModel $couponInfo): bool
{
if (empty($couponInfo)) {
$this->error = '当前优惠券不存在';
return false;
}
// 验证优惠券状态是否可领取
$model = new CouponModel;
if (!$model->checkReceive($couponInfo)) {
$this->error = $model->getError() ?: '优惠券状态不可领取';
return false;
}
// 验证当前用户是否已领取
if (static::checktUserCoupon($couponInfo['coupon_id'], $userId)) {
$this->error = '当前用户已领取该优惠券';
return false;
}
return true;
}
/**
* 订单结算优惠券列表
* @param int $userId 用户id
* @param float $orderPayPrice 订单商品总金额
* @return array
* @throws \think\db\exception\DbException
*/
public static function getUserCouponList(int $userId, float $orderPayPrice): array
{
// 获取用户可用的优惠券列表
$list = (new static)->getList($userId, ['dataType' => 'isUsable', 'amount' => $orderPayPrice]);
$data = $list->isEmpty() ? [] : $list->toArray()['data'];
foreach ($data as &$item) {
// 计算最大能折扣的金额
if ($item['coupon_type'] == CouponTypeEnum::DISCOUNT) {
$reducePrice = helper::bcmul($orderPayPrice, $item['discount'] / 10);
$item['reduced_price'] = helper::bcsub($orderPayPrice, $reducePrice);
} else {
$item['reduced_price'] = $item['reduce_price'];
}
}
// 根据折扣金额排序并返回
return !empty($data) ? array_sort($data, 'reduced_price', true) : [];
}
/**
* 判断当前优惠券是否满足订单使用条件
* @param array $couponList
* @param array $orderGoodsIds 订单商品ID集
* @return array
*/
public static function couponListApplyRange(array $couponList, array $orderGoodsIds): array
{
// 名词解释(is_apply):允许用于抵扣当前订单
foreach ($couponList as &$item) {
if ($item['apply_range'] == ApplyRangeEnum::ALL) {
// 1. 全部商品
$item['is_apply'] = true;
} elseif ($item['apply_range'] == ApplyRangeEnum::SOME) {
// 2. 指定商品, 判断订单商品是否存在可用
$applyGoodsIds = array_intersect($item['apply_range_config']['applyGoodsIds'], $orderGoodsIds);
$item['is_apply'] = !empty($applyGoodsIds);
} elseif ($item['apply_range'] == ApplyRangeEnum::EXCLUDE) {
// 2. 排除商品, 判断订单商品是否全部都在排除行列
$excludedGoodsIds = array_intersect($item['apply_range_config']['excludedGoodsIds'], $orderGoodsIds);
$item['is_apply'] = count($excludedGoodsIds) != count($orderGoodsIds);
}
!$item['is_apply'] && $item['not_apply_info'] = '该优惠券不支持当前商品';
}
return $couponList;
}
}

44
app/api/model/UserOauth.php

@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\UserOauth as UserOauthModel;
/**
* 模型类:第三方用户信息
* Class UserOauth
* @package app\api\model
*/
class UserOauth extends UserOauthModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
'is_delete',
'create_time',
'update_time',
];
/**
* 新增数据
* @param array $data
* @return bool
*/
public function add(array $data)
{
return $this->save($data);
}
}

36
app/api/model/article/Category.php

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\article;
use app\common\model\article\Category as CategoryModel;
/**
* 文章分类模型
* Class Category
* @package app\api\model\article
*/
class Category extends CategoryModel
{
/**
* 获取分类列表(未隐藏的)
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getShowList()
{
$where = ['status', '=', 1];
return $this->getList([$where]);
}
}

54
app/api/model/goods/Service.php

@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\goods;
use app\common\model\goods\Service as ServiceModel;
use app\api\model\goods\ServiceRel as ServiceRelModel;
/**
* 商品服务与承诺模型
* Class Service
*/
class Service extends ServiceModel
{
// 隐藏的字段
protected $hidden = [
'is_default',
'status',
'sort',
'is_delete',
'store_id',
'update_time',
];
/**
* 获取指定商品的服务与承诺
* @param int $goodsId
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getListByGoods(int $goodsId)
{
// 获取指定商品的服务承诺id集
$serviceIds = ServiceRelModel::getServiceIds($goodsId);
// 获取服务与承诺列表
return $this->where('service_id', 'in', $serviceIds)
->where('status', '=', 1)
->where('is_delete', '=', 0)
->order(['sort', $this->getPk()])
->select();
}
}

24
app/api/model/goods/ServiceRel.php

@ -0,0 +1,24 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\goods;
use app\common\model\goods\ServiceRel as ServiceRelModel;
/**
* 商品服务与承诺模型
* Class ServiceRel
*/
class ServiceRel extends ServiceRelModel
{
}

35
app/api/model/h5/Setting.php

@ -0,0 +1,35 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\h5;
use app\common\model\h5\Setting as SettingModel;
/**
* H5设置模型
* Class Setting
* @package app\api\model\h5
*/
class Setting extends SettingModel
{
/**
* 验证当前是否允许访问
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function checkStatus(): bool
{
return (bool)static::getItem('basic', static::$storeId)['enabled'];
}
}

251
app/api/model/recharge/Order.php

@ -0,0 +1,251 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\recharge;
use app\api\model\Setting as SettingModel;
use app\api\model\recharge\Plan as PlanModel;
use app\api\model\recharge\OrderPlan as OrderPlanModel;
use app\api\service\User as UserService;
use app\common\library\helper;
use app\common\model\recharge\Order as OrderModel;
use app\common\service\Order as OrderService;
use app\common\enum\recharge\order\PayStatus as PayStatusEnum;
use app\common\enum\recharge\order\RechargeType as RechargeTypeEnum;
use app\common\exception\BaseException;
/**
* 用户充值订单模型
* Class Order
* @package app\api\model\recharge
*/
class Order extends OrderModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'transaction_id',
'store_id',
'create_time',
'update_time',
];
/**
* 获取订单列表
* @return \think\Paginator
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function getList()
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 获取列表数据
return $this->where('user_id', '=', $userId)
->where('pay_status', '=', PayStatusEnum::SUCCESS)
->order(['create_time' => 'desc'])
->paginate(15);
}
/**
* 获取订单详情(待付款状态)
* @param $orderNo
* @return array|null|static
*/
public static function getPayDetail(string $orderNo)
{
return self::detail(['order_no' => $orderNo, 'pay_status' => PayStatusEnum::PENDING]);
}
/**
* 创建充值订单
* @param int|null $planId
* @param float $customMoney
* @return bool|int
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function createOrder(?int $planId = null, float $customMoney = 0.00)
{
// 确定充值方式
$rechargeType = $planId > 0 ? RechargeTypeEnum::PLAN : RechargeTypeEnum::CUSTOM;
// 验证用户输入
if (!$this->validateForm($rechargeType, $planId, $customMoney)) {
$this->error = $this->error ?: '数据验证错误';
return false;
}
// 获取订单数据
$data = $this->getOrderData($rechargeType, $planId, $customMoney);
// 记录订单信息
return $this->saveOrder($data);
}
/**
* 保存订单记录
* @param $data
* @return bool|false|int
*/
private function saveOrder(array $data)
{
// 写入订单记录
$this->save($data['order']);
// 记录订单套餐快照
if (!empty($data['plan'])) {
$PlanModel = new OrderPlanModel;
return $PlanModel->add($this['order_id'], $data['plan']);
}
return true;
}
/**
* 生成充值订单
* @param int $rechargeType 充值方式
* @param int $planId 方案ID
* @param float $customMoney 自定义金额
* @return array|array[]|bool
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getOrderData(int $rechargeType, int $planId, float $customMoney)
{
// 订单信息
$data = [
'order' => [
'user_id' => UserService::getCurrentLoginUserId(),
'order_no' => 'RC' . OrderService::createOrderNo(),
'recharge_type' => $rechargeType,
'gift_money' => 0.00,
'store_id' => self::$storeId,
],
'plan' => [] // 订单套餐快照
];
// 自定义金额充值
if ($rechargeType == RechargeTypeEnum::CUSTOM) {
$data = $this->createDataByCustom($data, $customMoney);
}
// 套餐充值
if ($rechargeType == RechargeTypeEnum::PLAN) {
$data = $this->createDataByPlan($data, $planId);
}
// 实际到账金额
$data['order']['actual_money'] = helper::bcadd($data['order']['pay_price'], $data['order']['gift_money']);
return $data;
}
/**
* 创建套餐充值订单数据
* @param array $order
* @param int $planId
* @return array
* @throws BaseException
*/
private function createDataByPlan(array $order, int $planId)
{
// 获取套餐详情
$planInfo = PlanModel::detail($planId);
if (empty($planInfo)) {
throwError('充值套餐不存在');
}
$order['plan'] = $planInfo;
$order['order']['plan_id'] = $planInfo['plan_id'];
$order['order']['gift_money'] = $planInfo['gift_money'];
$order['order']['pay_price'] = $planInfo['money'];
return $order;
}
/**
* 创建自定义充值订单数据
* @param array $order
* @param float $customMoney
* @return array|bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function createDataByCustom(array $order, float $customMoney)
{
// 用户支付金额
$order['order']['pay_price'] = $customMoney;
// 充值设置
$setting = SettingModel::getItem('recharge');
if ($setting['is_custom'] == false) {
return true;
}
// 根据自定义充值金额匹配满足的套餐
if ($setting['is_match_plan'] == true) {
$matchPlanInfo = (new PlanModel)->getMatchPlan($customMoney);
if (!empty($matchPlanInfo)) {
$order['plan'] = $matchPlanInfo;
$order['order']['plan_id'] = $matchPlanInfo['plan_id'];
$order['order']['gift_money'] = $matchPlanInfo['gift_money'];
}
}
return $order;
}
/**
* 表单验证
* @param int $rechargeType
* @param int $planId
* @param float $customMoney
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function validateForm(int $rechargeType, int $planId, float $customMoney)
{
if (empty($planId) && $customMoney <= 0) {
$this->error = '请选择充值套餐或输入充值金额';
return false;
}
// 验证自定义的金额
if ($rechargeType == RechargeTypeEnum::CUSTOM && !$this->validateFormCustom($customMoney)) {
return false;
}
return true;
}
/**
* 表单验证 [自定义充值]
* @param float $customMoney 充值金额
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function validateFormCustom(float $customMoney)
{
// 充值设置
$setting = SettingModel::getItem('recharge');
if ($setting['is_custom'] == false) {
$this->error = '很抱歉,当前不允许充值自定义金额';
return false;
}
if ($customMoney <= 0) {
$this->error = '请输入正确的充值金额';
return false;
}
// 验证最低充值金额
if (helper::bccomp($customMoney, $setting['lowest_money']) === -1) {
$this->error = "很抱歉,当前最低充值金额不能低于{$setting['lowest_money']}元";
return false;
}
return true;
}
}

42
app/api/model/recharge/OrderPlan.php

@ -0,0 +1,42 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\recharge;
use app\common\model\recharge\OrderPlan as OrderPlanModel;
/**
* 用户充值订单套餐快照模型
* Class OrderPlan
* @package app\api\model\recharge
*/
class OrderPlan extends OrderPlanModel
{
/**
* 新增记录
* @param $orderId
* @param $data
* @return false|int
*/
public function add($orderId, $data)
{
return $this->save([
'order_id' => $orderId,
'plan_id' => $data['plan_id'],
'plan_name' => $data['plan_name'],
'money' => $data['money'],
'gift_money' => $data['gift_money'],
'store_id' => self::$storeId
]);
}
}

67
app/api/model/recharge/Plan.php

@ -0,0 +1,67 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\recharge;
use app\common\model\recharge\Plan as PlanModel;
/**
* 用户充值订单模型
* Class Plan
* @package app\api\model\recharge
*/
class Plan extends PlanModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'sort',
'is_delete',
'store_id',
'create_time',
'update_time',
];
/**
* 获取可用的充值套餐列表
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getList()
{
// 获取列表数据
return $this->where('is_delete', '=', 0)
->order(['sort' => 'asc', 'money' => 'desc', 'create_time' => 'desc'])
->select();
}
/**
* 根据自定义充值金额匹配满足的套餐
* @param $payPrice
* @return array|\think\Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getMatchPlan($payPrice)
{
return (new static)->where('money', '<=', $payPrice)
->where('is_delete', '=', 0)
->order(['money' => 'desc'])
->find();
}
}

49
app/api/model/user/BalanceLog.php

@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\user;
use app\api\service\User as UserService;
use app\common\model\user\BalanceLog as BalanceLogModel;
/**
* 用户余额变动明细模型
* Class BalanceLog
* @package app\api\model\user
*/
class BalanceLog extends BalanceLogModel
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'store_id',
];
/**
* 获取账单明细列表
* @return \think\Paginator
* @throws \app\common\exception\BaseException
* @throws \think\db\exception\DbException
*/
public function getList()
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 获取列表数据
return $this->where('user_id', '=', $userId)
->order(['create_time' => 'desc'])
->paginate(15);
}
}

25
app/api/model/user/Grade.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\user;
use app\common\model\user\Grade as GradeModel;
/**
* 用户会员等级模型
* Class Grade
* @package app\api\model\user
*/
class Grade extends GradeModel
{
}

25
app/api/model/user/GradeLog.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\user;
use app\common\model\user\GradeLog as GradeLogModel;
/**
* 用户会员等级变更记录模型
* Class GradeLog
* @package app\api\model\user
*/
class GradeLog extends GradeLogModel
{
}

41
app/api/model/user/PointsLog.php

@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\user;
use app\api\service\User as UserService;
use app\common\model\user\PointsLog as PointsLogModel;
/**
* 用户余额变动明细模型
* Class PointsLog
* @package app\api\model\user
*/
class PointsLog extends PointsLogModel
{
/**
* 获取日志明细列表
* @return \think\Paginator
* @throws \cores\exception\BaseException
* @throws \think\db\exception\DbException
*/
public function getList()
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 获取列表数据
return $this->where('user_id', '=', $userId)
->order(['create_time' => 'desc'])
->paginate(15);
}
}

25
app/api/model/wxapp/Setting.php

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model\wxapp;
use app\common\model\wxapp\Setting as SettingModel;
/**
* 微信小程序设置模型
* Class Setting
* @package app\api\model\wxapp
*/
class Setting extends SettingModel
{
}

171
app/api/service/Cart.php

@ -0,0 +1,171 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\service;
use app\api\model\Cart as CartModel;
use app\api\model\Goods as GoodsModel;
use app\api\service\User as UserService;
use app\common\library\helper;
use app\common\service\BaseService;
use cores\exception\BaseException;
/**
* 服务类: 购物车
* Class Cart
* @package app\api\service
*/
class Cart extends BaseService
{
/**
* 购物车商品列表(用于购物车页面)
* @param array $cartIds 购物车记录ID集
* @param bool $isGoodsGradeMoney 是否设置商品会员价
* @return array|\think\Collection
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getList(array $cartIds = [], bool $isGoodsGradeMoney = true)
{
// 购物车列表
$cartList = $this->getCartList($cartIds);
// 整理商品ID集
$goodsIds = helper::getArrayColumn($cartList, 'goods_id');
if (empty($goodsIds)) return [];
// 获取商品列表
$goodsList = $this->getGoodsListByIds($goodsIds, $isGoodsGradeMoney);
// 整理购物车商品列表
foreach ($cartList as $cartIdx => $item) {
// 查找商品, 商品不存在则删除该购物车记录
$result = $this->findGoods($goodsList, $item, $isGoodsGradeMoney);
if ($result !== false) {
$cartList[$cartIdx]['goods'] = $result;
} else {
$this->clear([$item['id']]);
unset($cartList[$cartIdx]);
}
}
return $cartList;
}
/**
* 获取购物车商品列表(用于订单结算台)
* @param array $cartIds 购物车记录ID集
* @return array
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getOrderGoodsList(array $cartIds = []): array
{
// 购物车列表
$cartList = $this->getList($cartIds, false);
// 订单商品列表
$goodsList = [];
foreach ($cartList as $item) {
// 商品记录
$goods = $item['goods'];
// 商品单价
$goods['goods_price'] = $goods['skuInfo']['goods_price'];
// 商品购买数量
$goods['total_num'] = $item['goods_num'];
// 商品SKU索引
$goods['goods_sku_id'] = $item['goods_sku_id'];
// 商品购买总金额
$goods['total_price'] = helper::bcmul($goods['goods_price'], $item['goods_num']);
$goodsList[] = $goods;
}
return $goodsList;
}
/**
* 检索查询商品
* @param mixed $goodsList 商品列表
* @param CartModel $item 购物车记录
* @param bool $isGoodsGradeMoney 是否设置商品会员价
* @return false|mixed
* @throws BaseException
*/
private function findGoods($goodsList, CartModel $item, bool $isGoodsGradeMoney = true)
{
// 查找商品记录
$goodsInfo = helper::getArrayItemByColumn($goodsList, 'goods_id', $item['goods_id']);
if (empty($goodsInfo)) {
return false;
}
// 获取当前选择的商品SKU信息
$goodsInfo['skuInfo'] = GoodsModel::getSkuInfo($goodsInfo, $item['goods_sku_id'], $isGoodsGradeMoney);
if (empty($goodsInfo['skuInfo'])) {
return false;
}
// 商品封面 (优先sku封面)
$goodsInfo['goods_image'] = $goodsInfo['skuInfo']['goods_image'] ?: $goodsInfo['goods_image'];
// 这里需要用到clone, 因对象是引用传递 后面的值会覆盖前面的
return clone $goodsInfo;
}
/**
* 删除购物车中指定记录
* @param array $cartIds
* @return bool
* @throws BaseException
*/
public function clear(array $cartIds = []): bool
{
$model = new CartModel;
return $model->clear($cartIds);
}
/**
* 根据商品ID集获取商品列表
* @param array $goodsIds
* @param bool $isGoodsGradeMoney 是否设置会员折扣价
* @return mixed
*/
private function getGoodsListByIds(array $goodsIds, bool $isGoodsGradeMoney = true)
{
$model = new GoodsModel;
return $model->isGoodsGradeMoney($isGoodsGradeMoney)
->getListByIdsFromApi($goodsIds)
->hidden(GoodsModel::getHidden(['goods_images']));
}
/**
* 获取当前用户的购物车记录
* @param array $cartIds 购物车记录ID集
* @return \think\Collection
* @throws BaseException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getCartList(array $cartIds = []): \think\Collection
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 购物车记录模型
$model = new CartModel;
// 检索查询条件
$filter = [];
if (!empty($cartIds)) {
$filter[] = ['id', 'in', $cartIds];
}
// 查询列表记录
return $model->where($filter)
->where('user_id', '=', $userId)
->where('is_delete', '=', 0)
->select();
}
}

39
app/api/service/Goods.php

@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\service;
use app\api\model\GoodsSku as GoodsSkuModel;
use app\common\service\Goods as GoodsService;
/**
* 商品服务类
* Class Goods
* @package app\api\service
*/
class Goods extends GoodsService
{
/**
* 获取商品的指定的某个SKU信息
* @param int $goodsId
* @param string $goodsSkuId
* @return GoodsSkuModel|array|null
*/
public static function getSkuInfo(int $goodsId, string $goodsSkuId)
{
$detail = GoodsSkuModel::detail($goodsId, $goodsSkuId);
if (!empty($detail['image'])) {
$detail['goods_image'] = $detail['image']['preview_url'];
}
return $detail;
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save