diff --git a/src/components/office/OnlyOfficeEditor.vue b/src/components/office/OnlyOfficeEditor.vue new file mode 100644 index 0000000..4a9c428 --- /dev/null +++ b/src/components/office/OnlyOfficeEditor.vue @@ -0,0 +1,202 @@ + + + + diff --git a/src/utils/common.js b/src/utils/common.js new file mode 100755 index 0000000..a075a4e --- /dev/null +++ b/src/utils/common.js @@ -0,0 +1,1491 @@ +/** + * 基础函数 + */ +(function (window, $, undefined) { + window.systemInfo = window.systemInfo || {}; + + /** + * ============================================================================= + * ******************************* 基础函数类 ******************************* + * ============================================================================= + */ + $.extend({ + /** + * 是否数组 + * @param obj + * @returns {boolean} + */ + isArray(obj) { + return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() === '[object array]' && typeof obj.length == "number"; + }, + + /** + * 是否数组对象 + * @param obj + * @returns {boolean} + */ + isJson(obj) { + return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() === "[object object]" && typeof obj.length == "undefined"; + }, + + /** + * 是否在数组里 + * @param key + * @param array + * @returns {boolean|*} + */ + inArray(key, array) { + if (!this.isArray(array)) { + return false; + } + return array.includes(key); + }, + + /** + * 随机获取范围 + * @param Min + * @param Max + * @returns {*} + */ + randNum(Min,Max){ + let Range = Max - Min; + let Rand = Math.random(); + return Min + Math.round(Rand * Range); //四舍五入 + }, + + /** + * 获取数组最后一个值 + * @param array + * @returns {boolean} + */ + last(array) { + let str = false; + if (typeof array === 'object' && array.length > 0) { + str = array[array.length - 1]; + } + return str; + }, + + + /** + * 字符串是否包含 + * @param string + * @param find + * @param lower + * @returns {boolean} + */ + strExists(string, find, lower = false) { + string += ""; + find += ""; + if (lower !== true) { + string = string.toLowerCase(); + find = find.toLowerCase(); + } + return (string.indexOf(find) !== -1); + }, + + /** + * 字符串是否左边包含 + * @param string + * @param find + * @param lower + * @returns {boolean} + */ + leftExists(string, find, lower = false) { + string += ""; + find += ""; + if (lower !== true) { + string = string.toLowerCase(); + find = find.toLowerCase(); + } + return (string.substring(0, find.length) === find); + }, + + /** + * 删除左边字符串 + * @param string + * @param find + * @param lower + * @returns {string} + */ + leftDelete(string, find, lower = false) { + string += ""; + find += ""; + if (this.leftExists(string, find, lower)) { + string = string.substring(find.length) + } + return string ? string : ''; + }, + + /** + * 字符串是否右边包含 + * @param string + * @param find + * @param lower + * @returns {boolean} + */ + rightExists(string, find, lower = false) { + string += ""; + find += ""; + if (lower !== true) { + string = string.toLowerCase(); + find = find.toLowerCase(); + } + return (string.substring(string.length - find.length) === find); + }, + + /** + * 删除右边字符串 + * @param string + * @param find + * @param lower + * @returns {string} + */ + rightDelete(string, find, lower = false) { + string += ""; + find += ""; + if (this.rightExists(string, find, lower)) { + string = string.substring(0, string.length - find.length) + } + return string ? string : ''; + }, + + /** + * 取字符串中间 + * @param string + * @param start + * @param end + * @returns {*} + */ + getMiddle(string, start = null, end = null) { + string = string.toString(); + if (this.isHave(start) && this.strExists(string, start)) { + string = string.substring(string.indexOf(start) + start.length); + } + if (this.isHave(end) && this.strExists(string, end)) { + string = string.substring(0, string.indexOf(end)); + } + return string; + }, + + /** + * 截取字符串 + * @param string + * @param start + * @param end + * @returns {string} + */ + subString(string, start, end) { + string += ""; + if (!this.isHave(end)) { + end = string.length; + } + return string.substring(start, end); + }, + + /** + * 随机字符 + * @param len + * @returns {string} + */ + randomString(len) { + len = len || 32; + let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678oOLl9gqVvUuI1'; + let maxPos = $chars.length; + let pwd = ''; + for (let i = 0; i < len; i++) { + pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; + }, + + /** + * 判断是否有 + * @param set + * @returns {boolean} + */ + isHave(set) { + return !!(set !== null && set !== "null" && set !== undefined && set !== "undefined" && set); + }, + + /** + * 相当于 intval + * @param str + * @param fixed + * @returns {number} + */ + runNum(str, fixed = null) { + let _s = Number(str); + if (_s + "" === "NaN") { + _s = 0; + } + if (fixed && /^\d*[1-9]\d*$/.test(fixed)) { + _s = _s.toFixed(fixed); + let rs = _s.indexOf('.'); + if (rs < 0) { + _s += "."; + for (let i = 0; i < fixed; i++) { + _s += "0"; + } + } + } + return _s; + }, + + /** + * 返回10位数时间戳 + * @param v + * @returns {number} + * @constructor + */ + Time(v) { + let time + if (typeof v === "string" && this.strExists(v, "-")) { + v = v.replace(/-/g, '/'); + time = new Date(v).getTime(); + } else { + time = new Date().getTime(); + } + return Math.round(time / 1000) + }, + + /** + * 返回 时间对象|时间戳 + * @param v + * @param stamp 是否返回时间戳 + * @returns {Date|number} + * @constructor + */ + Date(v, stamp = false) { + if (typeof v === "string" && this.strExists(v, "-")) { + v = v.replace(/-/g, '/'); + } + if (stamp === true) { + return Math.round(new Date(v).getTime() / 1000) + } + return new Date(v); + }, + + /** + * 补零 + * @param str + * @param length + * @param after + * @returns {*} + */ + zeroFill(str, length, after) { + str+= ""; + if (str.length >= length) { + return str; + } + let _str = '', _ret = ''; + for (let i = 0; i < length; i++) { + _str += '0'; + } + if (after || typeof after === 'undefined') { + _ret = (_str + "" + str).substr(length * -1); + } else { + _ret = (str + "" + _str).substr(0, length); + } + return _ret; + }, + + /** + * 时间戳转时间格式 + * @param format + * @param v + * @returns {string} + */ + formatDate(format, v) { + if (typeof format === 'undefined' || format === '') { + format = 'Y-m-d H:i:s'; + } + let dateObj; + if (v instanceof Date) { + dateObj = v; + }else { + if (typeof v === 'undefined') { + v = new Date().getTime(); + }else if (/^(-)?\d{1,10}$/.test(v)) { + v = v * 1000; + } else if (/^(-)?\d{1,13}$/.test(v)) { + v = v * 1000; + } else if (/^(-)?\d{1,14}$/.test(v)) { + v = v * 100; + } else if (/^(-)?\d{1,15}$/.test(v)) { + v = v * 10; + } else if (/^(-)?\d{1,16}$/.test(v)) { + v = v * 1; + } else { + return v; + } + dateObj = $A.Date(v); + } + // + format = format.replace(/Y/g, dateObj.getFullYear()); + format = format.replace(/m/g, this.zeroFill(dateObj.getMonth() + 1, 2)); + format = format.replace(/d/g, this.zeroFill(dateObj.getDate(), 2)); + format = format.replace(/H/g, this.zeroFill(dateObj.getHours(), 2)); + format = format.replace(/i/g, this.zeroFill(dateObj.getMinutes(), 2)); + format = format.replace(/s/g, this.zeroFill(dateObj.getSeconds(), 2)); + return format; + }, + + /** + * 租用时间差(不够1个小时算一个小时) + * @param s + * @param e + * @returns {*} + */ + timeDiff(s, e) { + if (typeof e === 'undefined') { + e = $A.Time(); + } + let d = e - s; + if (d > 86400) { + let day = Math.floor(d / 86400); + let hour = Math.ceil((d - (day * 86400)) / 3600); + if (hour > 0) { + return day + '天' + hour + '小时'; + } else { + return day + '天'; + } + } else if (d > 3600) { + return Math.ceil(d / 3600) + '小时'; + } else if (d > 60) { + return Math.ceil(d / 60) + '分钟'; + } else if (d > 10) { + return d + '秒'; + } else { + return '刚刚'; + } + }, + + /** + * 检测手机号码格式 + * @param str + * @returns {boolean} + */ + isMobile(str) { + return /^1([3456789])\d{9}$/.test(str); + }, + + /** + * 检测邮箱地址格式 + * @param email + * @returns {boolean} + */ + isEmail(email) { + return /^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*\.)+[a-zA-Z]*)$/i.test(email); + }, + + /** + * 根据两点间的经纬度计算距离 + * @param lng1 + * @param lat1 + * @param lng2 + * @param lat2 + * @returns {string|*} + */ + getDistance(lng1, lat1, lng2, lat2) { + let DEF_PI = 3.14159265359; // PI + let DEF_2PI = 6.28318530712; // 2*PI + let DEF_PI180 = 0.01745329252; // PI/180.0 + let DEF_R = 6370693.5; // radius of earth + // + let ew1, ns1, ew2, ns2; + let dx, dy, dew; + let distance; + // 角度转换为弧度 + ew1 = lng1 * DEF_PI180; + ns1 = lat1 * DEF_PI180; + ew2 = lng2 * DEF_PI180; + ns2 = lat2 * DEF_PI180; + // 经度差 + dew = ew1 - ew2; + // 若跨东经和西经180 度,进行调整 + if (dew > DEF_PI) + dew = DEF_2PI - dew; + else if (dew < -DEF_PI) + dew = DEF_2PI + dew; + // 东西方向长度(在纬度圈上的投影长度) + dx = DEF_R * Math.cos(ns1) * dew; + // 南北方向长度(在经度圈上的投影长度) + dy = DEF_R * (ns1 - ns2); + // 勾股定理求斜边长 + distance = Math.sqrt(dx * dx + dy * dy).toFixed(0); + return distance; + }, + + /** + * 设置网页标题 + * @param title + */ + setTile(title) { + document.title = title; + let mobile = navigator.userAgent.toLowerCase(); + if (/iphone|ipad|ipod/.test(mobile)) { + let iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + iframe.setAttribute('src', '/favicon.ico'); + let iframeCallback = function () { + setTimeout(function () { + iframe.removeEventListener('load', iframeCallback); + document.body.removeChild(iframe) + }, 0) + }; + iframe.addEventListener('load', iframeCallback); + document.body.appendChild(iframe) + } + }, + + /** + * 克隆对象 + * @param myObj + * @returns {*} + */ + cloneJSON(myObj) { + if(typeof(myObj) !== 'object') return myObj; + if(myObj === null) return myObj; + // + return $A.jsonParse($A.jsonStringify(myObj)) + }, + + /** + * 将一个 JSON 字符串转换为对象(已try) + * @param str + * @param defaultVal + * @returns {*} + */ + jsonParse(str, defaultVal = undefined) { + if (str === null) { + return defaultVal ? defaultVal : {}; + } + if (typeof str === "object") { + return str; + } + try { + return JSON.parse(str.replace(/\n/g,"\\n").replace(/\r/g,"\\r")); + } catch (e) { + return defaultVal ? defaultVal : {}; + } + }, + + /** + * 将 JavaScript 值转换为 JSON 字符串(已try) + * @param json + * @param defaultVal + * @returns {string} + */ + jsonStringify(json, defaultVal = undefined) { + if (typeof json !== 'object') { + return json; + } + try{ + return JSON.stringify(json); + }catch (e) { + return defaultVal ? defaultVal : ""; + } + }, + + /** + * 监听对象尺寸发生改变 + * @param obj + * @param callback + */ + resize(obj, callback) { + let myObj = $A(obj); + if (myObj.length === 0) return; + let height = parseInt(myObj.outerHeight()), + width = parseInt(myObj.outerWidth()); + let inter = setInterval(()=>{ + if (myObj.length === 0) clearInterval(inter); + let tmpHeight = parseInt(myObj.outerHeight()), + tmpWidth = parseInt(myObj.outerWidth()); + if (height !== tmpHeight || width !== tmpWidth) { + height = tmpHeight; + width = tmpWidth; + console.log(width, height); + if (typeof callback === 'function') callback(); + } + }, 250); + }, + + /** + * 是否IOS + * @returns {boolean|string} + */ + isIos() { + let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase(); + return ua && /iphone|ipad|ipod|ios/.test(ua); + }, + + /** + * 是否安卓 + * @returns {boolean|string} + */ + isAndroid() { + let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase(); + return ua && ua.indexOf('android') > 0; + }, + + /** + * 是否微信 + * @returns {boolean} + */ + isWeixin() { + let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase(); + return (ua.match(/MicroMessenger/i) + '' === 'micromessenger'); + }, + + /** + * 是否Chrome + * @returns {boolean} + */ + isChrome() { + let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase(); + return (ua.match(/Chrome/i) + '' === 'chrome'); + }, + + /** + * 是否桌面端 + * @returns {boolean} + */ + isDesktop(){ + let ua = typeof window !== 'undefined' && window.navigator.userAgent; + return !ua.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i); + }, + + /** + * 获取对象 + * @param obj + * @param keys + * @returns {string|*} + */ + getObject(obj, keys) { + let object = obj; + if (this.count(obj) === 0 || this.count(keys) === 0) { + return ""; + } + let array = keys.replace(/,/g, "|").replace(/\./g, "|").split("|"); + array.some(key => { + object = typeof object[key] === "undefined" ? "" : object[key]; + }) + return object; + }, + + /** + * 统计数组或对象长度 + * @param obj + * @returns {number} + */ + count(obj) { + try { + if (typeof obj === "undefined") { + return 0; + } + if (typeof obj === "number") { + obj+= ""; + } + if (typeof obj.length === 'number') { + return obj.length; + } else { + let i = 0, key; + for (key in obj) { + i++; + } + return i; + } + }catch (e) { + return 0; + } + }, + + /** + * 将数组或对象内容部分拼成字符串 + * @param obj + * @returns {string} + */ + objImplode(obj) { + if (obj === null) { + return ""; + } + let str = ""; + $A.each(obj, (val) => { + if (val !== null) { + if (typeof val === "object" && this.count(val) > 0) { + str += this.objImplode(val); + } else { + str += String(val); + } + } + }); + return str.replace(/\s/g, "").replace(/undefined/g, ""); + }, + + /** + * 指定键获取url参数 + * @param key + * @returns {*} + */ + urlParameter(key) { + let params = this.urlParameterAll(); + return typeof key === "undefined" ? params : params[key]; + }, + + urlParameterAll() { + let search = window.location.search || ""; + let arr = []; + if (this.strExists(search, "?")) { + arr = this.getMiddle(search, "?").split("&"); + } + let params = {}; + for (const element of arr) { + let data = element.split("="); + if (data.length === 2) { + params[data[0]] = data[1]; + } + } + return params; + }, + + /** + * 删除地址中的参数 + * @param url + * @param parameter + * @returns {string|*} + */ + removeURLParameter(url, parameter) { + if (parameter instanceof Array) { + parameter.forEach((key) => { + url = $A.removeURLParameter(url, key) + }); + return url; + } + let urlparts = url.split('?'); + if (urlparts.length >= 2) { + //参数名前缀 + let prefix = encodeURIComponent(parameter) + '='; + let pars = urlparts[1].split(/[&;]/g); + + //循环查找匹配参数 + for (let i = pars.length; i-- > 0;) { + if (pars[i].lastIndexOf(prefix, 0) !== -1) { + //存在则删除 + pars.splice(i, 1); + } + } + + return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : ''); + } + return url; + }, + + /** + * 连接加上参数 + * @param url + * @param params + * @returns {*} + */ + urlAddParams(url, params) { + if ($A.isJson(params)) { + if (url) { + url = this.removeURLParameter(url, Object.keys(params)) + } + url+= ""; + url+= url.indexOf("?") === -1 ? '?' : ''; + for (let key in params) { + if (!params.hasOwnProperty(key)) { + continue; + } + url+= '&' + key + '=' + params[key]; + } + } + return this.rightDelete(url.replace("?&", "?"), '?'); + }, + + /** + * 链接字符串 + * @param value 第一个参数为连接符 + * @returns {string} + */ + stringConnect(...value) { + let s = null; + let text = ""; + value.forEach((val) => { + if (s === null) { + s = val; + }else if (val){ + if (val && text) text+= s; + text+= val; + } + }); + return text; + }, + + /** + * 判断两个对象是否相等 + * @param x + * @param y + * @returns {boolean} + */ + objEquals(x, y) { + let f1 = x instanceof Object; + let f2 = y instanceof Object; + if (!f1 || !f2) { + return x === y + } + if (Object.keys(x).length !== Object.keys(y).length) { + return false + } + for (let p in x) { + if (x.hasOwnProperty(p)) { + let a = x[p] instanceof Object; + let b = y[p] instanceof Object; + if (a && b) { + if (!this.objEquals(x[p], y[p])) { + return false; + } + } else if (x[p] !== y[p]) { + return false; + } + } + } + return true; + }, + + /** + * 输入框内插入文本 + * @param object + * @param content + */ + insert2Input(object, content) { + if (object === null || typeof object !== "object") return; + if (typeof object.length === 'number' && object.length > 0) object = object[0]; + + let ele = typeof object.$el === "object" ? $A(object.$el) : $A(object); + if (ele.length === 0) return; + let eleDom = ele[0]; + + if (eleDom.tagName !== "INPUT" && eleDom.tagName !== "TEXTAREA") { + if (ele.find("input").length === 0) { + ele = ele.find("textarea"); + }else{ + ele = ele.find("input"); + } + } + if (ele.length === 0) return; + eleDom = ele[0]; + + if (eleDom.tagName !== "INPUT" && eleDom.tagName !== "TEXTAREA") return; + + let text = ele.val(); + let { selectionStart, selectionEnd } = eleDom; + + ele.val(`${text.substring(0, selectionStart)}${content}${text.substring(selectionEnd, text.length)}`); + eleDom.dispatchEvent(new Event('input')); + + setTimeout(() => { + if (eleDom.setSelectionRange) { + let pos = text.substring(0, selectionStart).length + content.length; + eleDom.focus(); + eleDom.setSelectionRange(pos, pos); + } + }, 10); + }, + + /** + * iOS上虚拟键盘引起的触控错位 + */ + iOSKeyboardFixer() { + if (!this.isIos()) { + return; + } + document.body.scrollTop = document.body.scrollTop + 1; + document.body.scrollTop = document.body.scrollTop - 1; + }, + + /** + * 动态加载js文件 + * @param url + * @param callback + */ + loadScript(url, callback) { + url = $A.originUrl(url); + if (this.rightExists(url, '.css')) { + this.loadCss(url, callback) + return; + } + if (this.__loadScript[url] === true) { + typeof callback === "function" && callback(null); + return; + } + let script = document.createElement("script"); + script.type = "text/javascript"; + if (script.readyState) { + script.onreadystatechange = () => { + if (script.readyState === "loaded" || script.readyState === "complete") { + script.onreadystatechange = null; + this.__loadScript[url] = true; + typeof callback === "function" && callback(null); + } + }; + } else { + script.onload = () => { + this.__loadScript[url] = true; + typeof callback === "function" && callback(null); + }; + script.onerror = (e) => { + typeof callback === "function" && callback(e); + }; + } + if (this.rightExists(url, '.js')) { + script.src = url + "?hash=" + window.systemInfo.version; + } else { + script.src = url; + } + document.body.appendChild(script); + }, + loadScriptS(urls, callback) { + let i = 0; + let recursiveCallback = () => { + if (++i < urls.length) { + this.loadScript(urls[i], recursiveCallback) + } else { + typeof callback === "function" && callback(null); + } + } + this.loadScript(urls[0], recursiveCallback); + }, + __loadScript: {}, + + /** + * 动态加载css + * @param url + * @param callback + */ + loadCss(url, callback) { + url = $A.originUrl(url); + if (this.rightExists(url, '.js')) { + this.loadScript(url, callback) + return; + } + if (this.__loadCss[url] === true) { + typeof callback === "function" && callback(null); + return; + } + let script = document.createElement('link'); + if (script.readyState) { + script.onreadystatechange = () => { + if (script.readyState === 'loaded' || script.readyState === 'complete') { + script.onreadystatechange = null; + this.__loadCss[url] = true; + typeof callback === "function" && callback(null); + + } + }; + } else { + script.onload = () => { + this.__loadCss[url] = true; + typeof callback === "function" && callback(null); + + }; + script.onerror = (e) => { + typeof callback === "function" && callback(e); + }; + } + script.rel = 'stylesheet'; + if (this.rightExists(url, '.css')) { + script.href = url + "?hash=" + window.systemInfo.version; + } else { + script.href = url; + } + document.getElementsByTagName('head').item(0).appendChild(script); + }, + loadCssS(urls, callback) { + let i = 0; + let recursiveCallback = () => { + if (++i < urls.length) { + this.loadCss(urls[i], recursiveCallback) + } else { + typeof callback === "function" && callback(null); + } + } + this.loadCss(urls[0], recursiveCallback); + }, + __loadCss: {}, + + /** + * 对象中有Date格式的转成指定格式 + * @param params + * @param format 默认格式:Y-m-d H:i:s + * @returns {*} + */ + date2string(params, format) { + if (params === null) { + return params; + } + if (typeof format === "undefined") { + format = "Y-m-d H:i:s"; + } + if (params instanceof Date) { + params = $A.formatDate(format, params); + } else if ($A.isJson(params)) { + params = Object.assign({}, params) + for (let key in params) { + if (!params.hasOwnProperty(key)) continue; + params[key] = $A.date2string(params[key], format); + } + } else if ($A.isArray(params)) { + params = Object.assign([], params) + params.forEach((val, index) => { + params[index] = $A.date2string(val, format); + }); + } + return params; + }, + + /** + * 字节转换 + * @param bytes + * @returns {string} + */ + bytesToSize(bytes) { + if (bytes === 0) return '0 B'; + let k = 1024; + let sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + let i = Math.floor(Math.log(bytes) / Math.log(k)); + if (typeof sizes[i] === "undefined") { + return '0 B'; + } + return $A.runNum((bytes / Math.pow(k, i)), 2) + ' ' + sizes[i]; + }, + + /** + * html代码转义 + * @param sHtml + * @returns {*} + */ + html2Escape(sHtml) { + if (!sHtml || sHtml === '') { + return ''; + } + return sHtml.replace(/[<>&"]/g, function (c) { + return {'<': '<', '>': '>', '&': '&', '"': '"'}[c]; + }); + }, + + /** + * 正则提取域名 + * @param weburl + * @returns {string|string} + */ + getDomain(weburl) { + let urlReg = /http(s)?:\/\/([^\/]+)/i; + let domain = (weburl + "").match(urlReg); + return ((domain != null && domain.length > 0) ? domain[2] : ""); + }, + + /** + * 滚动到View + * @param element + * @param options + */ + scrollToView(element, options) { + if (!element) { + return; + } + if (typeof options.scrollMode !== "undefined" && typeof window.scrollIntoView === "function") { + window.scrollIntoView(element, options) + return; + } + try { + element.scrollIntoView(options); + } catch (e) { + if (typeof window.scrollIntoView === "function") { + window.scrollIntoView(element, options) + } + } + } + }); + + /** + * ============================================================================= + * ******************************** storage ******************************** + * ============================================================================= + */ + $.extend({ + setStorage(key, value) { + return this.storage(key, value); + }, + + getStorage(key, def = null) { + let value = this.storage(key); + return value || def; + }, + + getStorageString(key, def = '') { + let value = this.storage(key); + return typeof value === "string" || typeof value === "number" ? value : def; + }, + + getStorageInt(key, def = 0) { + let value = this.storage(key); + return typeof value === "number" ? value : def; + }, + + getStorageBoolean(key, def = false) { + let value = this.storage(key); + return typeof value === "boolean" ? value : def; + }, + + getStorageArray(key, def = []) { + let value = this.storage(key); + return this.isArray(value) ? value : def; + }, + + getStorageJson(key, def = {}) { + let value = this.storage(key); + return this.isJson(value) ? value : def; + }, + + storage(key, value) { + if (!key) { + return; + } + let keyName = '__state__'; + if (key.substring(0, 5) === 'cache') { + keyName = '__state:' + key + '__'; + } + if (typeof value === 'undefined') { + return this.loadFromlLocal(key, '', keyName); + } else { + this.savaToLocal(key, value, keyName); + } + }, + + savaToLocal(key, value, keyName) { + try { + if (typeof keyName === 'undefined') keyName = '__seller__'; + let seller = window.localStorage[keyName]; + if (!seller) { + seller = {}; + } else { + seller = JSON.parse(seller); + } + seller[key] = value; + window.localStorage[keyName] = JSON.stringify(seller); + } catch (e) { + } + }, + + loadFromlLocal(key, def, keyName) { + try { + if (typeof keyName === 'undefined') keyName = '__seller__'; + let seller = window.localStorage[keyName]; + if (!seller) { + return def; + } + seller = JSON.parse(seller); + if (!seller || typeof seller[key] === 'undefined') { + return def; + } + return seller[key]; + } catch (e) { + return def; + } + }, + }); + + /** + * ============================================================================= + * ********************************* ihttp ********************************* + * ============================================================================= + */ + $.extend({ + serializeObject(obj, parents) { + if (typeof obj === 'string') return obj; + let resultArray = []; + let separator = '&'; + parents = parents || []; + let newParents; + + function var_name(name) { + if (parents.length > 0) { + let _parents = ''; + for (let j = 0; j < parents.length; j++) { + if (j === 0) _parents += parents[j]; + else _parents += '[' + encodeURIComponent(parents[j]) + ']'; + } + return _parents + '[' + encodeURIComponent(name) + ']'; + } + else { + return encodeURIComponent(name); + } + } + + function var_value(value) { + return encodeURIComponent(value); + } + + for (let prop in obj) { + if (obj.hasOwnProperty(prop)) { + let toPush; + if (Array.isArray(obj[prop])) { + toPush = []; + for (let i = 0; i < obj[prop].length; i++) { + if (!Array.isArray(obj[prop][i]) && typeof obj[prop][i] === 'object') { + newParents = parents.slice(); + newParents.push(prop); + newParents.push(i + ''); + toPush.push($.serializeObject(obj[prop][i], newParents)); + } + else { + toPush.push(var_name(prop) + '[]=' + var_value(obj[prop][i])); + } + + } + if (toPush.length > 0) resultArray.push(toPush.join(separator)); + } + else if (obj[prop] === null) { + resultArray.push(var_name(prop) + '='); + } + else if (typeof obj[prop] === 'object') { + // Object, convert to named array + newParents = parents.slice(); + newParents.push(prop); + toPush = $.serializeObject(obj[prop], newParents); + if (toPush !== '') resultArray.push(toPush); + } + else if (typeof obj[prop] !== 'undefined' && obj[prop] !== '') { + // Should be string or plain value + resultArray.push(var_name(prop) + '=' + var_value(obj[prop])); + } + else if (obj[prop] === '') resultArray.push(var_name(prop)); + } + } + return resultArray.join(separator); + }, + + // Global Ajax Setup + globalAjaxOptions: {}, + ajaxSetup (options) { + if (options.type) options.method = options.type; + $.each(options, function (optionName, optionValue) { + $.globalAjaxOptions[optionName] = optionValue; + }); + }, + + // Ajax + _jsonpRequests: 0, + ihttp(options) { + let defaults = { + method: 'GET', + data: false, + async: true, + cache: true, + user: '', + password: '', + headers: {}, + xhrFields: {}, + statusCode: {}, + processData: true, + dataType: 'text', + contentType: 'application/x-www-form-urlencoded', + timeout: 0 + }; + let callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode']; + + + //For jQuery guys + if (options.type) options.method = options.type; + + // Merge global and defaults + $.each($.globalAjaxOptions, function (globalOptionName, globalOptionValue) { + if (callbacks.indexOf(globalOptionName) < 0) defaults[globalOptionName] = globalOptionValue; + }); + + // Function to run XHR callbacks and events + function fireAjaxCallback(eventName, eventData, callbackName) { + let a = arguments; + if (eventName) $(document).trigger(eventName, eventData); + if (callbackName) { + // Global callback + if (callbackName in $.globalAjaxOptions) $.globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]); + // Options callback + if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]); + } + } + + // Merge options and defaults + $.each(defaults, function (prop, defaultValue) { + if (!(prop in options)) options[prop] = defaultValue; + }); + + // Default URL + if (!options.url) { + options.url = window.location.toString(); + } + // Parameters Prefix + let paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?'; + + // UC method + let _method = options.method.toUpperCase(); + // Data to modify GET URL + if ((_method === 'GET' || _method === 'HEAD' || _method === 'OPTIONS' || _method === 'DELETE') && options.data) { + let stringData; + if (typeof options.data === 'string') { + // Should be key=value string + if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1]; + else stringData = options.data; + } + else { + // Should be key=value object + stringData = $.serializeObject(options.data); + } + if (stringData.length) { + options.url += paramsPrefix + stringData; + if (paramsPrefix === '?') paramsPrefix = '&'; + } + } + // JSONP + if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) { + + let callbackName = 'f7jsonp_' + Date.now() + ($._jsonpRequests++); + let abortTimeout; + let callbackSplit = options.url.split('callback='); + let requestUrl = callbackSplit[0] + 'callback=' + callbackName; + if (callbackSplit[1].indexOf('&') >= 0) { + let addVars = callbackSplit[1].split('&').filter(function (el) { + return el.indexOf('=') > 0; + }).join('&'); + if (addVars.length > 0) requestUrl += '&' + addVars; + } + + // Create script + let script = document.createElement('script'); + script.type = 'text/javascript'; + script.onerror = function () { + clearTimeout(abortTimeout); + fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror'); + fireAjaxCallback('ajaxComplete ajax:complete', {scripterror: true}, 'complete', null, 'scripterror'); + }; + script.src = requestUrl; + + // Handler + window[callbackName] = function (data) { + clearTimeout(abortTimeout); + fireAjaxCallback(undefined, undefined, 'success', data); + script.parentNode.removeChild(script); + script = null; + delete window[callbackName]; + }; + document.querySelector('head').appendChild(script); + + if (options.timeout > 0) { + abortTimeout = setTimeout(function () { + script.parentNode.removeChild(script); + script = null; + fireAjaxCallback(undefined, undefined, 'error', null, 'timeout'); + }, options.timeout); + } + + return; + } + + // Cache for GET/HEAD requests + if (_method === 'GET' || _method === 'HEAD' || _method === 'OPTIONS' || _method === 'DELETE') { + if (options.cache === false) { + options.url += (paramsPrefix + '_nocache=' + Date.now()); + } + } + + // Create XHR + let xhr = new XMLHttpRequest(); + + // Save Request URL + xhr.requestUrl = options.url; + xhr.requestParameters = options; + + // Open XHR + xhr.open(_method, options.url, options.async, options.user, options.password); + + // Create POST Data + let postData = null; + + if ((_method === 'POST' || _method === 'PUT' || _method === 'PATCH') && options.data) { + if (options.processData) { + let postDataInstances = [ArrayBuffer, Blob, Document, FormData]; + // Post Data + if (postDataInstances.indexOf(options.data.constructor) >= 0) { + postData = options.data; + } + else { + // POST Headers + let boundary = '---------------------------' + Date.now().toString(16); + + if (options.contentType === 'multipart\/form-data') { + xhr.setRequestHeader('Content-Type', 'multipart\/form-data; boundary=' + boundary); + } + else { + xhr.setRequestHeader('Content-Type', options.contentType); + } + postData = ''; + let _data = $.serializeObject(options.data); + if (options.contentType === 'multipart\/form-data') { + boundary = '---------------------------' + Date.now().toString(16); + _data = _data.split('&'); + let _newData = []; + for (const element of _data) { + _newData.push('Content-Disposition: form-data; name="' + element.split('=')[0] + '"\r\n\r\n' + element.split('=')[1] + '\r\n'); + } + postData = '--' + boundary + '\r\n' + _newData.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n'; + } + else { + postData = _data; + } + } + } + else { + postData = options.data; + } + + } + + // Additional headers + if (options.headers) { + $.each(options.headers, function (headerName, headerCallback) { + xhr.setRequestHeader(headerName, headerCallback); + }); + } + + // Check for crossDomain + if (typeof options.crossDomain === 'undefined') { + options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== window.location.host; + } + + if (!options.crossDomain) { + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + + if (options.xhrFields) { + $.each(options.xhrFields, function (fieldName, fieldValue) { + xhr[fieldName] = fieldValue; + }); + } + + let xhrTimeout; + // Handle XHR + xhr.onload = function (e) { + if (xhrTimeout) clearTimeout(xhrTimeout); + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) { + let responseData; + if (options.dataType === 'json') { + try { + responseData = JSON.parse(xhr.responseText); + fireAjaxCallback('ajaxSuccess ajax:success', {xhr: xhr}, 'success', responseData, xhr.status, xhr); + } + catch (err) { + console.error(err); + fireAjaxCallback('ajaxError ajax:error', { + xhr: xhr, + parseerror: true + }, 'error', xhr, 'parseerror'); + } + } + else { + responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response; + fireAjaxCallback('ajaxSuccess ajax:success', {xhr: xhr}, 'success', responseData, xhr.status, xhr); + } + } + else { + fireAjaxCallback('ajaxError ajax:error', {xhr: xhr}, 'error', xhr, xhr.status); + } + if (options.statusCode) { + if ($.globalAjaxOptions.statusCode && $.globalAjaxOptions.statusCode[xhr.status]) $.globalAjaxOptions.statusCode[xhr.status](xhr); + if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr); + } + fireAjaxCallback('ajaxComplete ajax:complete', {xhr: xhr}, 'complete', xhr, xhr.status); + }; + + xhr.onerror = function (e) { + if (xhrTimeout) clearTimeout(xhrTimeout); + fireAjaxCallback('ajaxError ajax:error', {xhr: xhr}, 'error', xhr, xhr.status); + fireAjaxCallback('ajaxComplete ajax:complete', {xhr: xhr, error: true}, 'complete', xhr, 'error'); + }; + + // Ajax start callback + fireAjaxCallback('ajaxStart ajax:start', {xhr: xhr}, 'start', xhr); + fireAjaxCallback(undefined, undefined, 'beforeSend', xhr); + + // Timeout + if (options.timeout > 0) { + xhr.onabort = function () { + if (xhrTimeout) clearTimeout(xhrTimeout); + }; + xhrTimeout = setTimeout(function () { + xhr.abort(); + fireAjaxCallback('ajaxError ajax:error', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout'); + fireAjaxCallback('ajaxComplete ajax:complete', { + xhr: xhr, + timeout: true + }, 'complete', xhr, 'timeout'); + }, options.timeout); + } + + // Send XHR + xhr.send(postData); + + // Return XHR object + return xhr; + } + }); + + /** + * ============================================================================= + * ***************************** ajaxc **************************** + * ============================================================================= + */ + $.extend({ + ajaxc(params) { + if (!params) return false; + if (typeof params.url === 'undefined') return false; + if (typeof params.data === 'undefined') params.data = {}; + if (typeof params.cache === 'undefined') params.cache = false; + if (typeof params.method === 'undefined') params.method = 'GET'; + if (typeof params.timeout === 'undefined') params.timeout = 30000; + if (typeof params.dataType === 'undefined') params.dataType = 'json'; + if (typeof params.before === 'undefined') params.before = () => { }; + if (typeof params.complete === 'undefined') params.complete = () => { }; + if (typeof params.after === 'undefined') params.after = () => { }; + if (typeof params.success === 'undefined') params.success = () => { }; + if (typeof params.error === 'undefined') params.error = () => { }; + if (typeof params.header == 'undefined') params.header = {}; + // + params.before(); + $A.ihttp({ + url: params.url, + data: params.data, + cache: params.cache, + headers: params.header, + method: params.method.toUpperCase(), + contentType: "OPTIONS", + crossDomain: true, + dataType: params.dataType, + timeout: params.timeout, + success: function (data, status, xhr) { + params.complete(); + params.success(data, status, xhr); + params.after(true); + }, + error: function (xhr, status) { + params.complete(); + params.error(xhr, status); + params.after(false); + } + }); + } + }); + + window.$A = $; +})(window, window.$ = window.jQuery = require('jquery')); diff --git a/src/utils/onlyofficeUtil.js b/src/utils/onlyofficeUtil.js new file mode 100644 index 0000000..8408e99 --- /dev/null +++ b/src/utils/onlyofficeUtil.js @@ -0,0 +1,22 @@ +export function handleDocType(fileType) { + let docType = ''; + let fileTypesDoc = [ + 'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps' + ]; + let fileTypesCsv = [ + 'csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx' + ]; + let fileTypesPPt = [ + 'fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx' + ]; + if (fileTypesDoc.includes(fileType)) { + docType = 'text' + } + if (fileTypesCsv.includes(fileType)) { + docType = 'spreadsheet' + } + if (fileTypesPPt.includes(fileType)) { + docType = 'presentation' + } + return docType; +} diff --git a/src/utils/web.js b/src/utils/web.js new file mode 100755 index 0000000..7ed7835 --- /dev/null +++ b/src/utils/web.js @@ -0,0 +1,757 @@ +/** + * 页面专用 + */ +(function (window) { + const $ = window.$A; + /** + * ============================================================================= + * ******************************* web extra ******************************* + * ============================================================================= + */ + $.extend({ + /** + * 接口地址 + * @param str + * @returns {string|string|*} + */ + apiUrl(str) { + if (str.substring(0, 2) === "//" || + str.substring(0, 7) === "http://" || + str.substring(0, 8) === "https://" || + str.substring(0, 6) === "ftp://" || + str.substring(0, 1) === "/") { + return str; + } + if (typeof window.systemInfo.apiUrl === "string") { + str = window.systemInfo.apiUrl + str; + } else { + str = window.location.origin + "/api/" + str; + } + while (str.indexOf("/../") !== -1) { + str = str.replace(/\/(((?!\/).)*)\/\.\.\//, "/") + } + return str + }, + + /** + * 服务地址 + * @param str + * @returns {string} + */ + originUrl(str) { + if (str.substring(0, 2) === "//" || + str.substring(0, 7) === "http://" || + str.substring(0, 8) === "https://" || + str.substring(0, 6) === "ftp://" || + str.substring(0, 1) === "/") { + return str; + } + if (typeof window.systemInfo.origin === "string") { + str = window.systemInfo.origin + str; + } else { + str = window.location.origin + "/" + str; + } + while (str.indexOf("/../") !== -1) { + str = str.replace(/\/(((?!\/).)*)\/\.\.\//, "/") + } + return str + }, + + /** + * 项目配置模板 + * @param project_id + * @returns {{showMy: boolean, showUndone: boolean, project_id, chat: boolean, showHelp: boolean, showCompleted: boolean, menuType: string, menuInit: boolean, completedTask: boolean}} + */ + projectParameterTemplate(project_id) { + return { + project_id, + menuInit: false, + menuType: 'column', + chat: false, + showMy: true, + showHelp: true, + showUndone: true, + showCompleted: false, + completedTask: false, + } + }, + + /** + * 格式化websocket的消息 + * @param data + */ + formatWebsocketMessageDetail(data) { + if ($A.isJson(data)) { + for (let key in data) { + if (!data.hasOwnProperty(key)) continue; + data[key] = $A.formatWebsocketMessageDetail(data[key]); + } + } else if ($A.isArray(data)) { + data.forEach((val, index) => { + data[index] = $A.formatWebsocketMessageDetail(val); + }); + } else if (typeof data === "string") { + data = data.replace(/\{\{RemoteURL\}\}/g, this.apiUrl('../')) + } + return data; + }, + + /** + * 格式化时间 + * @param date + * @returns {*|string} + */ + formatTime(date) { + let time = $A.Date(date, true), + string = ''; + if ($A.formatDate('Ymd') === $A.formatDate('Ymd', time)) { + string = $A.formatDate('H:i', time) + } else if ($A.formatDate('Y') === $A.formatDate('Y', time)) { + string = $A.formatDate('m-d', time) + } else { + string = $A.formatDate('Y-m-d', time) + } + return string || ''; + }, + + /** + * 小于9补0 + * @param val + * @returns {number|string} + */ + formatBit(val) { + val = +val + return val > 9 ? val : '0' + val + }, + + /** + * 秒转时间 + * @param second + * @returns {string} + */ + formatSeconds(second) { + let duration + let days = Math.floor(second / 86400); + let hours = Math.floor((second % 86400) / 3600); + let minutes = Math.floor(((second % 86400) % 3600) / 60); + let seconds = Math.floor(((second % 86400) % 3600) % 60); + if (days > 0) { + if (hours > 0) duration = days + "d," + this.formatBit(hours) + "h"; + else if (minutes > 0) duration = days + "d," + this.formatBit(minutes) + "min"; + else if (seconds > 0) duration = days + "d," + this.formatBit(seconds) + "s"; + else duration = days + "d"; + } + else if (hours > 0) duration = this.formatBit(hours) + ":" + this.formatBit(minutes) + ":" + this.formatBit(seconds); + else if (minutes > 0) duration = this.formatBit(minutes) + ":" + this.formatBit(seconds); + else if (seconds > 0) duration = this.formatBit(seconds) + "s"; + return duration; + }, + + /** + * 倒计时格式 + * @param date + * @param nowTime + * @returns {string|*} + */ + countDownFormat(date, nowTime) { + let time = Math.round(this.Date(date).getTime() / 1000) - nowTime; + if (time < 86400 * 7 && time > 0 ) { + return this.formatSeconds(time); + } else if (time < 0) { + return '-' + this.formatSeconds(time * -1); + } else if (time === 0) { + return 0 + 's'; + } + return this.formatTime(date) + }, + + /** + * 获取一些指定时间 + * @param str + * @param retInt + * @returns {*|string} + */ + getData(str, retInt = false) { + let now = new Date(); //当前日期 + let nowDayOfWeek = now.getDay(); //今天本周的第几天 + let nowDay = now.getDate(); //当前日 + let nowMonth = now.getMonth(); //当前月 + let nowYear = now.getYear(); //当前年 + nowYear += (nowYear < 2000) ? 1900 : 0; + let lastMonthDate = new Date(); //上月日期 + lastMonthDate.setDate(1); + lastMonthDate.setMonth(lastMonthDate.getMonth()-1); + let lastMonth = lastMonthDate.getMonth(); + let getQuarterStartMonth = () => { + let quarterStartMonth = 0; + if(nowMonth < 3) { + quarterStartMonth = 0; + } + if (2 < nowMonth && nowMonth < 6) { + quarterStartMonth = 3; + } + if (5 < nowMonth && nowMonth < 9) { + quarterStartMonth = 6; + } + if (nowMonth > 8) { + quarterStartMonth = 9; + } + return quarterStartMonth; + }; + let getMonthDays = (myMonth) => { + let monthStartDate = new Date(nowYear, myMonth, 1); + let monthEndDate = new Date(nowYear, myMonth + 1, 1); + return (monthEndDate - monthStartDate)/(1000 * 60 * 60 * 24); + }; + // + let time = now.getTime(); + switch (str) { + case '今天': + time = now; + break; + case '昨天': + time = now - 86400000; + break; + case '前天': + time = now - 86400000 * 2; + break; + case '本周': + time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek); + break; + case '本周结束': + time = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek)); + break; + case '上周': + time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 7); + break; + case '上周结束': + time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 1); + break; + case '本周2': + time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek + 1); + break; + case '本周结束2': + time = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek) + 1); + break; + case '上周2': + time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 7 + 1); + break; + case '上周结束2': + time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 1 + 1); + break; + case '本月': + time = new Date(nowYear, nowMonth, 1); + break; + case '本月结束': + time = new Date(nowYear, nowMonth, getMonthDays(nowMonth)); + break; + case '上个月': + time = new Date(nowYear, lastMonth, 1); + break; + case '上个月结束': + time = new Date(nowYear, lastMonth, getMonthDays(lastMonth)); + break; + case '本季度': + time = new Date(nowYear, getQuarterStartMonth(), 1); + break; + case '本季度结束': + let quarterEndMonth = getQuarterStartMonth() + 2; + time = new Date(nowYear, quarterEndMonth, getMonthDays(quarterEndMonth)); + break; + } + if (retInt === true) { + return time; + } + return $A.formatDate("Y-m-d", parseInt(time / 1000)) + }, + + /** + * 获取日期选择器的 shortcuts 模板参数 + * @returns {(*)[]|[{text, value(): [Date,*]},{text, value(): [Date,*]},{text, value(): [*,*]},{text, value(): [*,*]},{text, value(): [Date,*]},null,null]|(Date|*)[]} + */ + timeOptionShortcuts() { + const lastSecond = (e) => { + return $A.Date($A.formatDate("Y-m-d 23:59:29", Math.round(e / 1000))) + }; + return [{ + text: $A.L('今天'), + value() { + return [new Date(), lastSecond(new Date().getTime())]; + } + }, { + text: $A.L('明天'), + value() { + let e = new Date(); + e.setDate(e.getDate() + 1); + return [new Date(), lastSecond(e.getTime())]; + } + }, { + text: $A.L('本周'), + value() { + return [$A.getData('今天', true), lastSecond($A.getData('本周结束2', true))]; + } + }, { + text: $A.L('本月'), + value() { + return [$A.getData('今天', true), lastSecond($A.getData('本月结束', true))]; + } + }, { + text: $A.L('3天'), + value() { + let e = new Date(); + e.setDate(e.getDate() + 2); + return [new Date(), lastSecond(e.getTime())]; + } + }, { + text: $A.L('5天'), + value() { + let e = new Date(); + e.setDate(e.getDate() + 4); + return [new Date(), lastSecond(e.getTime())]; + } + }, { + text: $A.L('7天'), + value() { + let e = new Date(); + e.setDate(e.getDate() + 6); + return [new Date(), lastSecond(e.getTime())]; + } + }]; + }, + + /** + * 对话标签 + * @param dialog + * @returns {*[]} + */ + dialogTags(dialog) { + let tags = []; + if (dialog.type === 'group') { + if (['project', 'task'].includes(dialog.group_type) && $A.isJson(dialog.group_info)) { + if (dialog.group_type === 'task' && dialog.group_info.complete_at) { + tags.push({ + color: 'success', + text: '已完成' + }) + } + if (dialog.group_info.deleted_at) { + tags.push({ + color: 'red', + text: '已删除' + }) + } else if (dialog.group_info.archived_at) { + tags.push({ + color: 'default', + text: '已归档' + }) + } + } + } + return tags; + }, + + /** + * 对话完成 + * @param dialog + * @returns {*[]} + */ + dialogCompleted(dialog) { + return this.dialogTags(dialog).find(({color}) => color === 'success'); + }, + + /** + * 返回对话未读数量 + * @param dialog + * @returns {*|number} + */ + getDialogUnread(dialog) { + return dialog ? (dialog.unread || dialog.mark_unread || 0) : 0 + }, + }); + + /** + * ============================================================================= + * ***************************** iviewui assist **************************** + * ============================================================================= + */ + $.extend({ + // 加载器 + spinnerShow() { + $A.spinnerLoadNum++ + if ($A.spinnerLoadNum > 0) { + const spinner = document.getElementById("common-spinner"); + if (spinner) { + spinner.style.display = "block" + } + } + }, + + spinnerHide() { + $A.spinnerLoadNum-- + if ($A.spinnerLoadNum <= 0) { + const spinner = document.getElementById("common-spinner"); + if (spinner) { + spinner.style.display = "none" + } + } + }, + spinnerLoadNum: 0, + + // 弹窗 + modalConfig(config) { + if (typeof config === "undefined") { + config = {content: "Undefined"}; + } else if (typeof config === "string") { + config = {content: config}; + } + config.title = $A.L(config.title || (typeof config.render === 'undefined' ? '温馨提示' : '')); + config.content = $A.L(config.content || ''); + config.okText = $A.L(config.okText || '确定'); + config.cancelText = $A.L(config.cancelText || '取消'); + return config; + }, + + modalInput(config, millisecond = 0) { + if (millisecond > 0) { + setTimeout(() => { $A.modalInput(config) }, millisecond); + return; + } + if (typeof config === "string") config = {title:config}; + let inputId = "modalInput_" + $A.randomString(6); + const onOk = () => { + if (typeof config.onOk === "function") { + if (config.onOk(config.value, () => { + $A.Modal.remove(); + }) === true) { + $A.Modal.remove(); + } + } else { + $A.Modal.remove(); + } + }; + const onCancel = () => { + if (typeof config.onCancel === "function") { + config.onCancel(); + } + }; + $A.Modal.confirm({ + render: (h) => { + return h('div', [ + h('div', { + style: { + fontSize: '16px', + fontWeight: '500', + marginBottom: '20px', + } + }, $A.L(config.title)), + h('Input', { + props: { + value: config.value, + placeholder: $A.L(config.placeholder), + elementId: inputId, + }, + on: { + input: (val) => { + config.value = val; + }, + 'on-enter': (e) => { + $A(e.target).parents(".ivu-modal-body").find(".ivu-btn-primary").click(); + } + } + }) + ]) + }, + onOk, + onCancel, + loading: true, + okText: $A.L(config.okText || '确定'), + cancelText: $A.L(config.cancelText || '取消'), + }); + setTimeout(() => { + document.getElementById(inputId) && document.getElementById(inputId).focus(); + }); + }, + + modalConfirm(config, millisecond = 0) { + if (config === false) { + return; + } + if (millisecond > 0) { + setTimeout(() => { $A.modalConfirm(config) }, millisecond); + return; + } + $A.Modal.confirm($A.modalConfig(config)); + }, + + modalSuccess(config, millisecond = 0) { + if (config === false) { + return; + } + if (millisecond > 0) { + setTimeout(() => { $A.modalSuccess(config) }, millisecond); + return; + } + $A.Modal.success($A.modalConfig(config)); + }, + + modalInfo(config, millisecond = 0) { + if (config === false) { + return; + } + if (millisecond > 0) { + setTimeout(() => { $A.modalInfo(config) }, millisecond); + return; + } + $A.Modal.info($A.modalConfig(config)); + }, + + modalWarning(config, millisecond = 0) { + if (config === false) { + return; + } + if (millisecond > 0) { + setTimeout(() => { $A.modalWarning(config) }, millisecond); + return; + } + $A.Modal.warning($A.modalConfig(config)); + }, + + modalError(config, millisecond = 0) { + if (config === false) { + return; + } + if (millisecond > 0) { + setTimeout(() => { $A.modalError(config) }, millisecond); + return; + } + $A.Modal.error($A.modalConfig(config)); + }, + + modalAlert(msg) { + if (msg === false) { + return; + } + alert($A.L(msg)); + }, + + //提示 + messageSuccess(msg) { + $A.Message.success($A.L(msg)); + }, + + messageWarning(msg) { + $A.Message.warning($A.L(msg)); + }, + + messageError(msg) { + $A.Message.error($A.L(msg)); + }, + + //通知 + noticeConfig(config) { + if (typeof config === "undefined") { + config = {desc: "Undefined"}; + } else if (typeof config === "string") { + config = {desc: config}; + } + config.title = $A.L(config.title || (typeof config.render === 'undefined' ? '温馨提示' : '')); + config.desc = $A.L(config.desc || ''); + return config; + }, + + noticeSuccess(config) { + $A.Notice.success($A.noticeConfig(config)); + }, + + noticeWarning(config) { + $A.Notice.warning($A.noticeConfig(config)); + }, + + noticeError(config) { + if (typeof config === "string") { + config = { + desc: config, + duration: 6 + }; + } + $A.Notice.error($A.noticeConfig(config)); + }, + }); + + /** + * ============================================================================= + * ********************************** dark ********************************* + * ============================================================================= + */ + + $.extend({ + dark: { + utils: { + filter: '-webkit-filter: url(#dark-mode-filter) !important; filter: url(#dark-mode-filter) !important;', + reverseFilter: '-webkit-filter: url(#dark-mode-reverse-filter) !important; filter: url(#dark-mode-reverse-filter) !important;', + noneFilter: '-webkit-filter: none !important; filter: none !important;', + + addExtraStyle() { + try { + return ''; + } catch (e) { + return ''; + } + }, + + addStyle(id, tag, css) { + tag = tag || 'style'; + let doc = document, styleDom = doc.getElementById(id); + if (styleDom) return; + let style = doc.createElement(tag); + style.rel = 'stylesheet'; + style.id = id; + tag === 'style' ? style.innerHTML = css : style.href = css; + document.head.appendChild(style); + }, + + getClassList(node) { + return node.classList || []; + }, + + addClass(node, name) { + this.getClassList(node).add(name); + return this; + }, + + removeClass(node, name) { + this.getClassList(node).remove(name); + return this; + }, + + hasClass(node, name) { + return this.getClassList(node).contains(name); + }, + + hasElementById(eleId) { + return document.getElementById(eleId); + }, + + removeElementById(eleId) { + let ele = document.getElementById(eleId); + ele && ele.parentNode.removeChild(ele); + }, + }, + + createDarkFilter() { + if (this.utils.hasElementById('dark-mode-svg')) return; + let svgDom = ''; + let div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div'); + div.innerHTML = svgDom; + let frag = document.createDocumentFragment(); + while (div.firstChild) + frag.appendChild(div.firstChild); + document.head.appendChild(frag); + }, + + createDarkStyle() { + this.utils.addStyle('dark-mode-style', 'style', ` + @media screen { + html { + ${this.utils.filter} + } + + /* Default Reverse rule */ + img, + video, + iframe, + canvas, + :not(object):not(body) > embed, + object, + svg image, + [style*="background:url"], + [style*="background-image:url"], + [style*="background: url"], + [style*="background-image: url"], + [background], + twitterwidget, + .sr-reader, + .no-dark-mode, + .no-dark-mode-before:before, + .sr-backdrop { + ${this.utils.reverseFilter} + } + + [style*="background:url"] *, + [style*="background-image:url"] *, + [style*="background: url"] *, + [style*="background-image: url"] *, + input, + [background] *, + twitterwidget .NaturalImage-image { + ${this.utils.noneFilter} + } + + /* Text contrast */ + html { + text-shadow: 0 0 0 !important; + } + + /* Full screen */ + .no-filter, + :-webkit-full-screen, + :-webkit-full-screen *, + :-moz-full-screen, + :-moz-full-screen *, + :fullscreen, + :fullscreen * { + ${this.utils.noneFilter} + } + + /* Page background */ + html { + background: #fff !important; + } + ${this.utils.addExtraStyle()} + } + + @media print { + .no-print { + display: none !important; + } + }`); + }, + + enableDarkMode() { + if (!$A.isChrome()) { + return; + } + if (this.isDarkEnabled()) { + return + } + this.createDarkFilter(); + this.createDarkStyle(); + this.utils.addClass(document.body, "dark-mode-reverse") + }, + + disableDarkMode() { + if (!this.isDarkEnabled()) { + return + } + this.utils.removeElementById('dark-mode-svg'); + this.utils.removeElementById('dark-mode-style'); + this.utils.removeClass(document.body, "dark-mode-reverse") + }, + + autoDarkMode() { + let darkScheme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches + if (darkScheme) { + this.enableDarkMode() + } else { + this.disableDarkMode() + } + }, + + isDarkEnabled() { + return this.utils.hasClass(document.body, "dark-mode-reverse") + }, + } + }); + + window.$A = $; +})(window);