$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); }