manghe/app/common.php
2025-05-04 16:54:54 +08:00

953 lines
26 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// 应用公共文件
use think\facade\Request;
use think\facade\Db;
if (!function_exists('getRandStr')) {
/**
* @param int $len 长度
* @param bool $special 是否加入特殊字符
* @return string 字符串
*/
function getRandStr($len = 30, $special = false)
{
$chars = array(
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
);
if ($special) {
$chars = array_merge($chars, array(
"!",
"@",
"#",
"$",
"?",
"|",
"{",
"/",
":",
";",
"%",
"^",
"&",
"*",
"(",
")",
"-",
"_",
"[",
"]",
"}",
"<",
">",
"~",
"+",
"=",
",",
"."
));
}
$charsLen = count($chars) - 1;
shuffle($chars); //打乱数组顺序
$str = '';
for ($i = 0; $i < $len; $i++) {
$str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
}
return $str;
}
}
if (!function_exists('setConfig')) {
/**
* 设置系统配置
* @param string $type 配置关键词
* @param array $data 需要保存的数组
* @return void
*/
function setConfig($type, $data)
{
$data = empty($data) ? null : $data;
$content = DB::name('config')->where(['key' => $type])->find();
$json_str = json_encode($data, JSON_UNESCAPED_UNICODE);
if (!empty($content)) {
if ($data) {
$res = DB::name('config')->where(['key' => $type])->update(['value' => $json_str]);
} else {
$res = DB::name('config')->where(['key' => $type])->delete();
}
} else {
$res = DB::name('config')->insert(array('value' => $json_str, 'key' => $type));
}
return $res;
}
}
if (!function_exists('getConfig')) {
/**
* 获取系统配置
* @param string $type 配置关键词
* @return
*/
function getConfig($type)
{
// // 生成缓存键
// $redis = (new \app\common\server\RedisHelper())->getRedis();
// $cache_key = "config:{$type}";
// // 尝试从缓存获取数据
// $cached_data = $redis->get($cache_key);
// if ($cached_data) {
// return json_decode($cached_data, true);
// }
$content = Db::name('config')->where(['key' => $type])->value('value');
$config = json_decode($content, true);
// 将数据存入缓存设置10分钟过期时间
// if ($config) {
// $redis->set($cache_key, json_encode($config), 600);
// }
return $config;
}
}
if (!function_exists('imageUrl')) {
/**
* 图片补全路径
* @param string $type 配置关键词
* @return void
*/
function imageUrl($url = '')
{
if ($url == '') {
return '';
}
if (strpos($url, 'http') !== false) {
$path = $url;
}
// else if (strpos($pre, '192.168') !== false) {#测试环境
// $path = $pre . "ceshi/public/" . $url;
// }
else {
$pre = request()->domain();
if ($url === '0') {
$path = $pre;
} else {
$path = $pre . $url;
}
}
$path = str_replace('\\', '/', $path);
return $path;
}
}
if (!function_exists('contentUrl')) {
/**
* 补充富文本内容图片路径
* @param content 富文本内容
* @return 返回处理后的富文本内容
*/
function contentUrl($content)
{
$url = request()->domain() . '/';
// $url="https://mh.shhuanmeng.com/";
// if (strpos($url, '192.168') !== false) {#测试环境
// $url = $url . "ceshi/public/";
// }
$pregRule = "/<img[^>]*src=[\"'](?!http|https)([^\"']+\.(?:jpg|jpeg|png|gif|bmp))[\"'][^>]*>/i";
// 替换相对路径的图片
$content = preg_replace_callback($pregRule, function ($matches) use ($url) {
return '<img src="' . $url . $matches[1] . '" style="max-width:100%">';
}, htmlspecialchars_decode($content));
return $content;
}
}
if (!function_exists('shuffle_assoc')) {
/**
* 二维数组打乱顺序
* @param string $list 列表数组
* @return void
*/
function shuffle_assoc($list)
{
if (!is_array($list)) {
return $list;
}
$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach ($keys as $k => $key) {
$random[$k] = $list[$key];
}
return $random;
}
}
if (!function_exists('arraySequence')) {
/**
* 二位数组指定字段排序
* @param $array
* @param $field
* @param string $sort
* @return array
*/
function arraySequence($array, $field, $sort = 'SORT_DESC')
{
$else_data = [];
$arrSort = array();
$new_arrSort = array();
$len = 0;
foreach ($array as $uniqid => $row) {
$new_arrSort[] = $row;
foreach ($row as $key => $value) {
$arrSort[$key][$len] = $value;
}
$len++;
}
array_multisort($arrSort[$field], constant($sort), $new_arrSort);
$new_array = array_merge($else_data, $new_arrSort);
return $new_array;
}
}
if (!function_exists('create_order_no')) {
/**
* 生成订单号
* @param string $pre 订单前缀
* @param string $tale 表名
* @param string $field 字段名
* @return string
*/
function create_order_no($pre = 'NO_', $tale = 'order', $field = 'order_num')
{
// 检查是否包含多商户前缀标记,处理商户随机选择并获取前缀
if (strpos($pre, 'MH_') !== false || strpos($pre, 'FH_') !== false) {
// 引入微信支付帮助类
$wxpayConfig = \app\common\helper\WxPayHelper::getWxPayConfig();
// 如果存在商户信息并且有前缀,则使用商户前缀
if (!empty($wxpayConfig['merchant']) && !empty($wxpayConfig['merchant']['order_prefix'])) {
$merchant_prefix = $wxpayConfig['merchant']['order_prefix'];
// 在MH_后面添加商户前缀而不是替换MH_
$pre = $pre . $merchant_prefix;
}
// 获取当前域名的微信小程序配置
$miniprogramConfig = \app\common\helper\MiniprogramHelper::getMiniprogramConfig();
// 如果小程序配置存在且有订单前缀,则添加到订单号中
if (!empty($miniprogramConfig) && !empty($miniprogramConfig['order_prefix'])) {
// 在现有前缀后面添加小程序订单前缀
$pre .= $miniprogramConfig['order_prefix'];
}
}
$order_no = $pre . date('Ymd') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
$r = Db::name($tale)->field('id')->where([$field => $order_no])->find();
if ($r) {
$order_no = create_order_no($pre, $tale, $field);
}
return $order_no;
}
}
if (!function_exists('create_order_no_new')) {
/**
* 生成订单号
* @param string $pre 订单前缀
* @param string $tale 表名
* @param string $field 字段名
* @return string
*/
function create_order_no_new($pre = "", $merchant_prefix = "", $project_prefix = "", $pay_type = "")
{
$pre = $pre . $merchant_prefix . $project_prefix . $pay_type;
$order_no = $pre . date('Ymd') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8) . str_pad(mt_rand(1, 999), 3, '0', STR_PAD_LEFT);
if ($pre == "FH_") {
$r = Db::name('order_list_send')->field('id')->where(['send_num' => $order_no])->find();
} else {
$r = Db::name('order')->field('id')->where(['order_num' => $order_no])->find();
}
if ($r) {
$order_no = create_order_no_new($pre, $merchant_prefix, $project_prefix, $pay_type);
}
return $order_no;
}
}
if (!function_exists('getPrizeCode')) {
/**
* 获取盒子奖品编号
* @param int $len 推荐码长度
*/
function getPrizeCode($len = 10, $special = false)
{
$chars = array(
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
);
$charsLen = count($chars) - 1;
shuffle($chars); //打乱数组顺序
$str = '';
for ($i = 0; $i < $len; $i++) {
$str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
}
$i = Db::name('goods_list')->where(['prize_code' => $str])->find();
if ($i) {
$str = getPrizeCode();
}
return $str;
}
}
if (!function_exists('curlGet')) {
/**
* curl请求指定url (get)
* @param $url
* @param array $data
* @return mixed
*/
function curlGet($url)
{
$headerArray = array("Content-type:application/json;", "Accept:application/json");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
$output = curl_exec($ch);
curl_close($ch);
$output = json_decode($output, true);
return $output;
}
}
if (!function_exists('curlPost')) {
/**
* curl请求指定url (post)
* @param $url
* @param array $data
* @return mixed
*/
function curlPost($url, $data = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
if (!function_exists('admin_md5')) {
/**
* @param $msg 需要加密的参数
* @return bool
*/
function admin_md5($msg)
{
return sha1(md5(md5('admin_md5_password' . $msg)));
}
}
if (!function_exists('user_md5')) {
/**
* @param $msg 需要加密的参数
* @return bool
*/
function user_md5($msg)
{
return sha1('md5' . md5(md5('user_md5' . $msg)));
}
}
if (!function_exists('RegMoney')) {
/**
* @param $money 需要验证的金额
* @return bool
*/
function RegMoney($money = -1)
{
$preg_money = '/^(0|[1-9]\d{0,10})(\.\d{1,2})?$/';
if (!preg_match($preg_money, $money)) {
return true;
}
return false;
}
}
if (!function_exists('RegInt')) {
/**
* @param $num 需要验证的整数
* @return bool
*/
function RegInt($num = -1)
{
$preg_int = '/^[1-9]\d{0,10}$/';
if (!preg_match($preg_int, $num)) {
return true;
}
return false;
}
}
if (!function_exists('RegZero')) {
/**
* @param $num 需要验证的整数
* @return bool
*/
function RegZero($num = -1)
{
$preg_int = '/^[0-9]\d{0,10}$/';
if (!preg_match($preg_int, $num)) {
return true;
}
return false;
}
}
if (!function_exists('expressWuliu')) {
/**
* 查物流
* @param $no 订单号
* @param $type 快递公司编号
* @return array
*/
function expressWuliu($no = '', $type = '')
{
$host = "https://wuliu.market.alicloudapi.com";//api访问链接
$path = "/kdi";//API访问后缀
$method = "GET";
$appcode = getConfig('base')['logistics_code'];//开通服务后 买家中心-查看AppCode
$headers = array();
array_push($headers, "Authorization:APPCODE " . $appcode);
$querys = "no=" . $no . "&type=" . $type; //参数写在这里
$bodys = "";
$url = $host . $path . "?" . $querys;
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
if (1 == strpos("$" . $host, "https://")) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
}
$out_put = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
list($header, $body) = explode("\r\n\r\n", $out_put, 2);
if ($httpCode == 200) {
// print("正常请求计费(其他均不计费)<br>");
// print($body);
$body = json_decode($body, true);
if ($body['status'] == 0 && $body['msg'] == 'ok') {
return ['code' => 1, 'msg' => $body['result']];
} else {
return ['code' => 0, 'msg' => $body['msg']];
}
} else {
if ($httpCode == 400 && strpos($header, "Invalid Param Location") !== false) {
// print("参数错误");
return ['code' => 0, 'msg' => '参数错误'];
} elseif ($httpCode == 400 && strpos($header, "Invalid AppCode") !== false) {
// print("AppCode错误");
return ['code' => 0, 'msg' => 'AppCode错误'];
} elseif ($httpCode == 400 && strpos($header, "Invalid Url") !== false) {
// print("请求的 Method、Path 或者环境错误");
return ['code' => 0, 'msg' => '请求的 Method、Path 或者环境错误'];
} elseif ($httpCode == 403 && strpos($header, "Unauthorized") !== false) {
// print("服务未被授权或URL和Path不正确");
return ['code' => 0, 'msg' => '服务未被授权或URL和Path不正确'];
} elseif ($httpCode == 403 && strpos($header, "Quota Exhausted") !== false) {
// print("套餐包次数用完");
return ['code' => 0, 'msg' => '套餐包次数用完'];
} elseif ($httpCode == 500) {
// print("API网关错误");
return ['code' => 0, 'msg' => 'API网关错误'];
} elseif ($httpCode == 0) {
// print("URL错误");
return ['code' => 0, 'msg' => 'URL错误'];
} else {
// print("参数名错误 或 其他错误");
// print($httpCode);
return ['code' => 0, 'msg' => '参数名错误 或 其他错误'];
$headers = explode("\r\n", $header);
$headList = array();
foreach ($headers as $head) {
$value = explode(':', $head);
$headList[$value[0]] = $value[1];
}
print ($headList['x-ca-error-message']);
}
}
}
}
if (!function_exists('resCheck')) {
/**
* @param $rs 数据库结果集的判断
* @return bool
*/
function resCheck($data)
{
foreach ($data as $value) {
if (is_array($value)) {
foreach ($value as $val) {
if (is_array($val)) {
foreach ($val as $va) {
if (is_array($va)) {
foreach ($va as $v) {
if (!$v) {
return false;
}
}
} else {
if (!$va) {
return false;
}
}
}
} else {
if (!$val) {
return false;
}
}
}
} else {
if (!$value) {
return false;
}
}
}
return true;
}
}
function p($msg = '', $type = 0)
{
echo '<pre>';
if ($type == 0) {
print_r($msg);
} else {
var_dump($msg);
}
die;
}
if (!function_exists('thumbImage')) {
/**
* 缩放图片
* @param $url 图片路径
* @return int
*/
function thumbImage($path = '', $width = 0, $height = 0, $radius = 0, $bg = 0)
{
require_once('../vendor/topthink/think-image/src/Image.php');
$image = \think\Image::open($path);
// 按照原图的比例生成一个最大为150*150的缩略图并保存为thumb.png
$image->thumb($width, $height)->save($path);
return true;
}
}
if (!function_exists('time_jian')) {
/**
* 缩放图片
* @param $url 图片路径
* @return int
*/
function time_jian($star_time, $end_time)
{
// 计算两个时间戳之间的差值(单位:秒)
$timeDiff = $end_time - $star_time;
// 根据差值计算经过了多少秒、分钟、小时和天
$seconds = $timeDiff % 60;
$minutes = floor(($timeDiff / 60) % 60);
$hours = floor(($timeDiff / (60 * 60)) % 24);
$days = floor($timeDiff / (60 * 60 * 24));
$str = '';
if ($days) {
$str .= "{$days}";
}
if ($hours) {
$str .= "{$hours}小时";
}
if ($minutes) {
$str .= "{$minutes}分钟";
}
if ($seconds) {
$str .= "{$seconds}";
}
return $str;
}
}
if (!function_exists('order_callback')) {
/**
* 订单回调方法,设置通用的订单方法
* @param mixed $order_no
* @param mixed $notifyUrl
* @param mixed $callback_nonce_str
* @return void
*/
function order_callback($order_no, $notifyUrl, $callback_nonce_str)
{
// 将通知URL和随机字符串保存到订单表中
Db::name('order')->where('order_num', $order_no)->update([
'nonce_str' => $callback_nonce_str,
'order_notify' => $notifyUrl
]);
}
}
// 订单支付日志
function writelog($filename, $content)
{
try {
$date = date('Y-m-d');
$file = "./pay_log/" . $date;
if (!is_dir($file)) {
mkdir($file);
}
$file = $file . "/" . $filename . ".txt";
$content = "【收到信息" . date("Y-m-d H:i:s", time()) . "" . $content . "\r\n\r\n";
$open = fopen($file, "a");
fwrite($open, $content);
fclose($open);
} catch (\Throwable $th) {
}
}
//广告
function tencent_ad_attribution($click_id, $money, $account_id, $access_token, $user_action_set_id)
{
// $access_token = '80a2138abe0227598ea9ae8a2a55ba69';
// $user_action_set_id = 1200995945;
$interface = 'user_actions/add';
$url = 'https://api.e.qq.com/v1.1/' . $interface;
$common_parameters = array(
'access_token' => $access_token,
'timestamp' => time(),
'nonce' => md5(uniqid('', true))
);
$parameters = array(
'account_id' => $account_id,
'user_action_set_id' => $user_action_set_id,
'actions' =>
array(
0 =>
array(
'url' => 'ruiou.ruiouyifanshang.com',
'external_action_id' => strtolower(md5(rand(100000, 999999))) . '_complete_order_1492991000_30569088_1200995945',
'action_time' => time(),
'action_type' => 'COMPLETE_ORDER',
// 'custom_action' => 'my_type',
'trace' => [
'click_id' => $click_id,
],
'action_param' =>
[
'value' => $money
]
),
),
);
// dd($parameters);
// dump($common_parameters);
$parameters = json_encode($parameters);
$request_url = $url . '?' . http_build_query($common_parameters);
// var_dump($parameters);
// dd($request_url);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $request_url);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $parameters);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Content-Type:application/json"
));
$response = curl_exec($curl);
if (curl_error($curl)) {
$error_msg = curl_error($curl);
$error_no = curl_errno($curl);
curl_close($curl);
throw new \Exception($error_msg, $error_no);
}
curl_close($curl);
\think\facade\Log::write($response, 'warning');
return $response;
}
function getData($url, $header)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
$handles = curl_exec($ch);
curl_close($ch);
return $handles;
}
if (!function_exists('removeTrailingZeros')) {
function removeTrailingZeros($numStr)
{
if (strpos($numStr, '.') !== false) {
$numStr = rtrim($numStr, '0'); // 移除右侧的零
$numStr = rtrim($numStr, '.'); // 处理小数点后全零的情况
}
return $numStr;
}
}
/**
* 生成支付通知URL
* @param string $payment_type 支付方式(wxpay, alipay等)
* @param string $order_type 赏品类型(order_yfs, order_lts等)
* @param int $user_id 用户ID
* @param string $order_num 订单号
* @param string $nonce_str 随机字符串,用于签名
* @return string 完整的回调URL
*/
function generatePayNotifyUrl($payment_type = null, $order_type = null, $user_id = null, $order_num = null, $nonce_str = null)
{
// 验证所有必须参数
if (empty($payment_type) || empty($order_type) || empty($user_id) || empty($order_num)) {
throw new \Exception("支付通知URL的所有参数都是必选的");
}
// 如果没有传入随机字符串,则生成一个
if (empty($nonce_str)) {
$nonce_str = getRandStr(16, false);
}
$timestamp = time();
$data = [
'payment_type' => $payment_type,
'order_type' => $order_type,
'user_id' => $user_id,
'order_num' => $order_num,
'timestamp' => $timestamp,
'nonce_str' => $nonce_str
];
// 生成签名
$sign = generatePayNotifySign($data);
// 返回完整URL所有参数都是必选的
return request()->domain() . "/api/notify/{$payment_type}/{$order_type}/{$user_id}/{$order_num}/{$timestamp}/{$sign}";
// return "http://testapi.zfunbox.cn/api/notify/{$payment_type}/{$order_type}/{$user_id}/{$order_num}/{$timestamp}/{$sign}";
}
/**
* 生成支付通知URL的签名
* @param array $data 签名数据
* @return string 签名字符串
*/
function generatePayNotifySign($data)
{
// 移除空值
foreach ($data as $key => $value) {
if (empty($value)) {
unset($data[$key]);
}
}
// 按键名排序
ksort($data);
// 拼接字符串
$stringA = '';
foreach ($data as $key => $value) {
$stringA .= "{$key}={$value}&";
}
//加密
$key = 'l044imysi1vsmobyrkkfnaniu5bhiupd'; // 默认密钥
// 加上密钥
$stringA .= "key=" . $key;
// MD5加密并转大写
return strtoupper(md5($stringA));
}
/**
* 验证支付通知URL的签名
* @param array $data 待验证的数据
* @param string $sign 传入的签名
* @return bool 验证是否通过
*/
function verifyPayNotifySign($data, $sign)
{
// 生成签名
$newSign = generatePayNotifySign($data);
// 比较签名是否一致
return $sign === $newSign;
}