work/application/common.php
2024-01-03 09:54:57 +08:00

688 lines
20 KiB
PHP
Executable File
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 PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use service\DataService;
use service\NodeService;
use service\RandomService;
use think\Db;
use think\facade\Cache;
use think\facade\Log;
function isDebug()
{
return config('app.app_debug');
}
/**
* 日志记录
* @param string|array $content 内容
* @param string $type 日志类型
* @param string $path 日志地址
*/
function logRecord($content, $type = 'info', $path = 'default')
{
$path = 'log/' . $path;
Log::init(['path' => $path]);
if (is_array($content) || is_object($content)) {
$content = json_encode($content);
}
Log::write($content, $type);
Log::init();
}
function getCurrentMember()
{
return session('member');
}
function setCurrentMember($data)
{
$key = 'member:info:' . $data['code'];//Member 里的 code
if (!$data) {
Cache::rm($key);
}else{
Cache::set($key, $data, 3600 * 24 * 7);
}
return session('member', $data);
}
function getCurrentOrganizationCode()
{
return session('currentOrganizationCode');
}
function setCurrentOrganizationCode($data)
{
return session('currentOrganizationCode', $data);
}
function getCurrentOrganization()
{
return session('organization');
}
function setCurrentOrganization($data)
{
return session('organization', $data);
}
/**
* 打印输出数据到文件
* @param mixed $data 输出的数据
* @param bool $force 强制替换
* @param string|null $file
*/
function p($data, $force = false, $file = null)
{
is_null($file) && $file = env('runtime_path') . date('Ymd') . '.txt';
$str = (is_string($data) ? $data : ((is_array($data) || is_object($data)) ? print_r($data, true) : var_export($data, true))) . PHP_EOL;
$force ? file_put_contents($file, $str) : file_put_contents($file, $str, FILE_APPEND);
}
/**
* RBAC节点权限验证
* @param string $node
* @param string $moduleApp
* @return bool
*/
function auth($node, $moduleApp = 'project')
{
return NodeService::checkAuthNode($node, $moduleApp);
}
/**
* 生成表唯一标记
* @param string $tableName 表名
* @param string $fieldName 字段名
* @param int $len 长度
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
function createUniqueCode($tableName, $fieldName = 'code', $len = 24)
{
$code = RandomService::alnumLowercase($len);
$has = Db::name($tableName)->where([$fieldName => $code])->field($fieldName)->find();
if ($has) {
return createUniqueCode($tableName, $fieldName, $len);
}
return $code;
}
/**
* 设备或配置系统参数
* @param string $name 参数名称
* @param bool $value 默认是null为获取值否则为更新
* @return string|bool
* @throws \think\Exception
* @throws \think\exception\PDOException
*/
function sysconf($name, $value = null)
{
static $config = [];
if ($value !== null) {
list($config, $data) = [[], ['name' => $name, 'value' => $value]];
return DataService::save('SystemConfig', $data, 'name');
}
if (empty($config)) {
$config = Db::name('SystemConfig')->column('name,value');
}
return isset($config[$name]) ? $config[$name] : '';
}
/**
* 错误消息,一般用于向上抛出逻辑错误
* @param $errno
* @param string $message
* @return array
*/
function error($errno, $message = '')
{
return [
'errno' => $errno,
'msg' => $message,
];
}
/**
* 判断是否含有错误消息
* @param $data
* @return bool
*/
function isError($data)
{
if (empty($data) || !is_array($data) || !array_key_exists('errno', $data) || (array_key_exists('errno', $data) && $data['errno'] == 0)) {
return false;
} else {
return true;
}
}
/**
* 是否开启消息推送
* @return mixed
*/
function isOpenNoticePush()
{
return config('config.notice_push');
}
/**
* 是否开启钉钉消息推送
* @return mixed
*/
function isOpenDingTalkNoticePush()
{
return config('config.dingtalk_push');
}
/**
* 是否开启任务邮件推送
* @return mixed
*/
function isOpenMailNoticePush()
{
return config('config.mail_push');
}
/**
* 日期格式标准输出
* @param string $datetime 输入日期
* @param string $format 输出格式
* @return false|string
*/
function format_datetime($datetime, $format = 'Y年m月d日 H:i:s')
{
return date($format, strtotime($datetime));
}
/**
* 当前时间
* @return false|string
*/
function nowTime()
{
return date('Y-m-d H:i:s', time());
}
// 判断文件或目录是否有写的权限
function is_really_writable($file)
{
if (DIRECTORY_SEPARATOR == '/' AND @ ini_get("safe_mode") == FALSE) {
return is_writable($file);
}
if (!is_file($file) OR ($fp = @fopen($file, "r+")) === FALSE) {
return FALSE;
}
fclose($fp);
return TRUE;
}
/**
* 使用PHPEXECL导入
*
* @param string $file 文件地址
* @param int $sheet 工作表sheet(传0则获取第一个sheet)
* @param int $columnCnt 列数(传0则自动获取最大列)
* @param array $options 操作选项
* array mergeCells 合并单元格数组
* array formula 公式数组
* array format 单元格格式数组
*
* @return array
* @throws Exception
*/
function importExcel(string $file = '', int $sheet = 0, int $columnCnt = 0, &$options = [])
{
try {
/* 转码 */
$file = iconv("utf-8", "gb2312", $file);
if (empty($file) OR !file_exists($file)) {
throw new \Exception('文件不存在!');
}
/** @var Xlsx $objRead */
$objRead = IOFactory::createReader('Xlsx');
if (!$objRead->canRead($file)) {
/** @var Xls $objRead */
$objRead = IOFactory::createReader('Xls');
if (!$objRead->canRead($file)) {
throw new \Exception('只支持导入Excel文件');
}
}
/* 如果不需要获取特殊操作则只读内容可以大幅度提升读取Excel效率 */
empty($options) && $objRead->setReadDataOnly(true);
/* 建立excel对象 */
$obj = $objRead->load($file);
/* 获取指定的sheet表 */
$currSheet = $obj->getSheet($sheet);
if (isset($options['mergeCells'])) {
/* 读取合并行列 */
$options['mergeCells'] = $currSheet->getMergeCells();
}
if (0 == $columnCnt) {
/* 取得最大的列号 */
$columnH = $currSheet->getHighestColumn();
/* 兼容原逻辑,循环时使用的是小于等于 */
$columnCnt = Coordinate::columnIndexFromString($columnH);
}
/* 获取总行数 */
$rowCnt = $currSheet->getHighestRow();
$data = [];
/* 读取内容 */
for ($_row = 1; $_row <= $rowCnt; $_row++) {
$isNull = true;
for ($_column = 1; $_column <= $columnCnt; $_column++) {
$cellName = Coordinate::stringFromColumnIndex($_column);
$cellId = $cellName . $_row;
$cell = $currSheet->getCell($cellId);
if (isset($options['format'])) {
/* 获取格式 */
$format = $cell->getStyle()->getNumberFormat()->getFormatCode();
/* 记录格式 */
$options['format'][$_row][$cellName] = $format;
}
if (isset($options['formula'])) {
/* 获取公式,公式均为=号开头数据 */
$formula = $currSheet->getCell($cellId)->getValue();
if (0 === strpos($formula, '=')) {
$options['formula'][$cellName . $_row] = $formula;
}
}
if (isset($format) && 'm/d/yyyy' == $format) {
/* 日期格式翻转处理 */
$cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
}
$data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());
if (!empty($data[$_row][$cellName])) {
$isNull = false;
}
}
/* 判断是否整行数据为空,是的话删除该行数据 */
if ($isNull) {
unset($data[$_row]);
}
}
return $data;
} catch (\Exception $e) {
throw $e;
}
}
/**
* Excel导出TODO 可继续优化
*
* @param array $datas 导出数据,格式['A1' => 'XXXX公司报表', 'B1' => '序号']
* @param string $fileName 导出文件名称
* @param array $options 操作选项,例如:
* bool print 设置打印格式
* string freezePane 锁定行数例如表头为第一行则锁定表头输入A2
* array setARGB 设置背景色,例如['A1', 'C1']
* array setWidth 设置宽度,例如['A' => 30, 'C' => 20]
* bool setBorder 设置单元格边框
* array mergeCells 设置合并单元格,例如['A1:J1' => 'A1:J1']
* array formula 设置公式,例如['F2' => '=IF(D2>0,E42/D2,0)']
* array format 设置格式,整列设置,例如['A' => 'General']
* array alignCenter 设置居中样式,例如['A1', 'A2']
* array bold 设置加粗样式,例如['A1', 'A2']
* string savePath 保存路径,设置后则文件保存到服务器,不通过浏览器下载
* @return bool
*/
function exportExcel(array $datas, string $fileName = '', array $options = []): bool
{
try {
if (empty($datas)) {
return false;
}
set_time_limit(0);
/** @var Spreadsheet $objSpreadsheet */
$objSpreadsheet = app(Spreadsheet::class);
/* 设置默认文字居左,上下居中 */
$styleArray = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_LEFT,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
$objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray);
/* 设置Excel Sheet */
$activeSheet = $objSpreadsheet->setActiveSheetIndex(0);
/* 打印设置 */
if (isset($options['print']) && $options['print']) {
/* 设置打印为A4效果 */
$activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4);
/* 设置打印时边距 */
$pValue = 1 / 2.54;
$activeSheet->getPageMargins()->setTop($pValue / 2);
$activeSheet->getPageMargins()->setBottom($pValue * 2);
$activeSheet->getPageMargins()->setLeft($pValue / 2);
$activeSheet->getPageMargins()->setRight($pValue / 2);
}
/* 行数据处理 */
foreach ($datas as $sKey => $sItem) {
/* 默认文本格式 */
$pDataType = DataType::TYPE_STRING;
/* 设置单元格格式 */
if (isset($options['format']) && !empty($options['format'])) {
$colRow = Coordinate::coordinateFromString($sKey);
/* 存在该列格式并且有特殊格式 */
if (isset($options['format'][$colRow[0]]) &&
NumberFormat::FORMAT_GENERAL != $options['format'][$colRow[0]]) {
$activeSheet->getStyle($sKey)->getNumberFormat()
->setFormatCode($options['format'][$colRow[0]]);
if (false !== strpos($options['format'][$colRow[0]], '0.00') &&
is_numeric(str_replace(['¥', ','], '', $sItem))) {
/* 数字格式转换为数字单元格 */
$pDataType = DataType::TYPE_NUMERIC;
$sItem = str_replace(['¥', ','], '', $sItem);
}
} elseif (is_int($sItem)) {
$pDataType = DataType::TYPE_NUMERIC;
}
}
$activeSheet->setCellValueExplicit($sKey, $sItem, $pDataType);
/* 存在:形式的合并行列列入A1:B2则对应合并 */
if (false !== strstr($sKey, ":")) {
$options['mergeCells'][$sKey] = $sKey;
}
}
unset($datas);
/* 设置锁定行 */
if (isset($options['freezePane']) && !empty($options['freezePane'])) {
$activeSheet->freezePane($options['freezePane']);
unset($options['freezePane']);
}
/* 设置宽度 */
if (isset($options['setWidth']) && !empty($options['setWidth'])) {
foreach ($options['setWidth'] as $swKey => $swItem) {
$activeSheet->getColumnDimension($swKey)->setWidth($swItem);
}
unset($options['setWidth']);
}
/* 设置背景色 */
if (isset($options['setARGB']) && !empty($options['setARGB'])) {
foreach ($options['setARGB'] as $sItem) {
$activeSheet->getStyle($sItem)
->getFill()->setFillType(Fill::FILL_SOLID)
->getStartColor()->setARGB(Color::COLOR_YELLOW);
}
unset($options['setARGB']);
}
/* 设置公式 */
if (isset($options['formula']) && !empty($options['formula'])) {
foreach ($options['formula'] as $fKey => $fItem) {
$activeSheet->setCellValue($fKey, $fItem);
}
unset($options['formula']);
}
/* 合并行列处理 */
if (isset($options['mergeCells']) && !empty($options['mergeCells'])) {
$activeSheet->setMergeCells($options['mergeCells']);
unset($options['mergeCells']);
}
/* 设置居中 */
if (isset($options['alignCenter']) && !empty($options['alignCenter'])) {
$styleArray = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
foreach ($options['alignCenter'] as $acItem) {
$activeSheet->getStyle($acItem)->applyFromArray($styleArray);
}
unset($options['alignCenter']);
}
/* 设置加粗 */
if (isset($options['bold']) && !empty($options['bold'])) {
foreach ($options['bold'] as $bItem) {
$activeSheet->getStyle($bItem)->getFont()->setBold(true);
}
unset($options['bold']);
}
/* 设置单元格边框,整个表格设置即可,必须在数据填充后才可以获取到最大行列 */
if (isset($options['setBorder']) && $options['setBorder']) {
$border = [
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN, // 设置border样式
'color' => ['argb' => 'FF000000'], // 设置border颜色
],
],
];
$setBorder = 'A1:' . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow();
$activeSheet->getStyle($setBorder)->applyFromArray($border);
unset($options['setBorder']);
}
$fileName = !empty($fileName) ? $fileName : (date('YmdHis') . '.xlsx');
if (!isset($options['savePath'])) {
/* 直接导出Excel无需保存到本地输出07Excel文件 */
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header(
"Content-Disposition:attachment;filename=" . iconv(
"utf-8", "GB2312//TRANSLIT", $fileName
)
);
header('Cache-Control: max-age=0');//禁止缓存
$savePath = 'php://output';
} else {
$savePath = $options['savePath'];
}
ob_clean();
ob_start();
$objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx');
$objWriter->save($savePath);
/* 释放内存 */
$objSpreadsheet->disconnectWorksheets();
unset($objSpreadsheet);
ob_end_flush();
return true;
} catch (Exception $e) {
return false;
}
}
/**
* UTF8字符串加密
* @param string $string
* @return string
*/
function encode($string)
{
list($chars, $length) = ['', strlen($string = iconv('utf-8', 'gbk', $string))];
for ($i = 0; $i < $length; $i++) {
$chars .= str_pad(base_convert(ord($string[$i]), 10, 36), 2, 0, 0);
}
return $chars;
}
/**
* UTF8字符串解密
* @param string $string
* @return string
*/
function decode($string)
{
$chars = '';
foreach (str_split($string, 2) as $char) {
$chars .= chr(intval(base_convert($char, 36, 10)));
}
return @iconv('gbk', 'utf-8', $chars);
}
/**
* 获取锁
* @param String $key 锁标识
* @param Int $expire 锁过期时间
* @return Boolean
*/
function lock($key = '', $expire = 5)
{
$is_lock = Cache::store('redis')->get($key);
//不能获取锁
if (!$is_lock) {
Cache::store('redis')->set($key, time() + $expire);
}
return $is_lock ? true : false;
}
/**
* 释放锁
* @param String $key 锁标识
* @return Boolean
*/
function unlock($key = '')
{
return Cache::store('redis')->rm($key);
}
/**
* 下载远程文件到本地
* @param string $url 远程图片地址
* @return string
*/
function local_image($url)
{
return \service\FileService::download($url)['url'];
}
/**
* 提取base64
* @param $base64_url
* @return array
*/
function decodeFile($base64_url)
{
preg_match('/^data:image\/(\w+);base64/', $base64_url, $out);
$type = $out[1];
$type_param = 'data:image/' . $type . ';base64,';
$fileStream = str_replace($type_param, '', $base64_url);
$fileStream = base64_decode($fileStream);
return array(
'type' => $type,
'fileStream' => $fileStream
);
}
//不同环境下获取真实的IP
function get_ip()
{
//判断服务器是否允许$_SERVER
if (isset($_SERVER)) {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$realip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$realip = $_SERVER['REMOTE_ADDR'];
}
} else {
//不允许就使用getenv获取
if (getenv("HTTP_X_FORWARDED_FOR")) {
$realip = getenv("HTTP_X_FORWARDED_FOR");
} elseif (getenv("HTTP_CLIENT_IP")) {
$realip = getenv("HTTP_CLIENT_IP");
} else {
$realip = getenv("REMOTE_ADDR");
}
}
return $realip;
}
/**
* DES 加密
* @param $dat 需要加密的字符串
* @param $key 加密密钥
* @return string
*/
function javaDesEncrypt($dat, $key)
{
/*$block = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_ECB);
$len = strlen($dat);
$padding = $block - ($len % $block);
$dat .= str_repeat(chr($padding),$padding);
return bin2hex(mcrypt_encrypt(MCRYPT_DES, $key, $dat, MCRYPT_MODE_ECB));*/
return bin2hex(openssl_encrypt($dat, 'des-ecb', $key, OPENSSL_RAW_DATA));
}
/**
* DES 解密
* @param $dat 需要解密的字符串
* @param $key 加密密钥
* @return bool|string
*/
function javaDesDecrypt($dat, $key)
{
/*$str = hex2bin($dat);
$str = mcrypt_decrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
$pad = ord($str[($len = strlen($str)) - 1]);
return substr($str, 0, strlen($str) - $pad);*/
$str = hex2bin($dat);
return openssl_decrypt($str, 'des-ecb', $key, OPENSSL_RAW_DATA);
}