work/application/common.php

688 lines
20 KiB
PHP
Raw Normal View History

2019-01-17 11:05:47 +08:00
<?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;
2019-01-17 11:05:47 +08:00
use service\DataService;
use service\NodeService;
use service\RandomService;
use think\Db;
use think\facade\Cache;
use think\facade\Log;
2019-01-17 11:05:47 +08:00
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{
2020-12-20 12:03:30 +08:00
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);
}
2019-01-17 11:05:47 +08:00
/**
* 打印输出数据到文件
* @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';
2020-03-06 14:52:48 +08:00
$str = (is_string($data) ? $data : ((is_array($data) || is_object($data)) ? print_r($data, true) : var_export($data, true))) . PHP_EOL;
2019-01-17 11:05:47 +08:00
$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);
}
/**
2019-01-21 17:26:58 +08:00
* 生成表唯一标记
2019-01-17 11:05:47 +08:00
* @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] : '';
}
2019-01-21 17:26:58 +08:00
/**
* 错误消息,一般用于向上抛出逻辑错误
* @param $errno
* @param string $message
* @return array
*/
function error($errno, $message = '')
{
return [
'errno' => $errno,
'msg' => $message,
2019-01-21 17:26:58 +08:00
];
}
/**
* 判断是否含有错误消息
* @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');
}
2019-01-17 11:05:47 +08:00
/**
* 日期格式标准输出
* @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));
}
2019-01-21 17:26:58 +08:00
/**
* 当前时间
* @return false|string
*/
2019-01-17 11:05:47 +08:00
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;
}
}
2019-01-17 11:05:47 +08:00
/**
* 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 锁过期时间
2019-01-17 11:05:47 +08:00
* @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 锁标识
2019-01-17 11:05:47 +08:00
* @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);
}