2023-05-10 13:38:51 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Author: CRMEB Team <admin@crmeb.com>
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace app\common\model\system\merchant;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use app\common\dao\store\product\ProductDao;
|
|
|
|
|
use app\common\model\BaseModel;
|
|
|
|
|
use app\common\model\store\coupon\StoreCouponProduct;
|
|
|
|
|
use app\common\model\store\coupon\StoreCouponUser;
|
|
|
|
|
use app\common\model\store\product\Product;
|
|
|
|
|
use app\common\model\store\product\Spu;
|
|
|
|
|
use app\common\model\system\config\SystemConfigValue;
|
|
|
|
|
use app\common\model\system\financial\Financial;
|
2023-11-10 10:09:46 +08:00
|
|
|
|
use app\common\model\system\GeoStreet;
|
2023-05-10 13:38:51 +08:00
|
|
|
|
use app\common\model\system\serve\ServeOrder;
|
2024-02-27 18:05:17 +08:00
|
|
|
|
use app\common\model\user\User;
|
2023-05-10 13:38:51 +08:00
|
|
|
|
use app\common\repositories\store\StoreActivityRepository;
|
2023-11-10 10:09:46 +08:00
|
|
|
|
use think\facade\Db;
|
2023-05-10 13:38:51 +08:00
|
|
|
|
|
|
|
|
|
class Merchant extends BaseModel
|
|
|
|
|
{
|
|
|
|
|
|
2023-05-23 14:59:47 +08:00
|
|
|
|
const TypeStore = 10; //镇街店铺
|
2023-06-07 10:49:53 +08:00
|
|
|
|
const TypeCloudWarehouse = 11; //镇级云仓
|
2023-05-23 14:59:47 +08:00
|
|
|
|
const TypeSupplyChain = 12; //市级供应链
|
2023-09-04 11:55:08 +08:00
|
|
|
|
const TypePlatform = 13; //市级里海云
|
2023-05-25 16:35:16 +08:00
|
|
|
|
const TypeTeamServer = 14; //小组服务团
|
|
|
|
|
const TypeVillageServer = 15; //村服务团队
|
|
|
|
|
const TypeTownServer = 16; //镇服务团队
|
2023-08-25 09:45:25 +08:00
|
|
|
|
const TypeTownSupplyChain = 17; //镇级供应链
|
2023-05-25 16:35:16 +08:00
|
|
|
|
|
2023-09-04 10:54:16 +08:00
|
|
|
|
//定义店铺类型code
|
|
|
|
|
const TypeCode = [
|
2023-09-04 12:03:39 +08:00
|
|
|
|
'TypeStore' => 'TypeStore', //镇街店铺
|
|
|
|
|
'TypeCloudWarehouse' => 'TypeCloudWarehouse', //镇级云仓
|
|
|
|
|
'TypeSupplyChain' => 'TypeSupplyChain', //市级供应链
|
|
|
|
|
'TypePlatform' => 'TypePlatform', //市级里海云
|
|
|
|
|
'TypeTeamServer' => 'TypeTeamServer', //小组服务团
|
|
|
|
|
'TypeVillageServer' => 'TypeVillageServer', //村服务团队
|
|
|
|
|
'TypeTownServer' => 'TypeTownServer', //镇服务团队
|
|
|
|
|
'TypeTownSupplyChain' => 'TypeTownSupplyChain', //镇级供应链
|
|
|
|
|
'TypeFamousSpecialties' => 'TypeFamousSpecialties', //名优特产
|
|
|
|
|
'TypeLocalCuisine' => 'TypeLocalCuisine', //当地美食
|
|
|
|
|
'TypeFeaturedCultural' => 'TypeFeaturedCultural', //特色文旅
|
2023-09-04 10:54:16 +08:00
|
|
|
|
];
|
|
|
|
|
|
2023-05-25 16:35:16 +08:00
|
|
|
|
const TypeMap = [
|
|
|
|
|
self::TypeStore => '镇街店铺',
|
|
|
|
|
self::TypeCloudWarehouse => '里海云仓',
|
|
|
|
|
self::TypeSupplyChain => '市级供应链',
|
|
|
|
|
self::TypePlatform => '供销平台',
|
|
|
|
|
self::TypeTeamServer => '小组服务团',
|
|
|
|
|
self::TypeVillageServer => '村服务团队',
|
|
|
|
|
self::TypeTownServer => '镇服务团队',
|
2023-08-25 09:45:25 +08:00
|
|
|
|
self::TypeTownSupplyChain => '镇级供应链',
|
2023-05-25 16:35:16 +08:00
|
|
|
|
];
|
2023-06-07 14:42:50 +08:00
|
|
|
|
const AllowApply = [ //允许申请的类型
|
|
|
|
|
self::TypeStore,
|
|
|
|
|
self::TypeSupplyChain,
|
2023-08-25 09:45:25 +08:00
|
|
|
|
self::TypeTownSupplyChain,
|
2023-06-07 14:42:50 +08:00
|
|
|
|
];
|
|
|
|
|
const AllowDisplay = [ //允许展示的类型
|
|
|
|
|
self::TypeStore,
|
|
|
|
|
self::TypeCloudWarehouse,
|
|
|
|
|
self::TypeSupplyChain,
|
|
|
|
|
self::TypePlatform,
|
2023-08-25 09:49:45 +08:00
|
|
|
|
self::TypeTownSupplyChain,
|
2023-06-07 14:42:50 +08:00
|
|
|
|
];
|
2023-05-23 14:59:47 +08:00
|
|
|
|
|
2023-05-10 13:38:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
* @author xaboy
|
|
|
|
|
* @day 2020-03-30
|
|
|
|
|
*/
|
|
|
|
|
public static function tablePk(): string
|
|
|
|
|
{
|
|
|
|
|
return 'mer_id';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
* @author xaboy
|
|
|
|
|
* @day 2020-03-30
|
|
|
|
|
*/
|
|
|
|
|
public static function tableName(): string
|
|
|
|
|
{
|
|
|
|
|
return 'merchant';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getDeliveryWayAttr($value)
|
|
|
|
|
{
|
|
|
|
|
if (!$value) return [];
|
|
|
|
|
return explode(',',$value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function product()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(Product::class, 'mer_id', 'mer_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function config()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(SystemConfigValue::class, 'mer_id', 'mer_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function showProduct()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(Product::class, 'mer_id', 'mer_id')
|
|
|
|
|
->where((new ProductDao())->productShow())
|
|
|
|
|
->field('mer_id,product_id,store_name,image,price,is_show,status,is_gift_bag,is_good')
|
|
|
|
|
->order('is_good DESC,sort DESC');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TODO 商户列表下的推荐
|
|
|
|
|
* @return \think\Collection
|
|
|
|
|
* @author Qinii
|
|
|
|
|
* @day 4/20/22
|
|
|
|
|
*/
|
|
|
|
|
public function getAllRecommendAttr()
|
|
|
|
|
{
|
|
|
|
|
$list = Product::where('mer_id', $this['mer_id'])
|
|
|
|
|
->where((new ProductDao())->productShow())
|
2023-05-10 18:09:55 +08:00
|
|
|
|
->field('mer_id,product_id,product_type,store_name,image,price,is_show,status,is_gift_bag,is_good,cate_id')
|
2023-05-10 13:38:51 +08:00
|
|
|
|
->order('sort DESC, create_time DESC')
|
|
|
|
|
->limit(10)
|
|
|
|
|
->select()->append(['show_svip_info']);
|
|
|
|
|
if ($list) {
|
|
|
|
|
$data = [];
|
|
|
|
|
$make = app()->make(StoreActivityRepository::class);
|
|
|
|
|
foreach ($list as $item) {
|
2023-05-10 18:09:55 +08:00
|
|
|
|
$spu_id = Spu::where('product_id',$item->product_id)->where('product_type' ,$item->product_type)->value('spu_id');
|
|
|
|
|
$act = $make->getActivityBySpu(StoreActivityRepository::ACTIVITY_TYPE_BORDER,$spu_id,$item['cate_id'],$item['mer_id']);
|
|
|
|
|
$item['border_pic'] = $act['pic'] ?? '';
|
|
|
|
|
$data[] = $item;
|
|
|
|
|
}
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getAllRecommendTypeAttr()
|
|
|
|
|
{
|
|
|
|
|
$list = Product::where('mer_id', $this['mer_id'])
|
|
|
|
|
->where((new ProductDao())->productTypeShow(98))
|
2023-05-29 14:09:07 +08:00
|
|
|
|
->where('is_show', Product::IS_SHOW)
|
2023-05-10 18:09:55 +08:00
|
|
|
|
->field('mer_id,product_id,product_type,store_name,image,price,is_show,status,is_gift_bag,is_good,cate_id')
|
|
|
|
|
->order('sort DESC, create_time DESC')
|
|
|
|
|
->limit(10)
|
|
|
|
|
->select()->append(['show_svip_info']);
|
|
|
|
|
if ($list) {
|
|
|
|
|
$data = [];
|
|
|
|
|
$make = app()->make(StoreActivityRepository::class);
|
|
|
|
|
foreach ($list as $item) {
|
|
|
|
|
$spu_id = Spu::where('product_id',$item->product_id)->where('product_type' ,$item->product_type)->value('spu_id');
|
2023-05-10 13:38:51 +08:00
|
|
|
|
$act = $make->getActivityBySpu(StoreActivityRepository::ACTIVITY_TYPE_BORDER,$spu_id,$item['cate_id'],$item['mer_id']);
|
|
|
|
|
$item['border_pic'] = $act['pic'] ?? '';
|
|
|
|
|
$data[] = $item;
|
|
|
|
|
}
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getCityRecommendAttr()
|
|
|
|
|
{
|
|
|
|
|
$list = Product::where('mer_id', $this['mer_id'])
|
|
|
|
|
->where((new ProductDao())->productShow())
|
|
|
|
|
->whereLike('delivery_way',"%1%")
|
|
|
|
|
->field('mer_id,product_id,store_name,image,price,is_show,status,is_gift_bag,is_good,cate_id')
|
|
|
|
|
->order('sort DESC, create_time DESC')
|
|
|
|
|
->limit(10)
|
|
|
|
|
->select();
|
|
|
|
|
if ($list) {
|
|
|
|
|
$data = [];
|
|
|
|
|
$make = app()->make(StoreActivityRepository::class);
|
|
|
|
|
foreach ($list as $item) {
|
|
|
|
|
$spu_id = Spu::where('product_id',$item->product_id)->where('product_type' ,0)->value('spu_id');
|
|
|
|
|
$act = $make->getActivityBySpu(StoreActivityRepository::ACTIVITY_TYPE_BORDER,$spu_id,$item['cate_id'],$item['mer_id']);
|
|
|
|
|
$item['border_pic'] = $act['pic'] ?? '';
|
|
|
|
|
$data[] = $item;
|
|
|
|
|
}
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function recommend()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(Product::class, 'mer_id', 'mer_id')
|
|
|
|
|
->where((new ProductDao())->productShow())
|
|
|
|
|
->where('is_good', 1)
|
|
|
|
|
->field('mer_id,product_id,store_name,image,price,is_show,status,is_gift_bag,is_good,sales,create_time')
|
|
|
|
|
->order('is_good DESC,sort DESC,create_time DESC')
|
|
|
|
|
->limit(3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function coupon()
|
|
|
|
|
{
|
|
|
|
|
$time = date('Y-m-d H:i:s');
|
|
|
|
|
return $this->hasMany(StoreCouponUser::class, 'mer_id', 'mer_id')->where('start_time', '<', $time)->where('end_time', '>', $time)
|
|
|
|
|
->where('is_fail', 0)->where('status', 0)->order('coupon_price DESC, coupon_user_id ASC')
|
|
|
|
|
->with(['product' => function ($query) {
|
|
|
|
|
$query->field('coupon_id,product_id');
|
|
|
|
|
}, 'coupon' => function ($query) {
|
|
|
|
|
$query->field('coupon_id,type');
|
|
|
|
|
}]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getServicesTypeAttr()
|
|
|
|
|
{
|
|
|
|
|
return merchantConfig($this->mer_id,'services_type');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function marginOrder()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(ServeOrder::class, 'mer_id','mer_id')->where('type', 10)->order('create_time DESC');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function refundMarginOrder()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(Financial::class, 'mer_id', 'mer_id')
|
|
|
|
|
->where('type',1)
|
|
|
|
|
->where('status', -1)
|
|
|
|
|
->order('create_time DESC')
|
|
|
|
|
->limit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function merchantCategory()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(MerchantCategory::class, 'merchant_category_id', 'category_id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function merchantType()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(MerchantType::class, 'mer_type_id', 'type_id');
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-03 16:10:14 +08:00
|
|
|
|
public function typeNames()
|
2023-05-10 13:38:51 +08:00
|
|
|
|
{
|
|
|
|
|
return $this->merchantType()->bind(['type_name']);
|
|
|
|
|
}
|
2023-11-10 10:09:46 +08:00
|
|
|
|
public function streetNames()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(GeoStreet::class, 'street_code', 'street_id')->bind(['street_name']);
|
|
|
|
|
}
|
2023-05-10 13:38:51 +08:00
|
|
|
|
public function getMerCommissionRateAttr()
|
|
|
|
|
{
|
|
|
|
|
return $this->commission_rate > 0 ? $this->commission_rate : bcmul($this->merchantCategory->commission_rate, 100, 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getOpenReceiptAttr()
|
|
|
|
|
{
|
|
|
|
|
return merchantConfig($this->mer_id, 'mer_open_receipt');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function admin()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(MerchantAdmin::class, 'mer_id', 'mer_id')->where('level', 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function searchKeywordAttr($query, $value)
|
|
|
|
|
{
|
|
|
|
|
$query->whereLike('mer_name|mer_keyword', "%{$value}%");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getFinancialAlipayAttr($value)
|
|
|
|
|
{
|
|
|
|
|
return $value ? json_decode($value) : $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getFinancialWechatAttr($value)
|
|
|
|
|
{
|
|
|
|
|
return $value ? json_decode($value) : $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getFinancialBankAttr($value)
|
|
|
|
|
{
|
|
|
|
|
return $value ? json_decode($value) : $value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getMerCertificateAttr()
|
|
|
|
|
{
|
|
|
|
|
return merchantConfig($this->mer_id, 'mer_certificate');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getIssetCertificateAttr()
|
|
|
|
|
{
|
2023-05-16 11:31:28 +08:00
|
|
|
|
$merchantCertificate = merchantConfig($this->mer_id, 'mer_certificate');
|
|
|
|
|
if (!is_array($merchantCertificate)) {
|
|
|
|
|
$merchantCertificate = empty($merchantCertificate) ? [] : explode(',', $merchantCertificate);
|
|
|
|
|
}
|
|
|
|
|
return count($merchantCertificate) > 0;
|
2023-05-10 13:38:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function searchMerIdsAttr($query, $value)
|
|
|
|
|
{
|
|
|
|
|
$query->whereIn('mer_id',$value);
|
|
|
|
|
}
|
2024-01-24 10:14:09 +08:00
|
|
|
|
|
|
|
|
|
public function street()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasOne(GeoStreet::class, 'street_code', 'street_id');
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-27 18:05:17 +08:00
|
|
|
|
public function promoter()
|
|
|
|
|
{
|
|
|
|
|
return User::where('uid', $this->uid)->value('spread_uid');
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-10 13:38:51 +08:00
|
|
|
|
}
|