封装的DynamicCRM平台中最实用的JS工具类

包含了一个遮罩层的使用对象和一个通用的CRM平台JS操作对象。

使用示例:

常用的比如去除页面查找字段guid的'{}':commonUtil.delBrackets(commonUtil.getLookupId("xxx_xxxx"))
遮罩层使用方式:overflowLayer.open("耗时中...", toDo) :toDo为当前使用遮罩层的js方法名
注意使用遮罩层的js方法都需要加一个回调参数,在执行完耗时方法后调用:overflowLayer.close() 关闭
function toDo(callback) {
    console.log('开始审批(BPM)')
    if (!callback) {
        Xrm.Utility.confirmDialog("您将做一个耗时操作,是否确认?", function () {
            overflowLayer.open("操作执行中,请勿进行其他操作...", toDoM);
            return;
        })
    }
    else{
        //执行操作
        overflowLayer.close();
    }
}

通用commonUtil工具JS

  1 var isFirstDefineOverflowLayer = false;
  2 /**
  3  * 遮罩层的使用
  4  */
  5 var overflowLayer = overflowLayer || (function () {
  6     if (window == window.top) {
  7         return {
  8             open: function (msg) { },
  9             close: function () { },
 10             appendShadowCls: function () { },
 11             appendShadowDiv: function () { }
 12         };
 13     }
 14     isFirstDefineOverflowLayer = true;
 15     return {
 16         layerId: 'layer_shadow_in_top_window',
 17         /**
 18          * 打开遮罩层
 19          * @param {any} msg 遮罩层提示的信息
 20          */
 21         open: function (msg, callback) {
 22             $('#' + this.layerId + '_div', window.top.document).css('display', 'block');
 23             $('#' + this.layerId + '_msgDiv', window.top.document).css('display', 'block');
 24             $('#' + this.layerId + '_msg', window.top.document).text(msg);
 25             if (typeof callback === 'function') {
 26                 setTimeout(function () { callback(true); }, 100);// 中断JS线程让界面及时渲染
 27             }
 28         },
 29         /**
 30          * 关闭遮罩层
 31          */
 32         close: function () {
 33             $('#' + this.layerId + '_div', window.top.document).css('display', 'none');
 34             $('#' + this.layerId + '_msgDiv', window.top.document).css('display', 'none');
 35         },
 36         /**
 37          * 添加遮罩层样式至顶层页面 
 38          */
 39         appendShadowCls: function () {
 40             var doc = window.top.document;
 41             var shadowCssId = this.layerId + '_css';
 42             var shadowCss = doc.getElementById(shadowCssId);
 43             if (shadowCss) {
 44                 return;
 45             }
 46             var shadowDode = '.msgbox-shadow {position: fixed;left: 0;top: 0;right: 0;bottom: 0;background-color: #FFF;opacity: 0.8;z-index: 10000;}';
 47             var modalCode = '.msgbox-modal {position: fixed;top: 50%;left: 50%;opacity: 1;transform: translate(-50%, -50%);z-index: 10001;}';
 48             var style = doc.createElement('style');
 49             style.id = shadowCssId
 50             style.type = 'text/css';
 51             style.rel = 'stylesheet';
 52             //for Chrome Firefox Opera Safari
 53             style.appendChild(doc.createTextNode(shadowDode));
 54             style.appendChild(doc.createTextNode(modalCode));
 55             //for IE
 56             if (this.isIE()) {
 57                 style.styleSheet.cssText = shadowDode;
 58                 style.styleSheet.cssText = modalCode;
 59             }
 60             var head = doc.getElementsByTagName('head')[0];
 61             head.appendChild(style);
 62         },
 63         appendShadowDiv: function () {
 64             var doc = window.top.document;
 65             var shadowDivId = this.layerId + '_div';
 66             var shadowDiv = doc.getElementById(shadowDivId);
 67             if (shadowDiv) {
 68                 return;
 69             }
 70 
 71             var body = doc.getElementsByTagName('body')[0];
 72             var layerDiv = doc.createElement('div');
 73             body.appendChild(layerDiv);
 74             layerDiv.id = shadowDivId;
 75             layerDiv.classList.add('msgbox-shadow');
 76             var msgDiv = doc.createElement('div');
 77             msgDiv.id = this.layerId + '_msgDiv';
 78             body.appendChild(msgDiv);
 79             msgDiv.classList.add('msgbox-modal');
 80 
 81             msgDiv.style.textAlign = 'center';
 82             var img = doc.createElement('img');
 83             img.src = "/_imgs/processing_loader.gif";
 84             img.classList.add('ms-crm-inline-processing');
 85             msgDiv.appendChild(img);
 86             msgDiv.appendChild(document.createElement('br'));
 87             var msgText = doc.createElement('span');
 88             msgText.id = this.layerId + '_msg';
 89             msgText.style.fontSize = '20px';
 90             msgText.style.margin = '0px';
 91             msgText.style.padding = '0px';
 92             msgDiv.appendChild(msgText);
 93 
 94             layerDiv.style.display = 'none';
 95             msgDiv.style.display = 'none';
 96         },
 97         isIE: function () {
 98             var userAgent = navigator.userAgent;
 99             var isOpera = userAgent.indexOf("Opera") > -1; //判断是否Opera浏览器
100             return userAgent.indexOf("compatible") > -1
101                 && userAgent.indexOf("MSIE") > -1 && !isOpera; //判断是否IE浏览器
102         }
103     };
104 })();
105 
106 if (isFirstDefineOverflowLayer) {
107     overflowLayer.appendShadowCls(); // 添加CSS样式到document
108     overflowLayer.appendShadowDiv(); // 添加遮罩层到顶层document
109 }
110 
111 /**
112 * 封装常用CRM操作工具类
113 */
114 var commonUtil = (function () {
115     const BASE_URL = Xrm.Page.context.getClientUrl() + "/api/data/v8.2";
116     //是否本地
117     const IS_LOCAL = true;
118     /**
119      * 获取当前运行环境
120      */
121     const getEnvironment = function () {
122         if (Xrm.Page.context.getClientUrl().indexOf("Testf") >= 0)
123             return "1";//测试环境
124         else if (Xrm.Page.context.getClientUrl().indexOf("hwdms") >= 0)
125             return "2";//正式环境
126     }
127     /**
128      * 打开弹窗
129      */
130     const openDialog = function (page, params, cbfun, level, width, height, top) {
131         if (level == null || level == "")
132             level = 0;
133         if (width == null || width == "")
134             width = 1000;
135         if (height == null || height == "")
136             height = 550;
137         if (top == null || top == "")
138             top = -300;
139         var Clienturl = Xrm.Page.context.getClientUrl();
140         var URL = Clienturl + "/WebResources/" + page;
141         var DialogOption = new Xrm.DialogOptions;
142         DialogOption.width = width;
143         DialogOption.height = height;
144         DialogOption.top = top;
145         switch (level) {
146             case 0://0级子页面,即当前页面打开弹窗
147                 Xrm.Internal.openDialog(URL + "?Type=&data=" + params, DialogOption, null, null, cbfun);
148                 break;
149             case 1://1级子页面打开弹窗
150                 parent.Xrm.Internal.openDialog(URL + "?Type=&data=" + params, DialogOption, null, null, cbfun);
151                 break;
152         }
153     }
154     /**
155      * 根据查询URL执行查询操作
156      * @param {any} queryUrl  查询URL
157      * @param {any} callback  结果回调方法
158      * @param {any} async     是否异步查询,默认为true
159      * @param {int} maxRows   获取记录的最大条数,默认为空
160      */
161     const queryWithUrl = function (queryUrl, callback, async, maxRows) {
162         if (!queryUrl) {
163             callback && callback({ success: false, message: '参数queryUrl不可为空' })
164             return
165         }
166         var req = new XMLHttpRequest();
167         req.open("GET", BASE_URL + queryUrl, async !== false);
168         req.setRequestHeader("OData-MaxVersion", "4.0");
169         req.setRequestHeader("OData-Version", "4.0");
170         req.setRequestHeader("Accept", "application/json");
171         req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
172         req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"" + (maxRows ? (",odata.maxpagesize=" + maxRows) : ""));
173         req.onreadystatechange = function () {
174             if (this.readyState === 4) {
175                 req.onreadystatechange = null;
176                 let result = { success: false, message: this.statusText }
177                 if (this.status === 200) {
178                     result.success = true
179                     let data = JSON.parse(this.response)
180                     result.data = data.value || data
181                 } else {
182                     console.error(this.response)
183                 }
184                 callback && callback(result)
185             }
186         };
187         req.send();
188     }
189 
190     const createEntity = function (entitySetName, entityData, callback, async) {
191         if (!entitySetName) {
192             callback && callback({ success: false, message: '参数entitySetName不可为空' })
193             return
194         }
195         var req = new XMLHttpRequest();
196         req.open("POST", `${BASE_URL}/${entitySetName}`, async !== false);
197         req.setRequestHeader("OData-MaxVersion", "4.0");
198         req.setRequestHeader("OData-Version", "4.0");
199         req.setRequestHeader("Accept", "application/json");
200         req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
201         req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
202         req.onreadystatechange = function () {
203             let result = { success: false, message: this.responseText }
204             if (this.readyState === 4) {
205                 req.onreadystatechange = null;
206                 if (this.status === 204) {
207                     var uri = this.getResponseHeader("OData-EntityId");
208                     var regExp = /\(([^)]+)\)/;
209                     var matches = regExp.exec(uri);
210                     result.success = true
211                     result.data = { id: matches[1] }
212                 } else {
213                     console.error('----' + this.responseText)
214                 }
215             } else {
216                 console.error('==== ' + this.responseText)
217             }
218             callback && callback(result)
219         };
220         req.send(JSON.stringify(entityData));
221     }
222 
223     const updateEntity = function (entitySetName, entityId, entityData, callback, async) {
224         if (!entitySetName) {
225             callback && callback({ success: false, message: '参数entitySetName不可为空' })
226             return
227         }
228         var req = new XMLHttpRequest();
229         req.open("PATCH", `${BASE_URL}/${entitySetName}(${entityId})`, async !== false);
230         req.setRequestHeader("OData-MaxVersion", "4.0");
231         req.setRequestHeader("OData-Version", "4.0");
232         req.setRequestHeader("Accept", "application/json");
233         req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
234         req.onreadystatechange = function () {
235             let result = { success: false, message: this.statusText }
236             if (this.readyState === 4) {
237                 req.onreadystatechange = null;
238                 if (this.status === 204) {
239                     result.success = true
240                     result.data = { id: entityId }
241                 } else {
242                     console.error('----' + this.statusText)
243                 }
244             } else {
245                 console.error('==== ' + this.statusText)
246             }
247             callback && callback(result)
248         };
249         req.send(JSON.stringify(entityData));
250     }
251 
252     /**
253      * 根据业务实体集合名称及业务实体ID删除指定的记录
254      * @param {any} entitySetName 【必须】业务实体集合名称
255      * @param {any} entityId 【必须】业务实体ID
256      * @param {any} callback 【可选】回调方法,参数为:{success:true/false,message:null/具体错误信息}
257      * @param {any} async 【可选】是否异步操作,默认为true,传入false时则同步执行,否则按异常执行
258      */
259     const deleteEntity = function (entitySetName, entityId, callback, async) {
260         var req = new XMLHttpRequest();
261         req.open("DELETE", `${BASE_URL}/${entitySetName}(${entityId})`, async !== false);
262         req.setRequestHeader("Accept", "application/json");
263         req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
264         req.setRequestHeader("OData-MaxVersion", "4.0");
265         req.setRequestHeader("OData-Version", "4.0");
266         req.onreadystatechange = function () {
267             if (this.readyState === 4) {
268                 req.onreadystatechange = null;
269                 callback && callback({
270                     success: this.status === 204 || this.status === 1223,
271                     message: this.statusText
272                 })
273                 if (this.status !== 204 && this.status !== 1223) {
274                     console.error(this.response)
275                 }
276             }
277         };
278         req.send();
279     }
280     /**
281     * 通过实体id取得数据
282     */
283     const getEntityData = function (entity, id) {
284         var resultData = null;
285         var queryUrl = "/" + entity + "(" + commonUtil.delBrackets(id) + ")";
286         commonUtil.queryWithUrl(queryUrl,
287             (result) => {
288                 console.log("getEntityData", result)
289                 if (result != null && result.data != null)
290                     resultData = result.data;
291             }, false, 1);
292 
293         return resultData;
294     }
295     /**
296     * 通过查询url取得数据
297     */
298     const getEntityDatas = function (queryUrl) {
299         var resultData = null;
300         commonUtil.queryWithUrl(queryUrl, (result) => {
301             if (result && result.data && result.data.length) {
302                 resultData = result.data;
303             }
304         }, false);
305 
306         return resultData;
307     }
308     /**
309     * 在URL中解析ID
310     */
311     const getIdFromUrl = function () {
312         let objData = parseParams()
313         return objData['?_CreateFromId'] && decodeURIComponent(objData['?_CreateFromId'])
314     }
315     /**
316     * 解析URL传入的参数
317     */
318     const parseParams = function () {
319         var objData = {};
320         var vals = decodeURIComponent(getParameter("extraqs")).split("&");
321         for (var i = 0; i < vals.length; i++) {
322             var pr = vals[i].replace(/\+/g, " ").split("=");
323             if (pr.length != 2) {
324                 continue;
325             }
326             objData[pr[0]] = pr[1];
327         }
328         return objData;
329     }
330     /**
331     * 获取参数信息
332     * @param {any} param url参数
333     */
334     const getParameter = function (param) {
335         var query = window.top.location.search;
336         var iLen = param.length;
337         var iStart = query.indexOf(param);
338         if (iStart == -1)
339             return "";
340         iStart += iLen + 1;
341         var iEnd = query.indexOf("&", iStart);
342         if (iEnd == -1)
343             return query.substring(iStart);
344         return query.substring(iStart, iEnd);
345     }
398     /**
399     * 判断页面元素是否字段控件类型
400     * @param {any} control 控件对象
401     */
402     const controlIsAttribute = function (control) {
403         var controlType = control.getControlType();
404         return controlType != "iframe" && controlType != "webresource" && controlType != "subgrid";
405     }
406 
407     return {
408         /**
409          * 根据查询URL执行查询操作
410          * @param {any} queryUrl  查询URL
411          * @param {any} callback  结果回调方法
412          * @param {any} async     是否异步查询,默认为true
413          * @param {int} maxRows   获取记录的最大条数,默认为空
414          */
415         queryWithUrl: queryWithUrl,
416         /**
417          * 根据业务实体集合名称及业务实体ID删除指定的记录
418          * @param {any} entitySetName 【必须】业务实体集合名称
419          * @param {any} entityId 【必须】业务实体ID
420          * @param {any} callback 【可选】回调方法,参数为:{success:true/false,message:null/具体错误信息}
421          * @param {any} async 【可选】是否异步操作,默认为true,传入false时则同步执行,否则按异常执行
422          */
423         deleteEntity: deleteEntity,
424         /**
425          * 根据业务实体集合名称及业务实体数据创建新的记录
426          * @param {any} entitySetName 【必须】业务实体集合名称
427          * @param {any} entityData 【必须】业务实体数据
428          * @param {any} callback 【可选】回调方法,参数为:{success:true/false,message:null/具体错误信息}
429          * @param {any} async 【可选】是否异步操作,默认为true,传入false时则同步执行,否则按异常执行
430          */
431         createEntity: createEntity,
432         /**
433          * 根据业务实体集合名称及业务实体数据创建新的记录
434          * @param {any} entitySetName 【必须】业务实体集合名称
435          * @param {any} entityId 【必须】业务实体ID 
436          * @param {any} entityData 【必须】业务实体数据
437          * @param {any} callback 【可选】回调方法,参数为:{success:true/false,message:null/具体错误信息}
438          * @param {any} async 【可选】是否异步操作,默认为true,传入false时则同步执行,否则按异常执行
439          */
440         updateEntity: updateEntity,
441         /**
442          * 将传入的数值保留两位小数后返回
443          */
444         keep2DecimalPlace: (decimalValue) => {
445             if (!decimalValue || isNaN(decimalValue)) {
446                 return decimalValue
447             }
448             return Math.round(decimalValue * 100) / 100
449         },
450         /**
451          * 读取服务器时间
452          */
453         getServerTime: () => {
454             var xhr = null;
455             if (window.XMLHttpRequest) {
456                 xhr = new window.XMLHttpRequest();
457             } else { // ie
458                 xhr = new ActiveObject("Microsoft")
459             }
460             xhr.open("GET", "/", false)//false不可变
461             xhr.send(null);
462             return new Date(xhr.getResponseHeader("Date"))
463         },
464         /**
465          * 判断当前窗体是不是新建窗口
466          */
467         isCreateForm: () => { return Xrm.Page.ui.getFormType() === 1 },
468         /**
469          * 判断当前窗体是不是编辑窗口
470          */
471         isUpdateForm: () => { return Xrm.Page.ui.getFormType() === 2 },
472         /**
473          * 判断对象是否为字符串
474          */
475         isString: (obj) => { return Object.prototype.toString.call(obj) === "[object String]" },
476         /**
477          * 读取查询类型属性的id
478          */
479         getLookupId: (fieldName) => {
480             let attribute = Xrm.Page.getAttribute(fieldName)
481             if (!attribute) {
482                 Xrm.Utility.alertDialog(`不存在的属性【${fieldName}】,请传入正确的属性名`)
483                 return;
484             }
485             let fieldType = attribute.getAttributeType()
486             if (fieldType !== 'lookup') {
487                 Xrm.Utility.alertDialog(`属性【${fieldName}】不是查找类型的字段,不可使用getLookupId方法`)
488                 return
489             }
490             let lookupValue = attribute.getValue()
491             return lookupValue ? lookupValue[0].id : null
492         },
493         /**
494          * 读取查询类型属性的name
495          */
496         getLookupName: (fieldName) => {
497             let attribute = Xrm.Page.getAttribute(fieldName)
498             if (!attribute) {
499                 Xrm.Utility.alertDialog(`不存在的属性【${fieldName}】,请传入正确的属性名`)
500                 return;
501             }
502             let fieldType = attribute.getAttributeType()
503             if (fieldType !== 'lookup') {
504                 Xrm.Utility.alertDialog(`属性【${fieldName}】不是查找类型的字段,不可使用getLookupName方法`)
505                 return
506             }
507 
508             let lookupValue = attribute.getValue()
509             return lookupValue ? lookupValue[0].name : null
510         },
511         /**
512         * 设置Lookup类型的值
513         * @param {any} LookupAttribute lookup控件字段名
514         * @param {any} Type 实体类型
515         * @param {any} Id 设置值的Guid
516         * @param {any} Name 值 显示名称
517         */
518         setLookupValue: (LookupAttribute, Type, Id, Name) => {
519             var lookupReference = [];
520             lookupReference[0] = {};
521             lookupReference[0].id = Id;
522             lookupReference[0].entityType = Type;
523             lookupReference[0].name = Name;
524             Xrm.Page.getAttribute(LookupAttribute).setValue(lookupReference);
525         },
526         /**
527          * 取得登录角户角色
528          */
529         GetRoleNames: () => {
530             let roleNames = [];
531             let userId = Xrm.Page.context.getUserId();
532             let queryUrl = `/systemusers(${commonUtil.delBrackets(userId)})?$select=fullname&$expand=systemuserroles_association($select=name)`
533             commonUtil.queryWithUrl(queryUrl, (result) => {
534                 if (result.success) {
535                     result.data.systemuserroles_association.forEach(r => {
536                         roleNames.push(r.name);
537                     })
538                 }
539             }, false)
540             return roleNames;
541         },
542         /**
543          * 设置表单所有控件不可编辑
544          */
545         DisableALLControls: () => {
546             Xrm.Page.ui.controls.forEach(function (control, index) {
547                 if (controlIsAttribute(control)) {
548                     control.setDisabled(true);
549                 }
550             })
551         },
552         /**
553          * 删除传入字符串首尾的{}
554          */
555         delBrackets: (str) => {
556             if (!str) {
557                 return str;
558             }
559             return str.replace(/^\{|\}$/g, "").toUpperCase();
560         },
561         distinctArr: (arr, distinctKey) => {
562             const result = []
563             if (!arr || !arr.length) {
564                 return result
565             }
566             const obj = {}  // 标识是否存在相同的唯一标识
567             for (item of arr) {
568                 if (!obj[distinctKey ? item[distinctKey] : item]) {
569                     result.push(item)
570                     obj[distinctKey ? item[distinctKey] : item] = true
571                 }
572             }
573 
574             return result
575         },
576         /**
577         * 获取实体ObjectTypeCode
578         */
579         getObjectTypeCode:  ()=> {
580             var url = $("#crmContentPanel", window.top.document).attr("src");
581             var index = url.indexOf("etc=");
582             var objectTypeCode = url.substring(index + 4, index + 9);
583             return objectTypeCode
584         },
585         /**
586         * 获取数据Id
587         * @param {any} type 当前页面:0主页面 1子页面 2关联视图
588         */
589         getId: (type) =>{
590             var id = "";
591             switch ((type == null || type == "") ? 0 : type) {
592                 case 0://主页面获取
593                     id = Xrm.Page.data.entity.getId();
594                     break;
595                 case 1://从子页面获取
596                     id = Xrm.Page.context.getQueryStringParameters()._CreateFromId;
597                     break;
598                 case 2://从关联视图页面获取
599                     id = Xrm.Page.context.getQueryStringParameters().id;
600                     break;
601             }
602             return commonUtil.delBrackets(id);
603         },
604         /**
605         * 通过实体id获取实体数据
606         */
607         getEntityData: getEntityData,
608         /**
609         * 通过查询url获取相关实体数据
610         */
611         getEntityDatas: getEntityDatas,
612         /**
613         * 在URL中解析ID
614         */
615         getIdFromUrl: getIdFromUrl,
616         /*
617         * 解析URL传入的参数
618         * (自定义页面可用)
619         */
620         parseParams: parseParams,
621         /*
622         * 打开弹窗(自定义页面)
623         */
624         openDialog: openDialog,
625         /*
626         * 获取当前环境
627         */
628         getEnvironment: getEnvironment,
629         /**
630         * 激活按钮隐藏
631         */
632         isDisplayActivate: () => {
633             return false;
634         },
635         /**
636         * 停用按钮隐藏
637         */
638         isDisplayDeactivate: () => {
639             return false;
640         }, 669         /**
670         * 获取用户Id
671         */
672         GetUserId: () => {
673             var id = Xrm.Page.context.getUserId();
674             id = id.toString().replace("{", "").replace("}", "");
675 
676             return id;
677         }
678     }
679 })()

 

posted @ 2023-07-10 15:23  流浪阿丁  阅读(71)  评论(0编辑  收藏  举报