mirror of
https://gitee.com/technical-laohu/mpay.git
synced 2025-11-13 06:03:44 +08:00
Update .gitignore rules
This commit is contained in:
@@ -1,211 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\BaseModel;
|
||||
use app\model\PayAccount;
|
||||
use app\model\PayChannel;
|
||||
|
||||
class Order extends BaseModel
|
||||
{
|
||||
// 订单有效期
|
||||
private static $activity_time = 180;
|
||||
// 新建订单
|
||||
public static function createOrder($data): array
|
||||
{
|
||||
$my_time = time();
|
||||
$channel = self::setChannel($data['pid'], $data['type']);
|
||||
if ($channel['code'] !== 0) return $channel;
|
||||
$channel = $channel['data'];
|
||||
$new_order = [
|
||||
// 订单号
|
||||
'order_id' => self::createOrderID('H'),
|
||||
// 商户ID
|
||||
'pid' => $data['pid'],
|
||||
// 支付类型
|
||||
'type' => $data['type'],
|
||||
// 商户订单号
|
||||
'out_trade_no' => $data['out_trade_no'],
|
||||
// 异步通知
|
||||
'notify_url' => $data['notify_url'],
|
||||
// 跳转通知
|
||||
'return_url' => isset($data['return_url']) ? $data['return_url'] : '',
|
||||
// 商品名称
|
||||
'name' => $data['name'],
|
||||
// 商品金额
|
||||
'money' => $data['money'],
|
||||
// 实际成交金额
|
||||
'really_price' => self::checkMoney($data['money'], $data['type'], $channel['aid'], $channel['cid'], $channel['chan']),
|
||||
// 用户IP
|
||||
'clientip' => isset($data['clientip']) ? $data['clientip'] : '',
|
||||
// 设备类型
|
||||
'device' => isset($data['device']) ? $data['device'] : '',
|
||||
// 业务扩展参数
|
||||
'param' => serialize(isset($data['param']) ? $data['param'] : ''),
|
||||
// 等待/过期:0, 支付成功:1
|
||||
'state' => 0,
|
||||
// 开启监听:1, 关闭监听:0
|
||||
'patt' => $channel['patt'],
|
||||
// 订单创建时间
|
||||
'create_time' => self::getFormatTime($my_time),
|
||||
// 订单关闭时间
|
||||
'close_time' => self::getFormatTime($my_time + self::$activity_time),
|
||||
// 支付时间
|
||||
'pay_time' => self::getFormatTime($my_time),
|
||||
// 收款账号id
|
||||
'aid' => $channel['aid'],
|
||||
// 交易终端id
|
||||
'cid' => $channel['cid'],
|
||||
];
|
||||
$res = self::create($new_order);
|
||||
if ($res->order_id) {
|
||||
return backMsg(0, 'ok', ['order_id' => $res->order_id]);
|
||||
} else {
|
||||
return backMsg(4, '创建订单记录失败');
|
||||
}
|
||||
}
|
||||
// 查询订单列表
|
||||
public static function serchOrders($query)
|
||||
{
|
||||
$select = [];
|
||||
$allow_field = ['id', 'order_id', 'pid', 'type', 'out_trade_no', 'name', 'really_price', 'money', 'state', 'create_time_start', 'create_time_end', 'close_time', 'pay_time', 'platform', 'platform_order', 'aid', 'cid',];
|
||||
foreach ($query as $key => $value) {
|
||||
if (in_array($key, $allow_field) && isset($value)) {
|
||||
if ($key === 'name') {
|
||||
$select[] = [$key, 'like', '%' . $value . '%'];
|
||||
continue;
|
||||
}
|
||||
if ($key === 'create_time_start') {
|
||||
$select[] = ['create_time', '>', $value];
|
||||
continue;
|
||||
}
|
||||
if ($key === 'create_time_end') {
|
||||
$select[] = ['create_time', '<', $value];
|
||||
continue;
|
||||
}
|
||||
$select[] = [$key, '=', $value];
|
||||
}
|
||||
}
|
||||
return self::where($select);
|
||||
}
|
||||
// 查询订单详细
|
||||
public static function showOrderDetail($id)
|
||||
{
|
||||
$order = self::find($id);
|
||||
$a_list = PayAccount::withTrashed()->find($order->aid);
|
||||
$c_list = PayChannel::withTrashed()->find($order->cid);
|
||||
if (!$order) {
|
||||
return [];
|
||||
}
|
||||
$order->platform = $a_list['platform'] ?? '···';
|
||||
$order->account = $a_list['account'] ?? '···';
|
||||
$order->channel = $c_list['channel'] ?? '···';
|
||||
$order->qrcode = $c_list['qrcode'] ?? '···';
|
||||
$order->url_type = $c_list['type'] ?? '···';
|
||||
return $order->toArray();
|
||||
}
|
||||
// 选择收款通道
|
||||
private static function setChannel($pid, $type): array
|
||||
{
|
||||
// 查询有效收款账户及通道
|
||||
$aids = PayAccount::where('pid', $pid)->where('state', 1)->column('id');
|
||||
if (!$aids) return backMsg(1, '用户无可用收款账户');
|
||||
$channel_infos = PayChannel::whereIn('account_id', $aids)->where('state', 1)->order('last_time', 'asc')->select();
|
||||
if ($channel_infos->isEmpty()) return backMsg(2, '用户账户无可用收款码');
|
||||
// 微信/支付宝收款处理
|
||||
$channel_info = null;
|
||||
foreach ($channel_infos as $key => $value) {
|
||||
$check_wx = preg_match('/^wxpay\d+#/i', $value->channel);
|
||||
$check_ali = preg_match('/^alipay\d+#/i', $value->channel);
|
||||
if ($check_wx && $type === 'wxpay') {
|
||||
$channel_info = $channel_infos[$key];
|
||||
break;
|
||||
} elseif ($check_ali && $type === 'alipay') {
|
||||
$channel_info = $channel_infos[$key];
|
||||
break;
|
||||
} else {
|
||||
if ($check_wx || $check_ali) {
|
||||
continue;
|
||||
}
|
||||
$channel_info = $channel_infos[$key];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$channel_info) return backMsg(3, '用户账户无可用收款通道');
|
||||
// 选取收款通道
|
||||
$patt = PayAccount::find($channel_info->account_id);
|
||||
$channel = ['aid' => $channel_info->account_id, 'cid' => $channel_info->id, 'patt' => $patt->getData('pattern'), 'chan' => $channel_info->channel];
|
||||
PayChannel::update(['last_time' => self::getFormatTime(), 'id' => $channel['cid']]);
|
||||
return backMsg(0, 'ok', $channel);
|
||||
}
|
||||
// 获取扩展参数数组
|
||||
// private static function getParams(array $data): array
|
||||
// {
|
||||
// $keys = ['pid', 'type', 'out_trade_no', 'notify_url', 'return_url', 'name', 'money', 'sign', 'sign_type'];
|
||||
// $params = [];
|
||||
// foreach ($data as $key => $value) {
|
||||
// if (!in_array($key, $keys)) {
|
||||
// $params[$key] = $value;
|
||||
// }
|
||||
// }
|
||||
// return $params;
|
||||
// }
|
||||
// 检查金额
|
||||
private static function checkMoney($money, $type, $aid, $cid, $chan): float
|
||||
{
|
||||
$money = (float) $money;
|
||||
// Alipay免输
|
||||
if (preg_match('/^alipay4#\d+$/', $chan)) {
|
||||
return $money;
|
||||
}
|
||||
// 查询有效订单
|
||||
$query = self::scope('activeOrder')->where(['type' => $type, 'aid' => $aid, 'cid' => $cid]);
|
||||
$activeOrders = $query->column('really_price');
|
||||
$num = count($activeOrders);
|
||||
if ($num > 0) {
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
if (in_array($money, $activeOrders)) {
|
||||
$money += 0.01;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $money;
|
||||
}
|
||||
// 获取格式时间
|
||||
private static function getFormatTime($time = 0)
|
||||
{
|
||||
if ($time) {
|
||||
return date('Y-m-d H:i:s', $time);
|
||||
}
|
||||
return date('Y-m-d H:i:s', time());
|
||||
}
|
||||
// 生成订单号
|
||||
private static function createOrderID(string $prefix = ''): string
|
||||
{
|
||||
return $prefix . date('Ymd') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
|
||||
}
|
||||
// 查询有效期内的未支付订单
|
||||
public function scopeActiveOrder($query)
|
||||
{
|
||||
$query->where('close_time', '>', self::getFormatTime())->where('state', 0);
|
||||
}
|
||||
// 查询有效期内的成交订单
|
||||
public function scopeDealOrder($query)
|
||||
{
|
||||
$query->where('close_time', '>', self::getFormatTime(time() - self::$activity_time))->where('state', 1);
|
||||
}
|
||||
// 查询超时过期订单
|
||||
public function scopeTimeoutOrder($query)
|
||||
{
|
||||
$query->where('close_time', '<', self::getFormatTime())->where('state', 0);
|
||||
}
|
||||
// 模型多对一关联
|
||||
public function payAccount()
|
||||
{
|
||||
return $this->belongsTo(PayAccount::class, 'aid', 'id');
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\BaseModel;
|
||||
use app\model\User;
|
||||
use app\controller\api\PluginController;
|
||||
|
||||
class PayAccount extends BaseModel
|
||||
{
|
||||
// 查询账号列表
|
||||
public static function serchAccount($query)
|
||||
{
|
||||
$select = [];
|
||||
$allow_field = ['state', 'platform', 'account', 'pattern'];
|
||||
foreach ($query as $key => $value) {
|
||||
if (in_array($key, $allow_field) && isset($value)) {
|
||||
if ($key === 'account') {
|
||||
$select[] = [$key, 'like', '%' . $value . '%'];
|
||||
continue;
|
||||
}
|
||||
$select[] = [$key, '=', $value];
|
||||
}
|
||||
}
|
||||
return self::withCount(['payChannel' => 'channel'])->where($select);
|
||||
}
|
||||
// 获取账号配置
|
||||
public static function getAccountConfig($aid, $pid = null): array|bool
|
||||
{
|
||||
$aid_info = self::find($aid);
|
||||
if (!$aid_info) return false;
|
||||
// 插件配置
|
||||
$platform = PluginController::getPluginInfo($aid_info->getData('platform'));
|
||||
// 查询参数
|
||||
$params = json_decode($aid_info->params, true);
|
||||
if ($aid_info && $platform) {
|
||||
$config = [
|
||||
'pid' => $aid_info->pid,
|
||||
// 账号id
|
||||
'aid' => $aid_info->id,
|
||||
// 收款平台
|
||||
'platform' => $aid_info->getData('platform'),
|
||||
// 插件类名
|
||||
'payclass' => $platform['class_name'],
|
||||
// 账号
|
||||
'account' => $aid_info->account,
|
||||
// 密码
|
||||
'password' => $aid_info->password,
|
||||
// 配置参数
|
||||
'params' => $params,
|
||||
];
|
||||
if ($pid !== null) {
|
||||
$pid_info = User::where('pid', $pid)->find();
|
||||
$config['key'] = $pid_info->secret_key;
|
||||
}
|
||||
return $config;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 获取器
|
||||
public function getPlatformAttr($value)
|
||||
{
|
||||
$payplugin_path = config_path() . '/extend/payplugin.php';
|
||||
if (!file_exists($payplugin_path)) {
|
||||
return [];
|
||||
}
|
||||
// 加载插件配置
|
||||
$payplugin_config = require $payplugin_path;
|
||||
$option = [];
|
||||
foreach ($payplugin_config as $config) {
|
||||
$option[$config['platform']] = $config['name'];
|
||||
}
|
||||
return isset($option[$value]) ? $option[$value] : '[已卸载,请停用]';
|
||||
}
|
||||
public function getPatternAttr($value)
|
||||
{
|
||||
// 监听模式
|
||||
$pattern = ['0' => '单次监听·被动', '1' => '连续监听·主动'];
|
||||
return $pattern[$value];
|
||||
}
|
||||
// 一对多关联
|
||||
public function payChannel()
|
||||
{
|
||||
return $this->hasMany(PayChannel::class, 'account_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class PayChannel extends BaseModel
|
||||
{
|
||||
// 模型多对一关联
|
||||
public function payAccount()
|
||||
{
|
||||
return $this->belongsTo(PayAccount::class, 'account_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class User extends BaseModel
|
||||
{
|
||||
// 验证用户
|
||||
public static function checkUser($pid, $sign)
|
||||
{
|
||||
$user = self::where('pid', $pid)->find();
|
||||
$sign2 = md5($user->pid . $user->secret_key);
|
||||
if ($sign === $sign2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 创建用户
|
||||
public static function createUser(array $userinfo)
|
||||
{
|
||||
$last_pid = self::withTrashed()->max('pid');
|
||||
$find_username = self::withTrashed()->where(['username' => $userinfo['username']])->find();
|
||||
if ($find_username) {
|
||||
return 1; // 账户已注册
|
||||
}
|
||||
$pid = $last_pid ? $last_pid + 1 : 1000;
|
||||
$secret = md5($pid . time() . mt_rand());
|
||||
$res = self::create(['pid' => $pid, 'secret_key' => $secret, 'username' => $userinfo['username'], 'password' => $userinfo['password'], 'nickname' => self::getNickname('小可爱', 5)]);
|
||||
return $res;
|
||||
}
|
||||
// 随机用户昵称
|
||||
private static function getNickname($pre = '', $length = 8)
|
||||
{
|
||||
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.';
|
||||
$charactersLength = strlen($characters);
|
||||
$randomString = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||
}
|
||||
return $pre . $randomString;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user