This commit is contained in:
yaooo 2023-11-07 17:30:01 +08:00
commit c350d30893
3568 changed files with 216775 additions and 133245 deletions

View File

@ -29,6 +29,7 @@ class StoreCartDao extends BaseDao
const SOURCE_STORE_CLOUD = 101; //店铺内云商品
const SOURCE_CLOUD = 102; //云仓内店铺商品
const CITY_CLOUD = 103; //市级云仓商品
const SOURCE_COMMUNITY_RESALE = 201; //转售商品
const SOURCE_COMMUNITY_ENTRUST = 202; //委托商品
@ -78,7 +79,7 @@ class StoreCartDao extends BaseDao
$query->field('product_id,stock,price,unique,sku,image,svip_price');
},
'merchant' => function ($query) {
$query->field('mer_id,mer_name,mer_state,mer_avatar,is_trader,type_id,credit_buy')->with(['type_name']);
$query->field('mer_id,mer_name,mer_state,mer_avatar,is_trader,type_id,credit_buy')->with(['type_names']);
}
])->select();

View File

@ -1,160 +0,0 @@
<?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\dao\store\order;
use app\common\dao\BaseDao;
use app\common\model\BaseModel;
use app\common\model\store\order\StoreCart;
use app\common\model\user\UserAddress;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\model\Relation;
class StoreCartDao extends BaseDao
{
protected function getModel(): string
{
return StoreCart::class;
}
public function test()
{
return StoreCart::getDB()->with(['product' => function (Relation $query) {
$query->where('store_name', '儿童节礼物');
}])->select();
}
/**
* @param array $ids
* @param $uid
* @param int|null $merId
* @return array
* @author xaboy
* @day 2020/6/5
*/
public function validIntersection(array $ids, $uid, int $merId = null): array
{
return StoreCart::getDB()->whereIn('cart_id', $ids)
->when($merId, function ($query, $merId) {
$query->where('mer_id', $merId);
})
->where('is_del', 0)->where('is_fail', 0)->where('is_pay', 0)->where('uid', $uid)->column('cart_id');
}
/**
* @Author:Qinii
* @Date: 2020/6/1
* @param int $uid
* @return mixed
*/
public function getAll(int $uid)
{
$query = ($this->getModel())::where(['uid' => $uid, 'is_del' => 0, 'is_new' => 0, 'is_pay' => 0])
->with([
'product' => function ($query) {
$query->field('product_id,image,store_name,is_show,status,is_del,unit_name,price,mer_status,is_used,product_type,once_max_count,once_min_count,pay_limit,mer_svip_status,svip_price_type');
},
'productAttr' => function ($query) {
$query->field('product_id,stock,price,unique,sku,image,svip_price');
},
'merchant' => function ($query) {
$query->field('mer_id,mer_name,mer_state,mer_avatar,is_trader,type_id')->with(['type_name']);
}
])->select();
return $query;
}
public function cartIbByData(array $ids, int $uid, ?UserAddress $address)
{
return StoreCart::getDb()->where('uid', $uid)->with([
'product' => function (Relation $query) use ($address) {
$query->field('product_id,cate_id,image,store_name,is_show,status,is_del,unit_name,price,mer_status,temp_id,give_coupon_ids,is_gift_bag,is_used,product_type,old_product_id,integral_rate,delivery_way,delivery_free,type,extend,pay_limit,once_max_count,once_min_count,mer_svip_status,svip_price_type');
if ($address) {
$cityIds = array_filter([$address->province_id, $address->city_id, $address->district_id, $address->street_id]);
$query->with(['temp' => ['region' => function (Relation $query) use ($cityIds) {
$query->where(function ($query) use ($cityIds) {
foreach ($cityIds as $v) {
$query->whereOr('city_id', 'like', "%/{$v}/%");
}
$query->whereOr('city_id', '0');
})->order('shipping_template_region_id DESC')->withLimit(1);
}, 'undelives' => function ($query) use ($cityIds) {
foreach ($cityIds as $v) {
$query->whereOr('city_id', 'like', "%/{$v}/%");
}
}, 'free' => function (Relation $query) use ($cityIds) {
foreach ($cityIds as $v) {
$query->whereOr('city_id', 'like', "%/{$v}/%");
}
$query->order('shipping_template_free_id DESC')->withLimit(1);
}]]);
}
},
'productAttr' => function (Relation $query) {
$query->field('image,extension_one,extension_two,product_id,stock,price,unique,sku,volume,weight,ot_price,cost,svip_price')
->append(['bc_extension_one', 'bc_extension_two']);
},
'merchant' => function (Relation $query) use ($uid) {
$query->field('mer_id,mer_name,mer_state,mer_avatar,delivery_way,commission_rate,category_id')->with(['coupon' => function ($query) use ($uid) {
$query->where('uid', $uid);
},
'config' => function ($query) {
$query->whereIn('config_key', ['mer_integral_status', 'mer_integral_rate', 'mer_store_stock', 'mer_take_status', 'mer_take_name', 'mer_take_phone', 'mer_take_address', 'mer_take_location', 'mer_take_day', 'mer_take_time']);
},
'merchantCategory'
]);
}])->whereIn('cart_id', $ids)->order('product_type DESC,cart_id DESC')->select();
}
/**
* @param array $cartIds
* @param int $uid
* @author Qinii
*/
public function batchDelete(array $cartIds, int $uid)
{
return ($this->getModel()::getDB())->where('uid', $uid)->whereIn('cart_id', $cartIds)->delete();
}
/**
* @param int $uid
* @return mixed
* @author Qinii
*/
public function getCartCount(int $uid)
{
$data = ($this->getModel()::getDB())->where(['uid' => $uid, 'is_del' => 0, 'is_new' => 0, 'is_pay' => 0])->field('SUM(cart_num) as count')->select();
$data[0]['count'] = $data[0]['count'] ? $data[0]['count'] : 0;
return $data;
}
/**
* @param $source
* @param array|null $ids
* @author xaboy
* @day 2020/8/31
*/
public function getSourcePayInfo($source, ?array $ids = null)
{
return StoreCart::getDB()->alias('A')->where('A.source', $source)->where('A.is_pay', 1)->when($ids, function ($query, $ids) {
$query->whereIn('A.source_id', $ids);
})->leftJoin('StoreOrderProduct B', 'A.cart_id = B.cart_id')
->field('sum(B.product_num) as pay_num,sum(B.product_price) as pay_price,A.source_id')->group('A.source_id')->select();
}
}

View File

