初始化项目
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use cores\traits\ErrorTrait;
|
||||
use think\facade\Request;
|
||||
|
||||
/**
|
||||
* 系统服务基础类
|
||||
* Class BaseService
|
||||
* @package app\common\service
|
||||
*/
|
||||
class BaseService
|
||||
{
|
||||
use ErrorTrait;
|
||||
|
||||
// 请求管理类
|
||||
/* @var $request \think\Request */
|
||||
protected $request;
|
||||
|
||||
// 当前访问的商城ID
|
||||
protected $storeId;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* BaseService constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// 请求管理类
|
||||
$this->request = Request::instance();
|
||||
// 获取当前操作的商城ID
|
||||
$this->getStoreId();
|
||||
// 执行子类的构造方法
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造方法 (供继承的子类使用)
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前操作的商城ID
|
||||
* @return int|null
|
||||
*/
|
||||
protected function getStoreId(): ?int
|
||||
{
|
||||
if (empty($this->storeId) && in_array(app_name(), ['store', 'api'])) {
|
||||
$this->storeId = getStoreId();
|
||||
}
|
||||
return $this->storeId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\library\helper;
|
||||
use app\common\model\Goods as GoodsModel;
|
||||
use app\common\model\GoodsSku as GoodsSkuModel;
|
||||
|
||||
/**
|
||||
* 商品服务类
|
||||
* Class Goods
|
||||
* @package app\store\service
|
||||
*/
|
||||
class Goods extends BaseService
|
||||
{
|
||||
/**
|
||||
* 设置商品数据
|
||||
* @param mixed $data 源数据
|
||||
* @param bool $isMultiple 是否为列表数据
|
||||
* @param array $hidden 隐藏的属性
|
||||
* @param string $goodsIndex 商品ID字段名称
|
||||
* @return mixed
|
||||
*/
|
||||
public static function setGoodsData($data, bool $isMultiple = true, array $hidden = [], string $goodsIndex = 'goods_id')
|
||||
{
|
||||
if (!$isMultiple) $dataSource = [&$data]; else $dataSource = &$data;
|
||||
// 获取商品列表
|
||||
$model = new GoodsModel;
|
||||
$goodsData = $model->getListByIds(helper::getArrayColumn($dataSource, $goodsIndex));
|
||||
// 设置隐藏的属性
|
||||
$goodsData->hidden(array_merge(['images'], $hidden));
|
||||
// 整理列表数据
|
||||
$goodsList = helper::arrayColumn2Key($goodsData, 'goods_id');
|
||||
foreach ($dataSource as &$item) {
|
||||
$item['goods'] = $goodsList[$item[$goodsIndex]] ?? null;
|
||||
}
|
||||
return $dataSource->hidden($hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品的指定的某个SKU信息
|
||||
* @param int $goodsId
|
||||
* @param string $goodsSkuId
|
||||
* @return GoodsSkuModel|array|null
|
||||
*/
|
||||
public static function getSkuInfo(int $goodsId, string $goodsSkuId)
|
||||
{
|
||||
$detail = GoodsSkuModel::detail($goodsId, $goodsSkuId);
|
||||
if (!empty($detail['image'])) {
|
||||
$detail['goods_image'] = $detail['image']['preview_url'];
|
||||
}
|
||||
return $detail->hidden(['image']);
|
||||
}
|
||||
|
||||
/**
|
||||
* SKU的规格属性转换为可读的字符串
|
||||
* @param array $goodsPops
|
||||
* @return string
|
||||
*/
|
||||
public static function goodsPropsToAttr(array $goodsPops): string
|
||||
{
|
||||
$goodsAttr = '';
|
||||
foreach ($goodsPops as $pop) {
|
||||
$goodsAttr .= "{$pop['group']['name']}: {$pop['value']['name']}; ";
|
||||
}
|
||||
return $goodsAttr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\library\helper;
|
||||
use app\common\crypto\Idingju;
|
||||
|
||||
/**
|
||||
* 随机数据类
|
||||
* Class SybOil
|
||||
* @package app\store\service
|
||||
*/
|
||||
class IdingjuOil extends BaseService
|
||||
{
|
||||
public function mk_dir_store($dir, $mode = 0777)
|
||||
{
|
||||
if (is_dir($dir) || @mkdir($dir,$mode)) return true;
|
||||
if (!$this->mk_dir_store(dirname($dir),$mode)) return false;
|
||||
return @mkdir($dir,$mode);
|
||||
}
|
||||
|
||||
/** 记录日志
|
||||
* @param $data
|
||||
*/
|
||||
public function saveLogStore($data){
|
||||
$years = date('Ym');
|
||||
$day = date('Ymd');
|
||||
//设置路径目录信息
|
||||
$dir = runtime_path('storelog/').$years.'/'.$day;
|
||||
//目录不存在就创建
|
||||
$this->mk_dir_store($dir);
|
||||
$url = $dir.'/'.date('YmdH').'.txt';
|
||||
$fp = @fopen($url,"a");//打开文件资源通道 不存在则自动创建
|
||||
@fwrite($fp,date("Y-m-d H:i:s ").var_export($data,true)."\r\n");//写入文件
|
||||
@fclose($fp);//关闭资源通道
|
||||
}
|
||||
|
||||
/** 油站查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function baseGasStationList($data, $company)
|
||||
{
|
||||
$tool = new Idingju($company);
|
||||
// 1,获取Token
|
||||
$accessToken = $tool->getToken($company['orgNo']);
|
||||
$url = '/api/cnpcbp/stations';
|
||||
|
||||
$api = $tool->prefixUrl.$url;
|
||||
|
||||
// 2,组装参数
|
||||
$params = [
|
||||
'lng' => $data['longitude']??'',
|
||||
'lat' => $data['latitude']??'',
|
||||
'page' => $data['pageNum']??'1',
|
||||
];
|
||||
|
||||
// 3,获取签名
|
||||
$timestamp = time();
|
||||
$get = [
|
||||
'access_token' => $accessToken,
|
||||
'timestamp' => $timestamp,
|
||||
'signature' => $tool->signature($params,$accessToken,$timestamp,$url), // 获取签名
|
||||
];
|
||||
$httpUrl = $api.'?'.http_build_query($get); // 拼接url
|
||||
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
];
|
||||
// 4,调用业务接口
|
||||
$json = json_encode($params);
|
||||
$ret = $tool->request($httpUrl,$json,'post',$header);
|
||||
$this->saveLogStore("油站查询".$ret);
|
||||
return json_decode($ret, true);
|
||||
}
|
||||
|
||||
/** 油券库存
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function stockList($data, $company)
|
||||
{
|
||||
$tool = new Idingju($company);
|
||||
// 1,获取Token
|
||||
$accessToken = $tool->getToken($company['orgNo']);
|
||||
$url = '/api/cnpcbp/queryStock';
|
||||
|
||||
$api = $tool->prefixUrl.$url;
|
||||
|
||||
// 2,组装参数
|
||||
$params = [
|
||||
'shortname' => $data['goodsNo'] ?? '',
|
||||
];
|
||||
|
||||
// 3,获取签名
|
||||
$timestamp = time();
|
||||
$get = [
|
||||
'access_token' => $accessToken,
|
||||
'timestamp' => $timestamp,
|
||||
'signature' => $tool->signature($params,$accessToken,$timestamp,$url), // 获取签名
|
||||
];
|
||||
$httpUrl = $api.'?'.http_build_query($get); // 拼接url
|
||||
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
];
|
||||
// 4,调用业务接口
|
||||
$json = json_encode($params);
|
||||
$ret = $tool->request($httpUrl,$json,'post',$header);
|
||||
$this->saveLogStore("库存查询【".$data['goodsNo']."】".json_encode(json_decode($ret, true),320));
|
||||
return json_decode($ret, true);
|
||||
}
|
||||
|
||||
/** 油卡查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardSelect($data, $company)
|
||||
{
|
||||
$tool = new Idingju($company);
|
||||
// 1,获取Token
|
||||
$accessToken = $tool->getToken($company['orgNo']);
|
||||
$url = '/api/cnpcbp/detail';
|
||||
|
||||
$api = $tool->prefixUrl.$url;
|
||||
|
||||
// 2,组装参数
|
||||
$params = [
|
||||
'out_order_id' => '',
|
||||
];
|
||||
|
||||
// 3,获取签名
|
||||
$timestamp = time();
|
||||
$get = [
|
||||
'access_token' => $accessToken,
|
||||
'timestamp' => $timestamp,
|
||||
'signature' => $tool->signature($params,$accessToken,$timestamp,$url), // 获取签名
|
||||
];
|
||||
$httpUrl = $api.'?'.http_build_query($get); // 拼接url
|
||||
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
];
|
||||
|
||||
// 4,调用业务接口
|
||||
$json = json_encode($params);
|
||||
$ret = $tool->request($httpUrl,$json,'post',$header);
|
||||
$this->saveLogStore("订单查询".$ret);
|
||||
return json_decode($ret, true);
|
||||
}
|
||||
|
||||
/** 用户分油
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardShare($data, $company)
|
||||
{
|
||||
$tool = new Idingju($company);
|
||||
// 1,获取Token
|
||||
$accessToken = $tool->getToken($company['orgNo']);
|
||||
$url = '/api/cnpcbp/order';
|
||||
|
||||
$api = $tool->prefixUrl.$url;
|
||||
|
||||
// 2,组装参数
|
||||
$params = [
|
||||
'mobile' => $data['mobile']??'',
|
||||
'out_order_id' => $data['saleOrderNo'],
|
||||
'shortname' => $data['goodsNo']??'',
|
||||
'notify_url' => $data['notify_url']??(base_url() . 'oil.php'),
|
||||
'use_notify_url' => $data['use_notify_url']??(base_url() . 'oiluse.php'),
|
||||
];
|
||||
|
||||
// 3,获取签名
|
||||
$timestamp = time();
|
||||
$get = [
|
||||
'access_token' => $accessToken,
|
||||
'timestamp' => $timestamp,
|
||||
'signature' => $tool->signature($params,$accessToken,$timestamp,$url), // 获取签名
|
||||
];
|
||||
$httpUrl = $api.'?'.http_build_query($get); // 拼接url
|
||||
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
];
|
||||
|
||||
// 4,调用业务接口
|
||||
$json = json_encode($params);
|
||||
$ret = $tool->request($httpUrl,$json,'post',$header);
|
||||
$this->saveLogStore("分油下单".$ret);
|
||||
return json_decode($ret, true);
|
||||
}
|
||||
|
||||
/** 动态核销URL
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payQrCodeRequest($data, $company)
|
||||
{
|
||||
$tool = new Idingju($company);
|
||||
// 1,获取Token
|
||||
$accessToken = $tool->getToken($company['orgNo']);
|
||||
$url = '/api/cnpcbp/getUseCode';
|
||||
|
||||
$api = $tool->prefixUrl.$url;
|
||||
|
||||
// 2,组装参数
|
||||
$params = [
|
||||
'out_order_id' => $data['order_no'],
|
||||
];
|
||||
|
||||
// 3,获取签名
|
||||
$timestamp = time();
|
||||
$get = [
|
||||
'access_token' => $accessToken,
|
||||
'timestamp' => $timestamp,
|
||||
'signature' => $tool->signature($params,$accessToken,$timestamp,$url), // 获取签名
|
||||
];
|
||||
$httpUrl = $api.'?'.http_build_query($get); // 拼接url
|
||||
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
];
|
||||
|
||||
// 4,调用业务接口
|
||||
$json = json_encode($params);
|
||||
$ret = $tool->request($httpUrl,$json,'post',$header);
|
||||
$this->saveLogStore("动态核销URL".$ret);
|
||||
return json_decode($ret, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
/**
|
||||
* 消息通知服务
|
||||
* Class Message
|
||||
* @package app\common\service
|
||||
*/
|
||||
class Message extends BaseService
|
||||
{
|
||||
/**
|
||||
* 场景列表
|
||||
* [场景名称] => [场景类]
|
||||
* @var array
|
||||
*/
|
||||
private static $sceneList = [
|
||||
// 短信验证码
|
||||
'passport.captcha' => \app\common\service\message\passport\Captcha::class,
|
||||
// 订单支付成功
|
||||
'order.payment' => \app\common\service\message\order\Payment::class,
|
||||
// 订单发货
|
||||
'order.delivery' => \app\common\service\message\order\Delivery::class,
|
||||
// 订单退款
|
||||
'order.refund' => \app\common\service\message\order\Refund::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* 发送消息通知
|
||||
* @param string $sceneName 场景名称
|
||||
* @param array $param 参数
|
||||
* @param int $storeId 商城ID
|
||||
* @return mixed
|
||||
*/
|
||||
public static function send(string $sceneName, array $param, int $storeId)
|
||||
{
|
||||
if (!isset(self::$sceneList[$sceneName])) return false;
|
||||
$class = self::$sceneList[$sceneName];
|
||||
return (new $class($storeId))->send($param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\store\model\User as UserModel;
|
||||
use app\store\model\UserCoupon as UserCouponModel;
|
||||
use app\common\model\Order as OrderModel;
|
||||
use app\common\service\goods\source\Factory as FactoryStock;
|
||||
|
||||
/**
|
||||
* 订单服务类
|
||||
* Class Order
|
||||
* @package app\common\service
|
||||
*/
|
||||
class Order extends BaseService
|
||||
{
|
||||
/**
|
||||
* 生成订单号`
|
||||
* @return string
|
||||
*/
|
||||
public static function createOrderNo(): string
|
||||
{
|
||||
return date('Ymd') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件:订单取消
|
||||
* @param OrderModel $order
|
||||
*/
|
||||
public static function cancelEvent(OrderModel $order)
|
||||
{
|
||||
// 回退商品库存
|
||||
FactoryStock::getFactory($order['order_source'])->backGoodsStock($order['goods'], true);
|
||||
// 回退用户优惠券
|
||||
$order['coupon_id'] > 0 && UserCouponModel::setIsUse($order['coupon_id'], false);
|
||||
// 回退用户积分
|
||||
if ($order['points_num'] > 0) {
|
||||
$describe = "订单取消:{$order['order_no']}";
|
||||
UserModel::setIncPoints($order['user_id'], $order['points_num'], $describe, $order['store_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\library\helper;
|
||||
use app\common\crypto\RsaUtil;
|
||||
|
||||
/**
|
||||
* 随机数据类
|
||||
* Class SybOil
|
||||
* @package app\store\service
|
||||
*/
|
||||
class PartnersOil extends BaseService
|
||||
{
|
||||
public function mk_dir_store($dir, $mode = 0777)
|
||||
{
|
||||
if (is_dir($dir) || @mkdir($dir,$mode)) return true;
|
||||
if (!$this->mk_dir_store(dirname($dir),$mode)) return false;
|
||||
return @mkdir($dir,$mode);
|
||||
}
|
||||
|
||||
/** 记录日志
|
||||
* @param $data
|
||||
*/
|
||||
public function saveLogStore($data){
|
||||
$years = date('Ym');
|
||||
$day = date('Ymd');
|
||||
//设置路径目录信息
|
||||
$dir = runtime_path('storelog/').$years.'/'.$day;
|
||||
//目录不存在就创建
|
||||
$this->mk_dir_store($dir);
|
||||
$url = $dir.'/'.date('YmdH').'.txt';
|
||||
$fp = @fopen($url,"a");//打开文件资源通道 不存在则自动创建
|
||||
@fwrite($fp,date("Y-m-d H:i:s ").var_export($data,true)."\r\n");//写入文件
|
||||
@fclose($fp);//关闭资源通道
|
||||
}
|
||||
public function sendRequest($partners, $url, $businessParams = [], $appendHeaders = [], $file = null)
|
||||
{
|
||||
$this->saveLogStore(($appendHeaders['method'] ?? '').'请求原始数据:'.json_encode($businessParams,320));
|
||||
$crypto = new RsaUtil($partners);
|
||||
// 签名并组合header,并加密数据
|
||||
$requestData = $crypto->prepareRequest($appendHeaders, $businessParams);
|
||||
$businessParams = $requestData['encryptData'];
|
||||
// 构建默认的公共参数头
|
||||
$headers = [];
|
||||
foreach ($requestData['header'] as $k=>$val){
|
||||
$headers[] = $k.': '.$val;
|
||||
}
|
||||
$this->saveLogStore($requestData['header']['method'].'请求加密数据:'.json_encode(['header'=>$requestData['header'],'body'=>$businessParams],320));
|
||||
// 使用 cURL 发送请求
|
||||
$ch = curl_init();
|
||||
|
||||
// 设置请求 URL
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
||||
// 设置请求方式为 POST
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
|
||||
// 返回结果而不是输出
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
// 包含响应头在输出中
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
|
||||
$headers[] = 'Charset: UTF-8';
|
||||
if ($file) {
|
||||
// 如果有文件上传,设置 multipart/form-data 表单
|
||||
$filePath = $file->getPathname();
|
||||
$fileName = $file->getOriginalName();
|
||||
$fileMime = $file->getMimeType();
|
||||
$postFields = [
|
||||
'file' => new \CURLFile($filePath, $fileMime, $fileName),
|
||||
'businessParams' => json_encode($businessParams, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
|
||||
} else {
|
||||
// 如果没有文件上传,直接发送业务参数的 JSON 数据
|
||||
$postFields = json_encode($businessParams, JSON_UNESCAPED_UNICODE);
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
// 执行请求
|
||||
$response = curl_exec($ch);
|
||||
// 检查是否有错误
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return ['code' => '01', 'message' => $error_msg];
|
||||
}
|
||||
|
||||
// 获取响应头大小
|
||||
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
|
||||
// 分离响应头和响应体
|
||||
$headerString = substr($response, 0, $header_size);
|
||||
$bodyString = substr($response, $header_size);
|
||||
$this->saveLogStore($requestData['header']['method'].'返回值原文:'.$bodyString);
|
||||
// 关闭 cURL 句柄
|
||||
curl_close($ch);
|
||||
|
||||
// 解析响应头为数组
|
||||
$headerArray = [];
|
||||
foreach (explode("\r\n", $headerString) as $header) {
|
||||
if (trim($header) !== '' && strpos($header, ':') !== false) {
|
||||
list($key, $value) = explode(': ', $header, 2);
|
||||
$headerArray[strtolower(trim($key))] = trim($value);
|
||||
}
|
||||
}
|
||||
return json_decode($bodyString, true);
|
||||
/*
|
||||
$res = $crypto->processResponse(['header'=>$headerArray,'encryptData'=>json_decode($bodyString, true)]);
|
||||
if(!$res){
|
||||
return ['code' => '01', 'message' => $bodyString];
|
||||
}
|
||||
$this->saveLogStore($headerArray['method'].'返回值:'.json_encode($res,320));
|
||||
// 返回结果
|
||||
return $res;
|
||||
*/
|
||||
}
|
||||
|
||||
/** 油站查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function baseGasStationList($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.base.gasStation.list',
|
||||
];
|
||||
$body = [
|
||||
'oilCardType' => 'zsy_ticket',
|
||||
'goodsNo' => $data['goodsNo']??'',
|
||||
// 'province' => $data['province']??'',
|
||||
// 'city' => $data['city']??'',
|
||||
'longitude' => $data['longitude']??'',
|
||||
'latitude' => $data['latitude']??'',
|
||||
'pageLimit' => $data['pageLimit']??'30',
|
||||
'pageNum' => $data['pageNum']??'1',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/base/gasStationList', $body, $header);
|
||||
//$this->saveLogStore("油站查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 油券库存
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function stockList($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.stockList',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'goodsNo' => $data['goodsNo'] ?? '',
|
||||
];
|
||||
return $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/query', $body, $header);
|
||||
}
|
||||
|
||||
/** 文件上传接口
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function baseFileUpload($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.base.file.upload',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'file' => request()->file('file'),
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/base/uploadFile', $body, $header);
|
||||
//$this->saveLogStore("文件上传接口".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 油卡查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardSelect($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.select',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'mobile' => $data['mobile']??'',
|
||||
'userNo' => $data['userNo']??'',
|
||||
'oilCardNo' => $data['oilCardNo']??'',
|
||||
'pageLimit' => $data['pageLimit']??'10',
|
||||
'pageNum' => $data['pageNum']??'1',
|
||||
'oilCardType' => $data['oilCardType']??'card', //不填时默认为“E卡通平台自营卡”
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/select', $body, $header);
|
||||
//$this->saveLogStore("油卡查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 用户分油
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardShare($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.share',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'goodsNo' => $data['goodsNo']??'',
|
||||
'amount' => $data['oilCardType']=='card' ? round($data['amount'],2) : '',
|
||||
'userNo' => $data['userNo']??'',
|
||||
'mobile' => $data['mobile']??'',
|
||||
'saleOrderNo' => $data['saleOrderNo']??'',
|
||||
'oilCardType' => $data['oilCardType']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/share', $body, $header);
|
||||
//$this->saveLogStore("用户分油结果".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 分油撤销接口
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardCancelShare($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.cancelShare',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'amount' => !empty($data['amount']??'') ? round($data['amount'],2) : '',
|
||||
'saleOrderNo' => $data['saleOrderNo']??'',
|
||||
'type' => $data['type']??'',
|
||||
'oilCardType' => $data['oilCardType']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/cancelShare', $body, $header);
|
||||
//$this->saveLogStore("分油撤销接口".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 用户分油记录查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardShareList($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.shareList',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'userNo' => $data['userNo']??'',
|
||||
'mobile' => $data['mobile']??'',
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'saleOrderNo' => $data['saleOrderNo']??'',
|
||||
'beginDate' => $data['beginDate']??'',
|
||||
'endDate' => $data['endDate']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/opt/oilCard/shareList', $body, $header);
|
||||
//$this->saveLogStore("用户分油记录查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 加油记录查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function orderListSale($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.order.list.sale',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'mobile' => $data['mobile']??'',
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'beginDate' => $data['beginDate']??'',
|
||||
'endDate' => $data['endDate']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/opt/list/sale', $body, $header);
|
||||
//$this->saveLogStore("加油记录查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 付款二维码申请
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payQrCodeRequest($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.qrCode.request',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'oilCardNo' => $data['oilCardNo']??'',
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'mobile' => $data['mobile']??'',
|
||||
'oilCardType' => $data['oilCardType']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/pay/getPayQrCode', $body, $header);
|
||||
//$this->saveLogStore("付款二维码申请".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 主扫订单创建
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payActiveScan($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.active.scan',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'oilCardNo' => $data['oilCardNo']??'',
|
||||
'qrInfo' => $data['qrInfo']??'',
|
||||
'longitude' => $data['longitude']??'',
|
||||
'latitude' => $data['latitude']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/pay/activeScan', $body, $header);
|
||||
//$this->saveLogStore("主扫订单创建".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 主扫订单信息确认
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payActiveVerify($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.active.verify',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'activeOrderId' => $data['activeOrderId']??'',
|
||||
'amount' => !empty($data['amount']??'') ? round($data['amount'],2) : '',
|
||||
'deviceId' => $data['deviceId']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/pay/activeVerify', $body, $header);
|
||||
//$this->saveLogStore("主扫订单信息确认".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 账户余额查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payAmountBalance($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.account.balance',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/finance/account/balance', $body, $header);
|
||||
//$this->saveLogStore("账户余额查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 申请发票
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payInvoiceRequest($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.invoice.request',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'amount' => !empty($data['amount']??'') ? round($data['amount'],2) : '',
|
||||
'oilNo' => $data['oilNo']??'',
|
||||
'invoiceAddress' => $data['invoiceAddress']??'',
|
||||
'invoiceHeader' => $data['invoiceHeader']??'',
|
||||
'invoicePhone' => $data['invoicePhone']??'',
|
||||
'invoiceOpenBank' => $data['invoiceOpenBank']??'',
|
||||
'taxIdentifyNo' => $data['taxIdentifyNo']??'',
|
||||
'invoiceCardNo' => $data['invoiceCardNo']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/finance/invoice/request', $body, $header);
|
||||
//$this->saveLogStore("申请发票".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 开票状态查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payInvoiceStatus($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.invoice.status',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'invoiceNo' => $data['invoiceNo']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/finance/invoice/status', $body, $header);
|
||||
//$this->saveLogStore("开票状态查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 添加用户
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function userOptAdd($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.user.opt.add',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'mobile' => $data['mobile']??'',
|
||||
'userName' => $data['userName']??'',
|
||||
'userIdCard' => $data['userIdCard']??'',
|
||||
'userType' => $data['userType']??'user',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/user/opt/add', $body, $header);
|
||||
//$this->saveLogStore("添加用户".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 优惠券下单
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function voucherCreateOrder($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.opt.voucher.createOrder',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'model' => $data['model']??'',
|
||||
'voucherAmount' => $data['voucherAmount']??'',
|
||||
'fullAmount' => $data['fullAmount']??'',
|
||||
'storeNum' => $data['storeNum']??'',
|
||||
'validTime' => $data['validTime']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/voucher/createOrder', $body, $header);
|
||||
//$this->saveLogStore("优惠券下单".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 优惠券订单查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function voucherOrderListPage($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.opt.voucher.order.listPage',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'orderNo' => $data['orderNo']??'',
|
||||
'model' => $data['model']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/voucher/order/listPage', $body, $header);
|
||||
//$this->saveLogStore("优惠券订单查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 卡券查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function voucherItemListPage($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.opt.voucher.item.listPage',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'orderNo' => $data['orderNo']??'',
|
||||
'model' => $data['model']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/voucher/item/listPage', $body, $header);
|
||||
//$this->saveLogStore("卡券查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace app\common\service;
|
||||
|
||||
use Predis\Client as RedisClient;
|
||||
|
||||
class QueueService
|
||||
{
|
||||
protected $redis;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->redis = new RedisClient([
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
// 'password' => '', // 如果有密码
|
||||
]);
|
||||
}
|
||||
|
||||
// 推送消息到队列
|
||||
public function push($queueName, $message)
|
||||
{
|
||||
$this->redis->rpush($queueName, json_encode($message));
|
||||
}
|
||||
|
||||
// 从队列中取出消息
|
||||
public function pop($queueName)
|
||||
{
|
||||
$message = $this->redis->lpop($queueName);
|
||||
return $message ? json_decode($message, true) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟推送(ZSET)
|
||||
* @param string $queueName
|
||||
* @param array|string $data
|
||||
* @param int $delay 延迟秒数
|
||||
*/
|
||||
public function laterPush($queueName, $data, $delay)
|
||||
{
|
||||
$score = time() + $delay;
|
||||
$payload = is_string($data) ? $data : json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
return $this->redis->zadd($queueName . ':delayed', [$payload => $score]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查延迟队列,将到期任务迁移到普通队列
|
||||
* @param string $queueName
|
||||
*/
|
||||
public function migrateDelayedToReady($queueName)
|
||||
{
|
||||
$now = time();
|
||||
// 获取到期任务
|
||||
$tasks = $this->redis->zrangebyscore($queueName . ':delayed', 0, $now);
|
||||
if (!empty($tasks)) {
|
||||
foreach ($tasks as $task) {
|
||||
// 放回普通队列
|
||||
$this->push($queueName, $task);
|
||||
// 从延迟队列中移除
|
||||
$this->redis->zrem($queueName . ':delayed', $task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,545 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\library\helper;
|
||||
use app\common\crypto\Crypto;
|
||||
|
||||
/**
|
||||
* 随机数据类
|
||||
* Class SybOil
|
||||
* @package app\store\service
|
||||
*/
|
||||
class SybOil extends BaseService
|
||||
{
|
||||
public function mk_dir_store($dir, $mode = 0777)
|
||||
{
|
||||
if (is_dir($dir) || @mkdir($dir,$mode)) return true;
|
||||
if (!$this->mk_dir_store(dirname($dir),$mode)) return false;
|
||||
return @mkdir($dir,$mode);
|
||||
}
|
||||
|
||||
/** 记录日志
|
||||
* @param $data
|
||||
*/
|
||||
public function saveLogStore($data){
|
||||
$years = date('Ym');
|
||||
$day = date('Ymd');
|
||||
//设置路径目录信息
|
||||
$dir = runtime_path('storelog/').$years.'/'.$day;
|
||||
//目录不存在就创建
|
||||
$this->mk_dir_store($dir);
|
||||
$url = $dir.'/'.date('YmdH').'.txt';
|
||||
$fp = @fopen($url,"a");//打开文件资源通道 不存在则自动创建
|
||||
@fwrite($fp,date("Y-m-d H:i:s ").var_export($data,true)."\r\n");//写入文件
|
||||
@fclose($fp);//关闭资源通道
|
||||
}
|
||||
public function sendRequest($company, $url, $businessParams = [], $appendHeaders = [], $file = null)
|
||||
{
|
||||
$this->saveLogStore('businessParams:'.json_encode($businessParams,320));
|
||||
$crypto = new Crypto($company);
|
||||
// 签名并组合header,并加密数据
|
||||
$requestData = $crypto->prepareRequest($appendHeaders, $businessParams);
|
||||
$businessParams = $requestData['encryptData'];
|
||||
// 构建默认的公共参数头
|
||||
$headers = [];
|
||||
foreach ($requestData['header'] as $k=>$val){
|
||||
$headers[] = $k.': '.$val;
|
||||
}
|
||||
$this->saveLogStore($requestData['header']['method'].'请求:'.json_encode(['header'=>$requestData['header'],'body'=>$businessParams],320));
|
||||
// 使用 cURL 发送请求
|
||||
$ch = curl_init();
|
||||
|
||||
// 设置请求 URL
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
||||
// 设置请求方式为 POST
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
|
||||
// 返回结果而不是输出
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
// 包含响应头在输出中
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
|
||||
$headers[] = 'Charset: UTF-8';
|
||||
if ($file) {
|
||||
// 如果有文件上传,设置 multipart/form-data 表单
|
||||
$filePath = $file->getPathname();
|
||||
$fileName = $file->getOriginalName();
|
||||
$fileMime = $file->getMimeType();
|
||||
$postFields = [
|
||||
'file' => new \CURLFile($filePath, $fileMime, $fileName),
|
||||
'businessParams' => json_encode($businessParams, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
|
||||
} else {
|
||||
// 如果没有文件上传,直接发送业务参数的 JSON 数据
|
||||
$postFields = json_encode($businessParams, JSON_UNESCAPED_UNICODE);
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
// 执行请求
|
||||
$response = curl_exec($ch);
|
||||
// 检查是否有错误
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return ['code' => '01', 'message' => $error_msg];
|
||||
}
|
||||
|
||||
// 获取响应头大小
|
||||
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
|
||||
// 分离响应头和响应体
|
||||
$headerString = substr($response, 0, $header_size);
|
||||
$bodyString = substr($response, $header_size);
|
||||
$this->saveLogStore($requestData['header']['method'].'返回值原文:'.$bodyString);
|
||||
// 关闭 cURL 句柄
|
||||
curl_close($ch);
|
||||
|
||||
// 解析响应头为数组
|
||||
$headerArray = [];
|
||||
foreach (explode("\r\n", $headerString) as $header) {
|
||||
if (trim($header) !== '' && strpos($header, ':') !== false) {
|
||||
list($key, $value) = explode(': ', $header, 2);
|
||||
$headerArray[strtolower(trim($key))] = trim($value);
|
||||
}
|
||||
}
|
||||
$res = $crypto->processResponse(['header'=>$headerArray,'encryptData'=>json_decode($bodyString, true)]);
|
||||
if(!$res){
|
||||
return ['code' => '01', 'message' => $bodyString];
|
||||
}
|
||||
$this->saveLogStore($headerArray['method'].'返回值:'.json_encode($res,320));
|
||||
// 返回结果
|
||||
return $res;
|
||||
}
|
||||
|
||||
/** 油站查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function baseGasStationList($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.base.gasStation.list',
|
||||
];
|
||||
$body = [
|
||||
'oilCardType' => 'zsy_ticket',
|
||||
'goodsNo' => $data['goodsNo']??'',
|
||||
// 'province' => $data['province']??'',
|
||||
// 'city' => $data['city']??'',
|
||||
'longitude' => $data['longitude']??'',
|
||||
'latitude' => $data['latitude']??'',
|
||||
'pageLimit' => $data['pageLimit']??'30',
|
||||
'pageNum' => $data['pageNum']??'1',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/base/gasStationList', $body, $header);
|
||||
//$this->saveLogStore("油站查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 油券库存
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function stockList($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.stockList',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'goodsNo' => $data['goodsNo'] ?? '',
|
||||
];
|
||||
return $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/query', $body, $header);
|
||||
}
|
||||
|
||||
/** 文件上传接口
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function baseFileUpload($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.base.file.upload',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'file' => request()->file('file'),
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/base/uploadFile', $body, $header);
|
||||
//$this->saveLogStore("文件上传接口".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 油卡查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardSelect($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.select',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'mobile' => $data['mobile']??'',
|
||||
'userNo' => $data['userNo']??'',
|
||||
'oilCardNo' => $data['oilCardNo']??'',
|
||||
'pageLimit' => $data['pageLimit']??'10',
|
||||
'pageNum' => $data['pageNum']??'1',
|
||||
'oilCardType' => $data['oilCardType']??'card', //不填时默认为“E卡通平台自营卡”
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/select', $body, $header);
|
||||
//$this->saveLogStore("油卡查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 用户分油
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardShare($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.share',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'goodsNo' => $data['goodsNo']??'',
|
||||
'amount' => $data['oilCardType']=='card' ? round($data['amount'],2) : '',
|
||||
'userNo' => $data['userNo']??'',
|
||||
'mobile' => $data['mobile']??'',
|
||||
'saleOrderNo' => $data['saleOrderNo']??'',
|
||||
'oilCardType' => $data['oilCardType']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/share', $body, $header);
|
||||
//$this->saveLogStore("用户分油结果".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 分油撤销接口
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardCancelShare($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.cancelShare',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'amount' => !empty($data['amount']??'') ? round($data['amount'],2) : '',
|
||||
'saleOrderNo' => $data['saleOrderNo']??'',
|
||||
'type' => $data['type']??'',
|
||||
'oilCardType' => $data['oilCardType']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/oil/oilCard/cancelShare', $body, $header);
|
||||
//$this->saveLogStore("分油撤销接口".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 用户分油记录查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function oilOilCardShareList($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.oil.oilCard.shareList',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'userNo' => $data['userNo']??'',
|
||||
'mobile' => $data['mobile']??'',
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'saleOrderNo' => $data['saleOrderNo']??'',
|
||||
'beginDate' => $data['beginDate']??'',
|
||||
'endDate' => $data['endDate']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/opt/oilCard/shareList', $body, $header);
|
||||
//$this->saveLogStore("用户分油记录查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 加油记录查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function orderListSale($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.order.list.sale',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'mobile' => $data['mobile']??'',
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'beginDate' => $data['beginDate']??'',
|
||||
'endDate' => $data['endDate']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/opt/list/sale', $body, $header);
|
||||
//$this->saveLogStore("加油记录查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 付款二维码申请
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payQrCodeRequest($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.qrCode.request',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'oilCardNo' => $data['oilCardNo']??'',
|
||||
'shareNo' => $data['shareNo']??'',
|
||||
'mobile' => $data['mobile']??'',
|
||||
'oilCardType' => $data['oilCardType']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/pay/getPayQrCode', $body, $header);
|
||||
//$this->saveLogStore("付款二维码申请".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 主扫订单创建
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payActiveScan($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.active.scan',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'oilCardNo' => $data['oilCardNo']??'',
|
||||
'qrInfo' => $data['qrInfo']??'',
|
||||
'longitude' => $data['longitude']??'',
|
||||
'latitude' => $data['latitude']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/pay/activeScan', $body, $header);
|
||||
//$this->saveLogStore("主扫订单创建".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 主扫订单信息确认
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payActiveVerify($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.active.verify',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'activeOrderId' => $data['activeOrderId']??'',
|
||||
'amount' => !empty($data['amount']??'') ? round($data['amount'],2) : '',
|
||||
'deviceId' => $data['deviceId']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/pay/activeVerify', $body, $header);
|
||||
//$this->saveLogStore("主扫订单信息确认".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 账户余额查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payAmountBalance($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.account.balance',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/finance/account/balance', $body, $header);
|
||||
//$this->saveLogStore("账户余额查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 申请发票
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payInvoiceRequest($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.invoice.request',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'amount' => !empty($data['amount']??'') ? round($data['amount'],2) : '',
|
||||
'oilNo' => $data['oilNo']??'',
|
||||
'invoiceAddress' => $data['invoiceAddress']??'',
|
||||
'invoiceHeader' => $data['invoiceHeader']??'',
|
||||
'invoicePhone' => $data['invoicePhone']??'',
|
||||
'invoiceOpenBank' => $data['invoiceOpenBank']??'',
|
||||
'taxIdentifyNo' => $data['taxIdentifyNo']??'',
|
||||
'invoiceCardNo' => $data['invoiceCardNo']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/finance/invoice/request', $body, $header);
|
||||
//$this->saveLogStore("申请发票".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 开票状态查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function payInvoiceStatus($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.pay.invoice.status',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'invoiceNo' => $data['invoiceNo']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/finance/invoice/status', $body, $header);
|
||||
//$this->saveLogStore("开票状态查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 添加用户
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function userOptAdd($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.user.opt.add',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'mobile' => $data['mobile']??'',
|
||||
'userName' => $data['userName']??'',
|
||||
'userIdCard' => $data['userIdCard']??'',
|
||||
'userType' => $data['userType']??'user',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/user/opt/add', $body, $header);
|
||||
//$this->saveLogStore("添加用户".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 优惠券下单
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function voucherCreateOrder($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.opt.voucher.createOrder',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'model' => $data['model']??'',
|
||||
'voucherAmount' => $data['voucherAmount']??'',
|
||||
'fullAmount' => $data['fullAmount']??'',
|
||||
'storeNum' => $data['storeNum']??'',
|
||||
'validTime' => $data['validTime']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/voucher/createOrder', $body, $header);
|
||||
//$this->saveLogStore("优惠券下单".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 优惠券订单查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function voucherOrderListPage($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.opt.voucher.order.listPage',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'orderNo' => $data['orderNo']??'',
|
||||
'model' => $data['model']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/voucher/order/listPage', $body, $header);
|
||||
//$this->saveLogStore("优惠券订单查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** 卡券查询
|
||||
* @param $data
|
||||
* @param $company
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function voucherItemListPage($data, $company)
|
||||
{
|
||||
$header = [
|
||||
'method' => 'syb.opt.voucher.item.listPage',
|
||||
];
|
||||
$body = [
|
||||
'orgNo' => $company['orgNo'],
|
||||
'orderNo' => $data['orderNo']??'',
|
||||
'model' => $data['model']??'',
|
||||
'pageLimit' => $data['pageLimit']??'',
|
||||
'pageNum' => $data['pageNum']??'',
|
||||
];
|
||||
|
||||
$response = $this->sendRequest($company, $company['url'].'/api/1.0.0/voucher/item/listPage', $body, $header);
|
||||
//$this->saveLogStore("卡券查询".json_encode($response,320));
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\delivery;
|
||||
|
||||
use app\common\enum\Setting as SettingEnum;
|
||||
use app\common\library\helper;
|
||||
use app\common\model\store\Setting as SettingModel;
|
||||
use app\common\model\Delivery as DeliveryModel;
|
||||
use app\common\enum\OrderType as OrderTypeEnum;
|
||||
use app\common\service\BaseService;
|
||||
|
||||
/**
|
||||
* 快递配送服务类
|
||||
* Class Delivery
|
||||
* @package app\common\service
|
||||
*/
|
||||
class Express extends BaseService
|
||||
{
|
||||
private $cityId; // 用户收货城市id
|
||||
private $goodsList; // 订单商品列表
|
||||
private $notInRuleGoodsId; // 不在配送范围的商品ID
|
||||
|
||||
// 运费模板数据集
|
||||
private $data = [];
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* Express constructor.
|
||||
* @param int $cityId 城市ID
|
||||
* @param $goodsList
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function __construct(int $cityId, $goodsList)
|
||||
{
|
||||
parent::__construct();
|
||||
// 赋值传参
|
||||
$this->cityId = $cityId;
|
||||
$this->goodsList = $goodsList;
|
||||
// 整合运费模板
|
||||
$this->initDeliveryTemplate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户收货地址是否在配送范围
|
||||
* @return bool
|
||||
*/
|
||||
public function isIntraRegion(): bool
|
||||
{
|
||||
if (!$this->cityId) return false;
|
||||
foreach ($this->data as $item) {
|
||||
$cityIds = [];
|
||||
foreach ($item['delivery']['rule'] as $ruleItem) {
|
||||
$cityIds = array_merge($cityIds, $ruleItem['region']);
|
||||
}
|
||||
if (!in_array($this->cityId, $cityIds)) {
|
||||
$this->notInRuleGoodsId = current($item['goodsList'])['goods_id'];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取不在配送范围的商品名称
|
||||
* @return null
|
||||
*/
|
||||
public function getNotInRuleGoodsName()
|
||||
{
|
||||
$item = helper::getArrayItemByColumn($this->goodsList, 'goods_id', $this->notInRuleGoodsId);
|
||||
return !empty($item) ? $item['goods_name'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单的配送费用
|
||||
* @return string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getDeliveryFee()
|
||||
{
|
||||
if (empty($this->cityId) || empty($this->goodsList) || $this->notInRuleGoodsId > 0) {
|
||||
return helper::number2(0.00);
|
||||
}
|
||||
// 处理商品包邮
|
||||
$this->freeshipping();
|
||||
// 计算配送金额
|
||||
foreach ($this->data as &$item) {
|
||||
// 计算当前配送模板的运费
|
||||
$item['delivery_fee'] = $this->calcDeliveryAmount($item);
|
||||
}
|
||||
// 根据运费组合策略获取最终运费金额
|
||||
return helper::number2($this->getFinalFreight());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据运费组合策略 计算最终运费
|
||||
* @return float|int|mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getFinalFreight()
|
||||
{
|
||||
// 运费合集
|
||||
$expressPriceArr = helper::getArrayColumn($this->data, 'delivery_fee');
|
||||
// 最终运费金额
|
||||
$expressPrice = 0.00;
|
||||
// 判断运费组合策略
|
||||
switch (SettingModel::getItem('trade')['freight_rule']) {
|
||||
case '10': // 策略1: 叠加
|
||||
$expressPrice = array_sum($expressPriceArr);
|
||||
break;
|
||||
case '20': // 策略2: 以最低运费结算
|
||||
$expressPrice = min($expressPriceArr);
|
||||
break;
|
||||
case '30': // 策略3: 以最高运费结算
|
||||
$expressPrice = max($expressPriceArr);
|
||||
break;
|
||||
}
|
||||
return $expressPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品满额包邮
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function freeshipping(): bool
|
||||
{
|
||||
// 订单商品总金额
|
||||
$orderTotalPrice = helper::getArrayColumnSum($this->goodsList, 'total_price');
|
||||
// 获取满额包邮设置
|
||||
$options = SettingModel::getItem(SettingEnum::FULL_FREE);
|
||||
foreach ($this->data as &$item) {
|
||||
$item['free_goods_list'] = [];
|
||||
foreach ($item['goodsList'] as $goodsItem) {
|
||||
if (
|
||||
$options['is_open'] == true
|
||||
&& $orderTotalPrice >= $options['money']
|
||||
&& !in_array($goodsItem['goods_id'], $options['excludedGoodsIds'])
|
||||
&& !in_array($this->cityId, $options['excludedRegions']['cityIds'])
|
||||
) {
|
||||
$item['free_goods_list'][] = $goodsItem['goods_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当前配送模板的运费
|
||||
* @param $item
|
||||
* @return float|mixed|string
|
||||
*/
|
||||
private function calcDeliveryAmount($item)
|
||||
{
|
||||
// 获取运费模板下商品总数量or总重量
|
||||
if (!$totality = $this->getItemGoodsTotal($item)) {
|
||||
return 0.00;
|
||||
}
|
||||
// 当前收货城市配送规则
|
||||
$deliveryRule = $this->getCityDeliveryRule($item['delivery']);
|
||||
if ($totality <= $deliveryRule['first']) {
|
||||
return $deliveryRule['first_fee'];
|
||||
}
|
||||
// 续件or续重 数量
|
||||
$additional = $totality - $deliveryRule['first'];
|
||||
if ($additional <= $deliveryRule['additional']) {
|
||||
return helper::bcadd($deliveryRule['first_fee'], $deliveryRule['additional_fee']);
|
||||
}
|
||||
// 计算续重/件金额
|
||||
if ($deliveryRule['additional'] < 1) {
|
||||
// 配送规则中续件为0
|
||||
$additionalFee = 0.00;
|
||||
} else {
|
||||
$additionalFee = helper::bcdiv($deliveryRule['additional_fee'], $deliveryRule['additional']) * $additional;
|
||||
}
|
||||
return helper::bcadd($deliveryRule['first_fee'], $additionalFee);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运费模板下商品总数量or总重量
|
||||
* @param $item
|
||||
* @return int|string
|
||||
*/
|
||||
private function getItemGoodsTotal($item)
|
||||
{
|
||||
$totalWeight = 0; // 总重量
|
||||
$totalNum = 0; // 总数量
|
||||
foreach ($item['goodsList'] as $goodsItem) {
|
||||
// 如果商品为包邮,则不计算总量中
|
||||
if (!in_array($goodsItem['goods_id'], $item['free_goods_list'])) {
|
||||
$goodsWeight = helper::bcmul($goodsItem['skuInfo']['goods_weight'], $goodsItem['total_num']);
|
||||
$totalWeight = helper::bcadd($totalWeight, $goodsWeight);
|
||||
$totalNum = helper::bcadd($totalNum, $goodsItem['total_num']);
|
||||
}
|
||||
}
|
||||
return $item['delivery']['method'] == 10 ? $totalNum : $totalWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据城市id获取规则信息
|
||||
* @param
|
||||
* @return array|false
|
||||
*/
|
||||
private function getCityDeliveryRule($delivery)
|
||||
{
|
||||
foreach ($delivery['rule'] as $item) {
|
||||
if (in_array($this->cityId, $item['region'])) {
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 整合运费模板
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function initDeliveryTemplate()
|
||||
{
|
||||
// 运费模板ID集
|
||||
$deliveryIds = helper::getArrayColumn($this->goodsList, 'delivery_id');
|
||||
// 运费模板列表
|
||||
$deliveryList = (new DeliveryModel)->getListByIds(array_values(array_unique($deliveryIds)));
|
||||
// 整理数据集
|
||||
foreach ($deliveryList as $item) {
|
||||
$this->data[$item['delivery_id']]['delivery'] = $item;
|
||||
$this->data[$item['delivery_id']]['goodsList'] = $this->getGoodsListByDeliveryId($item['delivery_id']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据运费模板id整理商品集
|
||||
* @param $deliveryId
|
||||
* @return array
|
||||
*/
|
||||
private function getGoodsListByDeliveryId($deliveryId)
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->goodsList as $item) {
|
||||
$item['delivery_id'] == $deliveryId && $data[] = $item;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\goods\source;
|
||||
|
||||
use app\common\service\BaseService;
|
||||
|
||||
/**
|
||||
* 商品来源抽象类
|
||||
* Class Basics
|
||||
* @package app\common\service\stock
|
||||
*/
|
||||
abstract class Basics extends BaseService
|
||||
{
|
||||
/**
|
||||
* 更新商品库存 (针对下单减库存的商品)
|
||||
* @param $goodsList
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function updateGoodsStock($goodsList);
|
||||
|
||||
/**
|
||||
* 更新商品库存销量(订单付款后)
|
||||
* @param $goodsList
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function updateStockSales($goodsList);
|
||||
|
||||
/**
|
||||
* 回退商品库存
|
||||
* @param $goodsList
|
||||
* @param bool $isPayOrder 是否为已支付订单
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function backGoodsStock($goodsList, bool $isPayOrder = false);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\goods\source;
|
||||
|
||||
use app\common\service\BaseService;
|
||||
use app\common\enum\order\OrderSource as OrderSourceEnum;
|
||||
|
||||
/**
|
||||
* 商品来源工厂类
|
||||
* Class Factory
|
||||
* @package app\common\service\stock
|
||||
*/
|
||||
class Factory extends BaseService
|
||||
{
|
||||
// 订单来源的结算台服务类
|
||||
private static $class = [
|
||||
OrderSourceEnum::MAIN => Main::class
|
||||
];
|
||||
|
||||
/**
|
||||
* 根据订单来源获取商品库存类
|
||||
* @param int $orderSource
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getFactory($orderSource = OrderSourceEnum::MAIN)
|
||||
{
|
||||
static $classObj = [];
|
||||
if (!isset($classObj[$orderSource])) {
|
||||
// $className = __NAMESPACE__ . '\\' . static::$class[$orderSource];
|
||||
$classObj[$orderSource] = new static::$class[$orderSource];
|
||||
}
|
||||
return $classObj[$orderSource];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\goods\source;
|
||||
|
||||
use app\common\model\Goods as GoodsModel;
|
||||
use app\common\model\GoodsSku as GoodsSkuModel;
|
||||
use app\common\enum\goods\DeductStockType as DeductStockTypeEnum;
|
||||
|
||||
/**
|
||||
* 商品来源-普通商品扩展类
|
||||
* Class Main
|
||||
* @package app\common\service\stock
|
||||
*/
|
||||
class Main extends Basics
|
||||
{
|
||||
/**
|
||||
* 更新商品库存 (针对下单减库存的商品)
|
||||
* @param $goodsList
|
||||
* @return bool
|
||||
*/
|
||||
public function updateGoodsStock($goodsList)
|
||||
{
|
||||
$goodsData = [];
|
||||
$goodsSkuData = [];
|
||||
foreach ($goodsList as $goods) {
|
||||
// 是否减库存 (下单减库存)
|
||||
$isUpdateStockNum = $goods['deduct_stock_type'] == DeductStockTypeEnum::CREATE;
|
||||
// 商品的数据
|
||||
$isUpdateStockNum && $goodsData[] = [
|
||||
'where' => ['goods_id' => $goods['goods_id']],
|
||||
'data' => [
|
||||
// 递减商品总库存
|
||||
'stock_total' => ['dec', $goods['total_num']]
|
||||
]
|
||||
];
|
||||
// 商品SKU数据
|
||||
$isUpdateStockNum && $goodsSkuData[] = [
|
||||
'data' => ['stock_num' => ['dec', $goods['total_num']]],
|
||||
'where' => [
|
||||
'goods_id' => $goods['goods_id'],
|
||||
'goods_sku_id' => $goods['goods_sku_id'],
|
||||
],
|
||||
];
|
||||
}
|
||||
// 更新商品总库存
|
||||
!empty($goodsData) && $this->updateGoods($goodsData);
|
||||
// 更新商品sku库存
|
||||
!empty($goodsSkuData) && $this->updateGoodsSku($goodsSkuData);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品库存销量(订单付款后)
|
||||
* @param $goodsList
|
||||
* @return bool
|
||||
*/
|
||||
public function updateStockSales($goodsList)
|
||||
{
|
||||
$goodsData = [];
|
||||
$goodsSkuData = [];
|
||||
foreach ($goodsList as $goods) {
|
||||
// 是否减库存 (付款减库存)
|
||||
$isUpdateStockNum = $goods['deduct_stock_type'] == DeductStockTypeEnum::PAYMENT;
|
||||
// 商品的数据
|
||||
$goodsDataItm = [
|
||||
'where' => ['goods_id' => $goods['goods_id']],
|
||||
'data' => [
|
||||
// 累计商品实际销量
|
||||
'sales_actual' => ['inc', $goods['total_num']]
|
||||
]
|
||||
];
|
||||
// 递减商品总库存
|
||||
$isUpdateStockNum && $goodsDataItm['data']['stock_total'] = ['dec', $goods['total_num']];
|
||||
$goodsData[] = $goodsDataItm;
|
||||
// 付款减库存
|
||||
$isUpdateStockNum && $goodsSkuData[] = [
|
||||
'where' => [
|
||||
'goods_id' => $goods['goods_id'],
|
||||
'goods_sku_id' => $goods['goods_sku_id'],
|
||||
],
|
||||
'data' => ['stock_num' => ['dec', $goods['total_num']]],
|
||||
];
|
||||
}
|
||||
// 更新商品信息
|
||||
!empty($goodsData) && $this->updateGoods($goodsData);
|
||||
// 更新商品sku信息
|
||||
!empty($goodsSkuData) && $this->updateGoodsSku($goodsSkuData);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回退商品库存事件 (用于取消订单时调用)
|
||||
* @param mixed $goodsList 订单商品列表
|
||||
* @param bool $isPayOrder 是否为已支付订单
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function backGoodsStock($goodsList, bool $isPayOrder = false)
|
||||
{
|
||||
$goodsData = [];
|
||||
$goodsSkuData = [];
|
||||
foreach ($goodsList as $goods) {
|
||||
// 更新条件: 订单已经支付或者订单商品为 "下单减库存"
|
||||
if ($isPayOrder == true || $goods['deduct_stock_type'] == DeductStockTypeEnum::CREATE) {
|
||||
$goodsData[] = [
|
||||
'where' => ['goods_id' => $goods['goods_id']],
|
||||
'data' => ['stock_total' => ['inc', $goods['total_num']]]
|
||||
];
|
||||
$goodsSkuData[] = [
|
||||
'where' => [
|
||||
'goods_id' => $goods['goods_id'],
|
||||
'goods_sku_id' => $goods['goods_sku_id'],
|
||||
],
|
||||
'data' => ['stock_num' => ['inc', $goods['total_num']]],
|
||||
];
|
||||
}
|
||||
}
|
||||
// 更新商品总库存
|
||||
!empty($goodsData) && $this->updateGoods($goodsData);
|
||||
// 更新商品sku库存
|
||||
!empty($goodsSkuData) && $this->updateGoodsSku($goodsSkuData);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品信息
|
||||
* @param array $data
|
||||
* @return array|false
|
||||
*/
|
||||
private function updateGoods(array $data)
|
||||
{
|
||||
return (new GoodsModel)->updateAll($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品sku信息
|
||||
* @param array $data
|
||||
* @return array|false
|
||||
*/
|
||||
private function updateGoodsSku(array $data)
|
||||
{
|
||||
return (new GoodsSkuModel)->updateAll($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\message;
|
||||
|
||||
use cores\traits\ErrorTrait;
|
||||
use app\common\service\BaseService;
|
||||
use app\common\library\sms\Driver as SmsDriver;
|
||||
use app\common\model\store\Setting as SettingModel;
|
||||
use app\common\model\wxapp\Setting as WxappSettingModel;
|
||||
|
||||
/**
|
||||
* 消息通知服务[基类]
|
||||
* Class Basics
|
||||
* @package app\common\service\message
|
||||
*/
|
||||
abstract class Basics extends BaseService
|
||||
{
|
||||
use ErrorTrait;
|
||||
|
||||
// 参数列表
|
||||
protected $param = [];
|
||||
|
||||
// 商城ID
|
||||
protected $storeId;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* Basics constructor.
|
||||
* @param int $storeId
|
||||
*/
|
||||
public function __construct(int $storeId)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->storeId = $storeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息通知
|
||||
* @param array $param 参数
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function send(array $param);
|
||||
|
||||
/**
|
||||
* 发送短信通知
|
||||
* @param string $sceneValue 短信发送场景
|
||||
* @param string $acceptPhone 接收的手机号
|
||||
* @param array $templateParams 短信模板参数
|
||||
* @return bool
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function sendSms(string $sceneValue, string $acceptPhone, array $templateParams): bool
|
||||
{
|
||||
// 短信通知设置
|
||||
$smsConfig = $this->getSmsConfig();
|
||||
// 短信服务
|
||||
$SmsDriver = new SmsDriver($smsConfig);
|
||||
try {
|
||||
// 判断短信服务是否开启
|
||||
$this->isEnableSms($smsConfig, $sceneValue);
|
||||
// 获取短信模板ID
|
||||
$templateCode = $this->getSmsTemplateCode($smsConfig, $sceneValue);
|
||||
// 执行发送短信
|
||||
$SmsDriver->sendSms($acceptPhone, $templateCode, $templateParams);
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
$this->error = $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信通知设置
|
||||
* @return array|mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getSmsConfig()
|
||||
{
|
||||
return SettingModel::getItem('sms', $this->storeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断短信服务是否开启
|
||||
* @param array $smsConfig 短信设置
|
||||
* @param string $sceneValue 短信发送场景
|
||||
* @throws \cores\exception\BaseException
|
||||
*/
|
||||
private function isEnableSms(array $smsConfig, string $sceneValue)
|
||||
{
|
||||
if (!$smsConfig['scene'][$sceneValue]['isEnable']) {
|
||||
throwError('短信通知服务未开启,请在商户后台中设置');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信模板ID
|
||||
* @param array $smsConfig 短信设置
|
||||
* @param string $sceneValue 短信发送场景
|
||||
* @return string
|
||||
*/
|
||||
private function getSmsTemplateCode(array $smsConfig, string $sceneValue): string
|
||||
{
|
||||
return $smsConfig['scene'][$sceneValue]['templateCode'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串截取前20字符
|
||||
* [用于兼容thing数据类型]
|
||||
* @param string $content
|
||||
* @param int $length
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function getSubstr(string $content, int $length = 20)
|
||||
{
|
||||
return str_substr($content, $length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\message\order;
|
||||
|
||||
use app\common\service\message\Basics;
|
||||
use app\common\model\store\Setting as SettingModel;
|
||||
|
||||
/**
|
||||
* 消息通知服务 [订单发货]
|
||||
* Class Delivery
|
||||
* @package app\common\service\message\order
|
||||
*/
|
||||
class Delivery extends Basics
|
||||
{
|
||||
/**
|
||||
* 参数列表
|
||||
* @var array
|
||||
*/
|
||||
protected $param = [
|
||||
'order' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* 订单页面链接
|
||||
* @var string
|
||||
*/
|
||||
private $pageUrl = 'pages/order/detail';
|
||||
|
||||
/**
|
||||
* 发送消息通知
|
||||
* @param array $param
|
||||
* @return mixed|void
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function send(array $param)
|
||||
{
|
||||
// 记录参数
|
||||
$this->param = $param;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化物流公司
|
||||
* @param $orderInfo
|
||||
* @return mixed
|
||||
*/
|
||||
private function getFormatExpressName($orderInfo)
|
||||
{
|
||||
return $this->getSubstr($orderInfo['express']['express_name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化用户收货地址
|
||||
* @param $orderInfo
|
||||
* @return string
|
||||
*/
|
||||
private function getFormatAddress($orderInfo)
|
||||
{
|
||||
return implode('', $orderInfo['address']['region']) . $orderInfo['address']['detail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化商品名称
|
||||
* @param $goodsData
|
||||
* @return string
|
||||
*/
|
||||
private function getFormatGoodsName($goodsData)
|
||||
{
|
||||
return $this->getSubstr($goodsData[0]['goods_name']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\message\order;
|
||||
|
||||
use app\common\service\message\Basics;
|
||||
use app\common\model\store\Setting as SettingModel;
|
||||
use app\common\enum\setting\sms\Scene as SettingSmsScene;
|
||||
|
||||
/**
|
||||
* 消息通知服务 [订单支付成功]
|
||||
* Class Payment
|
||||
* @package app\common\service\message\order
|
||||
*/
|
||||
class Payment extends Basics
|
||||
{
|
||||
/**
|
||||
* 参数列表
|
||||
* @var array
|
||||
*/
|
||||
protected $param = [
|
||||
'order' => []
|
||||
];
|
||||
|
||||
/**
|
||||
* 订单页面链接
|
||||
* @var array
|
||||
*/
|
||||
private $pageUrl = 'pages/order/detail';
|
||||
|
||||
/**
|
||||
* 发送消息通知
|
||||
* @param array $param
|
||||
* @return mixed|void
|
||||
* @throws \app\common\exception\BaseException
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function send(array $param)
|
||||
{
|
||||
// 记录参数
|
||||
$this->param = $param;
|
||||
// 短信通知商家
|
||||
$this->onSendSms();
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信通知商家
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function onSendSms(): void
|
||||
{
|
||||
$orderInfo = $this->param['order'];
|
||||
// 获取商家的手机号 (用于接受短信通知)
|
||||
$acceptPhone = $this->getStoreAcceptPhone();
|
||||
if (empty($acceptPhone)) {
|
||||
return;
|
||||
}
|
||||
// 发送短信通知
|
||||
$this->sendSms(SettingSmsScene::ORDER_PAY, $acceptPhone, ['order_no' => $orderInfo['order_no']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家手机号(用于接受短信通知)
|
||||
* @return string|false
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getStoreAcceptPhone()
|
||||
{
|
||||
// 短信通知设置
|
||||
$smsConfig = SettingModel::getItem('sms', $this->storeId);
|
||||
// 商家手机号 (后台设置)
|
||||
return $smsConfig['scene'][SettingSmsScene::ORDER_PAY]['acceptPhone'] ?? false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\message\order;
|
||||
|
||||
use app\common\service\message\Basics;
|
||||
use app\common\model\store\Setting as SettingModel;
|
||||
|
||||
/**
|
||||
* 消息通知服务 [订单售后]
|
||||
* Class Refund
|
||||
* @package app\common\service\message\order
|
||||
*/
|
||||
class Refund extends Basics
|
||||
{
|
||||
/**
|
||||
* 参数列表
|
||||
* @var array
|
||||
*/
|
||||
protected $param = [
|
||||
'refund' => [], // 退款单信息
|
||||
'order_no' => [], // 订单信息
|
||||
];
|
||||
|
||||
/**
|
||||
* 订单页面链接
|
||||
* @var array
|
||||
*/
|
||||
private $pageUrl = 'pages/order/refund/index';
|
||||
|
||||
/**
|
||||
* 发送消息通知
|
||||
* @param array $param
|
||||
* @return mixed|void
|
||||
* @throws \app\common\exception\BaseException
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function send(array $param)
|
||||
{
|
||||
// 记录参数
|
||||
$this->param = $param;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\message\passport;
|
||||
|
||||
use app\common\service\message\Basics;
|
||||
use app\common\enum\setting\sms\Scene as SettingSmsScene;
|
||||
|
||||
/**
|
||||
* 消息通知服务 [短信验证码]
|
||||
* Class Captcha
|
||||
* @package app\common\service\message\passport
|
||||
*/
|
||||
class Captcha extends Basics
|
||||
{
|
||||
/**
|
||||
* 发送消息通知
|
||||
* @param array $param
|
||||
* @return bool|mixed
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function send(array $param)
|
||||
{
|
||||
// 发送短信
|
||||
if (!$this->sendSms(SettingSmsScene::CAPTCHA, $param['mobile'], ['code' => $param['code']])) {
|
||||
throwError('短信发送失败:' . $this->getError());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\order;
|
||||
|
||||
use app\common\library\helper;
|
||||
use app\common\model\User as UserModel;
|
||||
use app\common\model\Order as OrderModel;
|
||||
use app\common\model\store\Setting as SettingModel;
|
||||
use app\common\model\user\PointsLog as PointsLogModel;
|
||||
use app\common\enum\Setting as SettingEnum;
|
||||
use app\common\service\BaseService;
|
||||
|
||||
/**
|
||||
* 已完成订单结算服务类
|
||||
* Class Complete
|
||||
* @package app\common\service\order
|
||||
*/
|
||||
class Complete extends BaseService
|
||||
{
|
||||
// 订单模型
|
||||
/* @var OrderModel $model */
|
||||
private $model;
|
||||
|
||||
// 用户模型
|
||||
/* @var UserModel $model */
|
||||
private $UserModel;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
* Complete constructor.
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->model = new OrderModel;
|
||||
$this->UserModel = new UserModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行订单完成后的操作
|
||||
* @param iterable $orderList
|
||||
* @param int $storeId
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function complete(iterable $orderList, int $storeId)
|
||||
{
|
||||
// 已完成订单结算
|
||||
// 条件:后台订单流程设置 - 已完成订单设置0天不允许申请售后
|
||||
if (SettingModel::getItem(SettingEnum::TRADE, $storeId)['order']['refund_days'] == 0) {
|
||||
$this->settled($orderList);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行订单结算
|
||||
* @param $orderList
|
||||
* @return bool
|
||||
*/
|
||||
public function settled($orderList)
|
||||
{
|
||||
// 订单id集
|
||||
$orderIds = helper::getArrayColumn($orderList, 'order_id');
|
||||
// 累积用户实际消费金额
|
||||
$this->setIncUserExpend($orderList);
|
||||
// 处理订单赠送的积分
|
||||
$this->setGiftPointsBonus($orderList);
|
||||
// 将订单设置为已结算
|
||||
$this->model->onBatchUpdate($orderIds, ['is_settled' => 1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理订单赠送的积分
|
||||
* @param $orderList
|
||||
* @return bool
|
||||
*/
|
||||
private function setGiftPointsBonus($orderList)
|
||||
{
|
||||
// 计算用户所得积分
|
||||
$userData = [];
|
||||
$logData = [];
|
||||
foreach ($orderList as $order) {
|
||||
// 计算用户所得积分
|
||||
$pointsBonus = $order['points_bonus'];
|
||||
if ($pointsBonus <= 0) continue;
|
||||
// 减去订单退款的积分
|
||||
foreach ($order['goods'] as $goods) {
|
||||
if (
|
||||
!empty($goods['refund'])
|
||||
&& $goods['refund']['type'] == 10 // 售后类型:退货退款
|
||||
&& $goods['refund']['audit_status'] == 10 // 商家审核:已同意
|
||||
) {
|
||||
$pointsBonus -= $goods['points_bonus'];
|
||||
}
|
||||
}
|
||||
// 计算用户所得积分
|
||||
!isset($userData[$order['user_id']]) && $userData[$order['user_id']] = 0;
|
||||
$userData[$order['user_id']] += $pointsBonus;
|
||||
// 整理用户积分变动明细
|
||||
$logData[] = [
|
||||
'user_id' => $order['user_id'],
|
||||
'value' => $pointsBonus,
|
||||
'describe' => "订单赠送:{$order['order_no']}",
|
||||
'store_id' => $order['store_id'],
|
||||
];
|
||||
}
|
||||
if (!empty($userData)) {
|
||||
// 累积到会员表记录
|
||||
$this->UserModel->onBatchIncPoints($userData);
|
||||
// 批量新增积分明细记录
|
||||
(new PointsLogModel)->onBatchAdd($logData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 累积用户实际消费金额
|
||||
* @param $orderList
|
||||
* @return bool
|
||||
*/
|
||||
private function setIncUserExpend($orderList)
|
||||
{
|
||||
// 计算并累积实际消费金额(需减去售后退款的金额)
|
||||
$userData = [];
|
||||
foreach ($orderList as $order) {
|
||||
// 订单实际支付金额
|
||||
$expendMoney = $order['pay_price'];
|
||||
// 减去订单退款的金额
|
||||
foreach ($order['goods'] as $goods) {
|
||||
if (
|
||||
!empty($goods['refund'])
|
||||
&& $goods['refund']['type'] == 10 // 售后类型:退货退款
|
||||
&& $goods['refund']['audit_status'] == 10 // 商家审核:已同意
|
||||
) {
|
||||
$expendMoney = helper::bcsub($expendMoney, $goods['refund']['refund_money']);
|
||||
}
|
||||
}
|
||||
!isset($userData[$order['user_id']]) && $userData[$order['user_id']] = 0.00;
|
||||
if ($expendMoney > 0) {
|
||||
$userData[$order['user_id']] = helper::bcadd($userData[$order['user_id']], $expendMoney);
|
||||
}
|
||||
}
|
||||
// 累积到会员表记录
|
||||
$this->UserModel->onBatchIncExpendMoney($userData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\order;
|
||||
|
||||
use app\common\exception\BaseException;
|
||||
use app\common\model\User as UserModel;
|
||||
use app\common\model\wxapp\Setting as WxappSettingModel;
|
||||
use app\common\model\user\BalanceLog as BalanceLogModel;
|
||||
use app\common\enum\order\PayType as OrderPayTypeEnum;
|
||||
use app\common\enum\user\balanceLog\Scene as SceneEnum;
|
||||
use app\common\library\wechat\WxPay;
|
||||
use app\common\service\BaseService;
|
||||
|
||||
/**
|
||||
* 订单退款服务类
|
||||
* Class Refund
|
||||
* @package app\common\service\order
|
||||
*/
|
||||
class Refund extends BaseService
|
||||
{
|
||||
/**
|
||||
* 执行订单退款
|
||||
* @param $order
|
||||
* @param null $money
|
||||
* @return bool
|
||||
* @throws \cores\exception\BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function execute($order, $money = null): bool
|
||||
{
|
||||
// 退款金额,如不指定则默认为订单实付款金额
|
||||
is_null($money) && $money = $order['pay_price'];
|
||||
// 1.微信支付退款
|
||||
if ($order['pay_type'] == OrderPayTypeEnum::WECHAT) {
|
||||
return $this->wxpay($order, (string)$money);
|
||||
}
|
||||
// 2.余额支付退款
|
||||
if ($order['pay_type'] == OrderPayTypeEnum::BALANCE) {
|
||||
return $this->balance($order, (string)$money);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额支付退款
|
||||
* @param $order
|
||||
* @param $money
|
||||
* @return bool
|
||||
*/
|
||||
private function balance($order, $money): bool
|
||||
{
|
||||
// 回退用户余额
|
||||
UserModel::setIncBalance((int)$order['user_id'], (float)$money);
|
||||
// 记录余额明细
|
||||
BalanceLogModel::add(SceneEnum::REFUND, [
|
||||
'user_id' => $order['user_id'],
|
||||
'money' => $money,
|
||||
], ['order_no' => $order['order_no']]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付退款
|
||||
* @param $order
|
||||
* @param string $money
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \cores\exception\BaseException
|
||||
*/
|
||||
private function wxpay($order, string $money): bool
|
||||
{
|
||||
$wxConfig = WxappSettingModel::getWxappConfig($order['store_id']);
|
||||
$WxPay = new WxPay($wxConfig, $order['store_id']);
|
||||
return $WxPay->refund($order['transaction_id'], $order['pay_price'], $money);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\order;
|
||||
|
||||
use app\common\service\BaseService;
|
||||
|
||||
class Source extends BaseService
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\common\service\store;
|
||||
|
||||
use think\facade\Cache;
|
||||
use app\common\service\BaseService;
|
||||
|
||||
/**
|
||||
* 商家用户服务类
|
||||
* Class User
|
||||
*/
|
||||
class User extends BaseService
|
||||
{
|
||||
// 用于生成token的自定义盐
|
||||
const TOKEN_SALT = '_store_user_salt_';
|
||||
|
||||
/**
|
||||
* 获取当前登录用户的信息
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getLoginInfo()
|
||||
{
|
||||
if (($token = self::getToken()) !== false) {
|
||||
return Cache::get($token);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户的ID
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getLoginUserId()
|
||||
{
|
||||
return (int)static::getLoginInfo()['user']['store_user_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
* @param array $userInfo
|
||||
* @return bool
|
||||
*/
|
||||
public static function login(array $userInfo)
|
||||
{
|
||||
// 生成token
|
||||
$token = self::makeToken((int)$userInfo['store_user_id']);
|
||||
// 记录缓存, 7天
|
||||
Cache::set($token, [
|
||||
'user' => $userInfo,
|
||||
'store_id' => $userInfo['store_id'],
|
||||
'is_login' => true,
|
||||
], 86400 * 7);
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空登录状态
|
||||
* @return bool
|
||||
*/
|
||||
public static function logout()
|
||||
{
|
||||
Cache::delete(self::getToken());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新登录信息
|
||||
* @param array $userInfo
|
||||
* @return mixed
|
||||
*/
|
||||
public static function update(array $userInfo)
|
||||
{
|
||||
return Cache::set(self::getToken(), [
|
||||
'user' => $userInfo,
|
||||
'store_id' => $userInfo['store_id'],
|
||||
'is_login' => true,
|
||||
], 86400 * 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成用户认证的token
|
||||
* @param int $userId
|
||||
* @return string
|
||||
*/
|
||||
protected static function makeToken(int $userId)
|
||||
{
|
||||
// 生成一个不会重复的随机字符串
|
||||
$guid = get_guid_v4();
|
||||
// 当前时间戳 (精确到毫秒)
|
||||
$timeStamp = microtime(true);
|
||||
// 自定义一个盐
|
||||
$salt = self::TOKEN_SALT;
|
||||
return md5("{$timeStamp}_{$userId}_{$guid}_{$salt}");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户认证Token
|
||||
* @return bool|string
|
||||
*/
|
||||
private static function getToken()
|
||||
{
|
||||
// 获取请求中的token
|
||||
$token = request()->header('Access-Token');
|
||||
// 调试模式下可通过param
|
||||
if (empty($token) && is_debug()) {
|
||||
$token = request()->param('Access-Token');
|
||||
}
|
||||
// 不存在token报错
|
||||
if (empty($token)) {
|
||||
return false;
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user