diff --git a/app/Helper/functions.php b/app/Helper/functions.php index b3fcbbd783c1840ed83209927d31b79cc92c4631..6148d071c022f5dce40e21b59f025a8c806bd91d 100644 --- a/app/Helper/functions.php +++ b/app/Helper/functions.php @@ -1,5 +1,99 @@ setUserAgent('Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36 Edg/87.0.664.75'); + + $content = $http->fetch(); + var_dump($content); + var_dump($http->getHttpCode()); + var_dump($http->getLastError()); + } + + //Pre-defined content types + const CONTENT_TYPE_XML = 'application/xml; charset=UTF-8'; + const CONTENT_TYPE_JSON = 'application/json; charset=UTF-8'; + const CONTENT_TYPE_FORM_DATA = 'multipart/form-data'; + const CONTENT_TYPE_URL_ENCODED = 'application/x-www-form-urlencoded'; + + //Job info + public $data = []; + public $file = []; + public $header = []; + + public $url = ''; + public $etag = ''; + public $cookie = ''; + public $referer = ''; + public $modified = ''; + public $curl_error = ''; + + public $proxy = ''; + public $proxy_passwd = ''; + + public $max_follow = 0; + public $response_code = 0; + + public $http_ver = 'HTTP/2'; //HTTP Version + public $method = 'GET'; //Request method + public $user_agent = 'Mozilla/5.0 (Compatible; NervSys/111)'; //User Agent string + public $connection = 'keep-alive'; //Connection type + + public $content_type = self::CONTENT_TYPE_URL_ENCODED; //Content type + public $accept_charset = 'UTF-8,*;q=0'; //Accept charset + public $accept_encoding = 'gzip,deflate,identity,*;q=0'; //Accept encoding + public $accept_language = 'en-US,en,zh-CN,zh,*;q=0'; //Accept language + + public $accept_type = 'application/json;q=0.9,application/xml;q=0.8,text/plain;q=0.7,text/html;q=0.6,*/*;q=0.5'; //Accept types + + /** + * libHttp constructor. + * + * @param string $url + */ + public function __construct(string $url = '') + { + $this->url = &$url; + unset($url); + } + + /** + * Add request data + * + * @param array ...$data + * + * @return $this + */ + public function addData(array ...$data): self + { + foreach ($data as $item) { + $this->data += $item; + } + + unset($data, $item); + return $this; + } + + /** + * Add upload file + * + * @param array ...$file + * + * @return $this + */ + public function addFile(array ...$file): self + { + foreach ($file as $key => $val) { + if (file_exists($val)) { + $this->file[$key] = new \CURLFile($val); + } + } + + unset($file, $key, $val); + return $this; + } + + /** + * Add header data + * + * @param array $header + * + * @return $this + */ + public function addHeader(array $header): self + { + $this->header += $header; + + unset($header); + return $this; + } + + /** + * Add cookie data + * + * @param array $cookie + * + * @return $this + */ + public function addCookie(array $cookie): self + { + foreach ($cookie as $key => $val) { + if ('' !== $this->cookie) { + $this->cookie .= '; '; + } + + $this->cookie .= $key . '=' . $val; + } + + unset($cookie, $key, $val); + return $this; + } + + /** + * Set method + * + * @param string $method + * + * @return $this + */ + public function setMethod(string $method = 'POST'): self + { + $this->method = strtoupper($method); + + unset($method); + return $this; + } + + /** + * Set content type + * + * @param string $content_type + * + * @return $this + */ + public function setContentType(string $content_type = self::CONTENT_TYPE_URL_ENCODED): self + { + $this->content_type = &$content_type; + + unset($content_type); + return $this; + } + + /** + * Set referer URL + * + * @param string $referer + * + * @return $this + */ + public function setReferer(string $referer): self + { + $this->referer = &$referer; + + unset($referer); + return $this; + } + + /** + * Set User-Agent string + * + * @param string $user_agent + * + * @return $this + */ + public function setUserAgent(string $user_agent): self + { + $this->user_agent = &$user_agent; + + unset($user_agent); + return $this; + } + + /** + * Set max follows + * + * @param int $max_follow + * + * @return $this + */ + public function setMaxFollow(int $max_follow): self + { + $this->max_follow = &$max_follow; + + unset($max_follow); + return $this; + } + + /** + * Set HTTP accept types + * + * @param string $accept_type + * + * @return $this + */ + public function setAcceptType(string $accept_type): self + { + $this->accept_type = &$accept_type; + + unset($accept_type); + return $this; + } + + /** + * Set ETag value + * + * @param string $etag + * + * @return $this + */ + public function setETag(string $etag): self + { + $this->etag = &$etag; + + unset($etag); + return $this; + } + + /** + * Set modified since value + * + * @param string $last_modified + * + * @return $this + */ + public function setLastModified(string $last_modified): self + { + $this->modified = &$last_modified; + + unset($last_modified); + return $this; + } + + /** + * Set proxy + * + * @param string $proxy + * @param string $proxy_passwd + * + * @return $this + */ + public function setProxy(string $proxy, string $proxy_passwd): self + { + $this->proxy = &$proxy; + $this->proxy_passwd = &$proxy_passwd; + + unset($proxy, $proxy_passwd); + return $this; + } + + /** + * Fetch response data + * + * @param bool $with_body + * @param bool $with_header + * + * @return string + * @throws \Exception + */ + public function fetch(bool $with_body = true, bool $with_header = false): string + { + if ('' === $this->url) { + throw new \Exception('URL not set!', E_USER_NOTICE); + } + + //Prepare data + if (!empty($this->file)) { + $this->data += $this->file; + $this->content_type = self::CONTENT_TYPE_FORM_DATA; + } + + //Set method + if (!empty($this->data)) { + $this->method = 'POST'; + } + + //Get URL units + $url_unit = $this->getUrlUnit($this->url); + + //Get cURL headers + $header = $this->getHeader($url_unit); + + //Initialize + $opt = []; + $curl = curl_init(); + + //Build options + $opt[CURLOPT_URL] = $this->url; + $opt[CURLOPT_PORT] = &$url_unit['port']; + $opt[CURLOPT_TIMEOUT] = 60; + $opt[CURLOPT_NOSIGNAL] = true; + $opt[CURLOPT_AUTOREFERER] = true; + $opt[CURLOPT_COOKIESESSION] = true; + $opt[CURLOPT_RETURNTRANSFER] = true; + $opt[CURLOPT_SSL_VERIFYHOST] = 2; + $opt[CURLOPT_SSL_VERIFYPEER] = false; + $opt[CURLOPT_HTTPHEADER] = &$header; + $opt[CURLOPT_ENCODING] = $this->accept_encoding; + $opt[CURLOPT_USERAGENT] = $this->user_agent; + $opt[CURLOPT_CUSTOMREQUEST] = strtoupper($this->method); + $opt[CURLOPT_POST] = ('POST' === $this->method); + $opt[CURLOPT_NOBODY] = !$with_body; + $opt[CURLOPT_HEADER] = &$with_header; + + if ('' !== $this->cookie) { + $opt[CURLOPT_COOKIE] = $this->cookie; + } + + if ('' !== $this->referer) { + $opt[CURLOPT_REFERER] = $this->referer; + } + + if (0 < $this->max_follow) { + $opt[CURLOPT_FOLLOWLOCATION] = true; + $opt[CURLOPT_MAXREDIRS] = $this->max_follow; + } + + if ('' !== $this->proxy) { + $opt[CURLOPT_PROXY] = $this->proxy; + + if ('' !== $this->proxy_passwd) { + $opt[CURLOPT_PROXYUSERPWD] = $this->proxy_passwd; + } + } + + if (!empty($this->data)) { + switch ($this->content_type) { + case self::CONTENT_TYPE_JSON: + $opt[CURLOPT_POSTFIELDS] = json_encode($this->data); + break; + + case self::CONTENT_TYPE_XML: + $opt[CURLOPT_POSTFIELDS] = IOUnit::new()->toXml($this->data); + break; + + case self::CONTENT_TYPE_URL_ENCODED: + $opt[CURLOPT_POSTFIELDS] = http_build_query($this->data); + break; + + default: + $opt[CURLOPT_POSTFIELDS] = &$this->data; + break; + } + } + + //Set cURL options + curl_setopt_array($curl, $opt); + + //Get response + $response = curl_exec($curl); + + //Collect HTTP CODE or ERROR + false !== $response + ? $this->response_code = curl_getinfo($curl, CURLINFO_RESPONSE_CODE) + : $this->curl_error = curl_error($curl); + + //Close cURL handle + curl_close($curl); + + unset($opt, $curl, $key, $val); + return (string)$response; + } + + /** + * Get last HTTP response code + * + * @return string + */ + public function getHttpCode() + { + return $this->response_code; + } + + /** + * Get last HTTP curl error + * + * @return string + */ + public function getLastError(): string + { + return $this->curl_error; + } + + /** + * Extract URL units + * + * @param string $url + * + * @return array + */ + private function getUrlUnit(string $url): array + { + //Parse URL + $unit = parse_url($url); + + //Check main components + if (false === $unit || !isset($unit['scheme']) || !isset($unit['host'])) { + return []; + } + + //Prepare URL unit + if (!isset($unit['path'])) { + $unit['path'] = '/'; + } + + $unit['query'] = isset($unit['query']) ? '?' . $unit['query'] : ''; + + if (!isset($unit['port'])) { + $unit['port'] = 'https' === $unit['scheme'] ? 443 : 80; + } + + unset($url); + return $unit; + } + + /** + * get request header + * + * @param array $url_unit + * + * @return array + */ + private function getHeader(array $url_unit): array + { + $header_list = ['Host' => $url_unit['host'] . ':' . $url_unit['port']]; + + if (!empty($this->header)) { + $header_list += $this->header; + } + + if ('' !== $this->cookie) { + $header_list['Cookie'] = $this->cookie; + } + + if ('' !== $this->etag) { + $header_list['If-None-Match'] = $this->etag; + } + + if ('' !== $this->modified) { + $header_list['If-Modified-Since'] = $this->modified; + } + + $header_list += [ + 'Accept' => $this->accept_type, + 'Accept-Charset' => $this->accept_charset, + 'Accept-Encoding' => $this->accept_encoding, + 'Accept-Language' => $this->accept_language, + 'Content-Type' => $this->content_type, + 'User-Agent' => $this->user_agent, + 'Connection' => $this->connection + ]; + + $headers = [$this->method . ' ' . $url_unit['path'] . $url_unit['query'] . ' ' . $this->http_ver]; + + foreach ($header_list as $key => $val) { + $headers[] = $key . ': ' . $val; + } + + unset($url_unit, $header_list, $key, $val); + return $headers; + } +} diff --git a/app/Modules/Admin/Resources/vue-element-admin/utils/index.js b/app/Modules/Admin/Resources/vue-element-admin/utils/index.js index 9089b7554293ecc5d78d25ce6e1cca5cd605a9ad..3eadf0f5c52049ca2e6f714c9472302c429ea8b6 100644 --- a/app/Modules/Admin/Resources/vue-element-admin/utils/index.js +++ b/app/Modules/Admin/Resources/vue-element-admin/utils/index.js @@ -9,46 +9,48 @@ * @returns {string | null} */ export function parseTime(time, cFormat) { - if (arguments.length === 0 || !time) { - return null - } - const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' - let date - if (typeof time === 'object') { - date = time - } else { - if ((typeof time === 'string')) { - if ((/^[0-9]+$/.test(time))) { - // support "1548221490638" - time = parseInt(time) - } else { - // support safari - // https://stackoverflow.com/questions/4310953/invalid-date-in-safari - time = time.replace(new RegExp(/-/gm), '/') - } + if (arguments.length === 0 || !time) { + return ''; } + const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string')) { + if ((/^[0-9]+$/.test(time))) { + // support "1548221490638" + time = parseInt(time) + } else { + // support safari + // https://stackoverflow.com/questions/4310953/invalid-date-in-safari + time = time.replace(new RegExp(/-/gm), '/') + } + } - if ((typeof time === 'number') && (time.toString().length === 10)) { - time = time * 1000 + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() } - date = new Date(time) - } - const formatObj = { - y: date.getFullYear(), - m: date.getMonth() + 1, - d: date.getDate(), - h: date.getHours(), - i: date.getMinutes(), - s: date.getSeconds(), - a: date.getDay() - } - const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { - const value = formatObj[key] - // Note: getDay() returns 0 on Sunday - if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } - return value.toString().padStart(2, '0') - }) - return time_str + const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { + const value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { + return ['日', '一', '二', '三', '四', '五', '六'][value] + } + return value.toString().padStart(2, '0') + }) + return time_str } /** @@ -57,41 +59,41 @@ export function parseTime(time, cFormat) { * @returns {string} */ export function formatTime(time, option) { - if (('' + time).length === 10) { - time = parseInt(time) * 1000 - } else { - time = +time - } - const d = new Date(time) - const now = Date.now() + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() - const diff = (now - d) / 1000 + const diff = (now - d) / 1000 - if (diff < 30) { - return '刚刚' - } else if (diff < 3600) { - // less 1 hour - return Math.ceil(diff / 60) + '分钟前' - } else if (diff < 3600 * 24) { - return Math.ceil(diff / 3600) + '小时前' - } else if (diff < 3600 * 24 * 2) { - return '1天前' - } - if (option) { - return parseTime(time, option) - } else { - return ( - d.getMonth() + - 1 + - '月' + - d.getDate() + - '日' + - d.getHours() + - '时' + - d.getMinutes() + - '分' - ) - } + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '月' + + d.getDate() + + '日' + + d.getHours() + + '时' + + d.getMinutes() + + '分' + ) + } } /** @@ -99,18 +101,18 @@ export function formatTime(time, option) { * @returns {Object} */ export function getQueryObject(url) { - url = url == null ? window.location.href : url - const search = url.substring(url.lastIndexOf('?') + 1) - const obj = {} - const reg = /([^?&=]+)=([^?&=]*)/g - search.replace(reg, (rs, $1, $2) => { - const name = decodeURIComponent($1) - let val = decodeURIComponent($2) - val = String(val) - obj[name] = val - return rs - }) - return obj + url = url == null ? window.location.href : url + const search = url.substring(url.lastIndexOf('?') + 1) + const obj = {} + const reg = /([^?&=]+)=([^?&=]*)/g + search.replace(reg, (rs, $1, $2) => { + const name = decodeURIComponent($1) + let val = decodeURIComponent($2) + val = String(val) + obj[name] = val + return rs + }) + return obj } /** @@ -118,15 +120,15 @@ export function getQueryObject(url) { * @returns {number} output value */ export function byteLength(str) { - // returns the byte length of an utf8 string - let s = str.length - for (var i = str.length - 1; i >= 0; i--) { - const code = str.charCodeAt(i) - if (code > 0x7f && code <= 0x7ff) s++ - else if (code > 0x7ff && code <= 0xffff) s += 2 - if (code >= 0xDC00 && code <= 0xDFFF) i-- - } - return s + // returns the byte length of an utf8 string + let s = str.length + for (var i = str.length - 1; i >= 0; i--) { + const code = str.charCodeAt(i) + if (code > 0x7f && code <= 0x7ff) s++ + else if (code > 0x7ff && code <= 0xffff) s += 2 + if (code >= 0xDC00 && code <= 0xDFFF) i-- + } + return s } /** @@ -134,13 +136,13 @@ export function byteLength(str) { * @returns {Array} */ export function cleanArray(actual) { - const newArray = [] - for (let i = 0; i < actual.length; i++) { - if (actual[i]) { - newArray.push(actual[i]) + const newArray = [] + for (let i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]) + } } - } - return newArray + return newArray } /** @@ -148,13 +150,13 @@ export function cleanArray(actual) { * @returns {Array} */ export function param(json) { - if (!json) return '' - return cleanArray( - Object.keys(json).map(key => { - if (json[key] === undefined) return '' - return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) - }) - ).join('&') + if (!json) return '' + return cleanArray( + Object.keys(json).map(key => { + if (json[key] === undefined) return '' + return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) + }) + ).join('&') } /** @@ -162,21 +164,21 @@ export function param(json) { * @returns {Object} */ export function param2Obj(url) { - const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') - if (!search) { - return {} - } - const obj = {} - const searchArr = search.split('&') - searchArr.forEach(v => { - const index = v.indexOf('=') - if (index !== -1) { - const name = v.substring(0, index) - const val = v.substring(index + 1, v.length) - obj[name] = val + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} } - }) - return obj + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj } /** @@ -184,9 +186,9 @@ export function param2Obj(url) { * @returns {string} */ export function html2Text(val) { - const div = document.createElement('div') - div.innerHTML = val - return div.textContent || div.innerText + const div = document.createElement('div') + div.innerHTML = val + return div.textContent || div.innerText } /** @@ -196,21 +198,21 @@ export function html2Text(val) { * @returns {Object} */ export function objectMerge(target, source) { - if (typeof target !== 'object') { - target = {} - } - if (Array.isArray(source)) { - return source.slice() - } - Object.keys(source).forEach(property => { - const sourceProperty = source[property] - if (typeof sourceProperty === 'object') { - target[property] = objectMerge(target[property], sourceProperty) - } else { - target[property] = sourceProperty + if (typeof target !== 'object') { + target = {} + } + if (Array.isArray(source)) { + return source.slice() } - }) - return target + Object.keys(source).forEach(property => { + const sourceProperty = source[property] + if (typeof sourceProperty === 'object') { + target[property] = objectMerge(target[property], sourceProperty) + } else { + target[property] = sourceProperty + } + }) + return target } /** @@ -218,19 +220,19 @@ export function objectMerge(target, source) { * @param {string} className */ export function toggleClass(element, className) { - if (!element || !className) { - return - } - let classString = element.className - const nameIndex = classString.indexOf(className) - if (nameIndex === -1) { - classString += '' + className - } else { - classString = - classString.substr(0, nameIndex) + - classString.substr(nameIndex + className.length) - } - element.className = classString + if (!element || !className) { + return + } + let classString = element.className + const nameIndex = classString.indexOf(className) + if (nameIndex === -1) { + classString += '' + className + } else { + classString = + classString.substr(0, nameIndex) + + classString.substr(nameIndex + className.length) + } + element.className = classString } /** @@ -238,26 +240,26 @@ export function toggleClass(element, className) { * @returns {Date} */ export function getTime(type) { - if (type === 'start') { - return new Date().getTime() - 3600 * 1000 * 24 * 90 - } else { - return new Date(new Date().toDateString()) - } + if (type === 'start') { + return new Date().getTime() - 3600 * 1000 * 24 * 90 + } else { + return new Date(new Date().toDateString()) + } } // 获取当前时间 export function getFormatDate() { - var date = new Date(); - var month = date.getMonth() + 1; - var strDate = date.getDate(); - if (month >= 1 && month <= 9) { - month = "0" + month; - } - if (strDate >= 0 && strDate <= 9) { - strDate = "0" + strDate; - } - return date.getFullYear() + "-" + month + "-" + strDate - + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); + var date = new Date(); + var month = date.getMonth() + 1; + var strDate = date.getDate(); + if (month >= 1 && month <= 9) { + month = "0" + month; + } + if (strDate >= 0 && strDate <= 9) { + strDate = "0" + strDate; + } + return date.getFullYear() + "-" + month + "-" + strDate + + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); } /** @@ -267,38 +269,38 @@ export function getFormatDate() { * @return {*} */ export function debounce(func, wait, immediate) { - let timeout, args, context, timestamp, result + let timeout, args, context, timestamp, result - const later = function() { - // 据上一次触发时间间隔 - const last = +new Date() - timestamp + const later = function () { + // 据上一次触发时间间隔 + const last = +new Date() - timestamp - // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait - if (last < wait && last > 0) { - timeout = setTimeout(later, wait - last) - } else { - timeout = null - // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 - if (!immediate) { - result = func.apply(context, args) - if (!timeout) context = args = null - } + // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last) + } else { + timeout = null + // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 + if (!immediate) { + result = func.apply(context, args) + if (!timeout) context = args = null + } + } } - } - return function(...args) { - context = this - timestamp = +new Date() - const callNow = immediate && !timeout - // 如果延时不存在,重新设定延时 - if (!timeout) timeout = setTimeout(later, wait) - if (callNow) { - result = func.apply(context, args) - context = args = null - } + return function (...args) { + context = this + timestamp = +new Date() + const callNow = immediate && !timeout + // 如果延时不存在,重新设定延时 + if (!timeout) timeout = setTimeout(later, wait) + if (callNow) { + result = func.apply(context, args) + context = args = null + } - return result - } + return result + } } /** @@ -309,18 +311,18 @@ export function debounce(func, wait, immediate) { * @returns {Object} */ export function deepClone(source) { - if (!source && typeof source !== 'object') { - throw new Error('error arguments', 'deepClone') - } - const targetObj = source.constructor === Array ? [] : {} - Object.keys(source).forEach(keys => { - if (source[keys] && typeof source[keys] === 'object') { - targetObj[keys] = deepClone(source[keys]) - } else { - targetObj[keys] = source[keys] + if (!source && typeof source !== 'object') { + throw new Error('error arguments', 'deepClone') } - }) - return targetObj + const targetObj = source.constructor === Array ? [] : {} + Object.keys(source).forEach(keys => { + if (source[keys] && typeof source[keys] === 'object') { + targetObj[keys] = deepClone(source[keys]) + } else { + targetObj[keys] = source[keys] + } + }) + return targetObj } /** @@ -328,16 +330,16 @@ export function deepClone(source) { * @returns {Array} */ export function uniqueArr(arr) { - return Array.from(new Set(arr)) + return Array.from(new Set(arr)) } /** * @returns {string} */ export function createUniqueString() { - const timestamp = +new Date() + '' - const randomNum = parseInt((1 + Math.random()) * 65536) + '' - return (+(randomNum + timestamp)).toString(32) + const timestamp = +new Date() + '' + const randomNum = parseInt((1 + Math.random()) * 65536) + '' + return (+(randomNum + timestamp)).toString(32) } /** @@ -347,7 +349,7 @@ export function createUniqueString() { * @returns {boolean} */ export function hasClass(ele, cls) { - return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) + return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) } /** @@ -356,7 +358,7 @@ export function hasClass(ele, cls) { * @param {string} cls */ export function addClass(ele, cls) { - if (!hasClass(ele, cls)) ele.className += ' ' + cls + if (!hasClass(ele, cls)) ele.className += ' ' + cls } /** @@ -365,8 +367,8 @@ export function addClass(ele, cls) { * @param {string} cls */ export function removeClass(ele, cls) { - if (hasClass(ele, cls)) { - const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') - ele.className = ele.className.replace(reg, ' ') - } + if (hasClass(ele, cls)) { + const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') + ele.className = ele.className.replace(reg, ' ') + } } diff --git a/app/Modules/Admin/Resources/vue-element-admin/views/admin_menus/components/detail.vue b/app/Modules/Admin/Resources/vue-element-admin/views/admin_menus/components/detail.vue index 00fa56a3962c2e70b3138ebe149880823980f8c0..328f7ad402957e57589851c821f5cff0b1e67754 100644 --- a/app/Modules/Admin/Resources/vue-element-admin/views/admin_menus/components/detail.vue +++ b/app/Modules/Admin/Resources/vue-element-admin/views/admin_menus/components/detail.vue @@ -47,7 +47,7 @@ - +