@ -139,7 +139,11 @@ class StoreOrderDao extends BaseDao
$query->whereIn('order_id', $where['order_ids']);
})
->when(isset($where['order_id']) && $where['order_id'] !== '', function ($query) use ($where) {
if(is_array($where['order_id'])){
$query->whereIn('order_id',$where['order_id']);
}else{
$query->where('order_id', $where['order_id']);
}
})
->when(isset($where['take_order']) && $where['take_order'] != '', function ($query) use ($where) {
$query->where('order_type', 1)->whereNotNull('verify_time');

View File

@ -246,7 +246,7 @@ class Merchant extends BaseModel
return $this->hasOne(MerchantType::class, 'mer_type_id', 'type_id');
}
public function typeName()
public function typeNames()
{
return $this->merchantType()->bind(['type_name']);
}

View File

@ -1,234 +0,0 @@
<?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;
use app\common\model\system\serve\ServeOrder;
use app\common\repositories\store\StoreActivityRepository;
class Merchant extends BaseModel
{
/**
* @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())
->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(3)
->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' ,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 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(3)
->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');
}
public function typeName()
{
return $this->merchantType()->bind(['type_name']);
}
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()
{
return count(merchantConfig($this->mer_id, 'mer_certificate') ?: []) > 0;
}
public function searchMerIdsAttr($query, $value)
{
$query->whereIn('mer_id',$value);
}
}

View File

@ -63,6 +63,7 @@ class StoreOrderCreateRepository extends StoreOrderRepository
$svip_integral_rate = $svip_status ? app()->make(MemberinterestsRepository::class)->getSvipInterestVal(MemberinterestsRepository::HAS_TYPE_PAY) : 0;
//订单活动类型
$order_type = 0;
$source = 2;
//虚拟订单
$order_model = 0;
//虚拟订单自定义数据
@ -84,7 +85,10 @@ class StoreOrderCreateRepository extends StoreOrderRepository
throw new ValidateException('[超出限购总数:'. $cart['product']['once_max_count'].']'.mb_substr($cart['product']['store_name'],0,10).'...');
}
}
if ($cart['product_type'] > 0) $order_type = $cart['product_type'];
if ($cart['product_type'] > 0){
$order_type = $cart['product_type'];
$source = $cart['source'];
}
if ($cart['product_type']<=97 &&$cart['product_type'] > 0 && (($cart['product_type'] != 10 && count($merchantCart['list']) != 1) || count($merchantCartList) != 1)) {
throw new ValidateException('活动商品必须单独购买');
}
@ -900,7 +904,6 @@ class StoreOrderCreateRepository extends StoreOrderRepository
$order_total_price = bcadd($order_total_price, $merchantCart['order']['svip_discount'], 2);
}
unset($merchantCart);
$status = ($address || $order_model || $allow_no_address) ? ($noDeliver ? 'noDeliver' : 'finish') : 'noAddress';
$order = $merchantCartList;
$total_price = $order_total_price;
@ -908,6 +911,7 @@ class StoreOrderCreateRepository extends StoreOrderRepository
$total_coupon = bcadd($order_svip_discount, bcadd(bcadd($total_platform_coupon_price, $order_coupon_price, 2), $order_total_integral_price, 2), 2);
return compact(
'order_type',
'source',
'order_model',
'order_extend',
'order_total_postage',
@ -1105,6 +1109,7 @@ class StoreOrderCreateRepository extends StoreOrderRepository
$_order = [
'cartInfo' => $merchantCart,
'activity_type' => $orderInfo['order_type'],
'source' => $orderInfo['source']??2,
'commission_rate' => (float)$rate,
'order_type' => $merchantCart['order']['isTake'] ? 1 : 0,
'is_virtual' => $order_model ? 1 : 0,
@ -1309,7 +1314,6 @@ class StoreOrderCreateRepository extends StoreOrderRepository
];
foreach ($cartInfo['list'] as $cart) {
$productPrice = $cart['true_price'];
$extension_one = $cart['extension_one'];
$extension_two = $cart['extension_two'];

View File

@ -11,6 +11,7 @@
// +----------------------------------------------------------------------
namespace app\common\repositories\store\order;
use app\common\dao\store\order\StoreCartDao;
use app\common\dao\store\order\StoreOrderDao;
use app\common\model\store\order\StoreGroupOrder;
use app\common\model\store\order\StoreOrder;
@ -477,7 +478,8 @@ class StoreOrderRepository extends BaseRepository
Queue::push(UserBrokerageLevelJob::class, ['uid' => $groupOrder->uid, 'type' => 'pay_money', 'inc' => $groupOrder->pay_price]);
Queue::push(UserBrokerageLevelJob::class, ['uid' => $groupOrder->uid, 'type' => 'pay_num', 'inc' => 1]);
app()->make(UserBrokerageRepository::class)->incMemberValue($groupOrder->uid, 'member_pay_num', $groupOrder->group_order_id);
// event('order.paySuccess', compact('groupOrder'));
$groupOrder=$groupOrder->toArray();
event('order.paySuccess', compact('groupOrder'));
//店内扫码支付
if (isset($groupOrder['micro_pay']) && $groupOrder['micro_pay'] == 1) {
$order = $this->dao->search(['uid' => $groupOrder->uid])->where('group_order_id', $groupOrder->group_order_id)->find();
@ -1767,7 +1769,7 @@ class StoreOrderRepository extends BaseRepository
$query = $this->dao->search($where)->where($this->getOrderType($status))->whereRaw("(StoreOrder.paid=0 and StoreOrder.pay_type!=8) or (StoreOrder.paid=1 and StoreOrder.pay_type=8 and StoreOrder.status=2)")->where('StoreOrder.is_del', 0);
} else {
$arr=$this->getOrderType($status);
$query = $this->dao->search($where)->where($arr);
$query = $this->dao->search($where)->where($arr)->where('StoreOrder.is_del', 0);
}
$count = $query->count();

View File

@ -230,7 +230,6 @@ class ProductReplyRepository extends BaseRepository
public function reply(array $data)
{
halt(1);
$storeOrderProductRepository = app()->make(StoreOrderProductRepository::class);
$orderProduct = $storeOrderProductRepository->userOrderProduct($data['order_product_id'], $data['uid']);
if (!$orderProduct || !$orderProduct->orderInfo)

View File

@ -312,7 +312,7 @@ class ProductRepository extends BaseRepository
}
$res = $this->dao->get($id);
$data['svip_price_type'] = $res['svip_price_type'];
$settleParams = $this->setAttrValue($data, $id, 0, 1);
$settleParams = $this->setAttrValue($data, $id, 0, 1,$merId);
$settleParams['cate'] = $this->setMerCate($data['mer_cate_id'], $id, $merId);
$settleParams['attr'] = $this->setAttr($data['attr'], $id);
$data['price'] = $settleParams['data']['price'];
@ -487,6 +487,7 @@ class ProductRepository extends BaseRepository
'pay_limit' => $data['pay_limit'] ?? 0,
'svip_price_type' => $data['svip_price_type'] ?? 0,
'source_product_id' => $data['source_product_id'] ?? 0,
'source_library_id' => $data['source_library_id'] ?? 0,
];
$result['bar_code'] = $data['attrValue'][0]['bar_code'] ?? '';
if (isset($data['mer_id']))
@ -1173,7 +1174,7 @@ class ProductRepository extends BaseRepository
'attrValue',
'oldAttrValue',
'merchant' => function ($query) {
$query->with(['type_name'])->append(['isset_certificate','services_type']);
$query->with(['type_names'])->append(['isset_certificate','services_type']);
},
'seckillActive' => function ($query) {
$query->field('start_day,end_day,start_time,end_time,product_id');
@ -1690,6 +1691,8 @@ class ProductRepository extends BaseRepository
], $product['mer_id']);
app()->make(SpuRepository::class)->changeStatus($id,$product->product_type);
event('product.sell', ['product_id' => [$id]]);
$this->switchShow($id,$status,'is_used',0);
}
/**
@ -1715,6 +1718,10 @@ class ProductRepository extends BaseRepository
'id' => $product['product_id']
]
], $product['mer_id']);
if($data['status']==1){
$this->switchShow($id,1,'is_used',0);
}
}
$this->dao->updates($id, $data);
Queue(ChangeSpuStatusJob::class, ['id' => $id, 'product_type' => $product_type]);

View File

@ -34,7 +34,7 @@ use think\facade\Queue;
class SpuRepository extends BaseRepository
{
public $dao;
public $merchantFiled = 'mer_id,mer_name,mer_avatar,is_trader,mer_info,mer_keyword,type_id';
public $merchantFiled = 'mer_id,mer_name,mer_avatar,is_trader,mer_info,mer_keyword,type_id,long,lat';
public $productFiled = 'P.bar_code,S.product_id,S.store_name,S.image,activity_id,S.keyword,S.price,S.mer_id,spu_id,S.status,store_info,brand_id,cate_id,unit_name,S.star,S.rank,S.sort,sales,S.product_type,rate,reply_count,extension_type,S.sys_labels,S.mer_labels,P.delivery_way,P.delivery_free,P.ot_price,svip_price_type,stock,mer_svip_status';
public $userInfo;
@ -147,7 +147,7 @@ class SpuRepository extends BaseRepository
$query->with([
'merchant' => function ($query) {
$query->field($this->merchantFiled)->with(['type_name']);
$query->field($this->merchantFiled)->with(['type_names']);
},
'issetCoupon',
'product.attrValue',
@ -209,7 +209,7 @@ class SpuRepository extends BaseRepository
$count = $query->fetchSql(false)->count();
$query->with([
'merchant' => function ($query) {
$query->field($this->merchantFiled)->with(['type_name']);
$query->field($this->merchantFiled)->with(['type_names']);
},
'issetCoupon'
]);

View File

@ -1,531 +0,0 @@
<?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\repositories\store\product;
use app\common\repositories\store\coupon\StoreCouponProductRepository;
use app\common\repositories\store\coupon\StoreCouponRepository;
use app\common\repositories\store\StoreActivityRepository;
use app\common\repositories\user\UserRepository;
use crmeb\jobs\SendSmsJob;
use crmeb\jobs\SyncProductTopJob;
use crmeb\services\CopyCommand;
use crmeb\services\RedisCacheService;
use think\exception\ValidateException;
use think\facade\Log;
use app\common\repositories\BaseRepository;
use app\common\dao\store\product\SpuDao;
use app\common\repositories\store\StoreCategoryRepository;
use app\common\repositories\store\StoreSeckillActiveRepository;
use app\common\repositories\user\UserVisitRepository;
use think\facade\Queue;
class SpuRepository extends BaseRepository
{
public $dao;
public $merchantFiled = 'mer_id,mer_name,mer_avatar,is_trader,mer_info,mer_keyword,type_id';
public $productFiled = 'S.product_id,S.store_name,S.image,activity_id,S.keyword,S.price,S.mer_id,spu_id,S.status,store_info,brand_id,cate_id,unit_name,S.star,S.rank,S.sort,sales,S.product_type,rate,reply_count,extension_type,S.sys_labels,S.mer_labels,P.delivery_way,P.delivery_free,P.ot_price,svip_price_type,stock,mer_svip_status';
public function __construct(SpuDao $dao)
{
$this->dao = $dao;
}
public function create(array $param, int $productId, int $activityId, $productType = 0)
{
$data = $this->setparam($param, $productId, $activityId, $productType);
return $this->dao->create($data);
}
public function baseUpdate(array $param, int $productId, int $activityId, $productType = 0)
{
if ($productType == 1) {
$make = app()->make(StoreSeckillActiveRepository::class);
$activityId = $make->getSearch(['product_id' => $productId])->value('seckill_active_id');
}
$where = [
'product_id' => $productId,
'activity_id' => $activityId,
'product_type' => $productType,
];
$ret = $this->dao->getSearch($where)->find();
if (!$ret) {
return $this->create($param, $productId, $activityId, $productType);
} else {
$data = $this->setparam($param, $productId, $activityId, $productType);
$value = $data['mer_labels'];
if (!empty($value)) {
if (!is_array($value)) {
$data['mer_labels'] = ',' . $value . ',';
} else {
$data['mer_labels'] = ',' . implode(',', $value) . ',';
}
}
return $this->dao->update($ret->spu_id, $data);
}
}
public function setparam(array $param, $productId, $activityId, $productType)
{
$data = [
'product_id' => $productId,
'product_type' => $productType ?? 0,
'activity_id' => $activityId,
'store_name' => $param['store_name'],
'keyword' => $param['keyword'] ?? '',
'image' => $param['image'],
'price' => $param['price'],
'status' => 0,
'rank' => $param['rank'] ?? 0,
'temp_id' => $param['temp_id'],
'sort' => $param['sort'] ?? 0,
'mer_labels' => $param['mer_labels'] ?? '',
];
if (isset($param['mer_id'])) $data['mer_id'] = $param['mer_id'];
return $data;
}
/**
* TODO 修改排序
* @param $productId
* @param $activityId
* @param $productType
* @param $data
* @author Qinii
* @day 1/19/21
*/
public function updateSort($productId, $activityId, $productType, $data)
{
$where = [
'product_id' => $productId,
'activity_id' => $activityId,
'product_type' => $productType,
];
$ret = $this->dao->getSearch($where)->find();
if ($ret) $this->dao->update($ret['spu_id'], $data);
}
/**
* TODO 移动端列表
* @param $where
* @param $page
* @param $limit
* @param $userInfo
* @return array
* @author Qinii
* @day 12/18/20
*/
public function getApiSearch($where, $page, $limit, $userInfo = null)
{
if (isset($where['keyword']) && !empty($where['keyword'])) {
if (preg_match('/^(\/@[1-9]{1}).*\*\//', $where['keyword'])) {
$command = app()->make(CopyCommand::class)->getMassage($where['keyword']);
if (!$command || in_array($command['type'], [30, 40])) return ['count' => 0, 'list' => []];
if ($userInfo && $command['uid']) app()->make(UserRepository::class)->bindSpread($userInfo, $command['uid']);
$where['spu_id'] = $command['id'];
unset($where['keyword']);
} else {
app()->make(UserVisitRepository::class)->searchProduct($userInfo ? $userInfo['uid'] : 0, $where['keyword'], (int)($where['mer_id'] ?? 0));
}
}
$where['spu_status'] = 1;
$where['mer_status'] = 1;
$query = $this->dao->search($where);
$query->with([
'merchant' => function ($query) {
$query->field($this->merchantFiled)->with(['type_name']);
},
'issetCoupon',
]);
$productMake = app()->make(ProductRepository::class);
$count = $query->count();
$list = $query->page($page, $limit)->setOption('field', [])->field($this->productFiled)->select();
$append = ['stop_time','svip_price','show_svip_info','is_svip_price'];
if ($productMake->getUserIsPromoter($userInfo))
$append[] = 'max_extension';
$list->append($append);
$list = $this->getBorderList($list);
return compact('count', 'list');
}
public function getBorderList($list)
{
$make = app()->make(StoreActivityRepository::class);
foreach ($list as $item) {
$act = $make->getActivityBySpu(StoreActivityRepository::ACTIVITY_TYPE_BORDER,$item['spu_id'],$item['cate_id'],$item['mer_id']);
$item['border_pic'] = $act['pic'] ?? '';
}
return $list;
}
/**
* TODO 修改状态
* @param array $data
* @author Qinii
* @day 12/18/20
*/
public function changeStatus(int $id, int $productType)
{
$make = app()->make(ProductRepository::class);
$where = [];
$status = 1;
try {
switch ($productType) {
case 0:
$where = [
'activity_id' => 0,
'product_id' => $id,
'product_type' => $productType,
];
break;
case 1:
$_make = app()->make(StoreSeckillActiveRepository::class);
$res = $_make->getSearch(['product_id' => $id])->find();
$endday = strtotime($res['end_day']);
if ($res['status'] == -1 || $endday < time()) $status = 0;
$where = [
'activity_id' => $res['seckill_active_id'],
'product_id' => $id,
'product_type' => $productType,
];
break;
case 2:
$_make = app()->make(ProductPresellRepository::class);
$res = $_make->getWhere([$_make->getPk() => $id]);
$endttime = strtotime($res['end_time']);
if ($endttime <= time()) {
$status = 0;
} else {
if (
$res['product_status'] !== 1 ||
$res['status'] !== 1 ||
$res['action_status'] !== 1 ||
$res['is_del'] !== 0 ||
$res['is_show'] !== 1
) {
$status = 0;
}
}
$where = [
'activity_id' => $id,
'product_id' => $res['product_id'],
'product_type' => $productType,
];
break;
case 3:
$_make = app()->make(ProductAssistRepository::class);
$res = $_make->getWhere([$_make->getPk() => $id]);
$endttime = strtotime($res['end_time']);
if ($endttime <= time()) {
$status = 0;
} else {
if (
$res['product_status'] !== 1 ||
$res['status'] !== 1 ||
$res['is_show'] !== 1 ||
$res['action_status'] !== 1 ||
$res['is_del'] !== 0
) {
$status = 0;
}
}
$where = [
'activity_id' => $id,
'product_id' => $res['product_id'],
'product_type' => $productType,
];
break;
case 4:
$_make = app()->make(ProductGroupRepository::class);
$wher = $_make->actionShow();
$wher[$_make->getPk()] = $id;
$res = $_make->getWhere([$_make->getPk() => $id]);
$endttime = strtotime($res['end_time']);
if ($endttime <= time()) {
$status = 0;
} else {
if (
$res['product_status'] !== 1 ||
$res['status'] !== 1 ||
$res['is_show'] !== 1 ||
$res['action_status'] !== 1 ||
$res['is_del'] !== 0
) {
$status = 0;
}
}
$where = [
'activity_id' => $id,
'product_id' => $res['product_id'],
'product_type' => $productType,
];
break;
default:
break;
}
$ret = $make->getWhere(['product_id' => $where['product_id']]);
if (!$ret || $ret['status'] !== 1 || $ret['mer_status'] !== 1 || $ret['is_del']) $status = 0;
if (in_array($productType, [0, 1]) && ($ret['is_show'] !== 1 || $ret['is_used'] !== 1)) $status = 0;
$result = $this->dao->getSearch($where)->find();
if (!$result && $ret) $result = $this->create($ret->toArray(), $where['product_id'], $where['activity_id'], $productType);
if ($result) $this->dao->update($result['spu_id'], ['status' => $status]);
if ($status == 1 && $productType == 0) {
Queue(SendSmsJob::class, ['tempId' => 'PRODUCT_INCREASE', 'id' => $id]);
}
if ($productType == 0) Queue::push(SyncProductTopJob::class,[]);
} catch (\Exception $exception) {
Log::info($exception->getMessage());
}
}
/**
* TODO 平台编辑商品同步修改
* @param int $id
* @param int $productId
* @param int $productType
* @param array $data
* @author Qinii
* @day 12/18/20
*/
public function changRank(int $id, int $productId, int $productType, array $data)
{
$where = [
'product_id' => $productId,
'product_type' => $productType,
'activity_id' => $id,
];
$res = $this->dao->getWhere($where);
if (!$res && $id) $this->changeStatus($id, $productType);
$res = $this->dao->getWhere($where);
if ($res) {
$res->store_name = $data['store_name'];
$res->rank = $data['rank'];
$res->star = $data['star'] ?? 1;
$res->save();
}
}
/**
* TODO 同步各类商品到spu表
* @param array|null $productType
* @author Qinii
* @day 12/25/20
*/
public function updateSpu(?array $productType)
{
if (!$productType) $productType = [0, 1, 2, 3, 4];
$_product_make = app()->make(ProductRepository::class);
$data = [];
foreach ($productType as $value) {
$ret = $_product_make->activitSearch($value);
$data = array_merge($data, $ret);
}
$this->dao->findOrCreateAll($data);
}
/**
* TODO 获取活动商品的一级分类
* @param $type
* @return mixed
* @author Qinii +0
* @day 1/12/21
*/
public function getActiveCategory($type)
{
$pathArr = $this->dao->getActivecategory($type);
$path = [];
foreach ($pathArr as $item) {
$path[] = explode('/', $item)[1];
}
$path = array_unique($path);
$cat = app()->make(StoreCategoryRepository::class)->getSearch(['ids' => $path])->field('store_category_id,cate_name')->select();
return $cat;
}
public function getSpuData($id, $productType, $merId)
{
try {
switch ($productType) {
case 0:
$where = [
'activity_id' => 0,
'product_id' => $id,
'product_type' => $productType,
];
break;
case 1:
$_make = app()->make(StoreSeckillActiveRepository::class);
$res = $_make->getSearch(['product_id' => $id])->find();
$where = [
'activity_id' => $res['seckill_active_id'],
'product_id' => $id,
'product_type' => $productType,
];
break;
case 2:
$_make = app()->make(ProductPresellRepository::class);
$res = $_make->getWhere([$_make->getPk() => $id]);
$where = [
'activity_id' => $id,
'product_id' => $res['product_id'],
'product_type' => $productType,
];
break;
case 3:
$_make = app()->make(ProductAssistRepository::class);
$res = $_make->getWhere([$_make->getPk() => $id]);
$where = [
'activity_id' => $id,
'product_id' => $res['product_id'],
'product_type' => $productType,
];
break;
case 4:
$_make = app()->make(ProductGroupRepository::class);
$where[$_make->getPk()] = $id;
$res = $_make->getWhere([$_make->getPk() => $id]);
$where = [
'activity_id' => $id,
'product_id' => $res['product_id'],
'product_type' => $productType,
];
break;
default:
$where = [
'activity_id' => 0,
'product_id' => $id,
'product_type' => 0,
];
break;
}
} catch (\Exception $e) {
throw new ValidateException('数据不存在');
}
if ($merId) $where['mer_id'] = $merId;
$result = $this->dao->getSearch($where)->find();
if (!$result) throw new ValidateException('数据不存在');
return $result;
}
public function setLabels($id, $productType, $data, $merId = 0)
{
$field = isset($data['sys_labels']) ? 'sys_labels' : 'mer_labels';
if ($data[$field]) app()->make(ProductLabelRepository::class)->checkHas($merId, $data[$field]);
$ret = $this->getSpuData($id, $productType, $merId);
$value = $data[$field] ? $data[$field] : '';
$ret->$field = $value;
$ret->save();
}
public function batchLabels($ids, $data,$merId)
{
$ids = is_array($ids) ? $ids : explode(',',$ids);
foreach ($ids as $id) {
$this->setLabels($id,0,$data,$merId);
}
}
public function getApiSearchByCoupon($where, $page, $limit, $userInfo)
{
$coupon = app()->make(StoreCouponRepository::class)->search(null, [
'status' => 1,
'coupon_id' => $where['coupon_id']
])->find();
$data['coupon'] = $coupon;
if ($coupon) {
switch ($coupon['type']) {
case 0:
$where['mer_id'] = $coupon['mer_id'];
break;
case 1:
$where['product_ids'] = app()->make(StoreCouponProductRepository::class)->search([
'coupon_id' => $where['coupon_id']
])->column('product_id');
break;
case 11:
$ids = app()->make(StoreCouponProductRepository::class)->search([
'coupon_id' => $where['coupon_id']
])->column('product_id');
$where['cate_pid'] = $ids;
break;
case 10:
break;
case 12:
$ids = app()->make(StoreCouponProductRepository::class)->search([
'coupon_id' => $where['coupon_id']
])->column('product_id');
$where['mer_ids'] = $ids;
break;
}
$where['is_coupon'] = 1;
$where['order'] = 'star';
$where['common'] = 1;
$where['svip'] = ($coupon['send_type'] == StoreCouponRepository::GET_COUPON_TYPE_SVIP) ? 1 : '';
$product = $this->getApiSearch($where, $page, $limit, $userInfo);
}
$data['count'] = $product['count'] ?? 0;
$data['list'] = $product['list'] ?? [];
return $data;
}
public function getHotRanking(int $cateId)
{
$RedisCacheService = app()->make(RedisCacheService::class);
$prefix = env('queue_name','merchant').'_hot_ranking_';
$ids = $RedisCacheService->handler()->get($prefix.'top_' . intval($cateId));
$ids = $ids ? explode(',', $ids) : [];
if (!count($ids)) {
return [];
}
$ids = array_map('intval', $ids);
$where['mer_status'] = 1;
$where['status'] = 1;
$where['is_del'] = 0;
$where['product_type'] = 0;
$where['order'] = 'sales';
$where['spu_ids'] = $ids;
$list = $this->dao->search($where)->setOption('field',[])->field('spu_id,S.image,S.price,S.product_type,P.product_id,P.sales,S.status,S.store_name,P.ot_price,P.cost')->select();
if ($list) $list = $list->toArray();
return $list;
}
/**
* TODO
* @param $where
* @param $page
* @param $limit
* @return array
* @author Qinii
* @day 2022/9/22
*/
public function makinList($where,$page, $limit)
{
$where['spu_status'] = 1;
$where['mer_status'] = 1;
$query = $this->dao->search($where);
$query->with([
'merchant' ,
'issetCoupon',
]);
$count = $query->count();
$list = $query->page($page, $limit)->setOption('field', [])->field($this->productFiled)->select();
return compact('count','list');
}
}

View File

@ -308,11 +308,10 @@ class MerchantRepository extends BaseRepository
];
}
}
if ($where['keyword'] !== '') {
app()->make(UserVisitRepository::class)->searchMerchant($userInfo ? $userInfo['uid'] : 0, $where['keyword']);
}
$query = $this->dao->search($where)->with(['type_name']);
$query = $this->dao->search($where)->with(['type_names']);
$count = $query->count();
$status = systemConfig('mer_location');
/** @var MerchantTakeRepository $repository */
@ -369,11 +368,8 @@ class MerchantRepository extends BaseRepository
*/
public function detail($id, $userInfo)
{
$merchant = $this->dao->apiGetOne($id)->hidden([
"real_name", "mer_phone", "reg_admin_id", "sort", "is_del", "is_audit", "is_best", "mer_state", "bank", "bank_number", "bank_name", 'update_time',
'financial_alipay', 'financial_bank', 'financial_wechat', 'financial_type','mer_take_phone'
]);
$merchant->append(['type_name', 'isset_certificate', 'services_type']);
$merchant = $this->dao->apiGetOne($id);
$merchant->append(['type_names', 'isset_certificate', 'services_type']);
$merchant['care'] = false;
if ($userInfo)
$merchant['care'] = $this->getCareByUser($id, $userInfo->uid);

View File

@ -1,621 +0,0 @@
<?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\repositories\system\merchant;
use app\common\dao\system\merchant\MerchantDao;
use app\common\model\store\order\StoreOrder;
use app\common\model\store\product\ProductReply;
use app\common\repositories\BaseRepository;
use app\common\repositories\store\coupon\StoreCouponRepository;
use app\common\repositories\store\coupon\StoreCouponUserRepository;
use app\common\repositories\store\product\ProductCopyRepository;
use app\common\repositories\store\product\ProductRepository;
use app\common\repositories\store\product\SpuRepository;
use app\common\repositories\store\shipping\ShippingTemplateRepository;
use app\common\repositories\store\StoreCategoryRepository;
use app\common\repositories\system\attachment\AttachmentRepository;
use app\common\repositories\user\UserBillRepository;
use app\common\repositories\user\UserRelationRepository;
use app\common\repositories\user\UserVisitRepository;
use app\common\repositories\wechat\RoutineQrcodeRepository;
use crmeb\jobs\ClearMerchantStoreJob;
use crmeb\services\QrcodeService;
use crmeb\services\UploadService;
use crmeb\services\WechatService;
use FormBuilder\Exception\FormBuilderException;
use FormBuilder\Factory\Elm;
use FormBuilder\Form;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Queue;
use think\facade\Route;
use think\Model;
/**
* Class MerchantRepository
* @package app\common\repositories\system\merchant
* @mixin MerchantDao
* @author xaboy
* @day 2020-04-16
*/
class MerchantRepository extends BaseRepository
{
/**
* MerchantRepository constructor.
* @param MerchantDao $dao
*/
public function __construct(MerchantDao $dao)
{
$this->dao = $dao;
}
/**
* @param array $where
* @param $page
* @param $limit
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @author xaboy
* @day 2020-04-16
*/
public function lst(array $where, $page, $limit)
{
$query = $this->dao->search($where);
$count = $query->count($this->dao->getPk());
$list = $query->page($page, $limit)->setOption('field', [])
->with([
'admin' => function ($query) {
$query->field('mer_id,account');
},
'merchantCategory',
'merchantType'
])
->field('sort, mer_id, mer_name, real_name, mer_phone, mer_address, mark, status, create_time,is_best,is_trader,type_id,category_id,copy_product_num,export_dump_num,is_margin,margin,mer_avatar')->select();
return compact('count', 'list');
}
public function count($where)
{
$where['status'] = 1;
$valid = $this->dao->search($where)->count();
$where['status'] = 0;
$invalid = $this->dao->search($where)->count();
return compact('valid', 'invalid');
}
/**
* @param int|null $id
* @param array $formData
* @return Form
* @throws FormBuilderException
* @author xaboy
* @day 2020-04-16
*/
public function form(?int $id = null, array $formData = [])
{
$form = Elm::createForm(is_null($id) ? Route::buildUrl('systemMerchantCreate')->build() : Route::buildUrl('systemMerchantUpdate', ['id' => $id])->build());
$is_margin = 0;
if ($formData && $formData['is_margin'] == 10) $is_margin = 1;
/** @var MerchantCategoryRepository $make */
$make = app()->make(MerchantCategoryRepository::class);
$merchantTypeRepository = app()->make(MerchantTypeRepository::class);
$options = $merchantTypeRepository->getOptions();
$margin = $merchantTypeRepository->getMargin();
$config = systemConfig(['broadcast_room_type', 'broadcast_goods_type']);
$rule = [
Elm::input('mer_name', '商户名称')->required(),
Elm::select('category_id', '商户分类')->options(function () use ($make) {
return $make->allOptions();
})->requiredNum(),
Elm::select('type_id', '店铺类型')->disabled($is_margin)->options($options)->requiredNum()->col(12)->control($margin),
Elm::input('mer_account', '商户账号')->required()->disabled(!is_null($id))->required(!is_null($id)),
Elm::password('mer_password', '登录密码')->required()->disabled(!is_null($id))->required(!is_null($id)),
Elm::input('real_name', '商户姓名'),
Elm::input('mer_phone', '商户手机号')->col(12)->required(),
Elm::number('commission_rate', '手续费(%)')->col(12),
Elm::input('mer_keyword', '商户关键字')->col(12),
Elm::input('mer_address', '商户地址'),
Elm::input('sub_mchid', '微信分账商户号'),
Elm::textarea('mark', '备注'),
Elm::number('sort', '排序', 0)->precision(0)->max(99999),
$id ? Elm::hidden('status', 1) : Elm::switches('status', '是否开启', 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
Elm::switches('is_bro_room', '直播间审核', $config['broadcast_room_type'] == 1 ? 0 : 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
Elm::switches('is_audit', '产品审核', 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
Elm::switches('is_bro_goods', '直播间商品审核', $config['broadcast_goods_type'] == 1 ? 0 : 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
Elm::switches('is_best', '是否推荐')->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
Elm::switches('is_trader', '是否自营')->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
];
$form->setRule($rule);
return $form->setTitle(is_null($id) ? '添加商户' : '编辑商户')->formData($formData);
}
/**
* @param array $formData
* @return Form
* @throws FormBuilderException
* @author xaboy
* @day 2020/6/25
*/
public function merchantForm(array $formData = [])
{
$form = Elm::createForm(Route::buildUrl('merchantUpdate')->build());
$rule = [
Elm::textarea('mer_info', '店铺简介')->required(),
Elm::input('service_phone', '服务电话')->required(),
Elm::frameImage('mer_banner', '店铺Banner(710*200px)', '/' . config('admin.merchant_prefix') . '/setting/uploadPicture?field=mer_banner&type=1')->modal(['modal' => false])->width('896px')->height('480px')->props(['footer' => false]),
Elm::frameImage('mer_avatar', '店铺头像(120*120px)', '/' . config('admin.merchant_prefix') . '/setting/uploadPicture?field=mer_avatar&type=1')->modal(['modal' => false])->width('896px')->height('480px')->props(['footer' => false]),
Elm::switches('mer_state', '是否开启', 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开')->col(12),
];
$form->setRule($rule);
return $form->setTitle('编辑店铺信息')->formData($formData);
}
/**
* @param $id
* @return Form
* @throws FormBuilderException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @author xaboy
* @day 2020-04-16
*/
public function updateForm($id)
{
$data = $this->dao->get($id)->toArray();
/** @var MerchantAdminRepository $make */
$make = app()->make(MerchantAdminRepository::class);
$data['mer_account'] = $make->merIdByAccount($id);
$data['mer_password'] = '***********';
if($data['category_id'] == 0){
$data['category_id'] = '';
}
if($data['type_id'] == 0){
$data['type_id'] = '';
}
return $this->form($id, $data);
}
/**
* @param array $data
* @author xaboy
* @day 2020-04-17
*/
public function createMerchant(array $data)
{
if ($this->fieldExists('mer_name', $data['mer_name']))
throw new ValidateException('商户名已存在');
if ($data['mer_phone'] && isPhone($data['mer_phone']))
throw new ValidateException('请输入正确的手机号');
$merchantCategoryRepository = app()->make(MerchantCategoryRepository::class);
$adminRepository = app()->make(MerchantAdminRepository::class);
if (!$data['category_id'] || !$merchantCategoryRepository->exists($data['category_id']))
throw new ValidateException('商户分类不存在');
if ($adminRepository->fieldExists('account', $data['mer_account']))
throw new ValidateException('账号已存在');
/** @var MerchantAdminRepository $make */
$make = app()->make(MerchantAdminRepository::class);
$margin = app()->make(MerchantTypeRepository::class)->get($data['type_id']);
$data['is_margin'] = $margin['is_margin'] ?? -1;
$data['margin'] = $margin['margin'] ?? 0;
return Db::transaction(function () use ($data, $make) {
$account = $data['mer_account'];
$password = $data['mer_password'];
unset($data['mer_account'], $data['mer_password']);
$merchant = $this->dao->create($data);
$make->createMerchantAccount($merchant, $account, $password);
app()->make(ShippingTemplateRepository::class)->createDefault($merchant->mer_id);
app()->make(ProductCopyRepository::class)->defaulCopyNum($merchant->mer_id);
return $merchant;
});
}
/**
* @Author:Qinii
* @Date: 2020/5/30
* @param $where
* @param $page
* @param $limit
* @return array
*/
public function getList($where, $page, $limit, $userInfo)
{
$field = 'care_count,is_trader,type_id,mer_id,mer_banner,mini_banner,mer_name, mark,mer_avatar,product_score,service_score,postage_score,sales,status,is_best,create_time,long,lat,is_margin';
$where['status'] = 1;
$where['mer_state'] = 1;
$where['is_del'] = 0;
if (isset($where['location'])) {
$data = @explode(',', (string)$where['location']);
if (2 != count(array_filter($data ?: []))) {
unset($where['location']);
} else {
$where['location'] = [
'lat' => (float)$data[0],
'long' => (float)$data[1],
];
}
}
if ($where['keyword'] !== '') {
app()->make(UserVisitRepository::class)->searchMerchant($userInfo ? $userInfo['uid'] : 0, $where['keyword']);
}
$query = $this->dao->search($where)->with(['type_name']);
$count = $query->count();
$status = systemConfig('mer_location');
$list = $query->page($page, $limit)->setOption('field', [])->field($field)->select()
->each(function ($item) use ($status, $where) {
if ($status && $item['lat'] && $item['long'] && isset($where['location']['lat'], $where['location']['long'])) {
$distance = getDistance($where['location']['lat'], $where['location']['long'], $item['lat'], $item['long']);
if ($distance < 0.9) {
$distance = max(bcmul($distance, 1000, 0), 1).'m';
if ($distance == '1m') {
$distance = '100m以内';
}
} else {
$distance .= 'km';
}
$item['distance'] = $distance;
}
$item['recommend'] = isset($where['delivery_way']) ? $item['CityRecommend'] : $item['AllRecommend'];
return $item;
});
return compact('count', 'list');
}
/**
* @Author:Qinii
* @Date: 2020/5/30
* @param int $id
* @return array|Model|null
*/
public function merExists(int $id)
{
return ($this->dao->get($id));
}
/**
* @Author:Qinii
* @Date: 2020/5/30
* @param $id
* @param $userInfo
* @return array|Model|null
*/
public function detail($id, $userInfo)
{
$merchant = $this->dao->apiGetOne($id)->hidden([
"real_name", "mer_phone", "reg_admin_id", "sort", "is_del", "is_audit", "is_best", "mer_state", "bank", "bank_number", "bank_name", 'update_time',
'financial_alipay', 'financial_bank', 'financial_wechat', 'financial_type','mer_take_phone'
]);
$merchant->append(['type_name', 'isset_certificate', 'services_type']);
$merchant['care'] = false;
if ($userInfo)
$merchant['care'] = $this->getCareByUser($id, $userInfo->uid);
return $merchant;
}
/**
* @Author:Qinii
* @Date: 2020/5/30
* @param int $merId
* @param int $userId
* @return bool
*/
public function getCareByUser(int $merId, int $userId)
{
if (app()->make(UserRelationRepository::class)->getWhere(['type' => 10, 'type_id' => $merId, 'uid' => $userId]))
return true;
return false;
}
/**
* @Author:Qinii
* @Date: 2020/5/30
* @param $merId
* @param $where
* @param $page
* @param $limit
* @param $userInfo
* @return mixed
*/
public function productList($merId, $where, $page, $limit, $userInfo)
{
return app()->make(ProductRepository::class)->getApiSearch($merId, $where, $page, $limit, $userInfo);
}
/**
* @Author:Qinii
* @Date: 2020/5/30
* @param int $id
* @return mixed
*/
public function categoryList(int $id)
{
return app()->make(StoreCategoryRepository::class)->getApiFormatList($id, 1);
}
public function wxQrcode($merId)
{
$siteUrl = systemConfig('site_url');
$name = md5('mwx' . $merId . date('Ymd')) . '.jpg';
$attachmentRepository = app()->make(AttachmentRepository::class);
$imageInfo = $attachmentRepository->getWhere(['attachment_name' => $name]);
if (isset($imageInfo['attachment_src']) && strstr($imageInfo['attachment_src'], 'http') !== false && curl_file_exist($imageInfo['attachment_src']) === false) {
$imageInfo->delete();
$imageInfo = null;
}
if (!$imageInfo) {
$codeUrl = rtrim($siteUrl, '/') . '/pages/store/home/index?id=' . $merId; //二维码链接
if (systemConfig('open_wechat_share')) {
$qrcode = WechatService::create(false)->qrcodeService();
$codeUrl = $qrcode->forever('_scan_url_mer_' . $merId)->url;
}
$imageInfo = app()->make(QrcodeService::class)->getQRCodePath($codeUrl, $name);
if (is_string($imageInfo)) throw new ValidateException('二维码生成失败');
$imageInfo['dir'] = tidy_url($imageInfo['dir'], null, $siteUrl);
$attachmentRepository->create(systemConfig('upload_type') ?: 1, -2, $merId, [
'attachment_category_id' => 0,
'attachment_name' => $imageInfo['name'],
'attachment_src' => $imageInfo['dir']
]);
$urlCode = $imageInfo['dir'];
} else $urlCode = $imageInfo['attachment_src'];
return $urlCode;
}
public function routineQrcode($merId)
{
$name = md5('smrt' . $merId . date('Ymd')) . '.jpg';
return tidy_url(app()->make(QrcodeService::class)->getRoutineQrcodePath($name, 'pages/store/home/index', 'id=' . $merId), 0);
}
public function copyForm(int $id)
{
$form = Elm::createForm(Route::buildUrl('systemMerchantChangeCopy', ['id' => $id])->build());
$form->setRule([
Elm::input('copy_num', '复制次数', $this->dao->getCopyNum($id))->disabled(true)->readonly(true),
Elm::radio('type', '修改类型', 1)
->setOptions([
['value' => 1, 'label' => '增加'],
['value' => 2, 'label' => '减少'],
]),
Elm::number('num', '修改数量', 0)->required()
]);
return $form->setTitle('修改复制商品次数');
}
public function delete($id)
{
Db::transaction(function () use ($id) {
$this->dao->update($id, ['is_del' => 1]);
app()->make(MerchantAdminRepository::class)->deleteMer($id);
Queue::push(ClearMerchantStoreJob::class, ['mer_id' => $id]);
});
}
/**
* TODO 清理删除商户但没有删除的商品数据
* @author Qinii
* @day 5/15/21
*/
public function clearRedundancy()
{
$ret = (int)$this->dao->search(['is_del' => 1])->value('mer_id');
if (!$ret) return;
try {
app()->make(ProductRepository::class)->clearMerchantProduct($ret);
app()->make(StoreCouponRepository::class)->getSearch([])->where('mer_id', $ret)->update(['is_del' => 1, 'status' => 0]);
app()->make(StoreCouponUserRepository::class)->getSearch([])->where('mer_id', $ret)->update(['is_fail' => 1, 'status'=>2]);
} catch (\Exception $exception) {
throw new ValidateException($exception->getMessage());
}
}
public function addLockMoney(int $merId, string $orderType, int $orderId, float $money)
{
if ($money <= 0) return;
if (systemConfig('mer_lock_time')) {
app()->make(UserBillRepository::class)->incBill($merId, 'mer_lock_money', $orderType, [
'link_id' => ($orderType === 'order' ? 1 : 2) . $orderId,
'mer_id' => $merId,
'status' => 0,
'title' => '商户冻结余额',
'number' => $money,
'mark' => '商户冻结余额',
'balance' => 0
]);
} else {
$this->dao->addMoney($merId, $money);
}
}
public function checkCrmebNum(int $merId, string $type)
{
$merchant = $this->dao->get($merId);
switch ($type) {
case 'copy':
if (!systemConfig('copy_product_status')) {
throw new ValidateException('复制商品未开启');
}
if (!$merchant['copy_product_num']) {
throw new ValidateException('复制商品剩余次数不足');
}
break;
case 'dump':
if (!systemConfig('crmeb_serve_dump')) {
throw new ValidateException('电子面单未开启');
}
if (!$merchant['export_dump_num']) {
throw new ValidateException('电子面单剩余次数不足');
}
break;
}
return true;
}
public function subLockMoney(int $merId, string $orderType, int $orderId, float $money)
{
if ($money <= 0) return;
$make = app()->make(UserBillRepository::class);
$bill = $make->search(['category' => 'mer_lock_money', 'type' => $orderType, 'mer_id' => $merId, 'link_id' => ($orderType === 'order' ? 1 : 2) . $orderId, 'status' => 0])->find();
if (!$bill) {
$this->dao->subMoney($merId, $money);
} else {
$make->decBill($merId, 'mer_refund_money', $orderType, [
'link_id' => ($orderType === 'order' ? 1 : 2) . $orderId,
'mer_id' => $merId,
'status' => 1,
'title' => '商户冻结余额退款',
'number' => $money,
'mark' => '商户冻结余额退款',
'balance' => 0
]);
}
}
public function computedLockMoney(StoreOrder $order)
{
Db::transaction(function () use ($order) {
$money = 0;
$make = app()->make(UserBillRepository::class);
$bill = $make->search(['category' => 'mer_lock_money', 'type' => 'order', 'link_id' => '1' . $order->order_id, 'status' => 0])->find();
if ($bill) {
$money = bcsub($bill->number, $make->refundMerchantMoney($bill->link_id, $bill->type, $bill->mer_id), 2);
if ($order->presellOrder) {
$presellBill = $make->search(['category' => 'mer_lock_money', 'type' => 'presell', 'link_id' => '2' . $order->presellOrder->presell_order_id, 'status' => 0])->find();
if ($presellBill) {
$money = bcadd($money, bcsub($presellBill->number, $make->refundMerchantMoney($presellBill->link_id, $presellBill->type, $presellBill->mer_id), 2), 2);
$presellBill->status = 1;
$presellBill->save();
}
}
$bill->status = 1;
$bill->save();
}
if ($money > 0) {
app()->make(UserBillRepository::class)->incBill($order->uid, 'mer_computed_money', 'order', [
'link_id' => $order->order_id,
'mer_id' => $order->mer_id,
'status' => 0,
'title' => '商户待解冻余额',
'number' => $money,
'mark' => '交易完成,商户待解冻余额' . floatval($money) . '元',
'balance' => 0
]);
}
});
}
public function checkMargin($merId, $typeId)
{
$merchant = $this->dao->get($merId);
$is_margin = 0;
$margin = 0;
if ($merchant['is_margin'] == 10) {
$margin = $merchant['margin'];
$is_margin = $merchant['is_margin'];
} else {
$marginData = app()->make(MerchantTypeRepository::class)->get($typeId);
if ($marginData) {
$is_margin = $marginData['is_margin'];
$margin = $marginData['margin'];
}
}
return compact('is_margin', 'margin');
}
public function setMarginForm(int $id)
{
$merchant = $this->dao->get($id);
if ($merchant->is_margin !== 10) {
throw new ValidateException('商户无保证金可扣');
}
$form = Elm::createForm(Route::buildUrl('systemMarginSet')->build());
$form->setRule([
Elm::input('mer_name', '商户名称', $merchant->mer_name)->disabled(true),
Elm::input('mer_id', '商户ID', $merchant->mer_id)->disabled(true),
Elm::input('margin', '商户剩余保证金', $merchant->margin)->disabled(true),
Elm::number('number', '保证金扣除金额', 0)->max($merchant->margin)->precision(2)->required(),
Elm::text('mark', '保证金扣除原因')->required(),
]);
return $form->setTitle('扣除保证金');
}
/**
* TODO
* @param $data
* @return \think\response\Json
* @author Qinii
* @day 2/7/22
*/
public function setMargin($data)
{
$merechant = $this->dao->get($data['mer_id']);
if ($merechant->is_margin !== 10) {
throw new ValidateException('商户未支付保证金或已申请退款');
}
if ($data['number'] < 0) {
throw new ValidateException('扣除保证金额不能小于0');
}
if (bccomp($merechant->margin, $data['number'], 2) == -1) {
throw new ValidateException('扣除保证金额不足');
}
$data['balance'] = bcsub($merechant->margin, $data['number'], 2);
Db::transaction(function () use ($merechant, $data) {
$merechant->margin = $data['balance'];
$merechant->save();
app()->make(UserBillRepository::class)->bill(0, 'mer_margin', $data['type'], 0, $data);
});
}
public function changeDeliveryBalance($merId,$number)
{
$merechant = $this->dao->get($merId);
if (bccomp($merechant->delivery_balance, $number, 2) == -1) {
throw new ValidateException('余额不足,请先充值(配送费用:'.$number.'元)');
}
Db::transaction(function () use ($merechant, $number) {
$merechant->delivery_balance = bcsub($merechant->delivery_balance, $number, 2);
$merechant->save();
});
}
}

View File

@ -0,0 +1,166 @@
<?php
namespace app\controller\admin;
use crmeb\basic\BaseController;
use think\facade\Db;
use think\facade\Log;
use crmeb\services\UploadService;
use think\api\Client;
class ProductLibrary extends BaseController
{
public function lst()
{
[$page, $limit] = $this->getPage();
$param = $this->request->param();
$where = ['is_del' => 0];
$list = Db::name('product_library')->where($where)->page($page)->limit($limit)->order('id desc')->select();
$count = Db::name('product_library')->count();
return app('json')->success(['list' => $list, 'count' => $count]);
}
public function add()
{
$param = $this->request->param();
$data['store_name'] = $param['store_name'];
$data['store_info'] = $param['store_info'];
$data['keyword'] = $param['keyword'];
$data['bar_code'] = $param['bar_code'];
$data['is_used'] = 1;
$data['status'] = 1;
$data['cate_id'] = $param['cate_id'];
$data['unit_name'] = $param['unit_name'];
$data['price'] = $param['price'];
$data['cost'] = $param['cost'];
$data['ot_price'] = $param['ot_price'];
$data['stock'] = $param['stock'];
$data['create_time'] = date('Y-m-d H:i:s');
$data['image'] = $param['image'];
$data['slider_image'] = $param['slider_image'];
$data['images'] = $param['images'];
$res = Db::name('product_library')->insert($data);
if ($res) {
return app('json')->success('添加成功');
} else {
return app('json')->fail('添加失败');
}
}
public function edit()
{
$param = $this->request->param();
$data['store_name'] = $param['store_name'];
$data['store_info'] = $param['store_info'];
$data['keyword'] = $param['keyword'];
$data['bar_code'] = $param['bar_code'];
$data['is_used'] = 1;
$data['status'] = 1;
$data['cate_id'] = $param['cate_id'];
$data['unit_name'] = $param['unit_name'];
$data['price'] = $param['price'];
$data['cost'] = $param['cost'];
$data['ot_price'] = $param['ot_price'];
$data['stock'] = $param['stock'];
$data['create_time'] = date('Y-m-d H:i:s');
$data['image'] = $param['image'];
$data['slider_image'] = $param['slider_image'];
$data['images'] = $param['images'];
$res = Db::name('product_library')->where('id', $param['id'])->update($data);
if ($res) {
return app('json')->success('修改成功');
} else {
return app('json')->fail('修改失败');
}
}
public function del()
{
$param = $this->request->param();
$res = Db::name('product_library')->where('id', $param['id'])->update(['is_del' => 1]);
if ($res) {
return app('json')->success('删除成功');
} else {
return app('json')->fail('删除失败');
}
}
public function caiji($code = '')
{
if ($code == '') {
return app('json')->fail('编码不能为空');
}
$first_char = substr($code, 0, 1);
if($first_char!=0){
$codes='0'.$code;
}else{
$codes=$code;
}
$client = new Client("b1eb52b9-0379-4c56-b795-47d90a73ca6a");
$result = $client->barcodeQuery()
->withCode($codes)
->request();
try {
if ($result['code'] == 0) {
$upload = UploadService::create();
$dir = 'def/' . date('Y-m-d');
$param = $result['data'];
$data['store_name'] = $param['goodsName'];
$data['store_info'] = '';
$data['keyword'] = '';
$data['bar_code'] = $code;
$data['is_used'] = 1;
$data['status'] = 1;
$data['cate_id'] = 0;
$data['unit_name'] = '';
$data['spec'] =$param['spec'];
$data['trademark'] =$param['trademark'];
$data['goods_type'] =$param['goodsType'];
$data['ycg'] =$param['ycg'];
$data['note'] =$param['note'];
$data['manu_address'] =$param['manuAddress'];
$data['price'] = $param['price']??0;
$data['cost'] = 0;
$data['ot_price'] = 0;
$data['stock'] = 9999999;
$data['create_time'] = date('Y-m-d H:i:s');
$data['images'] = '';
if ($param['img'] != '') {
$oss = $upload->to($dir)->stream(file_get_contents($param['img']));
$data['image'] = $oss->filePath;
} else {
$data['image'] = 'https://lihai001.oss-cn-chengdu.aliyuncs.com/uploads/20230130/00ebcfdf75684f5494c0193075055d1.png';
$data['slider_image'] = 'https://lihai001.oss-cn-chengdu.aliyuncs.com/uploads/20230130/00ebcfdf75684f5494c0193075055d1.png';
}
$arr=[];
foreach($param['imgList'] as $k=>$v){
$oss=$upload->to($dir)->stream(file_get_contents($v));
$arr[] = $oss->filePath;
}
if(count($arr)>0){
$data['slider_image'] =implode(',',$arr);
}else{
$data['slider_image']=$data['image'];
}
$data['images'] = '';
$res = Db::name('product_library')->insert($data);
if ($res) {
return app('json')->success('添加成功');
} else {
throw new \think\exception\ValidateException('添加失败');
}
} else {
Log::error('商品采集错误:' . $result['message']);
throw new \think\exception\ValidateException($result['message']);
}
} catch (\Exception $e) {
throw new \think\exception\ValidateException($e->getMessage());
}
}
}

View File

@ -496,7 +496,7 @@ class Common extends BaseController
//获取云店铺
public function get_cloud_shop($street_code){
//更新查询镇级供应链店铺
$typeTownSupplyChainId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeTownSupplyChain'])->value('mer_type_id');
// $typeTownSupplyChainId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeTownSupplyChain'])->value('mer_type_id');
/*
$find=DB::name('merchant')
->alias('m')

View File

@ -29,6 +29,8 @@ use app\common\repositories\system\merchant\MerchantRepository as repository;
use think\facade\Db;
use think\facade\Queue;
use app\common\model\system\merchant\Merchant as MerchantModel;
use crmeb\services\QrcodeService;
use app\common\repositories\system\attachment\AttachmentRepository;
class Merchant extends BaseController
{
@ -124,7 +126,27 @@ class Merchant extends BaseController
{
if(!$this->repository->merExists($id))
return app('json')->fail('店铺已打烊');
$url = $this->request->param('type') == 'routine' ? $this->repository->routineQrcode(intval($id)) : $this->repository->wxQrcode(intval($id));
if ($this->request->param('type') == 'routine') {
$url= $this->repository->routineQrcode(intval($id));
}elseif($this->request->param('type') == 'app'){
$attachmentRepository = app()->make(AttachmentRepository::class);
$name='merchant_code_'.$id.'.png';
$imageInfo = $attachmentRepository->getWhere(['attachment_name' => $name]);
if($imageInfo){
$url=$imageInfo['attachment_src'];
}else{
$info = app()->make(QrcodeService::class)->getQRCodePath(systemConfig('site_url').'pages/store/home/index?id=' . $id, $name);
$attachmentRepository->create(systemConfig('upload_type') ?: 1, -2, $id, [
'attachment_category_id' => 0,
'attachment_name' => $info['name'],
'attachment_src' => $info['dir']
]);
$url=$info['dir'];
}
}
else{
$url= $this->repository->wxQrcode(intval($id));
}
return app('json')->success(compact('url'));
}
@ -220,6 +242,11 @@ class Merchant extends BaseController
if ($data['mer_state'] && !$merchant['sub_mchid'] && systemConfig('open_wx_combine'))
return app('json')->fail('开启店铺前请先完成微信子商户入驻');
}
if($data['long']!=''&& $data['lat']!=''){
$long=$data['long'];
$lat=$data['lat'];
Db::query("UPDATE eb_merchant SET coordinates = ST_GeomFromText('POINT($long $lat)') WHERE mer_id = $id");
}
Db::name('merchant')->where('mer_id',$id)->update($data);
Queue::push(ChangeMerchantStatusJob::class, $id);

View File

@ -336,7 +336,7 @@ class MerchantIntention extends BaseController
'name',
'code',
'images',
'merchant_category_id',
'merchant_category_name',
'mer_type_id',
'social_credit_code',
'area_id',
@ -351,9 +351,18 @@ class MerchantIntention extends BaseController
if (!env('APP_DEBUG')) {
if (!$check) throw new ValidateException('验证码不正确');
}
if (!app()->make(MerchantCategoryRepository::class)->get($data['merchant_category_id'])) throw new ValidateException('商户分类不存在');
if ($data['mer_type_id'] && !app()->make(MerchantTypeRepository::class)->exists($data['mer_type_id']))
// if (!app()->make(MerchantCategoryRepository::class)->get($data['merchant_category_id'])) throw new ValidateException('商户分类不存在');
if ($data['mer_type_id'] && !app()->make(MerchantTypeRepository::class)->exists($data['mer_type_id'])) {
throw new ValidateException('店铺类型不存在');
}
if ($data['merchant_category_name'] == '') {
throw new ValidateException('商户分类,不能为空');
}
$merchant_category_id=Db::name('merchant_category')->where('category_name',$data['merchant_category_name'])->value('merchant_category_id');
if(!$merchant_category_id){
throw new ValidateException('没有对应的商户分类,请联系工作人员添加');
}
$data['merchant_category_id']=$merchant_category_id;
unset($data['code']);
return $data;
}
@ -392,4 +401,3 @@ class MerchantIntention extends BaseController
return app('json')->success($lst);
}
}

View File

@ -93,8 +93,12 @@ class StoreCart extends BaseController
case 99: //委托商品
$result = app()->make(ProductRepository::class)->cartCheck($data,$this->request->userInfo());
[$source, $sourceId, $pid] = explode(':', $this->request->param('source', '0'), 3) + ['', '', ''];
if($source==StoreCartDao::CITY_CLOUD){
$data['source'] = $source;
}else{
$data['source'] = (in_array($source, [0, 1]) && $pid == $data['product_id']) ? $source : 0;
if ($data['source'] > 0) $data['source_id'] = intval($sourceId);
}
break;
case 1: //秒杀商品
$result = app()->make(ProductRepository::class)->cartSeckillCheck($data,$this->request->userInfo());

View File

@ -95,7 +95,6 @@ class StoreOrder extends BaseController
if (!is_array($receipt)) throw new ValidateException('发票信息有误');
$validate->check($receipt);
}
$uid = $this->request->uid();
// halt(count($cartId), count($cartRepository->validIntersection($cartId, $uid)));
if (!($count = count($cartId)) || $count != count($cartRepository->validIntersection($cartId, $uid)))
@ -305,6 +304,9 @@ class StoreOrder extends BaseController
return app('json')->success(['qrcode' => $this->repository->wxQrcode($id, $order->verify_code)]);
}
/**
* 生成二维码
*/
public function logisticsCode($id)
{
$storeInfo = Db::name('store_service')->where('uid', $this->request->uid())->find();

View File

@ -0,0 +1,118 @@
<?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\controller\api\store\order;
use app\common\model\store\order\StoreGroupOrder;
use app\common\repositories\delivery\DeliveryOrderRepository;
use app\common\repositories\store\order\StoreOrderCreateRepository;
use app\common\repositories\store\order\StoreOrderReceiptRepository;
use app\validate\api\UserReceiptValidate;
use crmeb\basic\BaseController;
use app\common\repositories\store\order\StoreCartRepository;
use app\common\repositories\store\order\StoreGroupOrderRepository;
use app\common\repositories\store\order\StoreOrderRepository;
use app\common\repositories\user\UserAddressRepository;
use think\exception\ValidateException;
use crmeb\services\ExpressService;
use crmeb\services\LockService;
use think\facade\Db;
use think\App;
use think\facade\Log;
/**代发订单
* Class StoreOrder
* @package app\controller\api\store\order
* @author xaboy
* @day 2020/6/10
*/
class StoreOrderBehalf extends BaseController
{
/**
* @var StoreOrderRepository
*/
protected $repository;
/**
* StoreOrder constructor.
* @param App $app
* @param StoreOrderRepository $repository
*/
public function __construct(App $app, StoreOrderRepository $repository)
{
parent::__construct($app);
$this->repository = $repository;
}
/**
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author xaboy
* @day 2020/6/10
*/
public function lst()
{
[$page, $limit] = $this->getPage();
$status = $this->request->param('status',1);
$uid = $this->request->userInfo()['uid'];
$mer_id = Db::name('store_service')->where('uid', $uid)->where('is_del', 0)->value('mer_id');
if ($mer_id) {
$column = Db::name('store_order_behalf')->where('mer_id', $mer_id)->where('status', $status)->page($page)->limit($limit)->column('order_id');
if ($column) {
$where['order_id'] = $column;
return app('json')->success($this->repository->getList($where, 1, 100));
}
}
return app('json')->success([]);
}
/**
* @param $id
* @return mixed
* @author xaboy
* @day 2020/6/10
*/
public function detail($id)
{
$order = $this->repository->getDetail((int)$id, $this->request->uid());
if (!$order)
return app('json')->fail('订单不存在');
if ($order->order_type == 1) {
$order->append(['take', 'refund_status']);
}
return app('json')->success($order->toArray());
}
/**
* 生成二维码
*/
public function logisticsCode($id)
{
$status = $this->request->param('status',1);
$order_id = $this->request->param('order_id',0);
$uid = $this->request->userInfo()['uid'];
$mer_id = Db::name('store_service')->where('uid', $uid)->where('is_del', 0)->value('mer_id');
if ($mer_id) {
$order_id = Db::name('store_order_behalf')->where('mer_id', $mer_id)->where('status', $status)->where('order_id',$order_id)->value('order_id');
if ($order_id) {
$order = $this->repository->getWhere(['order_id' => $id,'is_del' => 0]);
return app('json')->success(['qrcode' => $this->repository->logisticsQrcode($id, $order->order_sn)]);
}
}
return app('json')->fail('信息有误:请联系官方人员');
}
}

View File

@ -44,14 +44,127 @@ class CloudWarehouse extends BaseController
* 指定类型的云仓商品列表
* @return mixed
*/
public function index()
// public function index()
// {
// // 除了市级供应链都可以查询
// $typeIdArray = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypePlatform'])->column('mer_type_id');
// $params = $this->request->params(['category_id', 'street_code', 'order', ['product_type', 0], 'keyword','page_num']);
// $search = [
// // 'street_id' => $params['street_code'],
// 'type_id' => $typeIdArray ?? [],
// 'status' => 1,
// 'is_del' => 0,
// 'mer_state' => 1,
// ];
// if (!empty($params['category_id'])) {
// $search['category_id'] = $params['category_id'];
// }
// $merchantIds = $this->merchantDao->search($search)->column('mer_id');
// [$page, $limit] = $this->getPage();
// if(isset($params['page_num'])&&$params['page_num']!=''){
// $page=$params['page_num'];
// }
// if (empty($merchantIds)) {
// return app('json')->success(['count' => 0, 'list' => []]);
// }
// // 隐藏镇级云仓
// // $typeCloudWarehouseId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeCloudWarehouse'])->value('mer_type_id');
// // $entryWhere = [
// // 'street_id' => $params['street_code'],
// // 'type_id' => $typeCloudWarehouseId,
// // 'status' => 1,
// // 'is_del' => 0,
// // 'mer_state' => 1,
// // ];
// // if (!empty($params['category_id'])) {
// // $entryWhere['category_id'] = $params['category_id'];
// // }
// // $where['entry_mer_id'] = $this->merchantDao->search($entryWhere)->value('mer_id');
// $where['entry_mer_id'] = 0;
// $where['keyword'] = $params['keyword'];
// $where['mer_ids'] = $merchantIds;
// $where['product_type'] = $params['product_type'];
// $where['is_gift_bag'] = 0;
// $where['order'] = $params['order'] ?: 'sort';
// $products = $this->spuRepository->getApiCloudSearch($where, $page, $limit, false);
// return app('json')->success($products);
// }
/**
* 云仓商品列表
* @return mixed
*/
public function index($street_code, $page_num = 1, $category_id = 0,$location='')
{
// if ($category_id == 0) {
// return app('json')->fail('分类id不能为0');
// }
$cloud_product = Db::name('cloud_product')->where('street_code', $street_code)->where('status', 1)->page($page_num)->column('product_id');
$where = [
'is_show' => 1,
'is_used' => 1,
'status' => 1,
'is_del' => 0,
'mer_status' => 1,
];
if (!$cloud_product) {
$list=[];
if($location){
[$lon,$lat]=explode(',',$location);
if($page_num==1){
$limit=0;
}else{
$limit=$page_num*10;
}
$select=Db::query("select mer_id,mer_name ,ST_Distance(coordinates, POINT($lon,$lat)) AS distance from eb_merchant where coordinates !='' ORDER BY distance LIMIT $limit, 10;");
foreach ($select as $k => $v) {
$where['mer_id']=$v['mer_id'];
$product_list = Db::name('store_product')->where($where)
->limit(3)
->withAttr('sku', function ($value, $data) {
$find = Db::name('store_product_attr_value')->where('mer_id', $data['mer_id'])->where('product_id', $data['product_id'])->find();
return ['' => $find];
})
->select();
foreach ($product_list as $k1 => $v1){
$arr=$v1;
$v['distance']=round($v['distance'],2).'km';
$arr['merchant']=$v;
$list[]=$arr;
}
}
}
return app('json')->success(['count' => 0, 'list' => $list]);
}
$count = Db::name('cloud_product')->where('street_code', $street_code)->where('status', 1)->count();
$select = Db::name('store_product')->whereIn('product_id', $cloud_product)->where($where)
->withAttr('merchant', function ($value, $data) {
$find= Db::name('merchant')->where('mer_id', $data['mer_id'])->field('mer_id,mer_name')->find();
return $find;
})
->withAttr('sku', function ($value, $data) {
$find = Db::name('store_product_attr_value')->where('mer_id', $data['mer_id'])->where('product_id', $data['product_id'])->find();
return ['' => $find];
})
// ->field('product_id,mer_id,store_name,bar_code,price,stock,product_type,image')
->select();
return app('json')->success(['count' => $count, 'list' => $select]);
}
/**
* 镇级供应链列表
* @return mixed
*/
public function town()
{
// 除了市级供应链都可以查询
$typeIdArray = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeTownSupplyChain'])->column('mer_type_id');
$params = $this->request->params(['category_id', 'street_code', 'order', ['product_type', 0], 'keyword', 'page_num']);
$search = [
'street_id' => $params['street_code'],
'type_id' => $typeIdArray ?? [],
'type_id' => Merchant::TypeTownSupplyChain,
'status' => 1,
'is_del' => 0,
'mer_state' => 1,
@ -67,19 +180,6 @@ class CloudWarehouse extends BaseController
if (empty($merchantIds)) {
return app('json')->success(['count' => 0, 'list' => []]);
}
// 隐藏镇级云仓
// $typeCloudWarehouseId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeCloudWarehouse'])->value('mer_type_id');
// $entryWhere = [
// 'street_id' => $params['street_code'],
// 'type_id' => $typeCloudWarehouseId,
// 'status' => 1,
// 'is_del' => 0,
// 'mer_state' => 1,
// ];
// if (!empty($params['category_id'])) {
// $entryWhere['category_id'] = $params['category_id'];
// }
// $where['entry_mer_id'] = $this->merchantDao->search($entryWhere)->value('mer_id');
$where['entry_mer_id'] = 0;
$where['keyword'] = $params['keyword'];
@ -87,8 +187,7 @@ class CloudWarehouse extends BaseController
$where['product_type'] = $params['product_type'];
$where['is_gift_bag'] = 0;
$where['order'] = $params['order'] ?: 'sort';
$products = $this->spuRepository->getApiCloudSearch($where, $page, $limit, false);
$products = $this->spuRepository->getApiSearch($where, $page, $limit, false);
return app('json')->success($products);
}
}

View File

@ -3,28 +3,45 @@ namespace app\controller\api\store\product;
use app\common\dao\system\merchant\MerchantDao;
use app\common\model\system\merchant\Merchant;
use app\common\repositories\store\product\ProductRepository;
use app\controller\admin\ProductLibrary;
use think\facade\Db;
use crmeb\basic\BaseController;
use Exception;
class StoreMicro extends BaseController
{
function seach_bar_code($mer_id,$code='',$name=''){
$category_id=Db::name('merchant')->where('mer_id',$mer_id)->value('category_id');
$typePlatformId = Db::name('MerchantType')->where('type_code', 'in',[Merchant::TypeCode['TypePlatform'],Merchant::TypeCode['TypeTownSupplyChain']])->column('mer_type_id');
$platformMerId = app()->make(MerchantDao::class)->getValidMerchant(['category_id' => $category_id])->whereIn('type_id',$typePlatformId)->column('mer_id');
if($platformMerId==null){
return app('json')->fail('没有市级供应链或者镇级供应链');
}
$productWhere = ['is_show' => 1, 'status' => 1, 'mer_status' => 1, 'is_del' => 0];
function seach_bar_code($code='',$name=''){
$where = ['is_used' => 1, 'status' => 1, 'is_del' => 0];
$field = 'id,store_name,bar_code,manu_address,price,stock,image,slider_image,spec,trademark,manu_name,manu_address,note';
if($code!=''){
if (strlen($code) != 13) {
return app('json')->success('条形码长度不正确');
$res=Db::name('product_library')->where('bar_code',$code)->where($where)->field($field)
->withAttr('slider_image',function($value,$data){
return $value?explode(',',$value):[];
})
->find();
if($res==null){
$ProductLibrary = app()->make(ProductLibrary::class);
try{
$ProductLibrary->caiji($code);
$res=Db::name('product_library')->where('bar_code',$code)->where($where)->field($field)
->withAttr('slider_image',function($value,$data){
return $value?explode(',',$value):[];
})
->find();
}catch(Exception $e){
return app('json')->fail('编码:'.$code.'。'.$e->getMessage());
}
$product_id_arr=Db::name('store_product_attr_value')->whereIn('mer_id',$platformMerId)->where('bar_code',$code)->column('product_id');
$product_id_arr=implode(',',$product_id_arr);
$find=Db::name('store_product')->where('product_id',$product_id_arr)->where($productWhere)->select();
}
$find[]=$res;
}else{
$find=Db::name('store_product')->whereIn('mer_id',$platformMerId)->where('store_name','like','%'.$name.'%')->where($productWhere)->select();
if($name==''){
return app('json')->fail('参数不能为空');
}
$find=Db::name('product_library')->where('store_name','like','%'.$name.'%')->where($where)->field($field)
->withAttr('slider_image',function($value,$data){
return $value?explode(',',$value):[];
})
->select();
}
if (count($find)==0){
if($code!=''){
@ -52,48 +69,129 @@ class StoreMicro extends BaseController
//提交导入商品id
public function ProductImport(){
$product_id = $this->request->param('id', 0);
$id = $this->request->param('id', 0);
$price = $this->request->param('price', 0);
$stock = $this->request->param('stock', 0);
$store_name = $this->request->param('store_name', '');
$user = $this->request->userInfo();
$where = ['is_used' => 1, 'status' => 1, 'is_del' => 0];
try {
/** @var ProductRepository $productRepository */
$productRepository = app()->make(ProductRepository::class);
$a = $productRepository->import($product_id, $user);
} catch (\Exception $e) {
return app('json')->fail($e->getMessage());
$mer_id = Db::name('store_service')->where('uid', $user['uid'])->where('status', 1)->value('mer_id');
if ($mer_id == 0) {
return app('json')->fail('商户不存在');
}
$mer= Db::name('merchant')->where('mer_id', $mer_id)->find();
$category_name= Db::name('merchant_category')->where('merchant_category_id', $mer['category_id'])->value('category_name');
$store_category_id= Db::name('store_category')->where(['cate_name'=>$category_name,'level'=>2,'mer_id'=>0])->value('store_category_id');
if(!$store_category_id){
return app('json')->fail('没有对应的分类,请联系工作人员添加');
}
$find=Db::name('product_library')->where('id',$id)->where($where)->find();
if ($find) {
$exist = Db::name('store_product')->where('source_library_id', $id)->where('mer_id', $mer_id)->find();
if ($exist) {
// return app('json')->fail('已经导入过该商品了');
}
$find['attrValue']=[
['image'=>$find['image'],'price'=>$price,'cost'=>$find['cost'],'ot_price'=>$find['ot_price'],
'svip_price'=>0,'stock'=>$stock,'bar_code'=>$find['bar_code'],'weight'=>0,'volume'=>0,'detail'=>''
]];
if($mer['type_id']==12){
$product_type=98;
}else{
$product_type=0;
}
$find['store_name'] =$store_name??$find['store_name'];
$find['content'] =['image'=>explode(',',$find['images'])];
$find['slider_image'] =explode(',',$find['slider_image']);
$find['is_show'] = 1;
$find['mer_id'] = $mer_id;
$find['temp_id'] = "";
$find['give_coupon_ids'] = [];
$find['params'] = [];
$find['extend'] = [];
$find['param_temp_id'] = [];
$find['mer_labels'] = [];
$find['delivery_way'] = [0 => "2",1=>'1'];
$find["guarantee_template_id"] = "";
$find['product_type'] = $product_type;
$find['mer_cate_id'] = [0 => 0];
$find['is_used'] = 1;
$find['status'] = 1;
$find['mer_status'] = 1;
$find['source_product_id'] = 0;
$find['source_library_id'] = $find['id'];
$find['spec_type'] = 0;
$find['delivery_free'] = 0;
$find['cate_id'] = $store_category_id;
$find['svip_price_type'] = 0;
$find['svip_price'] =0;
unset($find['create_time'], $find['id']);
}
$a= app()->make( ProductRepository::class)->create($find,$product_type,1);
if($a){
return app('json')->success(['data'=>$a,'msg'=>'导入成功']);
return app('json')->success(['data'=>['product_id'=>$a],'msg'=>'导入成功']);
}else{
return app('json')->fail('导入失败');
}
} catch (\Exception $e) {
return app('json')->fail($e->getMessage());
}
}
public function eadtProduct(){
$product_id = $this->request->param('id', 0);
if ($product_id==0) return app('json')->fail('商品id不能为空');
$price = $this->request->param('price', 0);
if ($price==0) return app('json')->fail('价格不能为空');
$stock = $this->request->param('stock', 0);
if ($stock==0) return app('json')->fail('库存不能为空');
$user = $this->request->userInfo();
$mer_id =Db::name('store_service')->where('uid',$user['uid'])->where('status',1)->value('mer_id');
if ($mer_id==0) return app('json')->fail('商户id不能为空');
$data = [
'price'=>$price,
'stock'=>$stock,
];
Db::startTrans();
$id = $this->request->param('id', 0);
$image = $this->request->param('image', '');
$slider_image = $this->request->param('slider_image', '');
if ($slider_image=='') return app('json')->fail('轮播图不能为空');
if ($image=='') return app('json')->fail('首屏图不能为空');
try {
Db::name('store_product')->where('mer_id',$mer_id)->where('product_id',$product_id)->update($data);
Db::name('store_product_attr_value')->where('mer_id',$mer_id)->where('product_id',$product_id)->update($data);
// 提交事务
Db::commit();
return app('json')->success(['data'=>'','msg'=>'更新成功']);
$res=Db::name('product_library')->where('id',$id)->update(['image'=>$image,'slider_image'=>$slider_image]);
if($res){
return app('json')->success('更新成功');
}else{
return app('json')->fail('更新失败');
}
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return app('json')->fail($e->getMessage());
}
}
/**
* 待审核添加
*/
public function add()
{
$param = $this->request->param();
$uid=$this->request->userInfo()['uid'];
$mer_id=Db::name('store_service')->where(['uid'=>$uid,'status'=>1,'is_del'=>0,'is_goods'=>1])->value('mer_id');
$data['store_name'] = $param['store_name'];
$data['bar_code'] = $param['bar_code'];
$data['store_info'] = '';
$data['keyword'] = '';
$data['cate_id'] = 0;
$data['unit_name'] = '';
$data['is_used'] = 1;
$data['status'] = 1;
$data['price'] = $param['price'];
$data['stock'] = $param['stock'];
$data['create_time'] = date('Y-m-d H:i:s');
$data['image'] = $param['image'];
$data['slider_image'] = $param['slider_image'];
$data['images'] = $param['images'];
$data['mer_id'] = $mer_id;
$data['product_library_id'] = $param['product_library_id'];
$res = Db::name('product_library_examine')->insert($data);
if ($res) {
return app('json')->success('添加成功,等待审核');
} else {
return app('json')->fail('添加失败');
}
}
}

View File

@ -66,6 +66,7 @@ return [
'pay_success_meal' => [\crmeb\listens\pay\MealSuccessListen::class],
// 'community_address'=>[\app\listener\CommunityAddress::class],
'order.paySuccessOrder'=>[\app\listener\paySuccessOrder::class],
'order.paySuccess'=>[\app\listener\paySuccess::class],
'pay_success_margin'=>[\app\listener\paySuccessMargin::class],
'order.sendGoodsCode'=>[\app\listener\SendGoodsCode::class],
'product.create'=>[\app\listener\ProductCreate::class],

View File

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace app\listener;
use app\common\model\system\merchant\Merchant;
use app\common\repositories\store\product\ProductRepository;
use think\facade\Db;
/**
* 备份数据请勿删除
*/
class ProductCreate
{
public function handle($event)
{
$product = $event['product'];
$data = $event['data'];
$contentType = $event['conType'];
$merchant = Db::name('merchant')->where('status', 1)->where('is_del', 0)->where('mer_id', $product['mer_id'])->find();
if (empty($merchant)) {
return false;
}
// 根据支持同步到云商的商户进行同步操作
$syncMerArray = Db::name('MerchantType')->where('is_sync_prod', 1)->column('mer_type_id');
if (!in_array($merchant['type_id'], $syncMerArray)) {
return false;
}
$typeCloudWarehouseId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeCloudWarehouse'])->value('mer_type_id');
$typePlatformId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypePlatform'])->value('mer_type_id');
if ($merchant['type_id'] == $typePlatformId || $merchant['type_id'] == $typeCloudWarehouseId) {
return false;
}
//查询市级云仓
$cityMerchant = Db::name('merchant')->where('status', 1)->where('mer_state', 1)->where('category_id', $merchant['category_id'])->where('type_id', Merchant::TypePlatform)->find();
if ($cityMerchant == null) {
return false;
}
$product_id = Db::name('store_product')->where('mer_id', $cityMerchant['mer_id'])->where('bar_code', $product['bar_code'])->value('product_id');
if ($product_id) {
return false;
}
$data['mer_id'] = $cityMerchant['mer_id'];
$data['status'] = $cityMerchant['is_audit'] ? 0 : 1;
$data['mer_status'] = ($cityMerchant['is_del'] || !$cityMerchant['mer_state'] || !$cityMerchant['status']) ? 0 : 1;
$data['rate'] = 3;
// $typeSupplyChainId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeSupplyChain'])->value('mer_type_id');
// $productType = $cityMerchant['type_id'] == $typeSupplyChainId ? 98 : 0;
$productType =0;
$data['update_time'] = date('Y-m-d H:i:s');
app()->make(ProductRepository::class)->create($data, $productType, $contentType);
}
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
namespace app\listener;
@ -6,52 +7,59 @@ namespace app\listener;
use app\common\model\system\merchant\Merchant;
use app\common\repositories\store\product\ProductRepository;
use think\facade\Db;
use think\facade\Log;
class ProductCreate
{
public function handle($event)
{
Log::error(json_encode($event));
$product = $event['product'];
$data = $event['data'];
$contentType = $event['conType'];
// $data = $event['data'];
// $contentType = $event['conType'];
//查询当前商品的店铺
$merchant = Db::name('merchant')->where('status', 1)->where('is_del', 0)->where('mer_id', $product['mer_id'])->find();
if (empty($merchant)) {
return false;
}
$typeCloudWarehouseId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeCloudWarehouse'])->value('mer_type_id');
$typePlatformId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypePlatform'])->value('mer_type_id');
if ($merchant['type_id'] == $typePlatformId || $merchant['type_id'] == $typeCloudWarehouseId) {
if($merchant['type_id']!=Merchant::TypeTownSupplyChain){
return false;
}
// 根据支持同步到云商的商户进行同步操作
$syncMerArray = Db::name('MerchantType')->where('is_sync_prod', 1)->column('mer_type_id');
if (!in_array($merchant['type_id'], $syncMerArray)) {
// $syncMerArray = Db::name('MerchantType')->where('is_sync_prod', 1)->column('mer_type_id');
// if (!in_array($merchant['type_id'], $syncMerArray)) {
// return false;
// }
// $typeCloudWarehouseId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeCloudWarehouse'])->value('mer_type_id');
// $typePlatformId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypePlatform'])->value('mer_type_id');
// if ($merchant['type_id'] == $typePlatformId || $merchant['type_id'] == $typeCloudWarehouseId) {
// return false;
// }
//查询市级供应链
$cityMerchant = Db::name('merchant')->where('status', 1)->where('mer_state', 1)->where('category_id', $merchant['category_id'])->where('type_id', Merchant::TypeSupplyChain)->find();
if ($cityMerchant == null) {
return false;
}
//市级云仓
$cityMerchant = Db::name('merchant')->where('status', 1)->where('mer_state', 1)->where('category_id', $merchant['category_id'])->where('type_id', $typePlatformId)->find();
if ($cityMerchant) {
$where = ['mer_id' => $cityMerchant['mer_id'], 'is_del' => 0];
if ($product['bar_code'] != '' && in_array($product['product_type'], [0, 98]) && $product['spec_type'] == 0) {
$where['bar_code'] = $product['bar_code'];
} else {
$where['store_name'] = $product['store_name'];
//查询市级供应链商品
$product_id = Db::name('store_product')->where('mer_id', $cityMerchant['mer_id'])->where('bar_code', $product['bar_code'])->value('product_id');
if (!$product_id) {
return false;
}
$exist = Db::name('store_product')->where($where)->find();
if (!$exist) {
$data['mer_id'] = $cityMerchant['mer_id'];
$data['status'] = $cityMerchant['is_audit'] ? 0 : 1;
$data['mer_status'] = ($cityMerchant['is_del'] || !$cityMerchant['mer_state'] || !$cityMerchant['status']) ? 0 : 1;
$data['rate'] = 3;
$typeSupplyChainId = Db::name('MerchantType')->where('type_code', Merchant::TypeCode['TypeSupplyChain'])->value('mer_type_id');
$productType = $cityMerchant['type_id'] == $typeSupplyChainId ? 98 : 0;
$data['update_time'] = date('Y-m-d H:i:s');
app()->make(ProductRepository::class)->create($data, $productType, $contentType);
//添加到云仓
$datas=[
'product_id'=>$product_id,
'mer_id'=>$merchant['mer_id'],
'source_mer_id'=>$cityMerchant['mer_id'],
'street_code'=>$merchant['street_id'],
'type_id'=>$merchant['type_id'],
'category_id'=>$merchant['category_id'],
'weight'=>1,
'status'=>1,
'create_time'=>date('Y-m-d H:i:s'),
];
Db::name('cloud_product')->insert($datas);
}
}
}
}

View File

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace app\listener;
use app\common\dao\store\order\StoreCartDao;
use app\common\dao\system\merchant\MerchantDao;
use app\common\model\system\merchant\Merchant;
use app\common\repositories\store\order\StoreOrderRepository;
use app\common\repositories\system\merchant\FinancialRecordRepository;
use app\common\repositories\system\merchant\MerchantRepository;
use crmeb\utils\DingTalk;
use think\facade\Db;
use think\facade\Log;
/**
* 支付后逻辑
*/
class paySuccess
{
public $totalAmount;
public $event;
public $finance = [];
public $streetId;
public $financeSn;
public $index = 1;
public $remain;
public function handle($event)
{
try{
$orderList = $event['groupOrder']['orderList'];
foreach ($orderList as $k => $order) {
$merchant = Merchant::find($order['mer_id']);
//添加到代发订单表里
if($merchant['type_id']==Merchant::TypeSupplyChain){
$codes=explode(',',$order['user_address_code']);
if(count($codes)>4){
$merchant_two= Db::name('merchant')->where('street_id',$codes[3])->where('type_id',17)->where('category_id',$merchant['category_id'])->find();
if($merchant_two){
$datas=[
'master_mer_id'=>$order['mer_id'],
'mer_id'=>$merchant_two['mer_id'],
'order_id'=>$order['order_id'],
'status'=>1
];
Db::name('store_order_behalf')->insert($datas);
}
}
}
}
}catch(\Exception $e){
Log::error($e->getMessage().'lien:'.$e->getLine());
}
}
}

View File

@ -12,7 +12,9 @@ use app\common\repositories\system\merchant\MerchantRepository;
use crmeb\utils\DingTalk;
use think\facade\Db;
use think\facade\Log;
/**
* 支付后逻辑
*/
class paySuccessOrder
{
@ -26,6 +28,7 @@ class paySuccessOrder
public function handle($event)
{
Log::info('支付后逻辑22323233');
$this->event = $event;
$this->finance = [];
$this->index = 1;

View File

@ -23,7 +23,7 @@ class MerchantIntentionValidate extends Validate
'phone|手机号' => 'require|mobile',
'name|姓名' => 'require',
'mer_name|姓名' => 'require|max:32',
'merchant_category_id|商户分类' => 'require',
'merchant_category_name|商户分类' => 'require',
'mer_type_id|店铺类型' => 'integer',
'code|验证码' => 'require',
'images|资质' => 'array',

View File

@ -49,15 +49,17 @@
"phpoffice/phpspreadsheet": "^1.14",
"riverslei/payment": "^5.1",
"lizhichao/word": "^2.1",
"joypack/tencent-map": "^1.0",
"obs/esdk-obs-php": "^3.21",
"ucloud/ufile-php-sdk": "^1.0",
"swoole/ide-helper": "^4.8",
"alibabacloud/dysmsapi-20170525": "2.0.9",
"fastknife/ajcaptcha": "^1.1",
"vlucas/phpdotenv": "^5.3",
"overtrue/pinyin": "4.1.0",
"jpush/jpush": "^3.6"
"jpush/jpush": "^3.6",
"guzzlehttp/guzzle": "^6.5",
"topthink/think-api": "1.0.27",
"intervention/image": "^2.7",
"fastknife/ajcaptcha": "^1.2"
},
"require-dev": {
"symfony/var-dumper": "^4.2",

3392
composer.lock generated

File diff suppressed because it is too large Load Diff

BIN
composer.phar Normal file

Binary file not shown.

View File

@ -159,7 +159,6 @@ class QrcodeService
*/
public function getRoutineQrcodePath($namePath, $page, $data)
{
try {
$imageInfo = app()->make(AttachmentRepository::class)->getWhere(['attachment_name' => $namePath]);
if (!$imageInfo) {
@ -182,7 +181,9 @@ class QrcodeService
'attachment_src' => $imageInfo['dir']
]);
$url = $imageInfo['dir'];
} else $url = $imageInfo['attachment_src'];
}else{
$url = $imageInfo['attachment_src'];
}
return $url;
} catch (\Throwable $e) {
return false;

31
route/admin/library.php Normal file
View File

@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
use think\facade\Route;
use app\common\middleware\AdminAuthMiddleware;
use app\common\middleware\AdminTokenMiddleware;
use app\common\middleware\AllowOriginMiddleware;
use app\common\middleware\LogMiddleware;
Route::group(function () {
Route::group('library', function () {
Route::get('product_list', '/lst');
Route::get('caiji', '/caiji');
Route::post('add', '/add');
Route::post('edit', '/edit');
Route::post('del', '/del');
})->prefix('admin.ProductLibrary');
})->middleware(AllowOriginMiddleware::class)
->middleware(AdminTokenMiddleware::class, true)
->middleware(AdminAuthMiddleware::class)
->middleware(LogMiddleware::class);

View File

@ -50,6 +50,7 @@ Route::group('api/', function () {
Route::get('product_details', '/ProductDetails');
Route::post('eadt_product', '/eadtProduct');
Route::post('product_import', '/ProductImport');
Route::post('product_add', '/add');
})->prefix('api.store.product.StoreMicro');
Route::group('v2', function () {
@ -343,6 +344,11 @@ Route::group('api/', function () {
Route::post('/confirm', '/confirm');
})->prefix('api.server.StoreOrder')->middleware(\app\common\middleware\MerchantServerMiddleware::class, 0);
//代发货订单
Route::group('behalf_admin', function () {
Route::get('/order_list', '/lst');
Route::get('/code', '/logisticsCode');
})->prefix('api.store.order.StoreOrderBehalf');
//管理员申请转账
Route::get('admin/:merId/apply', 'api.store.merchant.Merchant/apply');
Route::post('admin/:merId/create_apply', 'api.store.merchant.Merchant/createApply');
@ -588,6 +594,7 @@ Route::group('api/', function () {
Route::any('store/test', 'api.Test/test');
Route::get('subscribe', 'api.Common/subscribe');
Route::resource('store/product/cloudWarehouse', 'api.store.product.CloudWarehouse');
Route::get('store/product/town_cloud', 'api.store.product.CloudWarehouse/town');
})->middleware(UserTokenMiddleware::class, false);
//微信支付回调
@ -716,5 +723,3 @@ Route::group('/open-location', function () {
Route::miss('View/h5');
})->middleware(InstallMiddleware::class)
->middleware(CheckSiteOpenMiddleware::class);

View File

@ -11,12 +11,12 @@
}
],
"require": {
"php": ">=5.5",
"php": "^5.5 || ^7.0 || ^8.0",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^4.0|^5.0|^6.0",
"squizlabs/php_codesniffer": "^3.0"
"phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5",
"squizlabs/php_codesniffer": "^3.6"
},
"autoload": {
"files": [

View File

@ -29,14 +29,25 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
*/
protected $items = [];
/**
* The delimiter (alternative to a '.') to be used.
*
* @var string
*/
protected $delimiter = '.';
/**
* Create a new Dot instance
*
* @param mixed $items
* @param string $delimiter
*/
public function __construct($items = [])
public function __construct($items = [], $delimiter = '.')
{
$this->items = $this->getArrayItems($items);
$this->delimiter = strlen($delimiter) ? $delimiter : '.';
}
/**
@ -104,7 +115,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
}
$items = &$this->items;
$segments = explode('.', $key);
$segments = explode($this->delimiter, $key);
$lastSegment = array_pop($segments);
foreach ($segments as $segment) {
@ -148,6 +159,10 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
$items = $this->items;
}
if (!func_num_args()) {
$delimiter = $this->delimiter;
}
foreach ($items as $key => $value) {
if (is_array($value) && !empty($value)) {
$flatten = array_merge(
@ -179,13 +194,13 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
return $this->items[$key];
}
if (strpos($key, '.') === false) {
if (strpos($key, $this->delimiter) === false) {
return $default;
}
$items = $this->items;
foreach (explode('.', $key) as $segment) {
foreach (explode($this->delimiter, $key) as $segment) {
if (!is_array($items) || !$this->exists($items, $segment)) {
return $default;
}
@ -234,7 +249,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
continue;
}
foreach (explode('.', $key) as $segment) {
foreach (explode($this->delimiter, $key) as $segment) {
if (!is_array($items) || !$this->exists($items, $segment)) {
return false;
}
@ -446,7 +461,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
$items = &$this->items;
foreach (explode('.', $keys) as $key) {
foreach (explode($this->delimiter, $keys) as $key) {
if (!isset($items[$key]) || !is_array($items[$key])) {
$items[$key] = [];
}
@ -507,6 +522,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
* @param int|string $key
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return $this->has($key);
@ -518,6 +534,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
* @param int|string $key
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->get($key);
@ -529,6 +546,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
* @param int|string|null $key
* @param mixed $value
*/
#[\ReturnTypeWillChange]
public function offsetSet($key, $value)
{
if (is_null($key)) {
@ -545,6 +563,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
*
* @param int|string $key
*/
#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
$this->delete($key);
@ -562,6 +581,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
* @param int|string|null $key
* @return int
*/
#[\ReturnTypeWillChange]
public function count($key = null)
{
return count($this->get($key));
@ -578,6 +598,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
*
* @return \ArrayIterator
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->items);
@ -594,6 +615,7 @@ class Dot implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
*
* @return array
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->items;

View File

@ -11,13 +11,14 @@ use Adbar\Dot;
if (! function_exists('dot')) {
/**
* Create a new Dot object with the given items
* Create a new Dot object with the given items and optional delimiter
*
* @param mixed $items
* @param string $delimiter
* @return \Adbar\Dot
*/
function dot($items)
function dot($items, $delimiter = '.')
{
return new Dot($items);
return new Dot($items, $delimiter);
}
}

View File

@ -149,7 +149,7 @@ $rsaKeyPair->getPrivateKey();
use AlibabaCloud\Credentials\Credential;
$bearerToken = new Credential([
'type' => 'bearer_token',
'type' => 'bearer',
'bearer_token' => '<bearer_token>',
]);
$bearerToken->getBearerToken();

View File

@ -150,7 +150,7 @@ If credential is required by the Cloud Call Centre (CCC), please apply for Beare
use AlibabaCloud\Credentials\Credential;
$bearerToken = new Credential([
'type' => 'bearer_token',
'type' => 'bearer',
'bearer_token' => '<bearer_token>',
]);
$bearerToken->getBearerToken();

View File

@ -47,7 +47,7 @@
"ext-sockets": "*",
"drupal/coder": "^8.3",
"symfony/dotenv": "^3.4",
"phpunit/phpunit": "^4.8.35|^5.4.3",
"phpunit/phpunit": "^5.7|^6.6|^7.5",
"monolog/monolog": "^1.24",
"composer/composer": "^1.8",
"mikey179/vfsstream": "^1.6",
@ -68,7 +68,10 @@
},
"config": {
"preferred-install": "dist",
"optimize-autoloader": true
"optimize-autoloader": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"minimum-stability": "dev",
"prefer-stable": true,

View File

@ -18,13 +18,13 @@ class BearerTokenCredential implements CredentialsInterface
/**
* BearerTokenCredential constructor.
*
* @param $bearerToken
* @param $bearer_token
*/
public function __construct($bearerToken)
public function __construct($bearer_token)
{
Filter::bearerToken($bearerToken);
Filter::bearerToken($bearer_token);
$this->bearerToken = $bearerToken;
$this->bearerToken = $bearer_token;
}
/**

View File

@ -35,6 +35,7 @@ class Credential
'ecs_ram_role' => EcsRamRoleCredential::class,
'ram_role_arn' => RamRoleArnCredential::class,
'rsa_key_pair' => RsaKeyPairCredential::class,
'bearer' => BearerTokenCredential::class,
];
/**

View File

@ -35,11 +35,11 @@ class Filter
public static function bearerToken($bearerToken)
{
if (!is_string($bearerToken)) {
throw new InvalidArgumentException('Bearer Token must be a string');
throw new InvalidArgumentException('bearer_token must be a string');
}
if ($bearerToken === '') {
throw new InvalidArgumentException('Bearer Token cannot be empty');
throw new InvalidArgumentException('bearer_token cannot be empty');
}
return $bearerToken;

View File

@ -11,10 +11,11 @@
],
"require": {
"php": ">5.5",
"alibabacloud/tea-utils": "^0.2.0",
"alibabacloud/tea-utils": "^0.2.17",
"alibabacloud/credentials": "^1.1",
"alibabacloud/openapi-util": "^0.1.10",
"alibabacloud/gateway-spi": "^0.0.1"
"alibabacloud/openapi-util": "^0.1.10|^0.2.1",
"alibabacloud/gateway-spi": "^1",
"alibabacloud/tea-xml": "^0.2"
},
"autoload": {
"psr-4": {

View File

@ -1,14 +1,15 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace Darabonba\OpenApi\Models;
use AlibabaCloud\Credentials\Credential;
use AlibabaCloud\Tea\Model;
use AlibabaCloud\Credentials\Credential;
use Darabonba\OpenApi\Models\GlobalParameters;
/**
* Model for initing client.
* Model for initing client
*/
class Config extends Model
{
@ -37,12 +38,13 @@ class Config extends Model
'type' => '',
'signatureVersion' => '',
'signatureAlgorithm' => '',
'key' => '',
'cert' => '',
'ca' => '',
];
public function validate()
{
}
public function toMap()
{
$res = [];
@ -118,13 +120,22 @@ class Config extends Model
if (null !== $this->signatureAlgorithm) {
$res['signatureAlgorithm'] = $this->signatureAlgorithm;
}
if (null !== $this->globalParameters) {
$res['globalParameters'] = null !== $this->globalParameters ? $this->globalParameters->toMap() : null;
}
if (null !== $this->key) {
$res['key'] = $this->key;
}
if (null !== $this->cert) {
$res['cert'] = $this->cert;
}
if (null !== $this->ca) {
$res['ca'] = $this->ca;
}
return $res;
}
/**
* @param array $map
*
* @return Config
*/
public static function fromMap($map = [])
@ -202,219 +213,212 @@ class Config extends Model
if (isset($map['signatureAlgorithm'])) {
$model->signatureAlgorithm = $map['signatureAlgorithm'];
}
if (isset($map['globalParameters'])) {
$model->globalParameters = GlobalParameters::fromMap($map['globalParameters']);
}
if (isset($map['key'])) {
$model->key = $map['key'];
}
if (isset($map['cert'])) {
$model->cert = $map['cert'];
}
if (isset($map['ca'])) {
$model->ca = $map['ca'];
}
return $model;
}
/**
* @description accesskey id
*
* @var string
*/
public $accessKeyId;
/**
* @description accesskey secret
*
* @var string
*/
public $accessKeySecret;
/**
* @description security token
*
* @example a.txt
*
* @var string
*/
public $securityToken;
/**
* @description http protocol
*
* @example http
*
* @var string
*/
public $protocol;
/**
* @description http method
*
* @example GET
*
* @var string
*/
public $method;
/**
* @description region id
*
* @example cn-hangzhou
*
* @var string
*/
public $regionId;
/**
* @description read timeout
*
* @example 10
*
* @var int
*/
public $readTimeout;
/**
* @description connect timeout
*
* @example 10
*
* @var int
*/
public $connectTimeout;
/**
* @description http proxy
*
* @example http://localhost
*
* @var string
*/
public $httpProxy;
/**
* @description https proxy
*
* @example https://localhost
*
* @var string
*/
public $httpsProxy;
/**
* @description credential
*
* @example
*
* @var Credential
*/
public $credential;
/**
* @description endpoint
*
* @example cs.aliyuncs.com
*
* @var string
*/
public $endpoint;
/**
* @description proxy white list
*
* @example http://localhost
*
* @var string
*/
public $noProxy;
/**
* @description max idle conns
*
* @example 3
*
* @var int
*/
public $maxIdleConns;
/**
* @description network for endpoint
*
* @example public
*
* @var string
*/
public $network;
/**
* @description user agent
*
* @example Alibabacloud/1
*
* @var string
*/
public $userAgent;
/**
* @description suffix for endpoint
*
* @example aliyun
*
* @var string
*/
public $suffix;
/**
* @description socks5 proxy
*
* @var string
*/
public $socks5Proxy;
/**
* @description socks5 network
*
* @example TCP
*
* @var string
*/
public $socks5NetWork;
/**
* @description endpoint type
*
* @example internal
*
* @var string
*/
public $endpointType;
/**
* @description OpenPlatform endpoint
*
* @example openplatform.aliyuncs.com
*
* @var string
*/
public $openPlatformEndpoint;
/**
* @description credential type
*
* @example access_key
*
* @deprecated
*
* @var string
*/
public $type;
/**
* @description Signature Version
*
* @example v1
*
* @var string
*/
public $signatureVersion;
/**
* @description Signature Algorithm
*
* @example ACS3-HMAC-SHA256
*
* @var string
*/
public $signatureAlgorithm;
/**
* @description Global Parameters
* @var GlobalParameters
*/
public $globalParameters;
/**
* @description privite key for client certificate
* @example MIIEvQ
* @var string
*/
public $key;
/**
* @description client certificate
* @example -----BEGIN CERTIFICATE-----
xxx-----END CERTIFICATE-----
* @var string
*/
public $cert;
/**
* @description server certificate
* @example -----BEGIN CERTIFICATE-----
xxx-----END CERTIFICATE-----
* @var string
*/
public $ca;
}

View File

@ -0,0 +1,42 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace Darabonba\OpenApi\Models;
use AlibabaCloud\Tea\Model;
class GlobalParameters extends Model
{
public function validate()
{
}
public function toMap()
{
$res = [];
if (null !== $this->headers) {
$res['headers'] = $this->headers;
}
if (null !== $this->queries) {
$res['queries'] = $this->queries;
}
return $res;
}
/**
* @param array $map
* @return GlobalParameters
*/
public static function fromMap($map = [])
{
$model = new self();
if (isset($map['headers'])) {
$model->headers = $map['headers'];
}
if (isset($map['queries'])) {
$model->queries = $map['queries'];
}
return $model;
}
public $headers;
public $queries;
}

View File

@ -1,7 +1,6 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace Darabonba\OpenApi\Models;
use AlibabaCloud\Tea\Model;
@ -11,7 +10,6 @@ class OpenApiRequest extends Model
public function validate()
{
}
public function toMap()
{
$res = [];
@ -30,13 +28,13 @@ class OpenApiRequest extends Model
if (null !== $this->hostMap) {
$res['hostMap'] = $this->hostMap;
}
if (null !== $this->endpointOverride) {
$res['endpointOverride'] = $this->endpointOverride;
}
return $res;
}
/**
* @param array $map
*
* @return OpenApiRequest
*/
public static function fromMap($map = [])
@ -57,10 +55,11 @@ class OpenApiRequest extends Model
if (isset($map['hostMap'])) {
$model->hostMap = $map['hostMap'];
}
if (isset($map['endpointOverride'])) {
$model->endpointOverride = $map['endpointOverride'];
}
return $model;
}
public $headers;
public $query;
@ -70,4 +69,6 @@ class OpenApiRequest extends Model
public $stream;
public $hostMap;
public $endpointOverride;
}

View File

@ -1,7 +1,6 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace Darabonba\OpenApi\Models;
use AlibabaCloud\Tea\Model;
@ -19,7 +18,6 @@ class Params extends Model
Model::validateRequired('bodyType', $this->bodyType, true);
Model::validateRequired('reqBodyType', $this->reqBodyType, true);
}
public function toMap()
{
$res = [];
@ -50,13 +48,10 @@ class Params extends Model
if (null !== $this->style) {
$res['style'] = $this->style;
}
return $res;
}
/**
* @param array $map
*
* @return Params
*/
public static function fromMap($map = [])
@ -89,10 +84,8 @@ class Params extends Model
if (isset($map['style'])) {
$model->style = $map['style'];
}
return $model;
}
/**
* @var string
*/

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@ use Darabonba\GatewaySpi\Models\InterceptorContext;
use Darabonba\GatewaySpi\Models\AttributeMap;
abstract class Client {
public function __construct(){
}
/**
* @param InterceptorContext $context

View File

@ -16,7 +16,7 @@
"lizhichao/one-sm": "^1.5"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35|^5.4.3"
"phpunit/phpunit": "*"
},
"autoload": {
"psr-4": {

View File

@ -8,7 +8,7 @@
<directory>tests</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>

View File

@ -160,26 +160,26 @@ class OpenApiUtilClient
}
/**
* Parse array into a string with specified style.
* Parse object into a string with specified style.
*
* @style specified style e.g. repeatList
*
* @param mixed $array the array
* @param mixed $object the object
* @param string $prefix the prefix string
* @param string $style
*
* @return string the string
*/
public static function arrayToStringWithSpecifiedStyle($array, $prefix, $style)
public static function arrayToStringWithSpecifiedStyle($object, $prefix, $style)
{
if (null === $array) {
if (null === $object) {
return '';
}
if ('repeatList' === $style) {
return self::toForm([$prefix => $array]);
return self::toForm([$prefix => $object]);
}
if ('simple' == $style || 'spaceDelimited' == $style || 'pipeDelimited' == $style) {
$strs = self::flatten($array);
$strs = self::flatten($object);
switch ($style) {
case 'spaceDelimited':
@ -192,7 +192,8 @@ class OpenApiUtilClient
return implode(',', $strs);
}
} elseif ('json' === $style) {
return json_encode($array);
self::parse($object, $parsed);
return json_encode($parsed);
}
return '';
@ -436,6 +437,9 @@ class OpenApiUtilClient
self::flatten($value, $delimiter, $prepend . $pos . $delimiter)
);
} else {
if (\is_bool($value)) {
$value = true === $value ? 'true' : 'false';
}
$flatten[$prepend . $pos] = $value;
}
}

View File

@ -63,12 +63,14 @@ class OpenApiUtilClientTest extends TestCase
public function testToForm()
{
$this->assertEquals('client=test&strs.1=str1&strs.2=str2&tag.key=value', OpenApiUtilClient::toForm([
$this->assertEquals('bool=true&client=test&strs.1=str1&strs.2=str2&strs.3=false&tag.key=value', OpenApiUtilClient::toForm([
'client' => 'test',
'tag' => [
'key' => 'value',
],
'strs' => ['str1', 'str2'],
'strs' => ['str1', 'str2', false],
'bool' => true,
'null' => null,
]));
}
@ -83,6 +85,7 @@ class OpenApiUtilClientTest extends TestCase
$model = new MockModel();
$model->a = 'foo';
$model->c = 'boo';
$model->r = true;
$array = [
'a' => 'a',
@ -95,7 +98,9 @@ class OpenApiUtilClientTest extends TestCase
'c' => ['x', 'y', 'z'],
'd' => [
$model
]
],
'e' => true,
'f' => null,
];
$this->assertEquals([
'a' => 'a',
@ -107,6 +112,10 @@ class OpenApiUtilClientTest extends TestCase
'd.1.A' => 'foo',
'd.1.b' => '',
'd.1.c' => 'boo',
'd.1.c' => 'boo',
'd.1.r' => 'true',
'e' => 'true',
'f' => null
], OpenApiUtilClient::query($array));
}
@ -142,6 +151,48 @@ class OpenApiUtilClientTest extends TestCase
)
);
$test = new ParseModel([
'str' => 'A',
'model' => new ParseModel(['str' => 'sub model']),
'array' => [1, 2, 3],
]);
$this->assertEquals(
'{"str":"A","model":{"str":"sub model","model":null,"array":null},"array":[1,2,3]}',
OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
$test,
'instance',
'json'
)
);
// model item in array
$test = [
new ParseModel([
'str' => 'A',
]),
];
$this->assertEquals(
'[{"str":"A","model":null,"array":null}]',
OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
$test,
'instance',
'json'
)
);
// model item in map
$test = [
'model' => new ParseModel([
'str' => 'A',
]),
];
$this->assertEquals(
'{"model":{"str":"A","model":null,"array":null}}',
OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
$test,
'instance',
'json'
)
);
$this->assertEquals(
'ok,test,2,3',
OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
@ -295,7 +346,8 @@ class OpenApiUtilClientTest extends TestCase
'b9ff646822f41ef647c1416fa2b8408923828abc0464af6706e18db3e8553da8',
OpenApiUtilClient::hexEncode(OpenApiUtilClient::sign('secret', 'source', 'ACS3-HMAC-SM3'))
);
$this->assertEquals('1d93c62698a1c26427265668e79fac099aa26c1df873669599a2fb2f272e64c9',
$this->assertEquals(
'1d93c62698a1c26427265668e79fac099aa26c1df873669599a2fb2f272e64c9',
OpenApiUtilClient::hexEncode(OpenApiUtilClient::sign('secret', 'source', 'ACS3-HMAC-SHA256'))
);
}
@ -347,6 +399,12 @@ class OpenApiUtilClientTest extends TestCase
],
],
],
'expectedJsonStr' => [
'["NotArray"]',
'NotArray',
'NotArray',
'NotArray',
],
];
}
}

View File

@ -1,12 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false" backupStaticAttributes="false" bootstrap="tests/bootstrap.php" colors="true"
convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true"
executionOrder="depends,defects" processIsolation="false" stopOnFailure="false">
<logging>
<log type="coverage-html" target="cache/coverage" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="cache/coverage.clover"/>
</logging>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="tests/bootstrap.php" colors="true" executionOrder="depends,defects" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
<report>
<clover outputFile="cache/coverage.clover"/>
<html outputDirectory="cache/coverage" lowUpperBound="35" highLowerBound="70"/>
</report>
</coverage>
<logging/>
<testsuites>
<testsuite name="default">
<directory suffix="Test.php">tests</directory>

View File

@ -19,6 +19,9 @@ class Utils
*/
public static function toBytes($string)
{
if (self::is_bytes($string)) {
return $string;
}
$bytes = [];
for ($i = 0; $i < \strlen($string); ++$i) {
$bytes[] = \ord($string[$i]);
@ -36,6 +39,9 @@ class Utils
*/
public static function toString($bytes)
{
if (\is_string($bytes)) {
return $bytes;
}
$str = '';
foreach ($bytes as $ch) {
$str .= \chr($ch);
@ -177,15 +183,15 @@ class Utils
*/
public static function toJSONString($object)
{
if (null === $object) {
$object = new \stdClass();
if (is_string($object)) {
return $object;
}
if ($object instanceof Model) {
$object = $object->toMap();
}
return json_encode($object);
return json_encode($object, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);
}
/**
@ -314,7 +320,11 @@ class Utils
*/
public static function assertAsBoolean($value)
{
return \is_bool($value);
if (\is_bool($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a boolean value.');
}
/**
@ -322,21 +332,18 @@ class Utils
*
* @param mixed $value
*
* @return bool the string value
* @return string the string value
*/
public static function assertAsString($value)
{
return \is_string($value);
if (\is_string($value)) {
return $value;
}
/**
* Assert a value, if it is a bytes, return it, otherwise throws.
*
* @param mixed $value
*
* @return bool the bytes value
*/
public static function assertAsBytes($value)
throw new \InvalidArgumentException('It is not a string value.');
}
private static function is_bytes($value)
{
if (!\is_array($value)) {
return false;
@ -358,16 +365,49 @@ class Utils
return true;
}
/**
* Assert a value, if it is a bytes, return it, otherwise throws.
*
* @param mixed $value
*
* @return bytes the bytes value
*/
public static function assertAsBytes($value)
{
if (self::is_bytes($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a bytes value.');
}
/**
* Assert a value, if it is a number, return it, otherwise throws.
*
* @param mixed $value
*
* @return bool the number value
* @return int the number value
*/
public static function assertAsNumber($value)
{
return is_numeric($value);
if (\is_numeric($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a number value.');
}
/**
* Assert a value, if it is a integer, return it, otherwise throws
* @param mixed $value
* @return int the integer value
*/
public static function assertAsInteger($value){
if (\is_int($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a int value.');
}
/**

View File

@ -1,39 +1,261 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Tea\Model;
class RuntimeOptions extends Model
{
/**
* The common runtime options model
*/
class RuntimeOptions extends Model {
protected $_name = [
'autoretry' => 'autoretry',
'ignoreSSL' => 'ignoreSSL',
'key' => 'key',
'cert' => 'cert',
'ca' => 'ca',
'maxAttempts' => 'max_attempts',
'backoffPolicy' => 'backoff_policy',
'backoffPeriod' => 'backoff_period',
'readTimeout' => 'readTimeout',
'connectTimeout' => 'connectTimeout',
'httpProxy' => 'httpProxy',
'httpsProxy' => 'httpsProxy',
'noProxy' => 'noProxy',
'maxIdleConns' => 'maxIdleConns',
'localAddr' => 'localAddr',
'socks5Proxy' => 'socks5Proxy',
'socks5NetWork' => 'socks5NetWork',
'keepAlive' => 'keepAlive',
];
public function validate() {}
public function toMap() {
$res = [];
if (null !== $this->autoretry) {
$res['autoretry'] = $this->autoretry;
}
if (null !== $this->ignoreSSL) {
$res['ignoreSSL'] = $this->ignoreSSL;
}
if (null !== $this->key) {
$res['key'] = $this->key;
}
if (null !== $this->cert) {
$res['cert'] = $this->cert;
}
if (null !== $this->ca) {
$res['ca'] = $this->ca;
}
if (null !== $this->maxAttempts) {
$res['max_attempts'] = $this->maxAttempts;
}
if (null !== $this->backoffPolicy) {
$res['backoff_policy'] = $this->backoffPolicy;
}
if (null !== $this->backoffPeriod) {
$res['backoff_period'] = $this->backoffPeriod;
}
if (null !== $this->readTimeout) {
$res['readTimeout'] = $this->readTimeout;
}
if (null !== $this->connectTimeout) {
$res['connectTimeout'] = $this->connectTimeout;
}
if (null !== $this->httpProxy) {
$res['httpProxy'] = $this->httpProxy;
}
if (null !== $this->httpsProxy) {
$res['httpsProxy'] = $this->httpsProxy;
}
if (null !== $this->noProxy) {
$res['noProxy'] = $this->noProxy;
}
if (null !== $this->maxIdleConns) {
$res['maxIdleConns'] = $this->maxIdleConns;
}
if (null !== $this->localAddr) {
$res['localAddr'] = $this->localAddr;
}
if (null !== $this->socks5Proxy) {
$res['socks5Proxy'] = $this->socks5Proxy;
}
if (null !== $this->socks5NetWork) {
$res['socks5NetWork'] = $this->socks5NetWork;
}
if (null !== $this->keepAlive) {
$res['keepAlive'] = $this->keepAlive;
}
return $res;
}
/**
* @param array $map
* @return RuntimeOptions
*/
public static function fromMap($map = []) {
$model = new self();
if(isset($map['autoretry'])){
$model->autoretry = $map['autoretry'];
}
if(isset($map['ignoreSSL'])){
$model->ignoreSSL = $map['ignoreSSL'];
}
if(isset($map['key'])){
$model->key = $map['key'];
}
if(isset($map['cert'])){
$model->cert = $map['cert'];
}
if(isset($map['ca'])){
$model->ca = $map['ca'];
}
if(isset($map['max_attempts'])){
$model->maxAttempts = $map['max_attempts'];
}
if(isset($map['backoff_policy'])){
$model->backoffPolicy = $map['backoff_policy'];
}
if(isset($map['backoff_period'])){
$model->backoffPeriod = $map['backoff_period'];
}
if(isset($map['readTimeout'])){
$model->readTimeout = $map['readTimeout'];
}
if(isset($map['connectTimeout'])){
$model->connectTimeout = $map['connectTimeout'];
}
if(isset($map['httpProxy'])){
$model->httpProxy = $map['httpProxy'];
}
if(isset($map['httpsProxy'])){
$model->httpsProxy = $map['httpsProxy'];
}
if(isset($map['noProxy'])){
$model->noProxy = $map['noProxy'];
}
if(isset($map['maxIdleConns'])){
$model->maxIdleConns = $map['maxIdleConns'];
}
if(isset($map['localAddr'])){
$model->localAddr = $map['localAddr'];
}
if(isset($map['socks5Proxy'])){
$model->socks5Proxy = $map['socks5Proxy'];
}
if(isset($map['socks5NetWork'])){
$model->socks5NetWork = $map['socks5NetWork'];
}
if(isset($map['keepAlive'])){
$model->keepAlive = $map['keepAlive'];
}
return $model;
}
/**
* @description whether to try again
* @var bool
*/
public $autoretry;
/**
* @description ignore SSL validation
* @var bool
*/
public $ignoreSSL;
/**
* @description privite key for client certificate
* @var string
*/
public $key;
/**
* @description client certificate
* @var string
*/
public $cert;
/**
* @description server certificate
* @var string
*/
public $ca;
/**
* @description maximum number of retries
* @var int
*/
public $maxAttempts;
/**
* @description backoff policy
* @var string
*/
public $backoffPolicy;
/**
* @description backoff period
* @var int
*/
public $backoffPeriod;
/**
* @description read timeout
* @var int
*/
public $readTimeout;
/**
* @description connect timeout
* @var int
*/
public $connectTimeout;
/**
* @description http proxy url
* @var string
*/
public $httpProxy;
/**
* @description https Proxy url
* @var string
*/
public $httpsProxy;
/**
* @description agent blacklist
* @var string
*/
public $noProxy;
/**
* @description maximum number of connections
* @var int
*/
public $maxIdleConns;
/**
* @description local addr
* @var string
*/
public $localAddr;
/**
* @description SOCKS5 proxy
* @var string
*/
public $socks5Proxy;
/**
* @description SOCKS5 netWork
* @var string
*/
public $socks5NetWork;
protected $_name = [];
/**
* @description whether to enable keep-alive
* @var bool
*/
public $keepAlive;
}

View File

@ -4,6 +4,7 @@ namespace AlibabaCloud\Tea\Utils\Tests;
use AlibabaCloud\Tea\Model;
use AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use GuzzleHttp\Psr7\Stream;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
@ -24,6 +25,11 @@ final class UtilsTest extends TestCase
$this->assertEquals([
115, 116, 114, 105, 110, 103,
], Utils::toBytes('string'));
$this->assertEquals([
115, 116, 114, 105, 110, 103,
], Utils::toBytes([
115, 116, 114, 105, 110, 103,
]));
}
public function testToString()
@ -31,6 +37,7 @@ final class UtilsTest extends TestCase
$this->assertEquals('string', Utils::toString([
115, 116, 114, 105, 110, 103,
]));
$this->assertEquals('string', Utils::toString('string'));
}
public function testParseJSON()
@ -106,6 +113,22 @@ final class UtilsTest extends TestCase
{
$object = new \stdClass();
$this->assertJson(Utils::toJSONString($object));
$this->assertEquals('[]', Utils::toJSONString([]));
$this->assertEquals('["foo"]', Utils::toJSONString(['foo']));
$this->assertEquals(
'{"str":"test","number":1,"bool":false,"null":null,"chinese":"中文","http":"https://aliyun.com:8080/zh/中文.html"}',
Utils::toJSONString([
'str' => 'test',
'number' => 1,
'bool' => FALSE,
'null' => null,
'chinese' => '中文',
'http' => 'https://aliyun.com:8080/zh/中文.html',
])
);
$this->assertEquals('1', Utils::toJSONString(1));
$this->assertEquals('true', Utils::toJSONString(TRUE));
$this->assertEquals('null', Utils::toJSONString(null));
}
public function testEmpty()
@ -170,39 +193,88 @@ final class UtilsTest extends TestCase
public function testAssertAsBoolean()
{
$this->assertTrue(Utils::assertAsBoolean(true));
$this->assertFalse(Utils::assertAsBoolean('true'));
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a boolean value.');
Utils::assertAsBoolean('true');
try {
$map = true;
$this->assertEquals($map, Utils::assertAsBoolean($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsString()
{
$this->assertTrue(Utils::assertAsString('123'));
$this->assertFalse(Utils::assertAsString(123));
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a string value.');
Utils::assertAsString(123);
try {
$map = '123';
$this->assertEquals($map, Utils::assertAsString($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsBytes()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a bytes value.');
// failed because $var is not array
$this->assertFalse(Utils::assertAsBytes('test'));
Utils::assertAsBytes('test');
// failed because $var is map not array
$this->assertFalse(Utils::assertAsBytes(['foo' => 1]));
Utils::assertAsBytes(['foo' => 1]);
// failed because item value is not int
$this->assertFalse(Utils::assertAsBytes(['1']));
Utils::assertAsBytes(['1']);
// failed because item value is out off range
$this->assertFalse(Utils::assertAsBytes([256]));
Utils::assertAsBytes([256]);
try {
// success
$this->assertTrue(Utils::assertAsBytes([1, 2, 3]));
$this->assertTrue(Utils::assertAsBytes(Utils::toBytes('string')));
$map = [1, 2, 3];
$this->assertEquals($map, Utils::assertAsBytes($map));
$this->assertEquals([
115, 116, 114, 105, 110, 103,
], Utils::assertAsBytes(Utils::toBytes('string')));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsNumber()
{
$this->assertTrue(Utils::assertAsNumber(123));
$this->assertFalse(Utils::assertAsNumber('string'));
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a number value.');
Utils::assertAsNumber('is not number');
try {
$map = 123;
$this->assertEquals($map, Utils::assertAsNumber($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsInteger()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a int value.');
Utils::assertAsInteger('is not int');
try {
$map = 123;
$this->assertEquals($map, Utils::assertAsInteger($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsMap()
@ -326,6 +398,42 @@ final class UtilsTest extends TestCase
Utils::assertAsReadable(0);
}
public function testRuntimeOptions()
{
$opts = new RuntimeOptions([
"autoretry" => false,
"ignoreSSL" => false,
"key" => "key",
"cert" => "cert",
"ca" => "ca",
"maxAttempts" => 3,
"backoffPolicy" => "backoffPolicy",
"backoffPeriod" => 10,
"readTimeout" => 3000,
"connectTimeout" => 3000,
"httpProxy" => "httpProxy",
"httpsProxy" => "httpsProxy",
"noProxy" => "noProxy",
"maxIdleConns" => 300,
"keepAlive" => true,
]);
$this->assertEquals(false, $opts->autoretry);
$this->assertEquals(false, $opts->ignoreSSL);
$this->assertEquals("key", $opts->key);
$this->assertEquals("cert", $opts->cert);
$this->assertEquals("ca", $opts->ca);
$this->assertEquals(3, $opts->maxAttempts);
$this->assertEquals("backoffPolicy", $opts->backoffPolicy);
$this->assertEquals(10, $opts->backoffPeriod);
$this->assertEquals(3000, $opts->readTimeout);
$this->assertEquals(3000, $opts->connectTimeout);
$this->assertEquals("httpProxy", $opts->httpProxy);
$this->assertEquals("httpsProxy", $opts->httpsProxy);
$this->assertEquals("noProxy", $opts->noProxy);
$this->assertEquals(300, $opts->maxIdleConns);
$this->assertEquals(true, $opts->keepAlive);
}
private function convert($body, &$content)
{
$class = new \ReflectionClass($body);

12
vendor/alibabacloud/tea-xml/.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
composer.phar
/vendor/
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
composer.lock
.idea
.DS_Store
cache/
*.cache

View File

@ -0,0 +1,65 @@
<?php
/*
* This document has been generated with
* https://mlocati.github.io/php-cs-fixer-configurator/#version:2.15|configurator
* you can change this configuration by importing this file.
*/
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setIndent(' ')
->setRules([
'@PSR2' => true,
'@PhpCsFixer' => true,
'@Symfony:risky' => true,
'concat_space' => ['spacing' => 'one'],
'array_syntax' => ['syntax' => 'short'],
'array_indentation' => true,
'combine_consecutive_unsets' => true,
'method_separation' => true,
'single_quote' => true,
'declare_equal_normalize' => true,
'function_typehint_space' => true,
'hash_to_slash_comment' => true,
'include' => true,
'lowercase_cast' => true,
'no_multiline_whitespace_before_semicolons' => true,
'no_leading_import_slash' => true,
'no_multiline_whitespace_around_double_arrow' => true,
'no_spaces_around_offset' => true,
'no_unneeded_control_parentheses' => true,
'no_unused_imports' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'single_blank_line_before_namespace' => true,
'single_class_element_per_statement' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
'no_extra_consecutive_blank_lines' => [
'curly_brace_block',
'extra',
'parenthesis_brace_block',
'square_brace_block',
'throw',
'use',
],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true,
],
'braces' => [
'allow_single_line_closure' => true,
],
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude('vendor')
->exclude('tests')
->in(__DIR__)
);

View File

@ -0,0 +1,31 @@
English | [简体中文](README-CN.md)
![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
## Alibaba Cloud Tea XML Library for PHP
## Installation
### Composer
```bash
composer require alibabacloud/tea-xml
```
## Issues
[Opening an Issue](https://github.com/aliyun/tea-xml/issues/new), Issues not conforming to the guidelines may be closed immediately.
## Changelog
Detailed changes for each release are documented in the [release notes](./ChangeLog.txt).
## References
* [Latest Release](https://github.com/aliyun/tea-xml)
## License
[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

31
vendor/alibabacloud/tea-xml/README.md vendored Normal file
View File

@ -0,0 +1,31 @@
[English](README.md) | 简体中文
![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
## Alibaba Cloud Tea XML Library for PHP
## 安装
### Composer
```bash
composer require alibabacloud/tea-xml
```
## 问题
[提交 Issue](https://github.com/aliyun/tea-xml/issues/new),不符合指南的问题可能会立即关闭。
## 发行说明
每个版本的详细更改记录在[发行说明](./ChangeLog.txt)中。
## 相关
* [最新源码](https://github.com/aliyun/tea-xml)
## 许可证
[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

View File

@ -0,0 +1,44 @@
{
"name": "alibabacloud/tea-xml",
"description": "Alibaba Cloud Tea XML Library for PHP",
"type": "library",
"license": "Apache-2.0",
"authors": [
{
"name": "Alibaba Cloud SDK",
"email": "sdk-team@alibabacloud.com"
}
],
"require": {
"php": ">5.5"
},
"require-dev": {
"phpunit/phpunit": "*",
"symfony/var-dumper": "*"
},
"autoload": {
"psr-4": {
"AlibabaCloud\\Tea\\XML\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"AlibabaCloud\\Tea\\XML\\Tests\\": "tests"
}
},
"scripts": {
"fixer": "php-cs-fixer fix ./",
"test": [
"@clearCache",
"phpunit --colors=always"
],
"clearCache": "rm -rf cache/*"
},
"config": {
"sort-packages": true,
"preferred-install": "dist",
"optimize-autoloader": true
},
"prefer-stable": true,
"minimum-stability": "dev"
}

32
vendor/alibabacloud/tea-xml/phpunit.xml vendored Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php" colors="true" processIsolation="false" stopOnFailure="false"
convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true"
testSuiteLoaderFile="phpunit/src/Runner/StandardTestSuiteLoader.php">
<testsuites>
<testsuite name="All">
<directory>tests</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>integration</group>
</exclude>
</groups>
<logging>
<log type="coverage-html" target="cache/coverage" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="cache/coverage.clover"/>
</logging>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
</phpunit>

View File

@ -0,0 +1,151 @@
<?php
namespace AlibabaCloud\Tea\XML;
use XmlWriter;
/**
* Based on: http://stackoverflow.com/questions/99350/passing-php-associative-arrays-to-and-from-xml.
*/
class ArrayToXml
{
private $version;
private $encoding;
/**
* Construct ArrayToXML object with selected version and encoding
* for available values check XmlWriter docs http://www.php.net/manual/en/function.xmlwriter-start-document.php.
*
* @param string $xmlVersion XML Version, default 1.0
* @param string $xmlEncoding XML Encoding, default UTF-8
*/
public function __construct($xmlVersion = '1.0', $xmlEncoding = 'utf-8')
{
$this->version = $xmlVersion;
$this->encoding = $xmlEncoding;
}
/**
* Build an XML Data Set.
*
* @param array $data Associative Array containing values to be parsed into an XML Data Set(s)
* @param string $startElement Root Opening Tag, default data
*
* @return string XML String containing values
* @return mixed Boolean false on failure, string XML result on success
*/
public function buildXML($data, $startElement = 'data')
{
if (!\is_array($data)) {
$err = 'Invalid variable type supplied, expected array not found on line ' . __LINE__ . ' in Class: ' . __CLASS__ . ' Method: ' . __METHOD__;
trigger_error($err);
return false; //return false error occurred
}
$xml = new XmlWriter();
$xml->openMemory();
$xml->startDocument($this->version, $this->encoding);
$xml->startElement($startElement);
$data = $this->writeAttr($xml, $data);
$this->writeEl($xml, $data);
$xml->endElement(); //write end element
//returns the XML results
return $xml->outputMemory(true);
}
/**
* Write keys in $data prefixed with @ as XML attributes, if $data is an array.
* When an @ prefixed key is found, a '%' key is expected to indicate the element itself,
* and '#' prefixed key indicates CDATA content.
*
* @param XMLWriter $xml object
* @param array $data with attributes filtered out
*
* @return array $data | $nonAttributes
*/
protected function writeAttr(XMLWriter $xml, $data)
{
if (\is_array($data)) {
$nonAttributes = [];
foreach ($data as $key => $val) {
//handle an attribute with elements
if ('@' == $key[0]) {
$xml->writeAttribute(substr($key, 1), $val);
} elseif ('%' == $key[0]) {
if (\is_array($val)) {
$nonAttributes = $val;
} else {
$xml->text($val);
}
} elseif ('#' == $key[0]) {
if (\is_array($val)) {
$nonAttributes = $val;
} else {
$xml->startElement(substr($key, 1));
$xml->writeCData($val);
$xml->endElement();
}
} elseif ('!' == $key[0]) {
if (\is_array($val)) {
$nonAttributes = $val;
} else {
$xml->writeCData($val);
}
} //ignore normal elements
else {
$nonAttributes[$key] = $val;
}
}
return $nonAttributes;
}
return $data;
}
/**
* Write XML as per Associative Array.
*
* @param XMLWriter $xml object
* @param array $data Associative Data Array
*/
protected function writeEl(XMLWriter $xml, $data)
{
foreach ($data as $key => $value) {
if (\is_array($value) && !$this->isAssoc($value)) { //numeric array
foreach ($value as $itemValue) {
if (\is_array($itemValue)) {
$xml->startElement($key);
$itemValue = $this->writeAttr($xml, $itemValue);
$this->writeEl($xml, $itemValue);
$xml->endElement();
} else {
$itemValue = $this->writeAttr($xml, $itemValue);
$xml->writeElement($key, "{$itemValue}");
}
}
} elseif (\is_array($value)) { //associative array
$xml->startElement($key);
$value = $this->writeAttr($xml, $value);
$this->writeEl($xml, $value);
$xml->endElement();
} else { //scalar
$value = $this->writeAttr($xml, $value);
$xml->writeElement($key, "{$value}");
}
}
}
/**
* Check if array is associative with string based keys
* FROM: http://stackoverflow.com/questions/173400/php-arrays-a-good-way-to-check-if-an-array-is-associative-or-sequential/4254008#4254008.
*
* @param array $array Array to check
*
* @return bool
*/
protected function isAssoc($array)
{
return (bool) \count(array_filter(array_keys($array), 'is_string'));
}
}

59
vendor/alibabacloud/tea-xml/src/XML.php vendored Normal file
View File

@ -0,0 +1,59 @@
<?php
namespace AlibabaCloud\Tea\XML;
class XML
{
public static function parseXml($xmlStr, $response)
{
$res = self::parse($xmlStr);
if ($response === null) {
return $res;
} else {
if (\is_string($response)) {
$response = new $response();
}
$prop = get_object_vars($response);
$target = [];
foreach ($res as $k => $v) {
if (isset($prop[$k])) {
$target[$k] = $v;
}
}
return $target;
}
}
public static function toXML($array)
{
$arrayToXml = new ArrayToXml();
if (\is_object($array)) {
$tmp = explode('\\', \get_class($array));
$rootName = $tmp[\count($tmp) - 1];
$data = json_decode(json_encode($array), true);
} else {
$tmp = $array;
reset($tmp);
$rootName = key($tmp);
$data = $array[$rootName];
}
ksort($data);
return $arrayToXml->buildXML($data, $rootName);
}
private static function parse($xml)
{
if (\PHP_VERSION_ID < 80000) {
libxml_disable_entity_loader(true);
}
return json_decode(
json_encode(
simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)
),
true
);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace AlibabaCloud\Tea\XML\Tests;
use AlibabaCloud\Tea\XML\XML;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class RpcUtilsTest extends TestCase
{
private $xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
"<tests>\n" .
" <name>test</name>\n" .
" <value>1</value>\n" .
"</tests>\n";
public function testParseXml()
{
$res = XML::parseXml($this->xmlStr, new tests());
$name = $res['name'];
$value = $res['value'];
$this->assertEquals('test', $name);
$this->assertEquals(1, $value);
$res = XML::parseXml($this->xmlStr, null);
$name = $res['name'];
$value = $res['value'];
$this->assertEquals('test', $name);
$this->assertEquals(1, $value);
}
public function testArrayToXML()
{
$data = [
'tests' => [
'name' => 'test',
'value' => 1,
],
];
$this->assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tests><name>test</name><value>1</value></tests>", XML::toXML($data));
}
public function testObjectToXML()
{
$obj = new tests();
$obj->name = 'test';
$obj->value = 1;
$this->assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tests><name>test</name><value>1</value></tests>", XML::toXML($obj));
}
}
class tests
{
public $name = '';
public $value = 0;
}

View File

@ -0,0 +1,3 @@
<?php
require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

View File

@ -31,7 +31,7 @@
"ext-simplexml": "*",
"ext-xmlwriter": "*",
"guzzlehttp/guzzle": "^6.3|^7.0",
"adbario/php-dot-notation": "^2.2"
"adbario/php-dot-notation": "^2.4"
},
"require-dev": {
"symfony/dotenv": "^3.4",

View File

@ -13,6 +13,9 @@ class TeaError extends RuntimeException
public $code = 0;
public $data;
public $name = '';
public $statusCode;
public $description;
public $accessDeniedDetail;
private $errorInfo;
/**
@ -28,10 +31,13 @@ class TeaError extends RuntimeException
parent::__construct((string) $message, (int) $code, $previous);
$this->errorInfo = $errorInfo;
if (!empty($errorInfo)) {
$properties = ['name', 'message', 'code', 'data'];
$properties = ['name', 'message', 'code', 'data', 'description', 'accessDeniedDetail'];
foreach ($properties as $property) {
if (isset($errorInfo[$property])) {
$this->{$property} = $errorInfo[$property];
if ($property === 'data' && isset($errorInfo['data']['statusCode'])) {
$this->statusCode = $errorInfo['data']['statusCode'];
}
}
}
}

View File

@ -37,6 +37,50 @@ class Helper
return \JSON_ERROR_NONE == json_last_error();
}
/**
* @param mixed $value
*
* @return bool
*/
public static function isBytes($value)
{
if (!\is_array($value)) {
return false;
}
$i = 0;
foreach ($value as $k => $ord) {
if ($k !== $i) {
return false;
}
if (!\is_int($ord)) {
return false;
}
if ($ord < 0 || $ord > 255) {
return false;
}
++$i;
}
return true;
}
/**
* Convert a bytes to string(utf8).
*
* @param array $bytes
*
* @return string the return string
*/
public static function toString($bytes)
{
$str = '';
foreach ($bytes as $ch) {
$str .= \chr($ch);
}
return $str;
}
/**
* @return array
*/

View File

@ -15,6 +15,7 @@ abstract class Parameter implements IteratorAggregate
/**
* @return ArrayIterator|Traversable
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->toArray());

View File

@ -89,11 +89,15 @@ class Request extends PsrRequest
if ($this->body instanceof StreamInterface) {
$request = $request->withBody($this->body);
} else {
$body = $this->body;
if (Helper::isBytes($this->body)) {
$body = Helper::toString($this->body);
}
if (\function_exists('\GuzzleHttp\Psr7\stream_for')) {
// @deprecated stream_for will be removed in guzzlehttp/psr7:2.0
$request = $request->withBody(\GuzzleHttp\Psr7\stream_for($this->body));
$request = $request->withBody(\GuzzleHttp\Psr7\stream_for($body));
} else {
$request = $request->withBody(\GuzzleHttp\Psr7\Utils::streamFor($this->body));
$request = $request->withBody(\GuzzleHttp\Psr7\Utils::streamFor($body));
}
}
}

View File

@ -302,6 +302,7 @@ class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Co
/**
* Retrieve an external iterator.
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return $this->dot->getIterator();
@ -314,6 +315,7 @@ class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Co
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($offset)
{
return $this->dot->offsetExists($offset);
@ -326,6 +328,7 @@ class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Co
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->dot->offsetGet($offset);
@ -337,6 +340,7 @@ class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Co
* @param $offset
* @param $value
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->dot->offsetSet($offset, $value);
@ -347,6 +351,7 @@ class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Co
*
* @param $offset
*/
#[\ReturnTypeWillChange]
public function offsetUnset($offset)
{
$this->dot->offsetUnset($offset);
@ -359,6 +364,7 @@ class Response extends PsrResponse implements ArrayAccess, IteratorAggregate, Co
*
* @return int
*/
#[\ReturnTypeWillChange]
public function count($key = null)
{
return $this->dot->count($key);

View File

@ -173,7 +173,10 @@ class Tea
public static function allowRetry(array $runtime, $retryTimes, $now)
{
unset($now);
if (empty($runtime) || !isset($runtime['maxAttempts'])) {
if (!isset($retryTimes) || null === $retryTimes || !\is_numeric($retryTimes)) {
return false;
}
if ($retryTimes > 0 && (empty($runtime) || !isset($runtime['retryable']) || !$runtime['retryable'] || !isset($runtime['maxAttempts']))) {
return false;
}
$maxAttempts = $runtime['maxAttempts'];
@ -270,6 +273,9 @@ class Tea
if (isset($config['noProxy']) && !empty($config['noProxy'])) {
$options->set('proxy.no', $config['noProxy']);
}
if (isset($config['ignoreSSL']) && !empty($config['ignoreSSL'])) {
$options->set('verify',!((bool)$config['ignoreSSL']));
}
// readTimeout&connectTimeout unit is millisecond
$read_timeout = isset($config['readTimeout']) && !empty($config['readTimeout']) ? (int) $config['readTimeout'] : 0;
$con_timeout = isset($config['connectTimeout']) && !empty($config['connectTimeout']) ? (int) $config['connectTimeout'] : 0;

View File

@ -1,6 +1,51 @@
# ChangeLog - Aliyun OSS SDK for PHP
## v2.3.1 / 2019-011-15
## v2.6.0 / 2022-08-03
* Added: support credentials provider.
* Fixed: compatible with swoole curl handler.
* Added: support more bucket stat info.
## v2.5.0 / 2022-05-13
* Added: support bucket transfer acceleration.
* Added: support bucket cname token.
* Added: support listobjectsV2.
## v2.4.3 / 2021-08-25
* Fixed: integer overflow in PHP5.x.
## v2.4.2 / 2021-06-04
* Compatible with PHP8.
* Fixed: compatible with PHP5.4.
* Fixed: the signature is incorrect in some scenarios
* Update: change $requestUrl from a member variable to a local variable.
## v2.4.1 / 2020-09-29
* Fixed: the getBucketPolicy bug.
## v2.4.0 / 2020-08-31
* Added: disable Expect: 100-continue
* Added: support getBucketInfo
* Added: support getBucketStat
* Added: support bucket policy
* Added: support bucket encryption
* Added: support bucket tagging
* Added: support bucket worm
* Added: support versioning
* Added: support request payment
* Added: support object tagging
* Added: support code archive
* Added: support process object
* Added: support traffic limit paramter
* Added: support upload object from file handle
* Added: support getSimplifiedObjectMeta
* Fixed: the object name can not be '0' stirng.
* Update: endpoint validity check
* Update: add new pre-signed url api
## v2.3.1 / 2019-01-15
* translate chinese comments into english
* Added: endpoint validity check

View File

@ -111,7 +111,7 @@ OssClient提供的接口返回返回数据分为两种
$bucketListInfo = $ossClient->listBuckets();
$bucketList = $bucketListInfo->getBucketList();
foreach($bucketList as $bucket) {
print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n");
print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreateDate() . "\n");
}
```
上面代码中的$bucketListInfo的数据类型是 `OSS\Model\BucketListInfo`

View File

@ -1,4 +1,4 @@
# Alibaba Cloud OSS SDK for PHP
# Alibaba Cloud OSS SDK for PHP
[![Latest Stable Version](https://poser.pugx.org/aliyuncs/oss-sdk-php/v/stable)](https://packagist.org/packages/aliyuncs/oss-sdk-php)
[![Build Status](https://travis-ci.org/aliyun/aliyun-oss-php-sdk.svg?branch=master)](https://travis-ci.org/aliyun/aliyun-oss-php-sdk)
@ -50,12 +50,12 @@ Tips:
| Class | Explanation |
|:------------------|:------------------------------------|
|OSS\OSSClient | OSS client class. An OSSClient instance can be used to call the interface. |
|OSS\Core\OSSException |OSS Exception class . You only need to pay attention to this exception when you use the OSSClient. |
|OSS\OssClient | OSS client class. An OssClient instance can be used to call the interface. |
|OSS\Core\OssException |OSS Exception class . You only need to pay attention to this exception when you use the OssClient. |
### Initialize an OSSClient
### Initialize an OssClient
The SDK's operations for the OSS are performed through the OSSClient class. The code below creates an OSSClient object:
The SDK's operations for the OSS are performed through the OssClient class. The code below creates an OssClient object:
```php
<?php
@ -101,7 +101,7 @@ try {
### Handle returned results
The OSSClient provides the following two types of returned data from interfaces:
The OssClient provides the following two types of returned data from interfaces:
- Put and Delete interfaces: The *PUT* and *DELETE* operations are deemed successful if *null* is returned by the interfaces without *OSSException*.
- Get and List interfaces: The *GET* and *LIST* operations are deemed successful if the desired data is returned by the interfaces without *OSSException*. For example,
@ -111,7 +111,7 @@ The OSSClient provides the following two types of returned data from interfaces:
$bucketListInfo = $ossClient->listBuckets();
$bucketList = $bucketListInfo->getBucketList();
foreach($bucketList as $bucket) {
print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n");
print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreateDate() . "\n");
}
```
In the above code, $bucketListInfo falls into the 'OSS\Model\BucketListInfo' data type.

0
vendor/aliyuncs/oss-sdk-php/build-phar.sh vendored Normal file → Executable file
View File

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