Files
2026-03-11 18:24:59 +08:00

466 lines
12 KiB
PHP
Raw Permalink 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 app\common\service\FileService;
use think\helper\Str;
use think\facade\Db;
/**
* @notes 生成密码加密密钥
* @param string $plaintext
* @param string $salt
* @return string
* @author 段誉
* @date 2021/12/28 18:24
*/
function create_password(string $plaintext, string $salt) : string
{
return md5($salt . md5($plaintext . $salt));
}
/**
* @notes 随机生成token值
* @param string $extra
* @return string
* @author 段誉
* @date 2021/12/28 18:24
*/
function create_token(string $extra = '') : string
{
$salt = env('project.unique_identification', 'likeadmin');
$encryptSalt = md5( $salt . uniqid());
return md5($salt . $extra . time() . $encryptSalt);
}
/**
* @notes 截取某字符字符串
* @param $str
* @param string $symbol
* @return string
* @author 段誉
* @date 2021/12/28 18:24
*/
function substr_symbol_behind($str, $symbol = '.') : string
{
$result = strripos($str, $symbol);
if ($result === false) {
return $str;
}
return substr($str, $result + 1);
}
/**
* @notes 对比php版本
* @param string $version
* @return bool
* @author 段誉
* @date 2021/12/28 18:27
*/
function compare_php(string $version) : bool
{
return version_compare(PHP_VERSION, $version) >= 0 ? true : false;
}
/**
* User: 青程信息科技 xc
* Desc: 返回是否有下一页
* @param $count 总记录数
* @param $page 当前页码
* @param $size 每页记录数
* @return int
*/
function is_more($count, $page, $size)
{
$more = 0;
$last_page = ceil($count / $size); //总页数、也是最后一页
if ($last_page && $last_page > $page) {
$more = 1;
}
return $more;
}
/**
* @notes 检查文件是否可写
* @param string $dir
* @return bool
* @author 段誉
* @date 2021/12/28 18:27
*/
function check_dir_write(string $dir = '') : bool
{
$route = root_path() . '/' . $dir;
return is_writable($route);
}
/**
* @notes 获取未来7天时间
* @param string $dir
* @return array|bool
* @author 胥聪
* @date 2025/10/20 17:01
*/
function getNext7Days($startDate = null) {
$dates = [];
$weekDays = ['日', '一', '二', '三', '四', '五', '六'];
$current = $startDate ? new DateTime($startDate) : new DateTime();
for ($i = 0; $i < 7; $i++) {
$date = clone $current;
$date->add(new DateInterval("P{$i}D"));
$dateStr = $date->format('m/d');
$weekDay = $weekDays[$date->format('w')];
$dateOnly = $date->format('Y-m-d'); // 获取完整日期
$dates[$i] = [
'display' => $dateStr . '周' . $weekDay,
'date' => $dateOnly, // 添加日期字段
'timestamp' => $date->getTimestamp(), // 添加当天0点的时间戳
];
$startHour = 8; // 早上8点
$endHour = 24; // 晚上12点24点
$time_slots = array();
// 生成该天从8点到24点的时间段
for ($hour = $startHour; $hour < $endHour; $hour++) {
$startTime = sprintf("%02d:00", $hour);
$timeString = $dateOnly . ' ' . $startTime; // 完整日期时间字符串
$slotTimestamp = strtotime($timeString); // 时间段的时间戳
$time_slots[] = [
'start_time' => $startTime,
'timestamp' => $slotTimestamp, // 添加时间段的时间戳
'datetime' => $timeString, // 添加完整的日期时间
'disabled' => 1
];
}
$dates[$i]['time_slots'] = $time_slots;
}
return $dates;
}
/**
* @notes 生产订单编号
* @param string $dir
* @return array|bool
* @author 胥聪
* @date 2025/10/20 17:01
*/
function createSn($table, $field, $prefix = '', $rand_suffix_length = 4, $pool = [])
{
$suffix = '';
for ($i = 0; $i < $rand_suffix_length; $i++) {
if (empty($pool)) {
$suffix .= rand(0, 9);
} else {
$suffix .= $pool[array_rand($pool)];
}
}
$sn = $prefix . date('YmdHis') . $suffix;
if (Db::name($table)->where($field, $sn)->find()) {
return createSn($table, $field, $prefix, $rand_suffix_length, $pool);
}
return $sn;
}
/**
* 根据经纬度计算两点之间的距离(公里)
* @param float $lat1 起点纬度
* @param float $lng1 起点经度
* @param float $lat2 终点纬度
* @param float $lng2 终点经度
* @param int $precision 保留小数位数
* @return float 距离(公里)
*/
function calculateDistanceKm($lat1, $lng1, $lat2, $lng2, $precision = 2)
{
// 将角度转换为弧度
$radLat1 = deg2rad($lat1);
$radLat2 = deg2rad($lat2);
$radLng1 = deg2rad($lng1);
$radLng2 = deg2rad($lng2);
// 差值
$latDiff = $radLat2 - $radLat1;
$lngDiff = $radLng2 - $radLng1;
// Haversine公式
$a = sin($latDiff / 2) * sin($latDiff / 2) +
cos($radLat1) * cos($radLat2) *
sin($lngDiff / 2) * sin($lngDiff / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
// 地球半径(公里)
$earthRadius = 6371;
$distance = $earthRadius * $c;
return round($distance, $precision);
}
/**
* 计算两点地理坐标之间的距离
* @param Decimal $longitude1 起点经度
* @param Decimal $latitude1 起点纬度
* @param Decimal $longitude2 终点经度
* @param Decimal $latitude2 终点纬度
* @param Int $unit 单位 1:米 2:公里(千米)
* @param Int $decimal 精度 保留小数位数
* @return Decimal
*/
function getDistance(float $longitude1, float $latitude1, float $longitude2, float $latitude2, $unit = 2, $decimal = 2)
{
$EARTH_RADIUS = 6370.996; // 地球半径系数
$PI = 3.1415926;
$radLat1 = $latitude1 * $PI / 180.0;
$radLat2 = $latitude2 * $PI / 180.0;
$radLng1 = $longitude1 * $PI / 180.0;
$radLng2 = $longitude2 * $PI / 180.0;
$a = $radLat1 - $radLat2;
$b = $radLng1 - $radLng2;
$distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
$distance = $distance * $EARTH_RADIUS * 1000;
if ($unit == 2) {
$distance = $distance / 1000;
}
if ($unit == 1) {
$unit_msg = "m";
} else {
$unit_msg = "km";
}
return round($distance, $decimal) . $unit_msg;
}
/**
* 多级线性结构排序
* 转换前:
* [{"id":1,"pid":0,"name":"a"},{"id":2,"pid":0,"name":"b"},{"id":3,"pid":1,"name":"c"},
* {"id":4,"pid":2,"name":"d"},{"id":5,"pid":4,"name":"e"},{"id":6,"pid":5,"name":"f"},
* {"id":7,"pid":3,"name":"g"}]
* 转换后:
* [{"id":1,"pid":0,"name":"a","level":1},{"id":3,"pid":1,"name":"c","level":2},{"id":7,"pid":3,"name":"g","level":3},
* {"id":2,"pid":0,"name":"b","level":1},{"id":4,"pid":2,"name":"d","level":2},{"id":5,"pid":4,"name":"e","level":3},
* {"id":6,"pid":5,"name":"f","level":4}]
* @param array $data 线性结构数组
* @param string $symbol 名称前面加符号
* @param string $name 名称
* @param string $id_name 数组id名
* @param string $parent_id_name 数组祖先id名
* @param int $level 此值请勿给参数
* @param int $parent_id 此值请勿给参数
* @return array
*/
function linear_to_tree($data, $sub_key_name = 'sub', $id_name = 'id', $parent_id_name = 'pid', $parent_id = 0)
{
$tree = [];
foreach ($data as $row) {
if ($row[$parent_id_name] == $parent_id) {
$temp = $row;
$child = linear_to_tree($data, $sub_key_name, $id_name, $parent_id_name, $row[$id_name]);
if ($child) {
$temp[$sub_key_name] = $child;
}
$tree[] = $temp;
}
}
return $tree;
}
/**
* @notes 删除目标目录
* @param $path
* @param $delDir
* @return bool|void
* @author 段誉
* @date 2022/4/8 16:30
*/
function del_target_dir($path, $delDir)
{
//没找到,不处理
if (!file_exists($path)) {
return false;
}
//打开目录句柄
$handle = opendir($path);
if ($handle) {
while (false !== ($item = readdir($handle))) {
if ($item != "." && $item != "..") {
if (is_dir("$path/$item")) {
del_target_dir("$path/$item", $delDir);
} else {
unlink("$path/$item");
}
}
}
closedir($handle);
if ($delDir) {
return rmdir($path);
}
} else {
if (file_exists($path)) {
return unlink($path);
}
return false;
}
}
/**
* @notes 下载文件
* @param $url
* @param $saveDir
* @param $fileName
* @return string
* @author 段誉
* @date 2022/9/16 9:53
*/
function download_file($url, $saveDir, $fileName)
{
if (!file_exists($saveDir)) {
mkdir($saveDir, 0775, true);
}
$fileSrc = $saveDir . $fileName;
file_exists($fileSrc) && unlink($fileSrc);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$file = curl_exec($ch);
curl_close($ch);
$resource = fopen($fileSrc, 'a');
fwrite($resource, $file);
fclose($resource);
if (filesize($fileSrc) == 0) {
unlink($fileSrc);
return '';
}
return $fileSrc;
}
/**
* @notes 去除内容图片域名
* @param $content
* @return array|string|string[]
* @author 段誉
* @date 2022/9/26 10:43
*/
function clear_file_domain($content)
{
$fileUrl = FileService::getFileUrl();
$pattern = '/<img[^>]*\bsrc=["\']'.preg_quote($fileUrl, '/').'([^"\']+)["\']/i';
return preg_replace($pattern, '<img src="$1"', $content);
}
/**
* @notes 设置内容图片域名
* @param $content
* @return array|string|string[]|null
* @author 段誉
* @date 2024/2/5 16:36
*/
function get_file_domain($content)
{
$fileUrl = FileService::getFileUrl();
$imgPreg = '/(<img .*?src=")(?!https?:\/\/)([^"]*)(".*?>)/is';
$videoPreg = '/(<video .*?src=")(?!https?:\/\/)([^"]*)(".*?>)/is';
$content = preg_replace($imgPreg, "\${1}$fileUrl\${2}\${3}", $content);
$content = preg_replace($videoPreg, "\${1}$fileUrl\${2}\${3}", $content);
return $content;
}
/**
* @notes uri小写
* @param $data
* @return array|string[]
* @author 段誉
* @date 2022/7/19 14:50
*/
function lower_uri($data)
{
if (!is_array($data)) {
$data = [$data];
}
return array_map(function ($item) {
return strtolower(Str::camel($item));
}, $data);
}
/**
* @notes 获取无前缀数据表名
* @param $tableName
* @return mixed|string
* @author 段誉
* @date 2022/12/12 15:23
*/
function get_no_prefix_table_name($tableName)
{
$tablePrefix = config('database.connections.mysql.prefix');
$prefixIndex = strpos($tableName, $tablePrefix);
if ($prefixIndex !== 0 || $prefixIndex === false) {
return $tableName;
}
$tableName = substr_replace($tableName, '', 0, strlen($tablePrefix));
return trim($tableName);
}
/**
* @notes 生成编码
* @param $table
* @param $field
* @param string $prefix
* @param int $randSuffixLength
* @param array $pool
* @return string
* @author 段誉
* @date 2023/2/23 11:35
*/
function generate_sn($table, $field, $prefix = '', $randSuffixLength = 4, $pool = []) : string
{
$suffix = '';
for ($i = 0; $i < $randSuffixLength; $i++) {
if (empty($pool)) {
$suffix .= rand(0, 9);
} else {
$suffix .= $pool[array_rand($pool)];
}
}
$sn = $prefix . date('YmdHis') . $suffix;
if (app()->make($table)->where($field, $sn)->find()) {
return generate_sn($table, $field, $prefix, $randSuffixLength, $pool);
}
return $sn;
}
/**
* @notes 格式化金额
* @param $float
* @return int|mixed|string
* @author 段誉
* @date 2023/2/24 11:20
*/
function format_amount($float)
{
if ($float == intval($float)) {
return intval($float);
} elseif ($float == sprintf('%.1f', $float)) {
return sprintf('%.1f', $float);
}
return $float;
}