阶段更新
This commit is contained in:
20
modules/Mall/Models/Activity.php
Normal file
20
modules/Mall/Models/Activity.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use App\Traits\HasStatus;
|
||||
|
||||
class Activity extends Model
|
||||
{
|
||||
use HasStatus,HasCovers;
|
||||
|
||||
public $status_map = [
|
||||
0 => '关闭',
|
||||
1 => '正常',
|
||||
];
|
||||
protected $table = 'mall_activities';
|
||||
|
||||
}
|
||||
86
modules/Mall/Models/Address.php
Normal file
86
modules/Mall/Models/Address.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\HasRegion;
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Address extends Model
|
||||
{
|
||||
|
||||
use BelongsToUser,
|
||||
HasRegion,
|
||||
Versionable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_addresses';
|
||||
|
||||
protected $casts = [
|
||||
'is_default' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
/**
|
||||
* 如果当前地址为默认地址,取消其他地址的默认地址设置
|
||||
*/
|
||||
self::saved(function ($model) {
|
||||
if ($model->is_default && $model->id) {
|
||||
Address::where('id', '<>', $model->id)
|
||||
->where('user_id', $model->user_id)
|
||||
->where('is_default', 1)
|
||||
->update(['is_default' => 0]);
|
||||
}
|
||||
// else {
|
||||
// Address::where('user_id', $model->user_id)
|
||||
// ->where('is_default', 1)
|
||||
// ->update(['is_default' => 0]);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 保存默认地址时转换格式,非0的都转换成0
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2020/11/5 5:23 下午
|
||||
* @param $value
|
||||
*/
|
||||
protected function setIsDefaultAttribute($value): void
|
||||
{
|
||||
if (strtolower($value) === 'false' || $value === '0') {
|
||||
$this->attributes['is_default'] = 0;
|
||||
} else {
|
||||
$this->attributes['is_default'] = !!$value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 将地址设置为默认地址
|
||||
* @Date : 2021/4/23 1:34 下午
|
||||
* @Author : < Jason.C >
|
||||
*/
|
||||
public function setDefault(): void
|
||||
{
|
||||
$this->is_default = 1;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
}
|
||||
33
modules/Mall/Models/Banner.php
Normal file
33
modules/Mall/Models/Banner.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use App\Traits\WithPosition;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Linker\Traits\HasLinker;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
|
||||
class Banner extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
Cachable,
|
||||
HasCovers,
|
||||
SoftDeletes,
|
||||
HasLinker,
|
||||
WithPosition;
|
||||
|
||||
const POSITION_INDEX = 1;
|
||||
const POSITION_INDEX_CENTER = 2;
|
||||
|
||||
public array $position_map = [
|
||||
self::POSITION_INDEX => '首页顶部',
|
||||
self::POSITION_INDEX_CENTER => '体检官介绍',
|
||||
];
|
||||
|
||||
protected $table = 'mall_banners';
|
||||
|
||||
}
|
||||
39
modules/Mall/Models/Brand.php
Normal file
39
modules/Mall/Models/Brand.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Brand extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
Cachable,
|
||||
Versionable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_brands';
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
/**
|
||||
* Notes : 品牌下的商品
|
||||
* @Date : 2021/5/25 12:05 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function goods(): HasMany
|
||||
{
|
||||
return $this->hasMany(Goods::class);
|
||||
}
|
||||
|
||||
}
|
||||
29
modules/Mall/Models/Cart.php
Normal file
29
modules/Mall/Models/Cart.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
|
||||
class Cart extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
BelongsToUser;
|
||||
|
||||
protected $table = 'mall_carts';
|
||||
|
||||
/**
|
||||
* Notes : 购物车商品
|
||||
* @Date : 2021/5/13 2:25 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function sku(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(GoodsSku::class, 'sku_id');
|
||||
}
|
||||
|
||||
}
|
||||
56
modules/Mall/Models/Category.php
Normal file
56
modules/Mall/Models/Category.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use App\Traits\HasStatus;
|
||||
use App\Traits\OrderByOrderAsc;
|
||||
use Encore\Admin\Traits\AdminBuilder;
|
||||
use Encore\Admin\Traits\ModelTree;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
|
||||
use AdminBuilder,
|
||||
BelongsToShop,
|
||||
Cachable,
|
||||
HasCovers,
|
||||
ModelTree,
|
||||
OrderByOrderAsc,
|
||||
HasStatus,
|
||||
Versionable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_categories';
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
parent::__construct($attributes);
|
||||
|
||||
$this->setTitleColumn('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 分类商品
|
||||
* @Date : 2021/5/12 9:49 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function goods(): HasMany
|
||||
{
|
||||
return $this->hasMany(Goods::class);
|
||||
}
|
||||
|
||||
}
|
||||
39
modules/Mall/Models/Delivery.php
Normal file
39
modules/Mall/Models/Delivery.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
|
||||
class Delivery extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
Cachable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_deliveries';
|
||||
|
||||
const TYPE_BY_COUNT = 1;
|
||||
const TYPE_BY_WEIGHT = 2;
|
||||
|
||||
const TYPE_MAP = [
|
||||
self::TYPE_BY_COUNT => '按数量',
|
||||
self::TYPE_BY_WEIGHT => '按重量',
|
||||
];
|
||||
|
||||
/**
|
||||
* Notes : 模板对应的规则
|
||||
* @Date : 2021/3/15 1:11 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function rules(): HasMany
|
||||
{
|
||||
return $this->hasMany(DeliveryRule::class);
|
||||
}
|
||||
|
||||
}
|
||||
31
modules/Mall/Models/DeliveryRule.php
Normal file
31
modules/Mall/Models/DeliveryRule.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class DeliveryRule extends Model
|
||||
{
|
||||
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'mall_delivery_rules';
|
||||
|
||||
protected $casts = [
|
||||
'regions' => 'json',
|
||||
];
|
||||
|
||||
/**
|
||||
* Notes : 隶属的模板
|
||||
* @Date : 2021/3/15 1:12 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function delivery(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Delivery::class);
|
||||
}
|
||||
|
||||
}
|
||||
32
modules/Mall/Models/Express.php
Normal file
32
modules/Mall/Models/Express.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Express extends Model
|
||||
{
|
||||
|
||||
use Cachable,
|
||||
HasCovers,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_expresses';
|
||||
|
||||
/**
|
||||
* Notes : 使用该物流的公司
|
||||
* @Date : 2021/5/6 5:23 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function shops(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Shop::class, 'mall_shop_express')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
}
|
||||
267
modules/Mall/Models/Goods.php
Normal file
267
modules/Mall/Models/Goods.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasClicks;
|
||||
use App\Traits\HasCovers;
|
||||
use App\Traits\HasStatus;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Goods extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
HasStatus,
|
||||
HasClicks,
|
||||
HasCovers,
|
||||
Versionable,
|
||||
SoftDeletes;
|
||||
|
||||
/**
|
||||
* 规格,支持单规格和多规格
|
||||
*/
|
||||
const TYPE_SINGLE = 1;
|
||||
const TYPE_MULTIPLE = 2;
|
||||
const TYPE_MAP = [
|
||||
self::TYPE_SINGLE => '单规格',
|
||||
// self::TYPE_MULTIPLE => '多规格',
|
||||
];
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
const STATUS_AUDIT = 0;
|
||||
const STATUS_UP = 1;
|
||||
const STATUS_REJECT = 2;
|
||||
const STATUS_DOWN = 3;
|
||||
const STATUS_MAP = [
|
||||
self::STATUS_AUDIT => '审核中',
|
||||
self::STATUS_UP => '上架',
|
||||
self::STATUS_REJECT => '驳回',
|
||||
self::STATUS_DOWN => '下架',
|
||||
];
|
||||
/**
|
||||
* 库存的扣减方式
|
||||
*/
|
||||
const DEDUCT_STOCK_ORDER = 1;
|
||||
const DEDUCT_STOCK_PAID = 2;
|
||||
const DEDUCT_STOCK_MAP = [
|
||||
self::DEDUCT_STOCK_ORDER => '下单减库存',
|
||||
self::DEDUCT_STOCK_PAID => '付款减库存',
|
||||
];
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
const PAY_TYPE_ONLINE = 1;
|
||||
const PAY_TYPE_OFFLINE = 2;
|
||||
const PAY_TYPE_ALL = 3;
|
||||
const PAY_TYPE_MAP = [
|
||||
self::PAY_TYPE_ONLINE => '在线支付',
|
||||
self::PAY_TYPE_OFFLINE => '货到付款',
|
||||
self::PAY_TYPE_ALL => '在线支付/货到付款',
|
||||
];
|
||||
|
||||
/**
|
||||
* 商品类型
|
||||
*/
|
||||
const CHANNEL_NORMAL = 1;
|
||||
const CHANNEL_SCORE = 2;
|
||||
const CHANNEL_FREE = 3;
|
||||
|
||||
const Channels = [
|
||||
self::CHANNEL_NORMAL => '正常',
|
||||
self::CHANNEL_SCORE => '积分兑换',
|
||||
self::CHANNEL_FREE => '赠送',
|
||||
];
|
||||
|
||||
/**
|
||||
* 展示列表,从数据库查询的字段
|
||||
*/
|
||||
const LIST_SELECT_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'cover',
|
||||
'shop_id',
|
||||
'original_price',
|
||||
'sales',
|
||||
'clicks',
|
||||
];
|
||||
|
||||
protected $table = 'mall_goods';
|
||||
|
||||
protected $casts = [
|
||||
'pictures' => 'json',
|
||||
];
|
||||
|
||||
protected $with = [
|
||||
'specs',
|
||||
'skus',
|
||||
];
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
*
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['clicks', 'updated_at'];
|
||||
|
||||
/**
|
||||
* Notes : 商品分类
|
||||
*
|
||||
* @Date : 2021/5/12 9:48 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 标签
|
||||
*
|
||||
* @Date : 2021/5/12 10:14 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function tags(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'mall_goods_tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 所属品牌
|
||||
*
|
||||
* @Date : 2021/5/11 11:00 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function brand(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Brand::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 运费模板
|
||||
*
|
||||
* @Date : 2021/5/11 11:04 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function delivery(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Delivery::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 商品属性
|
||||
*
|
||||
* @Date : 2021/5/12 11:31 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function specs(): HasMany
|
||||
{
|
||||
return $this->hasMany(GoodsSpec::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 商品SKU
|
||||
*
|
||||
* @Date : 2021/5/11 1:47 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function skus(): HasMany
|
||||
{
|
||||
return $this->hasMany(GoodsSku::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取规格的价格区间
|
||||
*
|
||||
* @Date : 2021/5/13 11:49 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getPriceAttribute(): string
|
||||
{
|
||||
if ($this->type === self::TYPE_SINGLE) {
|
||||
return $this->price_min;
|
||||
} else {
|
||||
return $this->price_min.'|'.$this->price_max;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 返回最低积分
|
||||
*
|
||||
* @Date : 2021/5/20 11:26 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return float
|
||||
*/
|
||||
public function getScoreAttribute(): float
|
||||
{
|
||||
return $this->skus->min('score') ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 最低价格
|
||||
*
|
||||
* @Date : 2021/5/13 11:50 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return float
|
||||
*/
|
||||
public function getPriceMinAttribute(): float
|
||||
{
|
||||
return $this->skus->min('price') ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 最高价格
|
||||
*
|
||||
* @Date : 2021/5/13 11:51 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return float
|
||||
*/
|
||||
public function getPriceMaxAttribute(): float
|
||||
{
|
||||
return $this->skus->max('price') ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 按价格排序
|
||||
*
|
||||
* @Date : 2021/5/17 14:18
|
||||
* @Author : Mr.wang
|
||||
* @param Builder $query
|
||||
* @param string $direction
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeOrderByPrice(Builder $query, string $direction = 'asc'): Builder
|
||||
{
|
||||
if ($direction) {
|
||||
$price = DB::raw('MIN(price) as min_price');
|
||||
} else {
|
||||
$price = DB::raw('MAX(price) as min_price');
|
||||
}
|
||||
|
||||
$minPrice = DB::table('mall_goods_skus')
|
||||
->select('goods_id', $price)
|
||||
->whereNull('deleted_at')
|
||||
->groupBy('goods_id');
|
||||
|
||||
return $query->joinSub($minPrice, 'min_price', function ($join) {
|
||||
$join->on('mall_goods.id', '=', 'min_price.goods_id');
|
||||
})->orderBy('min_price', $direction);
|
||||
}
|
||||
|
||||
}
|
||||
62
modules/Mall/Models/GoodsSku.php
Normal file
62
modules/Mall/Models/GoodsSku.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\GoodsAttribute;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class GoodsSku extends Model
|
||||
{
|
||||
|
||||
use HasCovers,
|
||||
Versionable,
|
||||
GoodsAttribute,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_goods_skus';
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
*
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
/**
|
||||
* Notes : 所属品牌
|
||||
*
|
||||
* @Date : 2021/5/11 11:00 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function goods(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Goods::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 当前规格是否可购买
|
||||
*
|
||||
* @Date : 2021/5/14 10:08
|
||||
* @Author : Mr.wang
|
||||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function canBuy(int $qty = 1): bool
|
||||
{
|
||||
if ($this->goods->channel == Goods::CHANNEL_FREE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->goods->status == Goods::STATUS_UP && $this->stock >= $qty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
36
modules/Mall/Models/GoodsSpec.php
Normal file
36
modules/Mall/Models/GoodsSpec.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class GoodsSpec extends Model
|
||||
{
|
||||
|
||||
protected $table = 'mall_goods_specs';
|
||||
|
||||
/**
|
||||
* Notes : 所属商品
|
||||
* @Date : 2021/5/11 4:51 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function goods(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Goods::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 属性值
|
||||
* @Date : 2021/5/11 4:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function values(): HasMany
|
||||
{
|
||||
return $this->hasMany(GoodsSpecValue::class, 'spec_id');
|
||||
}
|
||||
|
||||
}
|
||||
24
modules/Mall/Models/GoodsSpecValue.php
Normal file
24
modules/Mall/Models/GoodsSpecValue.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class GoodsSpecValue extends Model
|
||||
{
|
||||
|
||||
protected $table = 'mall_goods_spec_values';
|
||||
|
||||
/**
|
||||
* Notes : 所属属性
|
||||
* @Date : 2021/5/11 4:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function spec(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(GoodsSpec::class);
|
||||
}
|
||||
|
||||
}
|
||||
19
modules/Mall/Models/Job.php
Normal file
19
modules/Mall/Models/Job.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
|
||||
class Job extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
Cachable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_jobs';
|
||||
|
||||
}
|
||||
313
modules/Mall/Models/Order.php
Normal file
313
modules/Mall/Models/Order.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\AreaCode;
|
||||
use App\Models\Model;
|
||||
use App\Traits\OrderByIdDesc;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Modules\Mall\Models\Traits\OrderActions;
|
||||
use Modules\Mall\Models\Traits\OrderCando;
|
||||
use Modules\Mall\Models\Traits\OrderScopes;
|
||||
use Modules\Mall\Traits\WithWorkflow;
|
||||
use Modules\Payment\Traits\WithPayments;
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
|
||||
use BelongsToUser,
|
||||
BelongsToShop,
|
||||
OrderByIdDesc,
|
||||
OrderCando,
|
||||
Versionable,
|
||||
WithWorkflow,
|
||||
OrderActions,
|
||||
WithPayments,
|
||||
OrderScopes,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_orders';
|
||||
|
||||
protected $dates = [
|
||||
'paid_at',
|
||||
'expired_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'source' => 'json',
|
||||
];
|
||||
protected $appends = ['total'];
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
*
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
const STATUS_INIT = 'INIT'; // 订单初始化:用户已下单,未付款
|
||||
const STATUS_CANCEL = 'CANCEL'; // 订单取消:用户未支付并取消订单,超时未支付后自动取消订单
|
||||
const STATUS_PAID = 'PAID'; // 已支付:用户付款完成,等待发货
|
||||
const STATUS_DELIVERED = 'DELIVERED'; // 已发货:卖家已发货
|
||||
const STATUS_SIGNED = 'SIGNED'; // 已签收:用户已签收
|
||||
const STATUS_COMPLETED = 'COMPLETED'; // 已完成:用户签收N天后,完成订单,不再做任何操作,
|
||||
|
||||
const REFUND_APPLY = 'REFUND_APPLY'; // 申请退款
|
||||
const REFUND_AGREE = 'REFUND_AGREE'; // 同意退款
|
||||
const REFUND_DELIVER = 'REFUND_DELIVER'; // 等待客户退货
|
||||
const REFUND_DELIVERD = 'REFUND_DELIVERD'; // 客户发货
|
||||
const REFUND_REFUSE = 'REFUND_REFUSE'; // 拒绝退款
|
||||
const REFUND_PROCESS = 'REFUND_PROCESS'; // 退款中
|
||||
const REFUND_COMPLETED = 'REFUND_COMPLETED'; // 退款完成
|
||||
|
||||
const STATUS_MAP = [
|
||||
self::STATUS_INIT => '未付款',
|
||||
self::STATUS_CANCEL => '已取消',
|
||||
self::STATUS_PAID => '待发货',
|
||||
self::STATUS_DELIVERED => '已发货',
|
||||
self::STATUS_SIGNED => '已签收',
|
||||
self::STATUS_COMPLETED => '完成',
|
||||
self::REFUND_APPLY => '申请退款',
|
||||
self::REFUND_AGREE => '同意退款',
|
||||
self::REFUND_REFUSE => '拒绝退款',
|
||||
self::REFUND_DELIVER => '等待退货',
|
||||
self::REFUND_DELIVERD => '客户退货',
|
||||
self::REFUND_PROCESS => '退款中',
|
||||
self::REFUND_COMPLETED => '退款完成',
|
||||
];
|
||||
|
||||
const CANCEL_BY_USER = 2; // 买家取消
|
||||
const CANCEL_BY_SELLER = 3; // 卖家取消
|
||||
const CANCEL_BY_SYSTEM = 4; // 系统取消
|
||||
|
||||
const TYPE_NORMAL = 1; // 正常
|
||||
const TYPE_SAMPLE = 2; // 提货
|
||||
const TYPE_SCORE = 3; // 积分兑换
|
||||
|
||||
const TYPE_MAP = [
|
||||
self::TYPE_NORMAL => '正常',
|
||||
self::TYPE_SAMPLE => '领取',
|
||||
self::TYPE_SCORE => '积分兑换',
|
||||
];
|
||||
|
||||
const CHANNEL_USER = 1;
|
||||
const CHANNEL_SYSTEM = 2;
|
||||
|
||||
const CHANNEL_MAP = [
|
||||
self::CHANNEL_USER => '会员',
|
||||
self::CHANNEL_SYSTEM => '公司',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
self::creating(function ($model) {
|
||||
$time = explode(' ', microtime());
|
||||
|
||||
$counter = $model->whereDate('created_at', Carbon::today())->count() + 1;
|
||||
|
||||
$len = config('mall.order_no_counter_length');
|
||||
|
||||
$len = $len < 6 ? 6 : $len;
|
||||
$len = $len > 16 ? 16 : $len;
|
||||
|
||||
$model->order_no = date('YmdHis').
|
||||
sprintf('%06d', $time[0] * 1e6).
|
||||
sprintf('%0'.$len.'d', $counter);
|
||||
|
||||
$model->state = self::STATUS_INIT;
|
||||
$model->expired_at = Carbon::now()->addMinutes(10);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该模型的路由的自定义键名
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'order_no';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取订单总额
|
||||
*
|
||||
* @Date : 2021/3/16 1:48 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return float
|
||||
*/
|
||||
public function getTotalAttribute(): float
|
||||
{
|
||||
if ($this->original) {
|
||||
return sprintf("%.2f", $this->original['amount'] + $this->original['freight']);
|
||||
}
|
||||
|
||||
return sprintf("%.2f", $this->amount + $this->freight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单状态文本
|
||||
*
|
||||
* @Date : 2021/5/10 3:24 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getStateTextAttribute(): string
|
||||
{
|
||||
return self::STATUS_MAP[$this->state];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 订单类型
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/10/13 16:53
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeTextAttribute(): string
|
||||
{
|
||||
return self::TYPE_MAP[$this->type];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单发货记录
|
||||
*
|
||||
* @Date : 2021/5/11 9:47 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return HasOne
|
||||
*/
|
||||
public function express(): HasOne
|
||||
{
|
||||
return $this->hasOne(OrderExpress::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单条目
|
||||
*
|
||||
* @Date : 2021/5/11 9:47 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return HasMany
|
||||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取商品
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/10/27 15:01
|
||||
* @return \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|mixed
|
||||
*/
|
||||
public function getGoodsAttribute()
|
||||
{
|
||||
return $this->items()->first()->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 退款单
|
||||
*
|
||||
* @Date : 2021/5/11 9:48 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return HasMany
|
||||
*/
|
||||
public function refunds(): HasMany
|
||||
{
|
||||
return $this->hasMany(Refund::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取退款商品数
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/19 9:50
|
||||
* @return int
|
||||
*/
|
||||
public function getRefundItemsCountAttribute(): int
|
||||
{
|
||||
$order_id = $this->id;
|
||||
|
||||
return RefundItem::query()
|
||||
->whereHas('order_item', function ($query) use ($order_id) {
|
||||
$query->where('order_id', $order_id);
|
||||
})
|
||||
->whereHas('refund', function ($query) {
|
||||
$query->whereNotIN('state', [Refund::REFUND_APPLY]);
|
||||
})
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 工作流获取状态
|
||||
*
|
||||
* @Date : 2021/5/8 3:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 工作流设置状态
|
||||
*
|
||||
* @Date : 2021/5/8 4:01 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param $state
|
||||
*/
|
||||
public function setCurrentState($state)
|
||||
{
|
||||
$this->state = $state;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 当前订单能不能查看物流
|
||||
*
|
||||
* @Date : 2021/5/19 11:55
|
||||
* @Author : Mr.wang
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsLogisticShowAttribute(): bool
|
||||
{
|
||||
return in_array($this->state, [
|
||||
self::STATUS_DELIVERED,
|
||||
self::STATUS_SIGNED,
|
||||
self::REFUND_COMPLETED,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getCanAction(): array
|
||||
{
|
||||
return [
|
||||
'pay' => $this->canPay(),
|
||||
'cancel' => $this->canCancel(),
|
||||
'sign' => $this->canSign(),
|
||||
'refund' => $this->canRefund(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 提货码
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2023/1/12 14:24
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function areaCode(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(AreaCode::class);
|
||||
}
|
||||
|
||||
}
|
||||
48
modules/Mall/Models/OrderExpress.php
Normal file
48
modules/Mall/Models/OrderExpress.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Traits\BelongsToOrder;
|
||||
use Modules\Mall\Models\Traits\HasRegion;
|
||||
|
||||
class OrderExpress extends Model
|
||||
{
|
||||
|
||||
use BelongsToOrder,
|
||||
HasRegion;
|
||||
|
||||
protected $table = 'mall_order_expresses';
|
||||
|
||||
protected $dates = [
|
||||
'deliver_at',
|
||||
'receive_at',
|
||||
];
|
||||
|
||||
const TYPE_EXPRESS = 1;
|
||||
const TYPE_LOGISTICS = 2;
|
||||
|
||||
const TYPE_MAP = [
|
||||
self::TYPE_EXPRESS => '快递',
|
||||
self::TYPE_LOGISTICS => '物流',
|
||||
];
|
||||
|
||||
/**
|
||||
* Notes : 订单物流信息
|
||||
*
|
||||
* @Date : 2021/5/25 12:04 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function express(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Express::class);
|
||||
}
|
||||
|
||||
public function getTypeTextAttribute(): string
|
||||
{
|
||||
return self::TYPE_MAP[$this->type];
|
||||
}
|
||||
|
||||
}
|
||||
130
modules/Mall/Models/OrderItem.php
Normal file
130
modules/Mall/Models/OrderItem.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Modules\Mall\Models\Traits\BelongsToOrder;
|
||||
|
||||
class OrderItem extends Model
|
||||
{
|
||||
|
||||
use BelongsToOrder;
|
||||
|
||||
protected $table = 'mall_order_items';
|
||||
|
||||
const UPDATED_AT = null;
|
||||
|
||||
public $casts = [
|
||||
'source' => 'json',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 关联商品
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/8/11 9:26
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function item(): morphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 关联退款单
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/19 9:30
|
||||
*/
|
||||
public function refund_items(): HasMany
|
||||
{
|
||||
return $this->hasMany(RefundItem::class, 'order_item_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 商品状态
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/6/17 9:07
|
||||
*/
|
||||
public function getRefundStatusTextAttribute()
|
||||
{
|
||||
if ($this->isRefund()) {
|
||||
$refund_item = $this->refund_items()->latest()->first();
|
||||
if ($refund_item) {
|
||||
return $refund_item->refund->status_test;
|
||||
} else {
|
||||
return '未知状态';
|
||||
}
|
||||
} else {
|
||||
return '正常';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否申请退款
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/21 11:15
|
||||
*/
|
||||
public function isRefund(): int
|
||||
{
|
||||
return $this->refund_items()->count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否可以退款/货
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/19 9:32
|
||||
*/
|
||||
public function canRefund(): bool
|
||||
{
|
||||
$can = true;
|
||||
|
||||
//是否已申请退款/货
|
||||
if ($this->isRefund()) {
|
||||
//最后一个申请
|
||||
$refundItem = $this->refund_items()->latest()->first();
|
||||
if ($refundItem && $refundItem->refund->state != Refund::REFUND_REFUSE) {
|
||||
$can = false;
|
||||
}
|
||||
}
|
||||
|
||||
$is_post_sale = $this->source['is_post_sale'] ?? 0;
|
||||
|
||||
return $is_post_sale && $can && $this->order->can('refund');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取总额
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/20 13:13
|
||||
* @return float
|
||||
*/
|
||||
public function getTotalAttribute(): float
|
||||
{
|
||||
return sprintf("%.2f", $this->price * $this->qty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取水晶总数
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/21 11:26
|
||||
*/
|
||||
public function getTotalScoreAttribute(): string
|
||||
{
|
||||
$score = $this->source['score'] ?? 0;
|
||||
|
||||
return sprintf("%.2f", $score * $this->qty);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
30
modules/Mall/Models/Reason.php
Normal file
30
modules/Mall/Models/Reason.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Reason extends Model
|
||||
{
|
||||
|
||||
use Cachable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_reasons';
|
||||
|
||||
/**
|
||||
* Notes: 关联店铺
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/18 15:28
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function shops(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Shop::class, 'mall_shop_reasons')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
}
|
||||
216
modules/Mall/Models/Refund.php
Normal file
216
modules/Mall/Models/Refund.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\OrderByIdDesc;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\BelongsToOrder;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Modules\Mall\Models\Traits\RefundActions;
|
||||
use Modules\Mall\Traits\WithWorkflow;
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Refund extends Model
|
||||
{
|
||||
|
||||
use BelongsToOrder,
|
||||
BelongsToShop,
|
||||
BelongsToUser,
|
||||
OrderByIdDesc,
|
||||
Versionable,
|
||||
WithWorkflow,
|
||||
RefundActions,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'mall_refunds';
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
const REFUND_APPLY = 'REFUND_APPLY'; // 申请退款
|
||||
const REFUND_AGREE = 'REFUND_AGREE'; // 同意退款
|
||||
const REFUND_REFUSE = 'REFUND_REFUSE'; // 拒绝退款
|
||||
const REFUND_PROCESS = 'REFUND_PROCESS'; // 退款中
|
||||
const REFUND_DELIVER = 'REFUND_DELIVER'; // 客户退货,等待签收
|
||||
const REFUND_DELIVERED = 'REFUND_DELIVERED'; // 客户退货,等待签收
|
||||
const REFUND_SIGNED = 'REFUND_SIGNED'; // 已签收
|
||||
const REFUND_COMPLETED = 'REFUND_COMPLETED'; // 退款完成
|
||||
|
||||
const STATUS_MAP = [
|
||||
self::REFUND_APPLY => '申请退款',
|
||||
self::REFUND_AGREE => '同意退款',
|
||||
self::REFUND_REFUSE => '拒绝退款',
|
||||
self::REFUND_DELIVER => '等待客户退货',
|
||||
self::REFUND_DELIVERED => '客户退货,等待签收',
|
||||
self::REFUND_SIGNED => '已签收',
|
||||
self::REFUND_PROCESS => '退款中',
|
||||
self::REFUND_COMPLETED => '退款完成',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $dates = [
|
||||
'refunded_at',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
self::creating(function ($model) {
|
||||
$model->state = self::REFUND_APPLY;
|
||||
|
||||
$time = explode(' ', microtime());
|
||||
|
||||
$counter = $model->whereDate('created_at', Carbon::today())->count() + 1;
|
||||
|
||||
$len = config('mall.refund_no_counter_length');
|
||||
$prefix = config('refund_no_counter_prefix');
|
||||
|
||||
$len = $len < 6 ? 6 : $len;
|
||||
$len = $len > 16 ? 16 : $len;
|
||||
|
||||
$model->refund_no = $prefix . date('YmdHis') .
|
||||
sprintf('%06d', $time[0] * 1e6) .
|
||||
sprintf('%0' . $len . 'd', $counter);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该模型的路由的自定义键名
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'refund_no';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 退款单详情
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/22 4:25 下午
|
||||
* @return HasMany
|
||||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(RefundItem::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 退款单物流
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/22 4:25 下午
|
||||
* @return HasOne
|
||||
*/
|
||||
public function express(): HasOne
|
||||
{
|
||||
return $this->hasOne(RefundExpress::class);
|
||||
}
|
||||
|
||||
/***
|
||||
* Notes: 获取状态
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/18 11:50
|
||||
*/
|
||||
public function getStatusTextAttribute(): string
|
||||
{
|
||||
return self::STATUS_MAP[$this->state] ?? '---';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取退款状态
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/22 4:25 下午
|
||||
* @return string
|
||||
*/
|
||||
protected function getStateTextAttribute(): string
|
||||
{
|
||||
switch ($this->state) {
|
||||
case self::REFUND_APPLY:
|
||||
$state = '退款申请中';
|
||||
break;
|
||||
case self::REFUND_AGREE:
|
||||
$state = '同意退款';
|
||||
break;
|
||||
case self::REFUND_PROCESS:
|
||||
$state = '退款中,请等待商家打款';
|
||||
break;
|
||||
case self::REFUND_COMPLETED:
|
||||
$state = '退款完毕';
|
||||
break;
|
||||
case self::REFUND_REFUSE:
|
||||
$state = '拒绝退款';
|
||||
break;
|
||||
case self::REFUND_DELIVER:
|
||||
$state = '您的申请已经通过,请将商品退回给商家';
|
||||
break;
|
||||
case self::REFUND_DELIVERED:
|
||||
$state = '客户退货,等待签收';
|
||||
break;
|
||||
case self::REFUND_SIGNED:
|
||||
$state = '店家已签收,等待打款';
|
||||
break;
|
||||
default:
|
||||
$state = '未知状态';
|
||||
break;
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 关联店铺
|
||||
* @Date : 2021/5/7 1:46 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function shop(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Shop::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 关联日志
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 11:38
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function logs(): HasMany
|
||||
{
|
||||
return $this->hasMany(RefundLog::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 工作流获取状态
|
||||
* @Date : 2021/5/8 3:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 工作流设置状态
|
||||
* @Date : 2021/5/8 4:01 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param $state
|
||||
*/
|
||||
public function setCurrentState($state)
|
||||
{
|
||||
$this->state = $state;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
}
|
||||
22
modules/Mall/Models/RefundExpress.php
Normal file
22
modules/Mall/Models/RefundExpress.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Modules\Mall\Models\Traits\BelongsToRefund;
|
||||
use Modules\Mall\Models\Traits\HasRegion;
|
||||
|
||||
class RefundExpress extends Model
|
||||
{
|
||||
|
||||
use BelongsToRefund,
|
||||
HasRegion;
|
||||
|
||||
protected $table = 'mall_refund_expresses';
|
||||
|
||||
protected $dates = [
|
||||
'deliver_at',
|
||||
'receive_at',
|
||||
];
|
||||
|
||||
}
|
||||
35
modules/Mall/Models/RefundItem.php
Normal file
35
modules/Mall/Models/RefundItem.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Traits\BelongsToOrder;
|
||||
use Modules\Mall\Models\Traits\BelongsToRefund;
|
||||
|
||||
class RefundItem extends Model
|
||||
{
|
||||
|
||||
use BelongsToOrder,
|
||||
BelongsToRefund;
|
||||
|
||||
const UPDATED_AT = null;
|
||||
|
||||
protected $table = 'mall_refund_items';
|
||||
|
||||
public $casts = [
|
||||
'source' => 'json',
|
||||
];
|
||||
|
||||
/**
|
||||
* Notes: 关联order_item
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/19 9:50
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function order_item(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(OrderItem::class);
|
||||
}
|
||||
|
||||
}
|
||||
40
modules/Mall/Models/RefundLog.php
Normal file
40
modules/Mall/Models/RefundLog.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Modules\Mall\Models\Traits\BelongsToRefund;
|
||||
|
||||
class RefundLog extends Model
|
||||
{
|
||||
|
||||
use BelongsToRefund;
|
||||
|
||||
const UPDATED_AT = null;
|
||||
|
||||
protected $table = 'mall_refund_logs';
|
||||
|
||||
/**
|
||||
* Notes: 操作用户
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 11:32
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function userable(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 状态
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/18 11:39
|
||||
* @return string
|
||||
*/
|
||||
public function getStateTextAttribute(): string
|
||||
{
|
||||
return Refund::STATUS_MAP[$this->state] ?? '---';
|
||||
}
|
||||
|
||||
}
|
||||
63
modules/Mall/Models/Region.php
Normal file
63
modules/Mall/Models/Region.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Region extends Model
|
||||
{
|
||||
|
||||
use Cachable;
|
||||
|
||||
protected $table = 'mall_regions';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* Notes: 上级地区
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/19 3:01 下午
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(__CLASS__, 'parent_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 下级地区
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/19 3:01 下午
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function children(): HasMany
|
||||
{
|
||||
return $this->hasMany(__CLASS__, 'parent_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取区划层级名称
|
||||
* @Date : 2021/5/6 1:47 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getDepthNameAttribute(): string
|
||||
{
|
||||
switch ($this->depth) {
|
||||
case 0:
|
||||
return '国家级';
|
||||
case 1:
|
||||
return '省级';
|
||||
case 2:
|
||||
return '市级';
|
||||
case 3:
|
||||
return '区县';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
187
modules/Mall/Models/Shop.php
Normal file
187
modules/Mall/Models/Shop.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use App\Traits\OrderByOrderAsc;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\Mall\Models\Traits\HasRegion;
|
||||
use Modules\Mall\Models\Traits\ShopActions;
|
||||
use Modules\User\Models\User;
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
use Overtrue\LaravelVersionable\Versionable;
|
||||
|
||||
class Shop extends Model
|
||||
{
|
||||
|
||||
use BelongsToUser,
|
||||
Cachable,
|
||||
HasCovers,
|
||||
HasRegion,
|
||||
OrderByOrderAsc,
|
||||
Versionable,
|
||||
ShopActions,
|
||||
SoftDeletes;
|
||||
|
||||
const STATUS_APPLYING = 0;
|
||||
const STATUS_NORMAL = 1;
|
||||
const STATUS_REJECT = 2;
|
||||
const STATUS_CLOSE = 3;
|
||||
|
||||
const STATUS_MAP = [
|
||||
self::STATUS_APPLYING => '待审核',
|
||||
self::STATUS_NORMAL => '正常',
|
||||
self::STATUS_REJECT => '驳回申请',
|
||||
self::STATUS_CLOSE => '关闭',
|
||||
];
|
||||
|
||||
const LABEL_MAP = [
|
||||
self::STATUS_APPLYING => 'default',
|
||||
self::STATUS_NORMAL => 'success',
|
||||
self::STATUS_REJECT => 'warning',
|
||||
self::STATUS_CLOSE => 'danger',
|
||||
];
|
||||
|
||||
protected $table = 'mall_shops';
|
||||
|
||||
protected $casts = [
|
||||
'pictures' => 'json',
|
||||
'configs' => 'json',
|
||||
];
|
||||
|
||||
/**
|
||||
* 不参与版本记录的字段
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected array $dontVersionable = ['updated_at'];
|
||||
|
||||
/**
|
||||
* Notes : 店铺支持的物流
|
||||
* @Date : 2021/5/6 5:20 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function expresses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Express::class, 'mall_shop_express')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 店铺的商品
|
||||
* @Date : 2021/5/6 5:32 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function goods(): HasMany
|
||||
{
|
||||
return $this->hasMany(Goods::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 分类
|
||||
* @Date : 2021/5/6 5:32 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function categories(): HasMany
|
||||
{
|
||||
return $this->hasMany(Category::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 店铺设置的标签
|
||||
* @Date : 2021/5/13 10:34 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function tags(): HasMany
|
||||
{
|
||||
return $this->hasMany(Tag::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 店铺的品牌
|
||||
* @Date : 2021/5/13 10:35 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function brands(): HasMany
|
||||
{
|
||||
return $this->hasMany(Brand::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 轮播图
|
||||
* @Date : 2021/5/13 11:34 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function banners(): HasMany
|
||||
{
|
||||
return $this->hasMany(Banner::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单
|
||||
* @Date : 2021/5/6 5:33 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function orders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 退款订单
|
||||
* @Date : 2021/5/7 9:16 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function refunds(): HasMany
|
||||
{
|
||||
return $this->hasMany(Refund::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取状态文本
|
||||
* @Date : 2021/5/7 10:57 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getStatusTextAttribute(): string
|
||||
{
|
||||
return self::STATUS_MAP[$this->status] ?? '未知状态';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 退货理由
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/18 15:31
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function reasons(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Reason::class, 'mall_shop_reasons')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 店铺的员工
|
||||
* @Date : 2021/7/1 4:25 下午
|
||||
* @Author : < Jason.C >
|
||||
*/
|
||||
public function staffers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'mall_shop_staffers')
|
||||
->using(ShopStaffer::class)
|
||||
->withPivot('job_id')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
}
|
||||
31
modules/Mall/Models/ShopStaffer.php
Normal file
31
modules/Mall/Models/ShopStaffer.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use Encore\Admin\Traits\DefaultDatetimeFormat;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
|
||||
class ShopStaffer extends Pivot
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
BelongsToUser,
|
||||
DefaultDatetimeFormat;
|
||||
|
||||
protected $table = 'mall_shop_staffers';
|
||||
|
||||
/**
|
||||
* Notes : 职位
|
||||
* @Date : 2021/7/1 4:38 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function job(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Job::class);
|
||||
}
|
||||
|
||||
}
|
||||
29
modules/Mall/Models/Tag.php
Normal file
29
modules/Mall/Models/Tag.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Modules\Mall\Models\Traits\BelongsToShop;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
|
||||
use BelongsToShop,
|
||||
Cachable;
|
||||
|
||||
protected $table = 'mall_tags';
|
||||
|
||||
/**
|
||||
* Notes : 标签下的商品
|
||||
* @Date : 2021/5/12 10:14 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function goods(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Goods::class, 'mall_goods_tag')->withTimestamps();
|
||||
}
|
||||
|
||||
}
|
||||
22
modules/Mall/Models/Traits/BelongsToOrder.php
Normal file
22
modules/Mall/Models/Traits/BelongsToOrder.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Order;
|
||||
|
||||
trait BelongsToOrder
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 隶属订单
|
||||
* @Date : 2021/3/15 1:29 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function order(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
|
||||
}
|
||||
22
modules/Mall/Models/Traits/BelongsToRefund.php
Normal file
22
modules/Mall/Models/Traits/BelongsToRefund.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Refund;
|
||||
|
||||
trait BelongsToRefund
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 所属退款单
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/20 13:58
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function refund(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Refund::class);
|
||||
}
|
||||
|
||||
}
|
||||
49
modules/Mall/Models/Traits/BelongsToShop.php
Normal file
49
modules/Mall/Models/Traits/BelongsToShop.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Shop;
|
||||
|
||||
trait BelongsToShop
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 隶属店铺
|
||||
* @Date : 2021/5/6 2:49 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function shop(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Shop::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 作用域查询
|
||||
* @Date : 2021/6/21 8:57 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Modules\Mall\Models\Shop $shop
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeByShop(Builder $query, Shop $shop): Builder
|
||||
{
|
||||
return $query->where('shop_id', $shop->getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 店铺ID 作用域查询
|
||||
* @Date : 2021/6/21 9:04 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param int $shopId
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeByShopId(Builder $query, int $shopId): Builder
|
||||
{
|
||||
return $query->where('shop_id', $shopId);
|
||||
}
|
||||
|
||||
}
|
||||
206
modules/Mall/Models/Traits/GoodsAttribute.php
Normal file
206
modules/Mall/Models/Traits/GoodsAttribute.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Modules\Mall\Models\Goods;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
trait GoodsAttribute
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 获取商品库存
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:17
|
||||
* @param int $user_id
|
||||
* @return int
|
||||
*/
|
||||
public function getGoodsStock(int $user_id = 0): int
|
||||
{
|
||||
if ($this->goods->type == Goods::TYPE_SINGLE) {
|
||||
|
||||
}
|
||||
return $this->stock ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 扣除库存方法
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:12
|
||||
* @param $stock
|
||||
* @param $user_id
|
||||
* @return bool
|
||||
*/
|
||||
public function deductStock($stock, $user_id): bool
|
||||
{
|
||||
$this->decrement('stock', $stock);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 增加库存方法
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:12
|
||||
* @param $stock
|
||||
*/
|
||||
public function addStock($stock)
|
||||
{
|
||||
$this->increment('stock', $stock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 增加销量
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:12
|
||||
* @param $sold
|
||||
*/
|
||||
public function addSold($sold)
|
||||
{
|
||||
$this->goods()->increment('sales', $sold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 减少销量
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:12
|
||||
* @param $sold
|
||||
*/
|
||||
public function deductSold($sold)
|
||||
{
|
||||
$this->goods()->decrement('sales', $sold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取卖家ID
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:14
|
||||
* @return int
|
||||
*/
|
||||
public function getShopIdAttribute(): int
|
||||
{
|
||||
return $this->goods->shop_id ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取卖家type
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:14
|
||||
* @return string|null
|
||||
*/
|
||||
public function getShopTypeAttribute(): ?string
|
||||
{
|
||||
if ($this->goods && $this->goods->shop) {
|
||||
return get_class($this->goods->shop);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取卖家名称
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:14
|
||||
* @return false|string|null
|
||||
*/
|
||||
public function getShopNameAttribute()
|
||||
{
|
||||
if ($this->goods && $this->goods->shop) {
|
||||
return $this->goods->shop->name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 重量
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:15
|
||||
* @return int
|
||||
*/
|
||||
public function getGoodsWeight(): int
|
||||
{
|
||||
return $this->weight ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 返回source
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:15
|
||||
* @return array
|
||||
*/
|
||||
public function getSource(): array
|
||||
{
|
||||
return [
|
||||
'goods_sku_id' => $this->id,
|
||||
'goods_id' => $this->goods_id,
|
||||
'deduct_stock_type' => $this->goods->deduct_stock_type,
|
||||
'goods_name' => $this->getGoodsName(),
|
||||
// 'unit' => $this->getItemValue(),
|
||||
'cover' => $this->goods->cover_url,
|
||||
'price' => $this->getItemPrice(),
|
||||
'stock' => $this->getGoodsStock(),
|
||||
'weight' => $this->weight,
|
||||
'is_post_sale' => $this->goods->is_post_sale ?? 0,
|
||||
'score' => $this->score, // 积分/原石
|
||||
'assets' => $this->assets, // 资产
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取商品名称
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:19
|
||||
* @return string
|
||||
*/
|
||||
public function getGoodsName(): string
|
||||
{
|
||||
return $this->goods->name ?? '--';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取商品规格名称
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:16
|
||||
* @return string
|
||||
*/
|
||||
public function getItemValue(): string
|
||||
{
|
||||
switch ($this->goods->type) {
|
||||
case Goods::TYPE_SINGLE:
|
||||
return '';
|
||||
case Goods::TYPE_MULTIPLE:
|
||||
return $this->unit ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取商品单价
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/14 11:16
|
||||
* @return mixed
|
||||
*/
|
||||
public function getItemPrice()
|
||||
{
|
||||
$tags = $this->goods->tags()->pluck('tag_id')->toArray();
|
||||
//1 为试用产品
|
||||
if (in_array(1, $tags)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->price;
|
||||
}
|
||||
|
||||
}
|
||||
69
modules/Mall/Models/Traits/HasRegion.php
Normal file
69
modules/Mall/Models/Traits/HasRegion.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Modules\Mall\Models\Region;
|
||||
|
||||
trait HasRegion
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 省份
|
||||
*
|
||||
* @Date : 2021/5/11 9:49 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function province(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Region::class, 'province_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 市
|
||||
*
|
||||
* @Date : 2021/5/11 9:50 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function city(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Region::class, 'city_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 区
|
||||
*
|
||||
* @Date : 2021/5/11 9:50 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function district(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Region::class, 'district_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取完整地址
|
||||
*
|
||||
* @Date : 2021/5/11 9:49 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param string $separators 地址的分隔符
|
||||
* @return string
|
||||
*/
|
||||
public function getFullAddress(string $separators = ' '): string
|
||||
{
|
||||
return
|
||||
$this->province->name.$separators.
|
||||
$this->city->name.$separators.
|
||||
$this->district->name.$separators.
|
||||
$this->address;
|
||||
}
|
||||
|
||||
public function getAllAddress()
|
||||
{
|
||||
return $this->name.' '.$this->mobile.' '.$this->getFullAddress();
|
||||
}
|
||||
|
||||
}
|
||||
185
modules/Mall/Models/Traits/OrderActions.php
Normal file
185
modules/Mall/Models/Traits/OrderActions.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use App\Notifications\SystemOrderDelivered;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Mall\Events\OrderCanceled;
|
||||
use Modules\Mall\Events\OrderCompleted;
|
||||
use Modules\Mall\Events\OrderDelivered;
|
||||
use Modules\Mall\Events\OrderPaid;
|
||||
use Modules\Mall\Events\OrderSigned;
|
||||
use Modules\Mall\Models\Order;
|
||||
|
||||
trait OrderActions
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 订单取消
|
||||
*
|
||||
* @Date : 2021/5/17 10:36 上午
|
||||
* @Author : < Jason.C >
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function cancel(): bool
|
||||
{
|
||||
if ($this->canCancel()) {
|
||||
// 修改状态机
|
||||
$this->apply('cancel');
|
||||
|
||||
event(new OrderCanceled($this));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可取消');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function pay(): bool
|
||||
{
|
||||
if ($this->can('pay')) {
|
||||
// 修改状态机
|
||||
$this->paid_at = Carbon::now();
|
||||
$this->apply('pay');
|
||||
|
||||
event(new OrderPaid($this));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可支付');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单发货
|
||||
*
|
||||
* @Date : 2021/5/14 16:45
|
||||
* @Author : Mr.wang
|
||||
* @param int $expressId 物流公司ID
|
||||
* @param string $expressNo 物流单号
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deliver($expressId, $expressNo, $type = 1, $person = ''): bool
|
||||
{
|
||||
if ($this->can('deliver')) {
|
||||
if ($this->refund_items_count == $this->items()->count()) {
|
||||
throw new \Exception('商品已全部退款/货不能发货');
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($expressId, $expressNo, $type, $person) {
|
||||
$this->express()->update([
|
||||
'express_id' => $expressId ?? null,
|
||||
'express_no' => $expressNo ?? null,
|
||||
'type' => $type,
|
||||
'person' => $person,
|
||||
'deliver_at' => now(),
|
||||
]);
|
||||
// 修改状态机
|
||||
$this->apply('deliver');
|
||||
|
||||
event(new OrderDelivered($this));
|
||||
|
||||
// if ($this->type == Order::TYPE_SAMPLE) {
|
||||
// $this->user->notify(new SystemOrderDelivered('发货提醒', $this));
|
||||
// }
|
||||
|
||||
});
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可发货');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单签收
|
||||
*
|
||||
* @Date : 2021/5/14 17:09
|
||||
* @Author : Mr.wang
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sign(): bool
|
||||
{
|
||||
if ($this->can('sign')) {
|
||||
DB::transaction(function () {
|
||||
$this->express()->update([
|
||||
'receive_at' => now(),
|
||||
]);
|
||||
// 修改状态机
|
||||
$this->apply('sign');
|
||||
});
|
||||
event(new OrderSigned($this));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可签收');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单完成
|
||||
*
|
||||
* @Date : 2021/5/21 2:57 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function complete(): bool
|
||||
{
|
||||
if ($this->can('complete')) {
|
||||
// 修改状态机
|
||||
$this->apply('complete');
|
||||
|
||||
event(new OrderCompleted($this));
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可完成');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 设置退款
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/6/9 9:53
|
||||
*/
|
||||
public function refund()
|
||||
{
|
||||
if ($this->can('refund')) {
|
||||
// 修改状态机
|
||||
$this->apply('refund');
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可设置退款');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 退款完成
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/6/9 12:00
|
||||
*/
|
||||
public function completed()
|
||||
{
|
||||
if ($this->can('completed')) {
|
||||
// 修改状态机
|
||||
$this->apply('completed');
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new \Exception('订单状态不可设置退款完成');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
82
modules/Mall/Models/Traits/OrderCando.php
Normal file
82
modules/Mall/Models/Traits/OrderCando.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Modules\Mall\Models\Order;
|
||||
|
||||
trait OrderCando
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 是否可支付
|
||||
*
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/20 3:39 下午
|
||||
* @return bool
|
||||
*/
|
||||
public function canPay(): bool
|
||||
{
|
||||
return $this->can('pay');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 是否可取消
|
||||
*
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2019/11/20 3:39 下午
|
||||
* @return bool
|
||||
*/
|
||||
public function canCancel(): bool
|
||||
{
|
||||
return in_array($this->state, [Order::STATUS_INIT,]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 可发货
|
||||
*
|
||||
* @Author:<C.Jason>
|
||||
* @Date :2018-10-22T17:12:13+0800
|
||||
* @return boolean
|
||||
*/
|
||||
public function canDeliver(): bool
|
||||
{
|
||||
return $this->can('deliver');
|
||||
}
|
||||
|
||||
/**
|
||||
* 可签收
|
||||
*
|
||||
* @Author:<C.Jason>
|
||||
* @Date :2018-10-22T17:12:43+0800
|
||||
* @return boolean
|
||||
*/
|
||||
public function canSign(): bool
|
||||
{
|
||||
return $this->can('sign');
|
||||
}
|
||||
|
||||
/**
|
||||
* 可完成订单
|
||||
*
|
||||
* @Author:<C.Jason>
|
||||
* @Date :2018-10-25T17:35:12+0800
|
||||
* @return boolean
|
||||
*/
|
||||
public function canComplete(): bool
|
||||
{
|
||||
return $this->can('complete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 可申请退款
|
||||
*
|
||||
* @Author:<C.Jason>
|
||||
* @Date :2018-10-22T17:11:45+0800
|
||||
* @return boolean
|
||||
*/
|
||||
public function canRefund(): bool
|
||||
{
|
||||
return $this->can('refund');
|
||||
}
|
||||
|
||||
}
|
||||
138
modules/Mall/Models/Traits/OrderScopes.php
Normal file
138
modules/Mall/Models/Traits/OrderScopes.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Modules\Mall\Models\Order;
|
||||
|
||||
trait OrderScopes
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 未支付
|
||||
*
|
||||
* @Date : 2021/5/17 10:59 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeUnPay(Builder $query): Builder
|
||||
{
|
||||
return $query->where('state', self::STATUS_INIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 已支付,待发货
|
||||
*
|
||||
* @Date : 2021/5/17 11:00 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopePaid(Builder $query): Builder
|
||||
{
|
||||
return $query->where('state', self::STATUS_PAID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 已发货,代签收
|
||||
*
|
||||
* @Date : 2021/5/17 11:03 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeDelivered(Builder $query): Builder
|
||||
{
|
||||
return $query->where('state', self::STATUS_DELIVERED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 已签收
|
||||
*
|
||||
* @Date : 2021/5/17 11:04 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeSigned(Builder $query): Builder
|
||||
{
|
||||
return $query->where('state', self::STATUS_SIGNED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 已完成的订单
|
||||
*
|
||||
* @Date : 2021/5/17 11:04 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeCompleted(Builder $query): Builder
|
||||
{
|
||||
return $query->where('state', self::STATUS_COMPLETED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 订单列表排除退款部分
|
||||
*
|
||||
* @Date : 2021/5/18 9:50
|
||||
* @Author : Mr.wang
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeCommon(Builder $query): Builder
|
||||
{
|
||||
return $query->whereIn('state', [
|
||||
self::STATUS_INIT,
|
||||
self::STATUS_CANCEL,
|
||||
self::STATUS_PAID,
|
||||
self::STATUS_DELIVERED,
|
||||
self::STATUS_SIGNED,
|
||||
self::STATUS_COMPLETED,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 签收和发货
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/30 8:33
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeDeliveredAndSigned(Builder $query): Builder
|
||||
{
|
||||
return $query->whereIn('state', [
|
||||
self::STATUS_DELIVERED,
|
||||
self::STATUS_SIGNED,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 积分兑换订单
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/19 14:40
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeTypeScore(Builder $query): Builder
|
||||
{
|
||||
return $query->where('type', Order::TYPE_SCORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 提货订单
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/19 14:40
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeTypeSample(Builder $query): Builder
|
||||
{
|
||||
return $query->where('type', Order::TYPE_SAMPLE);
|
||||
}
|
||||
|
||||
}
|
||||
318
modules/Mall/Models/Traits/RefundActions.php
Normal file
318
modules/Mall/Models/Traits/RefundActions.php
Normal file
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Encore\Admin\Facades\Admin;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Modules\Mall\Events\RefundAgreed;
|
||||
use Modules\Mall\Events\RefundCompleted;
|
||||
use Modules\Mall\Events\RefundRefused;
|
||||
use Modules\Payment\Models\Payment;
|
||||
|
||||
trait RefundActions
|
||||
{
|
||||
|
||||
public $operator;
|
||||
|
||||
/**
|
||||
* Notes: 设置操作人
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 16:12
|
||||
* @param $operator
|
||||
* @return $this
|
||||
*/
|
||||
public function setOperator($operator)
|
||||
{
|
||||
$this->operator = $operator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 设置备注
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 16:12
|
||||
* @param $remark
|
||||
* @return $this
|
||||
*/
|
||||
public function setRemark($remark)
|
||||
{
|
||||
$this->remark = $remark;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 同意退款
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 11:59
|
||||
* @param $remark
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function agree($remark = null): bool
|
||||
{
|
||||
if (! $this->can('agree')) {
|
||||
throw new Exception("退款单状态不可以同意退款");
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($remark) {
|
||||
$this->actual_total = $this->refund_total;
|
||||
$this->save();
|
||||
|
||||
$this->apply('agree');
|
||||
$this->setOrderApply($this->order, 'agree');
|
||||
|
||||
if ($this->order->express) {
|
||||
$this->express()->create();
|
||||
}
|
||||
|
||||
$this->setLogs($remark);
|
||||
|
||||
//订单已经进入发货流程,需要客户退货
|
||||
if ($this->order->express && $this->order->express->deliver_at) {
|
||||
$this->apply('deliver');
|
||||
$this->setOrderApply($this->order, 'user_deliver');
|
||||
} else {
|
||||
//未发货设置为退款中
|
||||
$this->apply('process');
|
||||
$this->setOrderApply($this->order, 'process');
|
||||
}
|
||||
|
||||
event(new RefundAgreed($this));
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 拒绝退款
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 12:01
|
||||
* @param string|null $remark
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function refuse(string $remark = null): bool
|
||||
{
|
||||
if (! $this->can('refuse')) {
|
||||
throw new Exception("退款单状态不可以拒绝退款");
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($remark) {
|
||||
|
||||
$this->apply('refuse');
|
||||
$this->setOrderApply($this->order, 'refuse');
|
||||
|
||||
$this->setLogs($remark);
|
||||
|
||||
event(new RefundRefused($this));
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 退货退款中
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 14:29
|
||||
* @param $company
|
||||
* @param string $number
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deliver($company, string $number): bool
|
||||
{
|
||||
if ($this->can('delivered')) {
|
||||
DB::transaction(function () use ($company, $number) {
|
||||
$this->express()->update([
|
||||
'company' => $company,
|
||||
'number' => $number,
|
||||
'deliver_at' => now(),
|
||||
]);
|
||||
|
||||
// 修改状态机
|
||||
$this->apply('delivered');
|
||||
$this->setOrderApply($this->order, 'user_deliverd');
|
||||
|
||||
$this->setLogs('客户退货');
|
||||
|
||||
});
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new Exception('订单状态不可发货');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 确认收货
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 14:30
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function receive(): bool
|
||||
{
|
||||
if (! $this->can('sign')) {
|
||||
throw new Exception('退款单状态不可以确认收货');
|
||||
}
|
||||
|
||||
$this->express->receive_at = now();
|
||||
$this->express->save();
|
||||
|
||||
$this->apply('sign');
|
||||
//设置为退款中
|
||||
$this->apply('process');
|
||||
$this->setOrderApply($this->order, 'process');
|
||||
|
||||
$this->setLogs('店家签收');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 标记退款完成
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 14:32
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function complete(): bool
|
||||
{
|
||||
if (! $this->can('completed')) {
|
||||
throw new Exception("订单状态不对,不可设置完成");
|
||||
}
|
||||
|
||||
DB::transaction(function () {
|
||||
$this->apply('completed');
|
||||
//设置时间
|
||||
$this->refunded_at = now();
|
||||
$this->save();
|
||||
|
||||
$this->setLogs('订单标记完成');
|
||||
|
||||
event(new RefundCompleted($this));
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 退款
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 14:52
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function returns(): bool
|
||||
{
|
||||
try {
|
||||
$payment = $this->order->payment;
|
||||
if (! $payment) {
|
||||
throw new Exception("退款失败,未找到支付信息");
|
||||
}
|
||||
//微信支付
|
||||
if ($payment->driver == Payment::DRIVER_WECHAT) {
|
||||
$order = [
|
||||
'out_trade_no' => $payment->trade_id,
|
||||
'out_refund_no' => $this->refund_no,
|
||||
'total_fee' => $payment->total * 100,
|
||||
'refund_fee' => $this->actual_total * 100,
|
||||
];
|
||||
$result = app('pay.wechat')->refund($order);
|
||||
|
||||
if ($result->result_code != 'SUCCESS') {
|
||||
throw new Exception("退款失败,".$result->return_msg);
|
||||
}
|
||||
|
||||
$this->setLogs('退款完成');
|
||||
|
||||
return true;
|
||||
} elseif ($payment->driver == Payment::DRIVER_ALIPAY) {//支付宝支付
|
||||
|
||||
$order = [
|
||||
'out_trade_no' => $this->order->order_no,
|
||||
'refund_amount' => $this->actual_total,
|
||||
];
|
||||
|
||||
$result = app('pay.alipay')->refund($order);
|
||||
|
||||
if ($result->code != '10000') {
|
||||
throw new Exception("退款失败,".$result->msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
} elseif ($payment->driver == Payment::DRIVER_SCORE) {//水滴支付
|
||||
|
||||
$this->user->account->rule('score_buy_refund', $this->actual_total, false, [
|
||||
'order_no' => $this->order->order_no,
|
||||
'refund_no' => $this->refund_no,
|
||||
]);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
throw new Exception("退款失败,未找到支付路径");
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
throw new Exception($exception->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 记录日志
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/5/17 16:03
|
||||
* @param null $remark
|
||||
* @param null $title
|
||||
* @param null $pictures
|
||||
*/
|
||||
public function setLogs($remark = null, $title = null, $pictures = null)
|
||||
{
|
||||
if (empty($this->operator)) {
|
||||
$this->operator = $this->user;
|
||||
}
|
||||
|
||||
if (empty($this->operator)) {
|
||||
$this->operator = Admin::user();
|
||||
}
|
||||
|
||||
$refund = $this->refresh();
|
||||
$logs = [
|
||||
'userable_type' => get_class($this->operator),
|
||||
'userable_id' => $this->operator->id,
|
||||
'remark' => $remark,
|
||||
'title' => $title,
|
||||
'pictures' => $pictures,
|
||||
'state' => $refund->state,
|
||||
];
|
||||
|
||||
$refund->logs()->create($logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 修改订单状态机
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/6/17 9:22
|
||||
*/
|
||||
public function setOrderApply($order, $status)
|
||||
{
|
||||
//如果都已经退款/货
|
||||
if ($order->refund_items_count == $order->items()->count()) {
|
||||
$order->apply($status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
94
modules/Mall/Models/Traits/ShopActions.php
Normal file
94
modules/Mall/Models/Traits/ShopActions.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models\Traits;
|
||||
|
||||
use Exception;
|
||||
use Modules\Mall\Models\Express;
|
||||
use Modules\Mall\Models\Reason;
|
||||
use Modules\Mall\Models\Shop;
|
||||
|
||||
trait ShopActions
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 关闭店铺
|
||||
* @Date : 2021/5/7 4:58 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function close(): bool
|
||||
{
|
||||
if ($this->status != Shop::STATUS_NORMAL) {
|
||||
throw new Exception('当前状态不可关闭');
|
||||
}
|
||||
|
||||
$this->status = Shop::STATUS_CLOSE;
|
||||
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 开启店铺
|
||||
* @Date : 2021/5/7 5:02 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function open(): bool
|
||||
{
|
||||
if ($this->status != Shop::STATUS_CLOSE) {
|
||||
throw new Exception('当前状态不可开启');
|
||||
}
|
||||
|
||||
$this->status = Shop::STATUS_NORMAL;
|
||||
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 通过申请
|
||||
* @Date : 2021/5/7 5:03 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function pass(): bool
|
||||
{
|
||||
if ($this->status != Shop::STATUS_APPLYING) {
|
||||
throw new Exception('当前状态不可审核' . $this->status);
|
||||
}
|
||||
|
||||
// 店铺审核通过后,增加物流的关联
|
||||
|
||||
$expressIds = Express::where('status', 1)->pluck('id');
|
||||
$this->expresses()->attach($expressIds);
|
||||
$reasonIds = Reason::where('status', 1)->pluck('id');
|
||||
$this->reasons()->attach($reasonIds);
|
||||
|
||||
$this->status = Shop::STATUS_CLOSE;
|
||||
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 驳回申请
|
||||
* @Date : 2021/5/7 5:03 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param string $reason
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function reject(string $reason): bool
|
||||
{
|
||||
if ($this->status != Shop::STATUS_APPLYING) {
|
||||
throw new Exception('当前状态不可驳回');
|
||||
}
|
||||
|
||||
$this->status = Shop::STATUS_REJECT;
|
||||
$this->reject_reason = $reason;
|
||||
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
}
|
||||
22
modules/Mall/Models/Video.php
Normal file
22
modules/Mall/Models/Video.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Mall\Models;
|
||||
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Traits\HasCovers;
|
||||
use App\Traits\HasStatus;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
|
||||
class Video extends Model
|
||||
{
|
||||
use HasStatus, HasCovers, Cachable;
|
||||
|
||||
protected $table = 'mall_videos';
|
||||
|
||||
public function getPathUrlAttribute(): string
|
||||
{
|
||||
return $this->parseImageUrl($this->path);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user