| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- export var camelToKebab = function (camelStr) {
- const isUpper = camelStr[0].charCodeAt(0) >= 65 && camelStr[0].charCodeAt(0) <= 90;
- const handleStr = camelStr.replace(/([A-Z])/g, "-$1").toLowerCase();
- let kebabStr = handleStr;
- if (isUpper) {
- kebabStr = handleStr.slice(1);
- }
- const newKebabArr = [];
- const kebabSplitArr = kebabStr.split("-");
- kebabSplitArr.forEach((item, index) => {
- if (item.length > 1) {
- newKebabArr.push(item);
- } else {
- let combineStr = "";
- const subKebabArr = kebabSplitArr.slice(index);
- for (let i = 0; i < subKebabArr.length; i++) {
- if (subKebabArr[i].length > 1)
- break;
- combineStr += subKebabArr[i];
- }
- newKebabArr.push(combineStr);
- kebabSplitArr.splice(index + 1, combineStr.length - 1);
- }
- });
- return newKebabArr.join("-");
- };
- export var isNum = function (num) {
- return typeof num === "number" && !isNaN(num);
- };
- export var toStyleStr = (styleObj, unit = "rpx") => {
- if (Array.isArray(styleObj)) {
- return styleObj.join(";");
- } else {
- if (typeof styleObj === "object" && styleObj !== null) {
- let style = [];
- for (const k in styleObj) {
- if (typeof k === "string") {
- let val = styleObj[k];
- if (val !== void 0) {
- if (typeof val === "number") {
- if (addUnitAttr.includes(k)) {
- val = val + unit;
- }
- }
- style.push(`${camelToKebab(k)}:${val}`);
- }
- }
- }
- return style.length > 0 ? style.join(";") + ";" : "";
- } else {
- return styleObj;
- }
- }
- };
- function isObject(value) {
- var type = typeof value;
- return value != null && (type == 'object' || type == 'function');
- }
- function toNumber(value) {
- if (typeof value == 'number') {
- return value;
- }
- if (isSymbol(value)) {
- return NAN;
- }
- if (isObject(value)) {
- var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
- value = isObject(other) ? (other + '') : other;
- }
- if (typeof value != 'string') {
- return value === 0 ? value : +value;
- }
- value = value.replace(reTrim, '');
- var isBinary = reIsBinary.test(value);
- return (isBinary || reIsOctal.test(value))
- ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
- : (reIsBadHex.test(value) ? NAN : +value);
- }
- export function debounce(func, wait, options) {
- var lastArgs,
- lastThis,
- maxWait,
- result,
- timerId,
- lastCallTime,
- lastInvokeTime = 0,
- leading = false,
- maxing = false,
- trailing = true;
- if (typeof func != 'function') {
- throw new TypeError(FUNC_ERROR_TEXT);
- }
- wait = toNumber(wait) || 0;
- if (isObject(options)) {
- leading = !!options.leading;
- maxing = 'maxWait' in options;
- maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
- trailing = 'trailing' in options ? !!options.trailing : trailing;
- }
- function invokeFunc(time) {
- var args = lastArgs,
- thisArg = lastThis;
- lastArgs = lastThis = undefined;
- lastInvokeTime = time;
- result = func.apply(thisArg, args);
- return result;
- }
- function leadingEdge(time) {
- // Reset any `maxWait` timer.
- lastInvokeTime = time;
- // Start the timer for the trailing edge.
- timerId = setTimeout(timerExpired, wait);
- // Invoke the leading edge.
- return leading ? invokeFunc(time) : result;
- }
- function remainingWait(time) {
- var timeSinceLastCall = time - lastCallTime,
- timeSinceLastInvoke = time - lastInvokeTime,
- timeWaiting = wait - timeSinceLastCall;
- return maxing
- ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
- : timeWaiting;
- }
- function shouldInvoke(time) {
- var timeSinceLastCall = time - lastCallTime,
- timeSinceLastInvoke = time - lastInvokeTime;
- // Either this is the first call, activity has stopped and we're at the
- // trailing edge, the system time has gone backwards and we're treating
- // it as the trailing edge, or we've hit the `maxWait` limit.
- return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
- (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
- }
- function timerExpired() {
- var time = now();
- if (shouldInvoke(time)) {
- return trailingEdge(time);
- }
- // Restart the timer.
- timerId = setTimeout(timerExpired, remainingWait(time));
- }
- function trailingEdge(time) {
- timerId = undefined;
- // Only invoke if we have `lastArgs` which means `func` has been
- // debounced at least once.
- if (trailing && lastArgs) {
- return invokeFunc(time);
- }
- lastArgs = lastThis = undefined;
- return result;
- }
- function cancel() {
- if (timerId !== undefined) {
- clearTimeout(timerId);
- }
- lastInvokeTime = 0;
- lastArgs = lastCallTime = lastThis = timerId = undefined;
- }
- function flush() {
- return timerId === undefined ? result : trailingEdge(now());
- }
- function debounced() {
- var time = now(),
- isInvoking = shouldInvoke(time);
- lastArgs = arguments;
- lastThis = this;
- lastCallTime = time;
- if (isInvoking) {
- if (timerId === undefined) {
- return leadingEdge(lastCallTime);
- }
- if (maxing) {
- // Handle invocations in a tight loop.
- timerId = setTimeout(timerExpired, wait);
- return invokeFunc(lastCallTime);
- }
- }
- if (timerId === undefined) {
- timerId = setTimeout(timerExpired, wait);
- }
- return result;
- }
- debounced.cancel = cancel;
- debounced.flush = flush;
- return debounced;
- }
- // 功能说明:统一处理后端可能返回的 {val}/{value} 结构,供组件内部字段适配复用 by xu 20260122
- export function normalizeMaybeVal(input) {
- if (input === undefined || input === null) return input;
- if (typeof input === "object") {
- if (Object.prototype.hasOwnProperty.call(input, "val")) return input.val;
- if (Object.prototype.hasOwnProperty.call(input, "value")) return input.value;
- }
- return input;
- }
- // 功能说明:缩略图 URL 构建(dlByHttp 直出图片),支持 thn 为字符串或 {val}/{value} by xu 20260122
- export function buildThumbUrl(thn) {
- const v = normalizeMaybeVal(thn);
- if (v === undefined || v === null || v === "") return "";
- return "/service?ssServ=dlByHttp&type=img&path=" + encodeURIComponent(String(v));
- }
- // 功能说明:统一按 fmt 动态格式化 {val, fmt}(支持任意组合 yyyy/MM/dd/HH/mm/ss),供卡片 tags/标题复用 by xu 20260122
- export function formatValByFmt(val, fmt) {
- try {
- if (!fmt || val === undefined || val === null || val === "") return val;
- const raw = typeof val === "string"
- ? val.replace(/[\u202f\u00a0]/g, " ").replace(/ /g, " ").trim()
- : val;
- const d = raw instanceof Date ? raw : new Date(raw);
- if (isNaN(d.getTime())) return val;
- const pad2 = (n) => String(n).padStart(2, "0");
- const tokens = {
- yyyy: String(d.getFullYear()),
- MM: pad2(d.getMonth() + 1),
- M: String(d.getMonth() + 1),
- dd: pad2(d.getDate()),
- d: String(d.getDate()),
- HH: pad2(d.getHours()),
- H: String(d.getHours()),
- mm: pad2(d.getMinutes()),
- m: String(d.getMinutes()),
- ss: pad2(d.getSeconds()),
- s: String(d.getSeconds()),
- };
- const f = String(fmt);
- if (!/(yyyy|MM|dd|HH|mm|ss|M|d|H|m|s)/.test(f)) return val;
- return f.replace(/yyyy|MM|dd|HH|mm|ss|M|d|H|m|s/g, (k) => tokens[k] ?? k);
- } catch (_) {
- return val;
- }
- }
- // 功能说明:解析 parm/param 参数(兼容 JSON 字符串、qs 字符串、对象) by xu 20260122
- export function parseParmLike(parmOrParam) {
- if (!parmOrParam) return {};
- if (typeof parmOrParam === "object") return parmOrParam;
- if (typeof parmOrParam !== "string") return {};
- const s = String(parmOrParam).trim();
- if (!s) return {};
- // JSON 格式
- if (s[0] === "{" || s[0] === "[") {
- try {
- const obj = JSON.parse(s);
- if (obj && typeof obj === "object") return obj;
- } catch (_) {}
- }
- // qs 格式(&a=b 或 a=b)
- return { __rawQs: s };
- }
- // 功能说明:追加查询参数到 URL(支持去重、数组值) by xu 20260122
- export function appendQueryParam(url, key, value) {
- if (!key) return url;
- if (value === undefined || value === null) return url;
- const s = String(value);
- if (s === "") return url;
- // 检查参数是否已存在
- const escapeRegExp = (str) => String(str || "").replace(/[.*+?^{}$()|[\]\\]/g, "\\$&");
- const hasParam = new RegExp("([?&])" + escapeRegExp(key) + "=").test(String(url || ""));
- if (hasParam) return url;
- const separator = url.indexOf("?") > -1 ? "&" : "?";
- return url + separator + encodeURIComponent(String(key)) + "=" + encodeURIComponent(s);
- }
- // 功能说明:从搜索字段列表和表单中提取参数(用于透传搜索条件到弹窗) by xu 20260122
- export function pickSearchParams(searchFieldList, form) {
- const params = {};
- if (!Array.isArray(searchFieldList) || !form) return params;
- searchFieldList.forEach((field) => {
- const key = field && field.name;
- if (!key) return;
- const value = form[key];
- if (value === undefined || value === null) return;
- if (Array.isArray(value)) {
- params[key] = value.filter((v) => v !== undefined && v !== null && v !== "");
- } else if (value !== "") {
- params[key] = value;
- }
- });
- return params;
- }
- // 功能说明:构建服务 URL(统一处理 ssToken/servName+dest+parm 三种模式) by xu 20260122
- export function buildServiceUrl(srv, options = {}) {
- if (!srv) return "";
- const { extraParams = {} } = options;
- let url = "";
- // 模式1:优先 ssToken
- const token = String(srv.ssToken || "").trim();
- if (token) {
- url = "/service?ssToken=" + encodeURIComponent(token);
- } else if (srv.servName) {
- // 模式2:servName + dest + parm
- url = "/service?ssServ=" + encodeURIComponent(String(srv.servName));
- if (srv.dest) url += "&ssDest=" + encodeURIComponent(String(srv.dest));
- // 解析 parm/param
- const parm = srv.parm !== undefined ? srv.parm : srv.param;
- const parsed = parseParmLike(parm);
- if (parsed.__rawQs) {
- // qs 格式直接拼接
- const qs = parsed.__rawQs;
- url += (qs.startsWith("&") ? "" : "&") + qs;
- } else {
- // 对象格式遍历拼接
- Object.entries(parsed).forEach(([k, v]) => {
- if (v === undefined || v === null) return;
- url += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(String(v));
- });
- }
- } else if (srv.dest) {
- // 模式3:仅 dest(报表场景)
- url = "/service?ssDest=" + encodeURIComponent(String(srv.dest));
- const parm = srv.parm !== undefined ? srv.parm : srv.param;
- const parsed = parseParmLike(parm);
- if (parsed.__rawQs) {
- const qs = parsed.__rawQs;
- url += (qs.startsWith("&") ? "" : "&") + qs;
- } else {
- Object.entries(parsed).forEach(([k, v]) => {
- if (v === undefined || v === null) return;
- url += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(String(v));
- });
- }
- }
- // 追加额外参数
- Object.entries(extraParams).forEach(([key, value]) => {
- if (Array.isArray(value)) {
- value.forEach((v) => {
- url = appendQueryParam(url, key, v);
- });
- } else {
- url = appendQueryParam(url, key, value);
- }
- });
- return url;
- }
- // 功能说明:打开服务弹窗(统一封装 wd.display.showComponent) by xu 20260122
- export function openServiceDialog(srv, options = {}) {
- if (!srv) return;
- const { extraParams = {}, onError = null } = options;
- const url = buildServiceUrl(srv, { extraParams });
- if (!url) return;
- try {
- window.wd.display.showComponent({
- show: ["wdDialog"],
- url,
- title: srv.title || srv.desc || "",
- width: srv.width,
- height: srv.height,
- minHeight: srv.minHeight,
- maxHeight: srv.maxHeight,
- showTitle: srv.showTitle,
- });
- } catch (error) {
- console.error("[openServiceDialog] failed:", error);
- if (onError) onError(error);
- }
- }
- // 功能说明:全局暴露工具函数,供 JSP 中的 Vue 实例使用 by xu 20260122
- if (typeof window !== "undefined") {
- window.ssTools = {
- normalizeMaybeVal,
- buildThumbUrl,
- formatValByFmt,
- parseParmLike,
- appendQueryParam,
- pickSearchParams,
- buildServiceUrl,
- openServiceDialog,
- };
- }
|