
- 添加 LinSuoKa 类实现临时锁卡功能 - 优化卡密订单关联逻辑,处理状态为 4 的订单- 新增 redis 记录订单详情,用于限单和退款处理 - 修改 Qiling 类中的签名生成逻辑 - 更新 Test 控制器中的 test_ts 方法,增加对不同订单表的处理
559 lines
18 KiB
PHP
559 lines
18 KiB
PHP
<?php
|
||
|
||
namespace app\channel\service;
|
||
|
||
use app\core\BtWafService;
|
||
use app\core\Service;
|
||
use think\admin\extend\DataExtend;
|
||
use app\merchant\service\MerchantService;
|
||
use app\merchant\service\OrderService;
|
||
use app\merchant\service\PercentService;
|
||
use app\merchant\service\ProjectService;
|
||
use app\merchant\service\ProductService as MerchantProductService;
|
||
use app\merchant\service\ProjectProductService as MerchantProjectProductService;
|
||
use app\setting\service\BlackCardService;
|
||
|
||
|
||
/**
|
||
* 渠道服务
|
||
* Class ChannelService
|
||
* @package app\channel\service
|
||
*/
|
||
class ChannelService extends Service
|
||
{
|
||
protected int $isp = 1;
|
||
/**
|
||
* 设置默认操作表
|
||
* @var string
|
||
*/
|
||
public $table = 'channel_list';
|
||
|
||
# 加载的类
|
||
public $class;
|
||
|
||
# 获取渠道信息
|
||
public function getInfo($key)
|
||
{
|
||
if (is_numeric($key)) {
|
||
$where['id'] = $key;
|
||
} else {
|
||
$where['key'] = $key;
|
||
}
|
||
//$where['status'] = 1;
|
||
//$where['is_deleted'] = 0;
|
||
$data = $this->db()->where($where)->find();
|
||
|
||
return $data;
|
||
}
|
||
|
||
# 获取缓存
|
||
public function get($key, $get = true)
|
||
{
|
||
if (!$get) {
|
||
return false;
|
||
}
|
||
$cache_key = 'channelv2_' . $key;
|
||
|
||
$data = !$get ? false : $this->cache($cache_key);
|
||
|
||
if (!$data) {
|
||
$data = $this->getInfo($key);
|
||
if ($data) {
|
||
$this->cache($cache_key, $data);
|
||
}
|
||
}
|
||
|
||
if ($data) {
|
||
if ($data['status'] != 1) {
|
||
return false;
|
||
}
|
||
if ($data['is_deleted'] != 0) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
|
||
# 获取能使用的服务功能
|
||
public function product($key)
|
||
{
|
||
/*
|
||
$config = array
|
||
(
|
||
# 电话充值 key是对外开放的,method是对内使用的
|
||
'dhcz' => array
|
||
(
|
||
'method' => 'dhcz',
|
||
),
|
||
'zsycz' => array
|
||
(
|
||
'method' => 'zsycz',
|
||
),
|
||
'zshcz' => array
|
||
(
|
||
'method' => 'zshcz',
|
||
),
|
||
'dfcz' => array
|
||
(
|
||
'method' => 'dfcz',
|
||
),
|
||
'qbcz' => array
|
||
(
|
||
'method' => 'qbcz',
|
||
),
|
||
'kmcz' => array
|
||
(
|
||
'method' => 'kmcz',
|
||
),
|
||
'query' => array
|
||
(
|
||
'method' => 'query',
|
||
),
|
||
);
|
||
if (isset($config[$key])) {
|
||
return $config[$key];
|
||
}
|
||
*/
|
||
|
||
if ($key == 'mcz') {
|
||
if (isset($this->isp) && $this->isp) {
|
||
if ($this->isp == 1) {
|
||
$key = 'mydcz';
|
||
} elseif ($this->isp == 2) {
|
||
$key = 'mltcz';
|
||
} elseif ($this->isp == 3) {
|
||
$key = 'mdxcz';
|
||
}
|
||
}
|
||
}
|
||
return array
|
||
(
|
||
'method' => $key,
|
||
);
|
||
}
|
||
|
||
public function rule($merchant, $key, $value)
|
||
{
|
||
if ($merchant == 2) {
|
||
return true;
|
||
}
|
||
if ($key == 'dhcz') {
|
||
# 验证是否是手机号
|
||
$check = "/^1\d{10}$/";
|
||
if (!preg_match($check, $value)) {
|
||
return false;
|
||
}
|
||
} elseif ($key == 'zshcz') {
|
||
# 验证是否中石化加油卡
|
||
$check = "/^1\d{18}$/";
|
||
if (!preg_match($check, $value)) {
|
||
return false;
|
||
}
|
||
} elseif ($key == 'zsycz') {
|
||
# 验证是否中石油加油卡
|
||
$check = "/^(?:7|9)\d{15}$/";
|
||
if (!preg_match($check, $value)) {
|
||
return false;
|
||
}
|
||
} elseif ($key == 'xtdc' || $key == 'xtdc') {
|
||
# 验证是否中石油、中石化加油卡
|
||
$check1 = "/^(?:7|9)\d{15}$/";
|
||
$check2 = "/^1\d{18}$/";
|
||
if (!preg_match($check1, $value) && !preg_match($check2, $value) ) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
# 使用渠道的服务
|
||
public function use($merchant, $product, $param = array(), $async = false, $order = '', $use_product = array(),$usequdao = '')
|
||
{
|
||
if (isset($param['card']) && $param['card']) {
|
||
$rule = $this->rule($merchant, $product, $param['card']);
|
||
if (!$rule) {
|
||
return $param['card'] . '不符合规则';
|
||
}
|
||
$check = BlackCardService::instance()->check($param['card']);
|
||
if (!$check && empty($usequdao)) {
|
||
return $param['card'] . '已被列入黑名单';
|
||
}elseif (!$check && $usequdao == 'kuaishou'){
|
||
$backCard = '1';
|
||
}
|
||
} elseif (isset($param['mobile']) && $param['mobile']) {
|
||
$rule = $this->rule($merchant, $product, $param['mobile']);
|
||
if (!$rule) {
|
||
return $param['mobile'] . '不符合规则';
|
||
}
|
||
$check = BlackCardService::instance()->check($param['mobile']);
|
||
if (!$check && empty($usequdao)) {
|
||
return $param['mobile'] . '已被列入黑名单';
|
||
}elseif(!$check && $usequdao == 'kuaishou'){
|
||
$backCard = '1';
|
||
}
|
||
|
||
}
|
||
|
||
# 检测订单号唯一性
|
||
if (isset($param['order']) && $param['order'] && !$use_product && !$order) {
|
||
$order_info = OrderService::instance()->get(false, $param['order'], $merchant);
|
||
if ($order_info) {
|
||
if ($async) {
|
||
return '订单号重复';
|
||
} elseif ($order_info['status'] > 1) {
|
||
return '订单已在处理中或者已完成';
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!$product) {
|
||
return '无效的产品';
|
||
}
|
||
if (is_numeric($product) && $product > 0) {
|
||
$product_info = ProductService::instance()->getInfo($product);
|
||
} elseif (is_array($product)) {
|
||
$product_info = $product;
|
||
} else {
|
||
# 验证是否有通道id
|
||
$project = false;
|
||
if (isset($param['project_id']) && $param['project_id'] && $param['project_id'] > 0) {
|
||
$project = ProjectService::instance()->getInfo($param['project_id'], $merchant);
|
||
if (!$project) {
|
||
return '通道已禁用或不存在';
|
||
}
|
||
}
|
||
if ($project) {
|
||
# 使用通道
|
||
$product_all = MerchantProjectProductService::instance()->getAll($merchant, $param['project_id'], $product);
|
||
} else {
|
||
# 获取当前商户的所有产品
|
||
$product_all = MerchantProductService::instance()->getAll($merchant, $product);
|
||
}
|
||
if (!$product_all) {
|
||
return '未分配产品';
|
||
}
|
||
|
||
$this->isp = $param['isp'] = false;
|
||
$param['value'] = false;
|
||
if ($product == 'dhcz') {
|
||
if (!isset($param['mobile'])) {
|
||
return '参数错误';
|
||
}
|
||
$this->isp = $param['isp'] = $this->isp($param['mobile']);
|
||
$isp = PercentService::instance()->getIsp();
|
||
if (isset($isp[$param['isp']]) && $isp[$param['isp']]) {
|
||
$param['value'] = $isp[$param['isp']];
|
||
}
|
||
}
|
||
|
||
# 根据面值做判断
|
||
|
||
$merchant_info = MerchantService::instance()->get($merchant);
|
||
|
||
$pid = false;
|
||
foreach ($product_all as $k => $v) {
|
||
if ($v['cash']) {
|
||
$cash = explode(',', $v['cash']);
|
||
if ($param['value']) {
|
||
if (in_array($param['value'], $cash)) {
|
||
$pid = $v['pid'];
|
||
if ($this->getNum($pid, $merchant_info)) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
if (in_array($param['cash'], $cash)) {
|
||
$pid = $v['pid'];
|
||
if ($this->getNum($pid, $merchant_info)) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
} else {
|
||
$pid = $v['pid'];
|
||
if ($this->getNum($pid, $merchant_info)) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!$pid) {
|
||
return '产品错误';
|
||
}
|
||
|
||
$product_info = ProductService::instance()->getInfo($pid);
|
||
if (!$product_info) {
|
||
return '产品无效';
|
||
}
|
||
|
||
if (strstr($product_info['key'], '_cash')) {
|
||
$product_info['value'] = $param['value'];
|
||
}
|
||
# 验证该产品是否符合面值
|
||
$state = $this->checkProductValue($product_info, $param, 'value');
|
||
if (!$state) {
|
||
return '面额无效';
|
||
}
|
||
|
||
# 验证该产品是否符合当前限制的面额
|
||
$state = $this->checkProductValue($product_info, $param, 'auto_value');
|
||
if (!$state) {
|
||
return '面额无效';
|
||
}
|
||
|
||
# 验证该产品是否符合开放时间
|
||
if ($product_info['opentime']) {
|
||
$state = $this->checkProductOpenTime($product_info);
|
||
if (!$state) {
|
||
return '产品未开放';
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
$merchant_info = MerchantService::instance()->get($merchant);
|
||
# 如果自动切换面值
|
||
if ($merchant_info && isset($merchant_info['auto']) && $merchant_info['auto'] == 2) {
|
||
$product_info = $this->getProductByValue($product_info, $param, $merchant_info['cids']);
|
||
if (!$product_info) {
|
||
return '产品错误';
|
||
}
|
||
} else {
|
||
# 如果非自动切换,检查当前产品是否符合开放时间
|
||
$open_product_info = false;
|
||
if ($product_info['opentime']) {
|
||
$open_product_info = $this->getProductByOpenTime($product_info, $merchant_info['cids']);
|
||
if (!$open_product_info) {
|
||
return '产品错误';
|
||
} else {
|
||
$product_info = $open_product_info;
|
||
}
|
||
}
|
||
}*/
|
||
|
||
}
|
||
$product = $product_info['key'];
|
||
|
||
$data = array();
|
||
$data['merchant'] = $merchant;
|
||
$data['product'] = $product_info['id'];
|
||
$data['product_key'] = $product;
|
||
$data['param'] = $param;
|
||
$data['order'] = $order;
|
||
|
||
if(isset($backCard)){
|
||
$data['backCard'] = $backCard;
|
||
}
|
||
|
||
# 如果当前渠道的产品无效,是否继续到下一个渠道的产品(相同key),此处记录已经用过的产品
|
||
$data['use_product'] = $use_product;
|
||
# 记录通道id
|
||
if (isset($project) && $project && $project['id']) {
|
||
$data['project_id'] = $project['id'];
|
||
} else {
|
||
$data['project_id'] = false;
|
||
}
|
||
|
||
$product = $this->product($product);
|
||
if($product['method'] == 'zshcz_wt' && isset($param['is_getMobileCode']) && $param['is_getMobileCode'] == 1){
|
||
$product['method'] = 'getMobileCode';
|
||
}
|
||
|
||
|
||
return $this->call($product['method'], $product_info['cid'], $param, $async, $data, $product_info);
|
||
}
|
||
|
||
# 获取产品信息
|
||
public function getNum($pid, $merchant)
|
||
{
|
||
# 检测当前的处理单数,如果超过多少单,就自动切换到另外一个渠道
|
||
if (isset($merchant['order_handle_num']) && $merchant['order_handle_num'] > 0) {
|
||
$total = OrderService::instance()->getNum($pid, 4);
|
||
if ($total >= $merchant['order_handle_num']) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
# 获取服务
|
||
public function call($method, $cid, $param, $async = false, $data = array(), $product = array())
|
||
{
|
||
$channel = $this->get($cid);
|
||
if (!$channel) {
|
||
return '渠道错误';
|
||
}
|
||
|
||
if (isset($channel['system_id']) && $channel['system_id'] && $channel['system_id'] > 0) {
|
||
$channel['key'] = 'common';
|
||
}
|
||
|
||
|
||
$name = ucfirst($channel['key']);
|
||
$class = '\\app\\channel\\service\\system\\' . $name;
|
||
|
||
|
||
$this->class = new $class($async, $data, $channel, $product);
|
||
if ($channel['key'] == 'common') {
|
||
return call_user_func(array($this->class, $method), $param);
|
||
} else {
|
||
$common = 'common';
|
||
if (method_exists($this->class, $method)) {
|
||
return call_user_func(array($this->class, $method), $param);
|
||
} elseif (method_exists($this->class, $common)) {
|
||
return call_user_func(array($this->class, $common), $param);
|
||
} else {
|
||
return call_user_func_array(array($this->class, 'def'), array($method, $param));
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
private function getProductByOpenTime($product_info, $cids)
|
||
{
|
||
$state = $this->checkProductOpenTime($product_info, 'opentime', $cids);
|
||
if (!$state) {
|
||
$product_data = ProductService::instance()->getByKey($product_info['key'], $product_info['id'], $cids);
|
||
if ($product_data) {
|
||
foreach ($product_data as $k => $v) {
|
||
if ($v['id'] != $product_info['id']) {
|
||
$state = $this->checkProductOpenTime($v, 'opentime');
|
||
if ($state) {
|
||
return $v;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $product_info;
|
||
}
|
||
*/
|
||
|
||
# 检查面值是否符合当前产品
|
||
private function checkProductOpenTime($product_info, $key = 'opentime')
|
||
{
|
||
if (isset($product_info[$key]) && $product_info[$key]) {
|
||
$product_info[$key] = str_replace(':', '', $product_info[$key]);
|
||
if (strstr($product_info[$key], '-')) {
|
||
$value = explode('-', $product_info[$key]);
|
||
$cur = intval(date('Hi'));
|
||
if ($cur < intval($value[0]) || $cur > intval($value[1])) {
|
||
return false;
|
||
}
|
||
} else {
|
||
$cur = intval(date('Hi'));
|
||
$product_info[$key] = intval($product_info[$key]);
|
||
if ($cur < $product_info[$key]) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/*
|
||
private function getProductByValue($product_info, $param, $cids)
|
||
{
|
||
$state = $this->checkProductValue($product_info, $param, 'auto_value');
|
||
if (!$state) {
|
||
$product_data = ProductService::instance()->getByKey($product_info['key'], $product_info['id'], $cids);
|
||
if ($product_data) {
|
||
foreach ($product_data as $k => $v) {
|
||
if ($v['id'] != $product_info['id']) {
|
||
$state = $this->checkProductValue($v, $param, 'auto_value');
|
||
if ($state) {
|
||
return $v;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
return $product_info;
|
||
}
|
||
*/
|
||
|
||
# 检查面值是否符合当前产品
|
||
private function checkProductValue($product_info, $param, $key = 'value')
|
||
{
|
||
if (isset($product_info[$key]) && $product_info[$key] && isset($param['cash']) && $param['cash']) {
|
||
$value = explode(',', $product_info[$key]);
|
||
if (isset($param['value']) && $param['value']) {
|
||
if (!in_array($param['value'], $value)) {
|
||
return false;
|
||
}
|
||
} else {
|
||
if (!in_array($param['cash'], $value)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
/*
|
||
# 符合面值 验证开放时间
|
||
$opentime = $this->checkProductOpenTime($product_info);
|
||
if ($opentime) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
*/
|
||
}
|
||
|
||
public function update_ipWhite($cid,$ip_white_data='')
|
||
{
|
||
$is_btWaf = sysconf('settingBtWafStatus');
|
||
$api_domain = sysconf('api_notify_host') ?: sysconf('BtWaf_domain');
|
||
|
||
// 提取域名部分
|
||
if ($api_domain) {
|
||
$api_domain = preg_replace('/^https?:\/\//', '', $api_domain);
|
||
$api_domain = explode('/', $api_domain)[0];
|
||
}
|
||
|
||
|
||
|
||
if(isset($is_btWaf) && $is_btWaf == 1) {
|
||
$ip_white_array = $ip_white_data?explode(',', $ip_white_data):[];
|
||
$bt = new BtWafService();
|
||
$list = $bt->get_customize_list();
|
||
$ip_white_id = '';
|
||
if($list){
|
||
$rule_list = $list['msg']['rules'];
|
||
$name = '渠道ip白名单-'.$cid;
|
||
foreach ($rule_list as $k=>$v){
|
||
if($v['name'] == $name){
|
||
$ip_white_id = $k;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if($ip_white_id){
|
||
$data = $bt->update_waf_whiteIp($ip_white_id,$name,$api_domain,$ip_white_array);
|
||
|
||
} else{
|
||
$data = $bt->update_waf_whiteIp('', $name, $api_domain, $ip_white_array);
|
||
}
|
||
|
||
if($data && isset($data['status']) && !$data['status']){
|
||
return '添加防火墙错误';
|
||
}
|
||
|
||
}
|
||
return $this->db()->where(array('id' => $cid))->update(['ip_white'=>$ip_white_data]);
|
||
|
||
|
||
}
|
||
|
||
} |