// +---------------------------------------------------------------------- namespace App\Services\Common; use App\Models\GoodsModel; use App\Models\GoodsSkuModel; use App\Services\BaseService; /** * 商品管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Common */ class GoodsService extends BaseService { /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * AdService constructor. */ public function __construct() { $this->model = new GoodsModel(); } /** * 列表(商品审核列表) * @param $params * @param int $pageSize * @return array */ public function getDataList($params, $pageSize = 15) { $query = $this->getQuery($params); $list = $query ->with(['store', 'category']) ->where(function ($query) use ($params) { if (isset($params['store_id']) && $params['store_id'] > 0) { $query->where('store_id', $params['store_id']); } }) ->orderBy('create_time', 'desc') ->orderBy('id', 'desc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list ? $list->toArray() : []; if ($list && isset($list['data'])) { foreach ($list['data'] as &$item) { $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H:i:s') : ''; $item['status_text'] = $this->getStatusText($item['status'] ?? 1); // 商家名称 if (isset($item['store']) && !empty($item['store'])) { $item['store_name'] = $item['store']['name'] ?? '平台商品'; } else { $item['store_name'] = $item['store_id'] > 0 ? '未知商家' : '平台商品'; } // 分类名称 if (isset($item['category']) && !empty($item['category'])) { $item['category_name'] = $item['category']['name'] ?? '未分类'; } else { $item['category_name'] = '未分类'; } // 商品图片 if (isset($item['thumb'])) { $item['thumb'] = get_image_url($item['thumb']); } // 计算总库存(单规格直接取stock,多规格需要计算skus的stock总和) if (isset($item['sku_type']) && $item['sku_type'] == 2) { // 多规格,需要查询skus表 $skuModel = new GoodsSkuModel(); $totalStock = $skuModel->where(['goods_id' => $item['id'], 'mark' => 1, 'status' => 1]) ->sum('stock'); $item['total_stock'] = $totalStock ?? 0; } else { // 单规格 $item['total_stock'] = $item['stock'] ?? 0; } } } return [ 'pageSize' => $pageSize, 'total' => isset($list['total']) ? $list['total'] : 0, 'list' => isset($list['data']) ? $list['data'] : [] ]; } /** * 获取状态文本 * @param int $status * @return string */ private function getStatusText($status) { $statusMap = [ 1 => '已发布', 2 => '待发布', 3 => '待审核', 4 => '审核失败' ]; return isset($statusMap[$status]) ? $statusMap[$status] : '未知'; } /** * 查询 * @param $params * @return \Illuminate\Database\Eloquent\Builder */ public function getQuery($params) { $where = ['mark' => 1]; // 审核状态筛选(1-发布,2-待发布,3-待审核,4-审核失败) $status = isset($params['status']) ? intval($params['status']) : 0; if ($status > 0) { $where['status'] = $status; } // 企业支持:如果当前登录用户关联了企业信息,则只查询该企业的商品 if (isset($params['store_id']) && $params['store_id'] > 0) { $where['store_id'] = $params['store_id']; } if (isset($params['is_recommend']) && $params['is_recommend'] > 0) { $where['is_recommend'] = $params['is_recommend']; } // 分类筛选 $categoryId = isset($params['category_id']) ? intval($params['category_id']) : 0; if ($categoryId > 0) { $where['category_id'] = $categoryId; } $model = $this->model->where($where); // 搜索条件 $model->where(function ($query) use ($params) { // 商品名称搜索 $goodsName = isset($params['goods_name']) ? trim($params['goods_name']) : ''; if ($goodsName) { $query->where('goods_name', 'like', "%{$goodsName}%"); } // 企业名称搜索(通过关联stores表) $storeName = isset($params['store_name']) ? trim($params['store_name']) : ''; if ($storeName) { $query->whereHas('store', function ($q) use ($storeName) { $q->where('name', 'like', "%{$storeName}%"); }); } }); return $model; } /** * 添加商品 * @param int $storeId 商家ID,用于数据隔离(0表示超级管理员,>0表示商户用户) * @return array */ public function add($storeId = 0) { $data = request()->all(); // 图片处理 if (isset($data['thumb'])) { $data['thumb'] = get_image_path($data['thumb']); } if (isset($data['albums']) && is_array($data['albums'])) { $data['albums'] = get_format_images($data['albums'],'url'); } // 验证商品名称 if (empty($data['goods_name'])) { return message('请填写商品名称', false); } // 验证分类 if (!isset($data['category_id']) || $data['category_id'] <= 0) { return message('请选择商品分类', false); } if (!isset($data['price']) || $data['price'] === '') { return message('请填写商品单价', false); } if (!is_numeric($data['price'])) { return message('商品单价格式不正确', false); } $data['price'] = (float)$data['price']; // 确保content字段存在(即使为空字符串或null) $contentValue = isset($data['content']) ? $data['content'] : ''; if ($contentValue === null) { $contentValue = ''; } $data['content'] = (string)$contentValue; // 数据隔离:商户用户添加商品时自动设置 store_id if ($storeId > 0) { // 商户用户:自动设置 store_id $data['store_id'] = $storeId; } else { // 超级管理员:如果没有指定 store_id,默认为 0(平台) if (!isset($data['store_id'])) { $data['store_id'] = 0; } } // 确保不包含 id 字段(新增不应该有 id) unset($data['id']); // 设置默认值 if (!isset($data['sku_type'])) { $data['sku_type'] = 1; // 默认单规格 } if (!isset($data['status'])) { $data['status'] = 3; // 默认待审核 } if (!isset($data['sort'])) { $data['sort'] = 0; } if (!isset($data['price'])) { $data['price'] = 0.00; } if (!isset($data['stock'])) { $data['stock'] = 0; } if (!isset($data['weight'])) { $data['weight'] = 0.00; } // 保存商品 $result = parent::edit($data); // 如果是多规格商品,需要处理规格数据 if ($result && isset($result['code']) && $result['code'] == 0 && isset($result['data']['id'])) { $goodsId = $result['data']['id']; // 确保content字段被正确保存(处理空字符串的情况) $this->model->where('id', $goodsId)->update(['content' => $data['content']]); // 如果是多规格商品,处理规格数据 if (isset($data['sku_type']) && $data['sku_type'] == 2) { if (isset($data['skus']) && is_array($data['skus']) && !empty($data['skus'])) { $this->saveGoodsSkus($goodsId, $data['skus']); } } } return $result; } /** * 编辑商品 * @param int $storeId 商家ID,用于数据隔离(0表示超级管理员,>0表示商户用户) * @return array * @since 2020/11/11 * @author laravel开发员 */ public function edit($storeId = 0) { $data = request()->all(); // 图片处理 if (isset($data['thumb'])) { $data['thumb'] = get_image_path($data['thumb']); } if (isset($data['albums']) && is_array($data['albums'])) { $data['albums'] = get_format_images($data['albums']); } // 验证商品名称 if (empty($data['goods_name'])) { return message('请填写商品名称', false); } // 验证分类 if (!isset($data['category_id']) || $data['category_id'] <= 0) { return message('请选择商品分类', false); } if (!isset($data['price']) || $data['price'] === '') { return message('请填写商品单价', false); } if (!is_numeric($data['price'])) { return message('商品单价格式不正确', false); } $data['price'] = (float)$data['price']; // 确保content字段存在(即使为空字符串或null)- 编辑时允许保存空字符串 $contentValue = isset($data['content']) ? $data['content'] : ''; if ($contentValue === null) { $contentValue = ''; } $data['content'] = (string)$contentValue; // 数据隔离:商户用户只能编辑自己的商品 $isEdit = !empty($data['id']); if ($storeId > 0) { // 商户用户:只能编辑自己的商品 if ($isEdit) { $goods = $this->model->where('id', $data['id'])->where('mark', 1)->first(); if (!$goods || $goods->store_id != $storeId) { return message('无权限操作', false); } // 商户用户修改时,自动设置状态为待审核(3) $data['status'] = 3; } // 自动设置 store_id $data['store_id'] = $storeId; } else { // 超级管理员:如果没有指定 store_id,默认为 0(平台) if (!isset($data['store_id'])) { $data['store_id'] = 0; } // 总后台管理员修改时,可以自由编辑状态 // 不做任何状态处理,保持用户提交的状态 } // 设置默认值(仅在新增时设置,编辑时保持用户提交的值,即使为空) if (!$isEdit) { // 新增商品时设置默认值 if (!isset($data['sku_type'])) { $data['sku_type'] = 1; // 默认单规格 } if (!isset($data['status'])) { $data['status'] = 3; // 默认待审核 } if (!isset($data['sort'])) { $data['sort'] = 0; } if (!isset($data['price'])) { $data['price'] = 0.00; } if (!isset($data['stock'])) { $data['stock'] = 0; } if (!isset($data['weight'])) { $data['weight'] = 0.00; } } else { // 编辑商品时,只设置必要的默认值,允许空值 if (!isset($data['sku_type'])) { $data['sku_type'] = 1; } if (!isset($data['sort'])) { $data['sort'] = 0; } // price, stock, weight 允许为空或 0 if (!isset($data['price'])) { $data['price'] = 0.00; } if (!isset($data['stock'])) { $data['stock'] = 0; } if (!isset($data['weight'])) { $data['weight'] = 0.00; } } // 保存商品 $result = parent::edit($data); // 如果是多规格商品,需要处理规格数据 if ($result && isset($result['code']) && $result['code'] == 0 && isset($result['data']['id'])) { $goodsId = $result['data']['id']; // 确保content字段被正确保存(处理空字符串的情况) $this->model->where('id', $goodsId)->update(['content' => $data['content']]); // 如果是多规格商品,处理规格数据 if (isset($data['sku_type']) && $data['sku_type'] == 2) { if (isset($data['skus']) && is_array($data['skus']) && !empty($data['skus'])) { $this->saveGoodsSkus($goodsId, $data['skus']); } } } return $result; } /** * 删除商品 * @param int $storeId 商家ID,用于数据隔离(0表示超级管理员,>0表示商户用户) * @return array */ public function delete($storeId = 0) { // 参数 $param = request()->all(); // 记录ID $ids = getter($param, "id"); if (empty($ids)) { return message("记录ID不能为空", false); } // 数据隔离:商户用户只能删除自己的商品 $query = $this->model; if ($storeId > 0) { $query = $query->where('store_id', $storeId); } // 清理已删除的记录 $query->where(['mark' => 0])->where('update_time', '<=', time() - 3600)->forceDelete(); if (is_array($ids)) { // 批量删除 $result = $query->whereIn('id', $ids)->update(['mark' => 0, 'update_time' => time()]); if (!$result) { return message("删除失败", false); } return message("删除成功"); } else { // 单个删除 $result = $query->where('id', $ids)->update(['mark' => 0, 'update_time' => time()]); if ($result !== false) { return message(); } return message("删除失败", false); } } /** * 保存商品规格 * @param int $goodsId * @param array $skus * @return bool */ protected function saveGoodsSkus($goodsId, $skus) { // 先删除旧的规格(软删除) GoodsSkuModel::where('goods_id', $goodsId)->update(['mark' => 0, 'update_time' => time()]); $now = time(); $skuModel = new GoodsSkuModel(); foreach ($skus as $sku) { if (isset($sku['id']) && $sku['id'] > 0) { // 更新 $skuModel->where('id', $sku['id'])->update([ 'goods_id' => $goodsId, 'sku_name' => $sku['sku_name'] ?? '', 'price' => $sku['price'] ?? 0.00, 'stock' => $sku['stock'] ?? 0, 'sort' => $sku['sort'] ?? 0, 'status' => $sku['status'] ?? 1, 'update_time' => $now, 'mark' => 1 ]); } else { // 新增 $skuModel->insert([ 'goods_id' => $goodsId, 'sku_name' => $sku['sku_name'] ?? '', 'price' => $sku['price'] ?? 0.00, 'stock' => $sku['stock'] ?? 0, 'sort' => $sku['sort'] ?? 0, 'status' => $sku['status'] ?? 1, 'create_time' => $now, 'update_time' => $now, 'mark' => 1 ]); } } // 计算多规格总库存并更新商品主表 $totalStock = $skuModel->where(['goods_id' => $goodsId, 'mark' => 1, 'status' => 1]) ->sum('stock'); $this->model->where('id', $goodsId)->update([ 'stock' => $totalStock ?? 0, 'update_time' => $now ]); return true; } /** * 审核商品 * @param int $userId 操作人ID * @param array $params 审核参数 * @return bool */ public function confirm($userId, $params) { $id = isset($params['id']) ? intval($params['id']) : 0; $status = isset($params['status']) ? intval($params['status']) : 0; $remark = isset($params['remark']) ? trim($params['remark']) : ''; if (!$id) { $this->error = '商品ID不能为空'; return false; } $info = $this->model->where(['id' => $id, 'mark' => 1])->first(); if (!$info) { $this->error = '商品信息不存在'; return false; } // 多商户支持:检查权限 if (isset($params['store_id']) && $params['store_id'] > 0) { $storeId = $params['store_id']; } else { $storeId = 0; } if ($storeId > 0 && $info->store_id != $storeId) { $this->error = '无权操作此商品'; return false; } // 审核通过 if ($status == 1) { $updateData = [ 'status' => 1, // 1-发布 'confirm_remark' => $remark ?: '审核通过', 'update_time' => time() ]; $this->model->where('id', $id)->update($updateData); $this->error = '审核通过成功'; return true; } // 审核驳回 elseif ($status == 4) { if (empty($remark)) { $this->error = '驳回理由不能为空'; return false; } $this->model->where('id', $id)->update([ 'status' => 4, // 4-审核失败 'confirm_remark' => $remark, 'update_time' => time() ]); $this->error = '审核驳回成功'; return true; } else { $this->error = '审核状态参数错误'; return false; } } /** * 修改状态(发布/待发布互转) */ public function status() { $params = request()->all(); $id = isset($params['id']) ? intval($params['id']) : 0; $status = isset($params['status']) ? intval($params['status']) : 0; if (!$id) { return ['code' => 1, 'msg' => '商品ID不能为空']; } if (!$status || ($status != 1 && $status != 2)) { return ['code' => 1, 'msg' => '状态参数错误']; } $info = $this->model->where(['id' => $id, 'mark' => 1])->first(); if (!$info) { return ['code' => 1, 'msg' => '商品信息不存在']; } // 只有已发布(1)和待发布(2)状态才能互转 if ($info->status != 1 && $info->status != 2) { return ['code' => 1, 'msg' => '只有已发布和待发布状态才能切换']; } $this->model->where('id', $id)->update([ 'status' => $status, 'update_time' => time() ]); return ['code' => 0, 'msg' => '状态修改成功']; } /** * 设置推荐 */ public function recommend() { $params = request()->all(); $id = isset($params['id']) ? intval($params['id']) : 0; $isRecommend = isset($params['is_recommend']) ? intval($params['is_recommend']) : 0; if (!$id) { return ['code' => 1, 'msg' => '商品ID不能为空']; } if (!$isRecommend || ($isRecommend != 1 && $isRecommend != 2)) { return ['code' => 1, 'msg' => '参数错误']; } $info = $this->model->where(['id' => $id, 'mark' => 1])->first(); if (!$info) { return ['code' => 1, 'msg' => '商品信息不存在']; } $this->model->where('id', $id)->update([ 'is_recommend' => $isRecommend, 'update_time' => time() ]); return ['code' => 0, 'msg' => $isRecommend==1?'设置推荐成功':'取消推荐成功']; } /** * 获取商品详情(重写父类方法) * @param int $storeId 商家ID,用于数据隔离(0表示超级管理员,>0表示商户用户) * @return array */ public function info($storeId = 0) { // 记录ID $id = request()->input("id", 0); $info = []; if ($id) { // 获取商品基本信息(使用关联查询) $goods = $this->model->with(['store', 'category', 'skus']) ->where(['id' => $id, 'mark' => 1]) ->first(); if ($goods) { // 数据隔离:商户用户只能查看自己的商品 if ($storeId > 0 && $goods->store_id != $storeId) { return message('无权查看此商品', false); } $info = $goods->toArray(); // 处理图片 if (isset($info['thumb'])) { $info['thumb'] = get_image_url($info['thumb']); } // 处理时间 if (isset($info['create_time'])) { $info['create_time'] = $info['create_time'] ? datetime($info['create_time'], 'Y-m-d H:i:s') : ''; } // 获取分类信息 if (isset($info['category']) && !empty($info['category'])) { $info['category_name'] = $info['category']['name'] ?? '未分类'; } else { $info['category_name'] = '未分类'; } // 获取商家信息 if (isset($info['store']) && !empty($info['store'])) { $info['store_name'] = $info['store']['name'] ?? '平台商品'; } else { $info['store_name'] = $info['store_id'] > 0 ? '未知商家' : '平台商品'; } // 添加状态文本 $info['status_text'] = $this->getStatusText($info['status'] ?? 1); } } return message(MESSAGE_OK, true, $info); } }