351 lines
12 KiB
PHP
351 lines
12 KiB
PHP
<?php
|
||
namespace app\common\model\food;
|
||
use think\facade\Db;
|
||
/**
|
||
* 商品模型
|
||
*/
|
||
class Goods extends BaseModel
|
||
{
|
||
// 定义表名
|
||
protected $name = 'food_goods';
|
||
// 定义主键
|
||
protected $pk = 'goods_id';
|
||
protected $append = ['goods_sales','stock','month_sales'];
|
||
|
||
/**
|
||
* 商品库存
|
||
*/
|
||
public function getStockAttr($value, $data)
|
||
{
|
||
return (new GoodsSpec)->where('goods_id',$data['goods_id'])->sum('stock_num');
|
||
}
|
||
/**
|
||
* 计算显示销量 (初始销量 + 实际销量)
|
||
*/
|
||
public function getGoodsSalesAttr($value, $data)
|
||
{
|
||
return $data['sales_initial'] + $data['sales_actual'];
|
||
}
|
||
/**
|
||
* 计算月销量
|
||
*/
|
||
public function getMonthSalesAttr($value, $data)
|
||
{
|
||
$time = time()-(30*24*60*60);
|
||
return OrderGoods::where('goods_id',$data['goods_id'])
|
||
->where('create_time','>',$time)
|
||
->sum('total_num');
|
||
}
|
||
/**
|
||
* 关联商品分类表
|
||
*/
|
||
public function category()
|
||
{
|
||
return $this->belongsTo('app\\common\\model\\food\\Category','category_id');
|
||
}
|
||
/**
|
||
* 关联商品规格表
|
||
*/
|
||
public function spec()
|
||
{
|
||
return $this->hasMany('app\\common\\model\\food\\GoodsSpec','goods_id')->order(['goods_spec_id' => 'asc']);
|
||
}
|
||
/**
|
||
* 关联商品规格关系表
|
||
*/
|
||
public function specRel()
|
||
{
|
||
return $this->belongsToMany('app\\common\\model\\food\\SpecValue', 'app\\common\\model\\food\\GoodsSpecRel','spec_value_id','goods_id');
|
||
}
|
||
/**
|
||
* 关联商品图片表
|
||
*/
|
||
public function image()
|
||
{
|
||
return $this->hasMany('app\\common\\model\\food\\GoodsImage','goods_id')->order(['id' => 'asc']);
|
||
}
|
||
/**
|
||
* 显示状态
|
||
*/
|
||
public function getGoodsStatusAttr($value)
|
||
{
|
||
$status = [10 => '上架', 20 => '下架'];
|
||
return ['text' => $status[$value], 'value' => $value];
|
||
}
|
||
/**
|
||
* 是否推荐
|
||
*/
|
||
public function getIsRecommendAttr($value)
|
||
{
|
||
$status = ['否', '是'];
|
||
return ['text' => $status[$value], 'value' => $value];
|
||
}
|
||
/**
|
||
* 获取商品列表
|
||
*/
|
||
public function getList($shop_id = 0,$status = 0, $category_id = 0, string $search = '', $sortType = 'all', $sortPrice = false)
|
||
{
|
||
// 筛选条件
|
||
$filter = [];
|
||
$shop_id > 0 && $filter['shop_id'] = $shop_id;
|
||
$status > 0 && $filter['goods_status'] = $status;
|
||
$category_id > 0 && $filter['category_id'] = $category_id;
|
||
!empty($search) && $filter['goods_name'] = ['like', '%' . trim($search) . '%'];
|
||
// 排序规则
|
||
$sort = [];
|
||
if ($sortType === 'all') {
|
||
$sort = ['goods_sort', 'goods_id' => 'desc'];
|
||
} elseif ($sortType === 'sales') {
|
||
$sort = ['goods_sales' => 'desc'];
|
||
} elseif ($sortType === 'price') {
|
||
$sort = $sortPrice ? ['goods_max_price' => 'desc'] : ['goods_min_price'];
|
||
}
|
||
// 商品表名称
|
||
$tableName = $this->getTable();
|
||
// 多规格商品 最高价与最低价
|
||
$GoodsSpec = new GoodsSpec;
|
||
$minPriceSql = $GoodsSpec->field(['MIN(goods_price)'])
|
||
->where('goods_id', 'EXP', "= `$tableName`.`goods_id`")->buildSql();
|
||
$maxPriceSql = $GoodsSpec->field(['MAX(goods_price)'])
|
||
->where('goods_id', 'EXP', "= `$tableName`.`goods_id`")->buildSql();
|
||
// 执行查询
|
||
$list = $this->field(['*', '(sales_initial + sales_actual) as goods_sales',
|
||
"$minPriceSql AS goods_min_price",
|
||
"$maxPriceSql AS goods_max_price"
|
||
])->with(['category', 'image.file', 'spec', 'spec.image'])
|
||
->where('is_delete', '=', 0)
|
||
->where($filter)
|
||
->order($sort)
|
||
->paginate(['list_rows'=>15,'query' => request()->param()]);
|
||
return $list;
|
||
}
|
||
/**
|
||
* 获取商品详情
|
||
*/
|
||
public static function detail($id)
|
||
{
|
||
return self::with(['category', 'image.file', 'spec', 'spec.image', 'spec_rel.spec'])->find($id);
|
||
}
|
||
/**
|
||
* 清除商品记录
|
||
*/
|
||
public function remove($goods_id)
|
||
{
|
||
$filter['goods_id'] = $goods_id;
|
||
// 开启事务
|
||
Db::startTrans();
|
||
try {
|
||
$this->where($filter)->delete();
|
||
GoodsImage::where($filter)->delete();
|
||
GoodsSpec::where($filter)->delete();
|
||
GoodsSpecRel::where($filter)->delete();
|
||
Db::commit();
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* 设置商品上下架
|
||
*/
|
||
public function status()
|
||
{
|
||
$this->goods_status['value'] == 10 ? $this->goods_status = 20 :$this->goods_status = 10;
|
||
return $this->save() !== false;
|
||
}
|
||
|
||
/**
|
||
* 获取商品总数
|
||
*/
|
||
public static function getCount($shop_id=0)
|
||
{
|
||
// 筛选条件
|
||
$filter = [];
|
||
$shop_id > 0 && $filter['shop_id'] = $shop_id;
|
||
return self::where($filter)->count();
|
||
}
|
||
|
||
/**
|
||
* 更新商品库存销量
|
||
*
|
||
*/
|
||
public function updateStockSales($goodsList,$stock = false,$inc= true)
|
||
{
|
||
// 整理批量更新商品销量
|
||
$goodsSave = [];
|
||
// 批量更新商品规格:sku销量、库存
|
||
$goodsSpecSave = [];
|
||
foreach ($goodsList as $goods) {
|
||
if($inc){
|
||
//判断商品是否存在
|
||
if($model = (new Goods)->get($goods['goods_id'])){
|
||
//增加销量
|
||
$model->sales_actual = ['inc', $goods['total_num']];
|
||
$model->save();
|
||
$model = (new GoodsSpec)->get($goods['goods_spec_id']);
|
||
$model->goods_sales = ['inc', $goods['total_num']];
|
||
// 判断是否减库存
|
||
if ($stock) {
|
||
if($model->stock_num > $goods['total_num']){
|
||
$model->stock_num = ['dec', $goods['total_num']];
|
||
}else{
|
||
$model->stock_num = 0;
|
||
}
|
||
}
|
||
$model->save();
|
||
}
|
||
}else{
|
||
//退销量
|
||
if($goods['refund_num'] > 0){
|
||
if($model = (new Goods)->get($goods['goods_id'])){
|
||
if($model->sales_actual > $goods['refund_num']){
|
||
$model->sales_actual = ['dec', $goods['refund_num']];
|
||
}else{
|
||
$model->sales_actual = 0;
|
||
}
|
||
$model->save();
|
||
$model = (new GoodsSpec)->get($goods['goods_spec_id']);
|
||
if($model->goods_sales > $goods['refund_num']){
|
||
$model->goods_sales = ['dec', $goods['refund_num']];
|
||
}else{
|
||
$model->goods_sales = 0;
|
||
}
|
||
// 判断是否减库存
|
||
if ($stock) {
|
||
$model->stock_num = ['inc', $goods['refund_num']];
|
||
}
|
||
$model->save();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
/**
|
||
* 获取商品列表 - DIY组件
|
||
*/
|
||
public static function getAll($shop_id = 0,$sortType = 'all',$limit=null)
|
||
{
|
||
// 筛选条件
|
||
$filter = [];
|
||
$filter['goods_status'] = 10;
|
||
$shop_id > 0 && $filter['shop_id'] = $shop_id;
|
||
if($sortType == 'recommend'){
|
||
$filter['is_recommend'] = 1;//推荐商品
|
||
}
|
||
// 排序规则
|
||
$sort = [];
|
||
if ($sortType === 'all') {
|
||
$sort = ['sales_actual', 'goods_id' => 'desc'];
|
||
} elseif ($sortType === 'sales') {
|
||
$sort = ['goods_sales' => 'desc'];
|
||
} elseif ($sortType === 'new') {
|
||
$sort = ['goods_id' => 'desc'];
|
||
}
|
||
// 执行查询
|
||
return self::with(['category', 'image.file', 'spec', 'spec.image'])
|
||
->field(['*','(sales_initial + sales_actual) as goods_sales'])
|
||
->where('is_delete', '=', 0)
|
||
->where($filter)
|
||
->order($sort)
|
||
->limit($limit)
|
||
->select();
|
||
}
|
||
/**
|
||
* 猜您喜欢
|
||
*/
|
||
public function getBestList($shop_id = 0,$limit=10)
|
||
{
|
||
// 筛选条件
|
||
$filter = [];
|
||
$filter['goods_status'] = 10;
|
||
$filter['is_delete'] = 0;
|
||
$shop_id > 0 && $filter['shop_id'] = $shop_id;
|
||
return $this->with(['spec', 'category', 'image.file'])
|
||
->where($filter)
|
||
->order(['sales_initial' => 'desc', 'goods_sort' => 'asc'])
|
||
->limit($limit)
|
||
->select();
|
||
}
|
||
/**
|
||
* 商品多规格信息
|
||
*/
|
||
public function getGoodsSku(string $goods_sku_id = '')
|
||
{
|
||
$goodsSkuData = array_column($this['spec']->toArray(), null, 'spec_sku_id');
|
||
if (!isset($goodsSkuData[$goods_sku_id])) {
|
||
return false;
|
||
}
|
||
$goods_sku = $goodsSkuData[$goods_sku_id];
|
||
// 多规格文字内容
|
||
$goods_sku['goods_attr'] = '';
|
||
if ($this['spec_type'] == 20) {
|
||
$attrs = explode('_', $goods_sku['spec_sku_id']);
|
||
$spec_rel = array_column($this['spec_rel']->toArray(), null, 'spec_value_id');
|
||
foreach ($attrs as $specValueId) {
|
||
if(!empty($goods_sku['goods_attr'])){
|
||
$goods_sku['goods_attr'] .= '/';
|
||
}
|
||
/*$goods_sku['goods_attr'] .= $spec_rel[$specValueId]['spec']['spec_name'] . ':'
|
||
. $spec_rel[$specValueId]['spec_value'];*/
|
||
$goods_sku['goods_attr'] .= $spec_rel[$specValueId]['spec_value'];
|
||
}
|
||
}
|
||
return $goods_sku;
|
||
}
|
||
|
||
/**
|
||
* 获取规格信息
|
||
*/
|
||
public function getManySpecData($spec_rel, $spec)
|
||
{
|
||
// spec_attr
|
||
$specAttrData = [];
|
||
foreach ($spec_rel as $item) {
|
||
if (!isset($specAttrData[$item['spec_id']])) {
|
||
$specAttrData[$item['spec_id']] = [
|
||
'group_id' => $item['spec']['spec_id'],
|
||
'group_name' => $item['spec']['spec_name'],
|
||
'spec_items' => [],
|
||
];
|
||
}
|
||
$specAttrData[$item['spec_id']]['spec_items'][] = [
|
||
'item_id' => $item['spec_value_id'],
|
||
'spec_value' => $item['spec_value'],
|
||
];
|
||
}
|
||
// spec_list
|
||
$specListData = [];
|
||
foreach ($spec as $item) {
|
||
$image = (isset($item['image']) && !empty($item['image'])) ? $item['image'] : ['file_id' => 0, 'url' => ''];
|
||
$spec_name = '';
|
||
$spec_id_list = explode('_',$item['spec_sku_id']);
|
||
for($n=0;$n<sizeof($spec_id_list);$n++) {
|
||
foreach ($spec_rel as $vo) {
|
||
if($spec_id_list[$n] == $vo['spec_value_id']){
|
||
$spec_name .= $vo['spec_value'];
|
||
if($n+1 != sizeof($spec_id_list)){
|
||
$spec_name .= '/';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$specListData[] = [
|
||
'goods_spec_id' => $item['goods_spec_id'],
|
||
'spec_sku_id' => $item['spec_sku_id'],
|
||
'spec_name' => $spec_name,
|
||
'rows' => [],
|
||
'form' => [
|
||
'image_id' => $image['file_id'],
|
||
'image_url' => $image['url'],
|
||
'goods_no' => $item['goods_no'],
|
||
'goods_price' => $item['goods_price'],
|
||
'line_price' => $item['line_price'],
|
||
'stock_num' => $item['stock_num']
|
||
],
|
||
];
|
||
}
|
||
return ['spec_attr' => array_values($specAttrData), 'spec_list' => $specListData];
|
||
}
|
||
} |