* @date 2016/10/25 14:49 */ class ToolsService { /** * Cors Options 授权处理 */ public static function corsOptionsHandler() { if (PHP_SESSION_ACTIVE !== session_status()) Session::init(config('session.')); try { $token = request()->header('token', input('token', '')); list($name, $value) = explode('=', decode($token) . '='); if (!empty($value) && session_name() === $name) session_id($value); } catch (\Exception $e) { } if (request()->isOptions()) { header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Credentials:true'); header('Access-Control-Allow-Methods:GET,POST,OPTIONS'); header("Access-Control-Allow-Headers:Accept,Referer,Host,Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Cookie,token"); header('Content-Type:text/plain charset=utf-8'); header('Access-Control-Max-Age:1728000'); header('HTTP/1.0 204 No Content'); header('Content-Length:0'); header('status:204'); exit; } } /** * Cors Request Header信息 * @return array */ public static function corsRequestHander() { return [ 'Access-Control-Allow-Origin' => request()->header('origin', '*'), 'Access-Control-Allow-Methods' => 'GET,POST,OPTIONS', 'Access-Control-Allow-Credentials' => "true", ]; } /** * 返回成功的操作 * @param mixed $msg 消息内容 * @param array $data 返回数据 * @param integer $code 返回代码 */ public static function success($msg, $data = [], $code = 1) { $result = ['code' => $code, 'msg' => $msg, 'data' => $data, 'token' => encode(session_name() . '=' . session_id())]; throw new HttpResponseException(Response::create($result, 'json', 200, self::corsRequestHander())); } /** * 返回失败的请求 * @param mixed $msg 消息内容 * @param array $data 返回数据 * @param integer $code 返回代码 */ public static function error($msg, $data = [], $code = 0) { $result = ['code' => $code, 'msg' => $msg, 'data' => $data, 'token' => encode(session_name() . '=' . session_id())]; throw new HttpResponseException(Response::create($result, 'json', 200, self::corsRequestHander())); } /** * Emoji原形转换为String * @param string $content * @return string */ public static function emojiEncode($content) { return json_decode(preg_replace_callback("/(\\\u[ed][0-9a-f]{3})/i", function ($str) { return addslashes($str[0]); }, json_encode($content))); } /** * Emoji字符串转换为原形 * @param string $content * @return string */ public static function emojiDecode($content) { return json_decode(preg_replace_callback('/\\\\\\\\/i', function () { return '\\'; }, json_encode($content))); } /** * 一维数据数组生成数据树 * @param array $list 数据列表 * @param string $id 父ID Key * @param string $pid ID Key * @param string $son 定义子数据Key * @return array */ public static function arr2tree($list, $id = 'id', $pid = 'pid', $son = 'sub') { list($tree, $map) = [[], []]; foreach ($list as $item) $map[$item[$id]] = $item; foreach ($list as $item) if (isset($item[$pid]) && isset($map[$item[$pid]])) { $map[$item[$pid]][$son][] = &$map[$item[$id]]; } else $tree[] = &$map[$item[$id]]; unset($map); return $tree; } /** * 一维数据数组生成数据树 * @param array $list 数据列表 * @param string $id ID Key * @param string $pid 父ID Key * @param string $path * @param string $ppath * @return array */ public static function arr2table(array $list, $id = 'id', $pid = 'pid', $path = 'path', $ppath = '') { $tree = []; foreach (self::arr2tree($list, $id, $pid) as $attr) { $attr[$path] = "{$ppath}-{$attr[$id]}"; $attr['sub'] = isset($attr['sub']) ? $attr['sub'] : []; $attr['spt'] = substr_count($ppath, '-'); $attr['spl'] = str_repeat("   ├  ", $attr['spt']); $sub = $attr['sub']; unset($attr['sub']); $tree[] = $attr; if (!empty($sub)) $tree = array_merge($tree, self::arr2table($sub, $id, $pid, $path, $attr[$path])); } return $tree; } /** * 获取数据树子ID * @param array $list 数据列表 * @param int $id 起始ID * @param string $key 子Key * @param string $pkey 父Key * @return array */ public static function getArrSubIds($list, $id = 0, $key = 'id', $pkey = 'pid') { $ids = [intval($id)]; foreach ($list as $vo) if (intval($vo[$pkey]) > 0 && intval($vo[$pkey]) === intval($id)) { $ids = array_merge($ids, self::getArrSubIds($list, intval($vo[$key]), $key, $pkey)); } return $ids; } /** * 写入CSV文件头部 * @param string $filename 导出文件 * @param array $headers CSV 头部(一级数组) */ public static function setCsvHeader($filename, array $headers) { header('Content-Type: application/octet-stream'); header("Content-Disposition: attachment; filename=" . iconv('utf-8', 'gbk//TRANSLIT', $filename)); echo @iconv('utf-8', 'gbk//TRANSLIT', "\"" . implode('","', $headers) . "\"\n"); } /** * 写入CSV文件内容 * @param array $list 数据列表(二维数组或多维数组) * @param array $rules 数据规则(一维数组) */ public static function setCsvBody(array $list, array $rules) { foreach ($list as $data) { $rows = []; foreach ($rules as $rule) { $item = self::parseKeyDot($data, $rule); $rows[] = $item === $data ? '' : $item; } echo @iconv('utf-8', 'gbk//TRANSLIT', "\"" . implode('","', $rows) . "\"\n"); flush(); } } /** * 根据数组key查询(可带点规则) * @param array $data 数据 * @param string $rule 规则,如: order.order_no * @return mixed */ private static function parseKeyDot(array $data, $rule) { list($temp, $attr) = [$data, explode('.', trim($rule, '.'))]; while ($key = array_shift($attr)) $temp = isset($temp[$key]) ? $temp[$key] : $temp; return (is_string($temp) || is_numeric($temp)) ? str_replace('"', '""', "\t{$temp}") : ''; } }