coupon-admin/app/common.php

781 lines
25 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------
use think\Collection;
use think\db\exception\DbException;
use think\exception\ClassNotFoundException;
use think\Model;
use think\Paginator;
// 应用公共文件
if (!function_exists('widget')) {
/**
* 渲染输出Widget
* @param string $name Widget名称
* @param array $data 传入的参数
* @return mixed
* milo 2019-05-08 从TP5.1代码中拿来修改的
*/
function widget($name, $data = [])
{
return action($name, $data, 'widget');
}
}
if (!function_exists('action')) {
/**
* 调用模块的操作方法 参数格式 [模块/控制器/]操作
* @param string $url 调用地址
* @param string|array $vars 调用参数 支持字符串和数组
* @param string $layer 要调用的控制层名称
* @param bool $appendSuffix 是否添加类名后缀
* @return mixed
* milo 2019-05-08 从TP5.1代码中拿来修改的
*/
function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
{
$info = pathinfo($url);
$action = $info['basename'];
$module = '.' != $info['dirname'] ? $info['dirname'] : request()->controller();
$class = controller($module, $layer);
if (is_scalar($vars)) {
if (strpos($vars, '=')) {
parse_str($vars, $vars);
} else {
$vars = [$vars];
}
}
return app()->invokeMethod([$class, $action . config('route.action_suffix')], $vars);
}
}
if (!function_exists('controller')) {
/**
* 实例化(分层)控制器 格式:[模块名/]控制器名
* @access public
* @param string $name 资源地址
* @param string $layer 控制层名称
* @param bool $appendSuffix 是否添加类名后缀
* @param string $empty 空控制器名称
* @return object
* @throws ClassNotFoundException
*
* milo 2019-05-08 从TP5.1代码中拿来修改的
*/
function controller($name, $layer = 'controller', $empty = '')
{
$class = parseClass($name, $layer);
if (class_exists($class)) {
return app()->make($class);
} elseif ($empty && class_exists($emptyClass = app()->parseClass($layer, $empty))) {
return app()->make($emptyClass);
}
throw new ClassNotFoundException('class not exists:' . $class, $class);
}
}
if (!function_exists('parseClass')) {
/**
* 解析模块和类名
* @access protected
* @param string $name 资源地址
* @param string $layer 验证层名称
* @param bool $appendSuffix 是否添加类名后缀
* @return array
*
* milo 2019-05-08 从TP5.1代码中拿来修改的
*/
function parseClass($name, $layer)
{
if (false !== strpos($name, '\\')) {
$class = $name;
} else {
if (strpos($name, '/')) {
$names = explode('/', $name, 2);
$name = $names[1];
}
$class = app()->parseClass($layer, $name);
}
return $class;
}
}
if (!function_exists('randomStr')) {
/**
* 获取随机字符串
* @param int $type 0数字(默认)1全部2:小写字母;3:大写字母4字母
* @param int $len 字符串长度
* @return string
*/
function randomStr($type = 0, $len = 5)
{
$strPol = "0123456789";
if ($type == 1) {
$strPol = "ABCDEFGHIJKLMOPQRSTUVWYZ0123456789abcdefghijklmopqrstuvwyz";
} elseif ($type == 2) {
$strPol = "abcdefghijklmopqrstuvwyz";
} elseif ($type == 3) {
$strPol = "ABCDEFGHIJKLMOPQRSTUVWYZ";
} elseif ($type == 4) {
$strPol = "ABCDEFGHIJKLMOPQRSTUVWYZabcdefghijklmopqrstuvwyz";
}
$max = strlen($strPol) - 1;
$str = '';
for ($i = 0; $i < $len; $i++) {
$str .= $strPol[rand(0, $max)];
}
return $str;
}
}
if (!function_exists('isMobile')) {
//判断访问终端是否为移动端
function isMobile()
{
// 如果有HTTP_X_WAP_PROFILE则一定是移动设备
if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
return true;
}
// 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
if (isset($_SERVER['HTTP_VIA'])) {
// 找不到为flase,否则为true
return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
}
// 脑残法,判断手机发送的客户端标志,兼容性有待提高。其中'MicroMessenger'是电脑微信
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$clientkeywords = [
'nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips',
'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront',
'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc',
'midp', 'wap', 'mobile', 'MicroMessenger'
];
// 从HTTP_USER_AGENT中查找手机浏览器的关键字
if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
return true;
}
}
// 协议法,因为有可能不准确,放到最后判断
if (isset ($_SERVER['HTTP_ACCEPT'])) {
// 如果只支持wml并且不支持html那一定是移动设备
// 如果支持wml和html但是wml在html之前则是移动设备
if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'],
'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'],
'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
return true;
}
}
return false;
}
}
//根据栏目获取路径
if (!function_exists('getUri')) {
function getUri($cate)
{
$url = '';
if (!empty($cate)) {
if ($cate['is_index']) {
$url = '/';
} elseif (!empty($cate['url'])) {
$url = $cate['url'];
} else {
$url = url($cate['template'] . '/index', ['category_id' => $cate['id']]);
}
}
return $url;
}
}
//根据文件大小转换为文字
if (!function_exists('sizeToStr')) {
function sizeToStr($size)
{
if (!is_numeric($size) || $size <= 0) {
return '';
}
$size = $size / 1024;
if ($size < 1024) {
return sprintf("%.2fK", $size);
}
$size = $size / 1024;
if ($size < 1024) {
return sprintf("%.2fM", $size);
}
$size = $size / 1024;
return sprintf("%.2fG", $size);
}
}
//根据路径获取文件名
if (!function_exists('getKeyByPath')) {
function getKeyByPath($path)
{
return substr($path, strrpos($path, '/') + 1);
}
}
//富文本中提取图片路径
if (!function_exists('getImageUrlFromText')) {
function getImageUrlFromText($content)
{
preg_match_all('/<img.*?src="(.*?)".*?>/is', $content, $imgs);
$data = [];
if (!empty($imgs) && !empty($imgs[1])) {
foreach ($imgs[1] as $img) {
if (substr($img, 0, 4) != 'http') {
$key = getKeyByPath($img);
$data[$key] = $img;
}
}
}
return $data;
}
}
//富文本中提取视频路径
if (!function_exists('getVideoUrlFromText')) {
function getVideoUrlFromText($content)
{
preg_match_all('/<video.*?src="(.*?)".*?>/is', $content, $videos);
$data = [];
if (!empty($videos) && !empty($videos[1])) {
foreach ($videos[1] as $video) {
if (substr($video, 0, 4) != 'http') {
$key = getKeyByPath($video);
$data[$key] = $video;
}
}
}
return $data;
}
}
//获取目录下的所有文件
if (!function_exists('getAllFilesByPath')) {
function getAllFilesByPath($path, $rootPath)
{
if (is_dir($path) && file_exists($path)) {
$items = scandir($path);
$files = [];
foreach ($items as $item) {
if (substr($item, 0, 1) != '.' && strpos($item, '_') == false) {
$itemPath = $path . '/' . $item;
if (is_file($itemPath)) {
$size = filesize($itemPath);
$files[$item] = [
'path' => str_replace($rootPath, '/', $itemPath),
'realPath' => $itemPath,
'size' => $size,
'sizeStr' => sizeToStr($size),
'suffix' => strtolower(substr($item, strrpos($item, '.') + 1)) //后缀
];
} elseif (is_dir($itemPath)) {
$childFiles = getAllFilesByPath($itemPath, $rootPath);
if (!empty($childFiles)) {
$files = array_merge($files, $childFiles);
} else {
rmdir($itemPath);
}
}
}
}
return $files;
}
return [];
}
}
//过滤get输入
if (!function_exists('getFilter')) {
function getFilter($value)
{
$getFilter = "'|(and|or)\b.+?(>|<|=|in|like)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
$forArray = false;
if (is_array($value)) {
$forFilter = implode($value);
$forArray = true;
} else {
$forFilter = $value;
}
if (preg_match("/" . $getFilter . "/is", $forFilter) == 1) {
$value = $forArray ? [] : '';
}
return filterExp($value);
}
}
//过滤post录入
if (!function_exists('postFilter')) {
function postFilter($value)
{
$postFilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
$forArray = false;
if (is_array($value)) {
$forFilter = implode($value);
$forArray = true;
} else {
$forFilter = $value;
}
if (preg_match("/" . $postFilter . "/is", $forFilter) == 1) {
$value = $forArray ? [] : '';
}
return filterExp($value);
}
}
//过滤cookie数据
if (!function_exists('cookieFilter')) {
function cookieFilter($value)
{
$cookieFilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|\/\*.+?\*\/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
$forArray = false;
if (is_array($value)) {
$forFilter = implode($value);
$forArray = true;
} else {
$forFilter = $value;
}
if (preg_match("/" . $cookieFilter . "/is", $forFilter) == 1) {
$value = $forArray ? [] : '';
}
return filterExp($value);
}
}
if (!function_exists('filterExp')) {
function filterExp($value)
{
$filter = '/^(\s)+(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)(\s)+$/i';
$forArray = false;
if (is_array($value)) {
$forFilter = implode($value);
$forArray = true;
} else {
$forFilter = $value;
}
if (preg_match($filter, $forFilter) == 1) {
$value = $forArray ? [] : '';
}
return $value;
}
}
if (!function_exists('arrayHtmlFilter')) {
function arrayHtmlFilter($arr)
{
foreach ($arr as $k => $one) {
if (is_array($one)) {
$arr[$k] = arrayHtmlFilter($one);
} else {
$one = trim($one);
$arr[$k] = strip_tags($one);
}
}
return $arr;
}
}
if (!function_exists('toCamelString')) {
/**
* 转驼峰
*
* @param string $string
* @param false $small 默认false 为true首字母小写
* @return string
*/
function toCamelString(string $string, bool $small = false): string
{
//例: xxx_yYy_zzZ 和 xxX-yyy-Zzz
//1. 字符串转小写 xxx_yyy_zzz xxx-yyy-zzz
//2. -和_转空格 xxx yyy zzz
//3. 单词首字母大写 Xxx Yyy Zzz
//4. 清除空格 XxxYyyZzz
//处理下划线、减号 统统专程大驼峰 如xxx_yyy_zzz xxx-yyy-zzz 均转为 XxxYyyZzz
$string = strtolower($string);
$string = str_replace('-', ' ', $string);
$string = str_replace('_', ' ', $string);
$string = str_replace(' ', '', ucwords($string));
if ($small) {
$string = lcfirst($string);
}
return $string;
}
}
if (!function_exists('unCamelize')) {
/**
* 驼峰命名转特定分隔符[如下划线]命名
* @param string $camelCaps
* @param string $separator
* @return string
*/
function unCamelize(string $camelCaps, string $separator = '-'): string
{
return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
}
}
if (!function_exists('generateRand')) {
/**
* 生成随机数
*
* @param int $length 长度
* @param string $type 模式 默认mix混合 number纯数字 alpha字母
* @return string
*/
function generateRand(int $length = 8, string $type = 'mix'): string
{
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$number = '0123456789';
$alphabetLen = strlen($alphabet) - 1;
$numberLen = 9;
switch ($type) {
case 'number':
$str = $number;
$len = $numberLen;
break;
case 'alpha':
$str = $alphabet;
$len = $alphabetLen;
break;
default:
$str = $alphabet . $number;
$len = $alphabetLen + $numberLen;
}
$randStr = '';
$str = str_shuffle($str);
for ($i = 0; $i < $length; $i++) {
$num = mt_rand(0, $len);
$randStr .= $str[$num];
}
return $randStr;
}
}
if (!function_exists('generateCode')) {
/**
* 生成特定编码
*
* @param string $type 类型 默认mix混合 number纯数字 alpha字母
* @param int $len 随机数长度
* @return string
*/
function generateCode(string $type = 'number', int $len = 6): string
{
//#时间戳+微秒+6位随机数
$time = microtime(true);
$timeStr = str_replace('.', '', $time);
return sprintf("%s%s", $timeStr, generateRand($len, $type));
}
}
if (!function_exists('checkMobile')) {
/**
* 检测手机号
*
* @param string $mobile
* @return bool
*/
function checkMobile(string $mobile): bool
{
if (preg_match("/^1[3456789]{1}\d{9}$/", $mobile)) {
return true;
} else {
return false;
}
}
}
if (!function_exists('arrayKeysFilter')) {
/**
* 数组键名过滤
*
* @param array $data
* @param array $allowKeys
* @return array
*/
function arrayKeysFilter(array $data, array $allowKeys): array
{
$list = [];
foreach ($data as $key => $val) {
if (in_array($key, $allowKeys)) {
$list[$key] = $val;
}
}
return $list;
}
}
if (!function_exists('getFilesize')) {
/**
* 尺寸单位转换
*
* @param $num
* @return string
*/
function getFilesize($num): string
{
$p = 0;
$format = 'B';
if ($num > 0 && $num < 1024) {
return number_format($num) . ' ' . $format;
}
if ($num >= 1024 && $num < pow(1024, 2)) {
$p = 1;
$format = 'KB';
}
if ($num >= pow(1024, 2) && $num < pow(1024, 3)) {
$p = 2;
$format = 'MB';
}
if ($num >= pow(1024, 3) && $num < pow(1024, 4)) {
$p = 3;
$format = 'GB';
}
if ($num >= pow(1024, 4) && $num < pow(1024, 5)) {
$p = 3;
$format = 'TB';
}
$num /= pow(1024, $p);
return number_format($num, 3) . ' ' . $format;
}
}
if (!function_exists('arrayNullToString')) {
/**
* 数组|或数据集中null值转为空字符串,并以数组格式返回
* 通常用于api json 返回内容null转换
*
* @param array $data 【array|collection】
* @return array
*/
function arrayNullToString($data)
{
if ($data instanceof Collection) {
$data = $data->toArray();
}
// 判断是否可以遍历
if (is_iterable($data)) {
foreach ($data as $key => $val) {
if ($val instanceof Collection) {
$val = $val->toArray();
}
if (is_iterable($val)) {
$data[$key] = arrayNullToString($val);
} elseif ($val === null) {
$data[$key] = '';
}
}
} else {
$data = [];
}
return $data;
}
}
if (!function_exists('arrayKeysExcludeFilter')) {
/**
* 数组键名排除过滤
*
* @param array $data
* @param array $excludeKeys 排除的字段
* @return array
*/
function arrayKeysExcludeFilter(array $data, array $excludeKeys): array
{
foreach ($data as $key => $val) {
if (in_array($key, $excludeKeys)) {
unset($data[$key]);
}
}
return $data;
}
}
if (!function_exists('getLatelyWeekDate')) {
/**
* 获取本周的周一 到周日的日期
*/
function getLatelyWeekDate()
{
//本周一
$oneDate = date('Y-m-d 00:00:00', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 86400)); //w为星期几的数字形式,这里0为周日
$oneDateTime = strtotime($oneDate);
//返回周一到周天 1-7
return [
"1" => ["date"=>$oneDate],
"2" => ["date"=>date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 1)))],
"3" => ["date"=>date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 2)))],
"4" => ["date"=>date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 3)))],
"5" => ["date"=>date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 4)))],
"6" => ["date"=>date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 5)))],
"7" => ["date"=>date('Y-m-d 00:00:00', $oneDateTime + ((86400 * 6)))],
];
}
}
if (!function_exists('stringDesensitization')) {
/**
* 字符串脱敏 默认给手机号脱敏 其他未兼容
*
* @param string $string
* @param string $s
* @param int $start
* @param int $len
* @return string
*/
function stringDesensitization(string $string, string $s = '****', int $start = 3, int $len = 4): string
{
return substr_replace($string, $s, $start, $len);
}
}
/**
* UUID
*/
if(!function_exists("createUuid")){
function createUuid($prefix = "")
{
$chars = md5(uniqid(mt_rand(), true));
$uuid = substr($chars, 0, 8) . '-'
. substr($chars, 8, 4) . '-'
. substr($chars, 12, 4) . '-'
. substr($chars, 16, 4) . '-'
. substr($chars, 20, 12);
return $prefix . str_replace("-", "", $uuid);
}
}
/**
* 格式化黑名单时间
*/
if(!function_exists("formatBlankTime")){
function formatBlankTime($startdate, $enddate) {
if (strtotime($startdate) > strtotime($enddate)) {
$ymd = $enddate;
$enddate = $startdate;
$startdate = $ymd;
}
$date=floor((strtotime($enddate)-strtotime($startdate))/86400);
//echo "相差天数:".$date."天<br/><br/>";
$hour=floor((strtotime($enddate)-strtotime($startdate))%86400/3600);
//echo "相差小时数:".$hour."小时<br/><br/>";
$minute=floor((strtotime($enddate)-strtotime($startdate))%86400/60);
//echo "相差分钟数:".$minute."分钟<br/><br/>";
$second=floor((strtotime($enddate)-strtotime($startdate))%86400%60);
//echo "相差秒数:".$second."秒";
return ($date>0?$date."":'').
($hour>0?$hour."小时":'').
($minute>0?$minute."分钟":'').
($second>0?$second."":'');
}
}
/**
* 生成用户默认昵称
*/
if (!function_exists('generateDefaultNickName')) {
function generateDefaultNickName()
{
return '用户'.generateRand('6', 'mix');
}
}
/**
* 根据当前坐标和范围距离计算方形范围内的经纬度坐标取值范围
* $curLat double类型 当前坐标纬度
* $curLng double类型 当前坐标经度
* $distance double类型 查询范围单位km,当前坐标所在园的半径,与此范围正方形内切
*
* 相关数学知识半正矢公式Haversine公式、正/反弦函数和正/反切函数等三角函数
* 平均地球半径6371km
* 经度范围:-180 ~ 180 注意差值180度限制时的计算
* 纬度范围:-90 ~ 90
*
*/
if (!function_exists('getEarthSquareRangePoint')) {
function getEarthSquareRangePoint($curLat, $curLng, $distance)
{
$list = [];
$earthRadius = 6371; // 地球平均半径 6371km
$disLat = rad2deg($distance / $earthRadius);
$disLng = rad2deg(2 * asin(sin($distance / (2 * $earthRadius) / cos(deg2rad($curLat)))));
$disLat = abs($disLat);
$disLng = abs($disLng);
$list['cur_lat'] = $curLat;
$list['cur_lng'] = $curLng;
$list['dis_lat'] = $disLat;
$list['dis_lng'] = $disLng;
$latTop = $curLat + $disLat;
$latBottom = $curLat - $disLat;
$lngLeft = $curLng - $disLng;
$lngRight = $curLng + $disLng;
$checkLatTopRem = abs(fmod(floatval($latTop), 180));
$checkLatTop = abs(fmod(intval($latTop / 90), 4));
if ($latTop >= 0) {
$latTop = floatval($checkLatTopRem > 90 ? (180 - $checkLatTopRem) : $checkLatTopRem);
$latTop = $checkLatTop >= 2 ? (-$latTop) : $latTop; // 南半球为负数
} else {
$latTop = floatval($checkLatTopRem > 90 ? (180 - $checkLatTopRem) : $checkLatTopRem);
$latTop = $checkLatTop < 2 ? (-$latTop) : $latTop; // 南半球为负数
}
$checkLatBottomRem = abs(fmod(floatval($latBottom) ,180));
$checkLatBottom = abs(intval($latBottom / 90) % 4);
if ($latBottom >= 0) {
$latBottom = floatval($checkLatBottomRem > 90 ? (180 - $checkLatBottomRem) : $checkLatBottomRem);
$latBottom = $checkLatBottom >= 2 ? (-$latBottom) : $latBottom; // 南半球为负数
} else {
$latBottom = floatval($checkLatBottomRem > 90 ? (180 - $checkLatBottomRem) : $checkLatBottomRem);
$latBottom = $checkLatBottom < 2 ? (-$latBottom) : $latBottom; // 南半球为负数
}
$list['lat_min'] = min([$latTop, $curLat, $latBottom]);
$list['lat_max'] = max([$latTop, $curLat, $latBottom]);
$checkLngLeftRem = abs(fmod(floatval($lngLeft), 360));
if ($lngLeft >= 0) {
$lngLeft = floatval($checkLngLeftRem > 180 ? -(360 - $checkLngLeftRem) : $checkLngLeftRem); // 西半球为负数
} else {
$lngLeft = floatval($checkLngLeftRem > 180 ? (360 - $checkLngLeftRem) : (-$checkLngLeftRem)); // 西半球为负数
}
$checkLngRightRem = abs(fmod(floatval($lngRight), 360));
if ($lngRight >= 0) {
$lngRight = floatval($checkLngRightRem > 180 ? -(360 - $checkLngRightRem) : $checkLngRightRem); // 西半球为负数
} else {
$lngRight = floatval($checkLngRightRem > 180 ? (360 - $checkLngRightRem) : (-$checkLngRightRem)); // 西半球为负数
}
$list['lng_min'] = min([$lngLeft, $curLng, $lngRight]);
$list['lng_max'] = max([$lngLeft, $curLng, $lngRight]);
$list['lat_top'] = $latTop;
$list['lat_bottom'] = $latBottom;
$list['lng_left'] = $lngLeft;
$list['lng_right'] = $lngRight;
return $list;
}
}