You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

common.js 16KB

5 maanden geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. // -------------------------- 通用常量 ---------------------------
  2. //OA门户网站用接口,配置默认服务器接口
  3. var OA_DOOR = {
  4. templateDataUrl: undefined, //正文模板列表接口
  5. templateBaseURL: undefined, //指定正文模板基础接口
  6. redHeadsPath: undefined, //默认红头模板列表获取路径
  7. getRedHeadPath: undefined, //默认获取红头文件路径
  8. bookmarkPath: undefined, //书签列表接口
  9. redHeadsPath: undefined, //默认红头模板列表获取路径
  10. }
  11. // -------------------------- 通用方法 ---------------------------
  12. //去除字符串左边空格
  13. String.prototype.ltrim = function () {
  14. return this.replace(/(^\s*)/g, "");
  15. }
  16. //去除字符串右边空格
  17. String.prototype.rtrim = function () {
  18. return this.replace(/(\s*$)/g, "");
  19. }
  20. //扩展js string endwith,startwith方法
  21. String.prototype.endWith = function (str) {
  22. if (str == null || str == "" || this.length == 0 || str.length > this.length)
  23. return false;
  24. if (this.substring(this.length - str.length) == str)
  25. return true;
  26. else
  27. return false;
  28. }
  29. String.prototype.startWith = function (str) {
  30. if (str == null || str == "" || this.length == 0 || str.length > this.length)
  31. return false;
  32. if (this.substr(0, str.length) == str)
  33. return true;
  34. else
  35. return false;
  36. }
  37. //UTF-16转UTF-8
  38. function utf16ToUtf8(s) {
  39. if (!s) {
  40. return;
  41. }
  42. var i, code, ret = [],
  43. len = s.length;
  44. for (i = 0; i < len; i++) {
  45. code = s.charCodeAt(i);
  46. if (code > 0x0 && code <= 0x7f) {
  47. //单字节
  48. //UTF-16 0000 - 007F
  49. //UTF-8 0xxxxxxx
  50. ret.push(s.charAt(i));
  51. } else if (code >= 0x80 && code <= 0x7ff) {
  52. //双字节
  53. //UTF-16 0080 - 07FF
  54. //UTF-8 110xxxxx 10xxxxxx
  55. ret.push(
  56. //110xxxxx
  57. String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)),
  58. //10xxxxxx
  59. String.fromCharCode(0x80 | (code & 0x3f))
  60. );
  61. } else if (code >= 0x800 && code <= 0xffff) {
  62. //三字节
  63. //UTF-16 0800 - FFFF
  64. //UTF-8 1110xxxx 10xxxxxx 10xxxxxx
  65. ret.push(
  66. //1110xxxx
  67. String.fromCharCode(0xe0 | ((code >> 12) & 0xf)),
  68. //10xxxxxx
  69. String.fromCharCode(0x80 | ((code >> 6) & 0x3f)),
  70. //10xxxxxx
  71. String.fromCharCode(0x80 | (code & 0x3f))
  72. );
  73. }
  74. }
  75. return ret.join('');
  76. }
  77. var Base64 = {
  78. _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  79. encode: function(e) {
  80. var t = "";
  81. var n, r, i, s, o, u, a;
  82. var f = 0;
  83. e = Base64._utf8_encode(e);
  84. while (f < e.length) {
  85. n = e.charCodeAt(f++);
  86. r = e.charCodeAt(f++);
  87. i = e.charCodeAt(f++);
  88. s = n >> 2;
  89. o = (n & 3) << 4 | r >> 4;
  90. u = (r & 15) << 2 | i >> 6;
  91. a = i & 63;
  92. if (isNaN(r)) {
  93. u = a = 64
  94. } else if (isNaN(i)) {
  95. a = 64
  96. }
  97. t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
  98. }
  99. return t
  100. },
  101. decode: function(e) {
  102. var t = "";
  103. var n, r, i;
  104. var s, o, u, a;
  105. var f = 0;
  106. e = e.replace(/[^A-Za-z0-9+/=]/g, "");
  107. while (f < e.length) {
  108. s = this._keyStr.indexOf(e.charAt(f++));
  109. o = this._keyStr.indexOf(e.charAt(f++));
  110. u = this._keyStr.indexOf(e.charAt(f++));
  111. a = this._keyStr.indexOf(e.charAt(f++));
  112. n = s << 2 | o >> 4;
  113. r = (o & 15) << 4 | u >> 2;
  114. i = (u & 3) << 6 | a;
  115. t = t + String.fromCharCode(n);
  116. if (u != 64) {
  117. t = t + String.fromCharCode(r)
  118. }
  119. if (a != 64) {
  120. t = t + String.fromCharCode(i)
  121. }
  122. }
  123. t = Base64._utf8_decode(t);
  124. return t
  125. },
  126. _utf8_encode: function(e) {
  127. e = e.replace(/rn/g, "n");
  128. var t = "";
  129. for (var n = 0; n < e.length; n++) {
  130. var r = e.charCodeAt(n);
  131. if (r < 128) {
  132. t += String.fromCharCode(r)
  133. } else if (r > 127 && r < 2048) {
  134. t += String.fromCharCode(r >> 6 | 192);
  135. t += String.fromCharCode(r & 63 | 128)
  136. } else {
  137. t += String.fromCharCode(r >> 12 | 224);
  138. t += String.fromCharCode(r >> 6 & 63 | 128);
  139. t += String.fromCharCode(r & 63 | 128)
  140. }
  141. }
  142. return t
  143. },
  144. _utf8_decode: function(e) {
  145. var t = "";
  146. var n = 0;
  147. var r = c1 = c2 = 0;
  148. while (n < e.length) {
  149. r = e.charCodeAt(n);
  150. if (r < 128) {
  151. t += String.fromCharCode(r);
  152. n++
  153. } else if (r > 191 && r < 224) {
  154. c2 = e.charCodeAt(n + 1);
  155. t += String.fromCharCode((r & 31) << 6 | c2 & 63);
  156. n += 2
  157. } else {
  158. c2 = e.charCodeAt(n + 1);
  159. c3 = e.charCodeAt(n + 2);
  160. t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
  161. n += 3
  162. }
  163. }
  164. return t
  165. }
  166. }
  167. //UTF-8转UTF-16
  168. function utf8ToUtf16(s) {
  169. if (!s) {
  170. return;
  171. }
  172. var i, codes, bytes, ret = [],
  173. len = s.length;
  174. for (i = 0; i < len; i++) {
  175. codes = [];
  176. codes.push(s.charCodeAt(i));
  177. if (((codes[0] >> 7) & 0xff) == 0x0) {
  178. //单字节 0xxxxxxx
  179. ret.push(s.charAt(i));
  180. } else if (((codes[0] >> 5) & 0xff) == 0x6) {
  181. //双字节 110xxxxx 10xxxxxx
  182. codes.push(s.charCodeAt(++i));
  183. bytes = [];
  184. bytes.push(codes[0] & 0x1f);
  185. bytes.push(codes[1] & 0x3f);
  186. ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1]));
  187. } else if (((codes[0] >> 4) & 0xff) == 0xe) {
  188. //三字节 1110xxxx 10xxxxxx 10xxxxxx
  189. codes.push(s.charCodeAt(++i));
  190. codes.push(s.charCodeAt(++i));
  191. bytes = [];
  192. bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf));
  193. bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f));
  194. ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1]));
  195. }
  196. }
  197. return ret.join('');
  198. }
  199. function currentTime() {
  200. var now = new Date();
  201. var year = now.getFullYear(); //年
  202. var month = now.getMonth() + 1; //月
  203. var day = now.getDate(); //日
  204. var hh = now.getHours(); //时
  205. var mm = now.getMinutes(); //分
  206. var ss = now.getSeconds();
  207. var clock = year + "";
  208. if (month < 10)
  209. clock += "0";
  210. clock += month + "";
  211. if (day < 10)
  212. clock += "0";
  213. clock += day + "";
  214. if (hh < 10)
  215. clock += "0";
  216. clock += hh + "";
  217. if (mm < 10) clock += '0';
  218. clock += mm;
  219. if (ss < 10) clock += '0';
  220. clock += ss;
  221. return (clock);
  222. }
  223. /**
  224. * 获取文件路径
  225. * @param {*} html 文件全称
  226. */
  227. function getHtmlURL(html) {
  228. //弹出辅助窗格框
  229. var GetUrlPath = ()=> {
  230. var e = document.location.toString();
  231. return -1 != (e = decodeURI(e)).indexOf("/") && (e = e.substring(0, e.lastIndexOf("/"))), e
  232. }
  233. var url = GetUrlPath();
  234. if (url.length != 0) {
  235. url = url.concat("/" + html);
  236. } else {
  237. url = url.concat("./" + html);
  238. }
  239. return url;
  240. }
  241. /**
  242. * wps内弹出web页面
  243. * @param {*} html 文件名
  244. * @param {*} title 窗口标题
  245. * @param {*} hight 窗口高
  246. * @param {*} width 窗口宽
  247. */
  248. function OnShowDialog(html, title, height, width, bModal) {
  249. var l_ActiveDoc = wps.WpsApplication().ActiveDocument;
  250. if (!l_ActiveDoc) {
  251. alert("WPS当前没有可操作文档!")
  252. return;
  253. }
  254. if (typeof bModal == "undefined" || bModal == null) {
  255. bModal = true;
  256. }
  257. width *= window.devicePixelRatio;
  258. height *= window.devicePixelRatio;
  259. var url = getHtmlURL(html);
  260. wps.ShowDialog(url, title, height, width, bModal);
  261. }
  262. /**
  263. * 解析返回response的参数
  264. * @param {*} resp
  265. * @return {*} body
  266. */
  267. function handleResultBody(resp) {
  268. var result = "";
  269. if (resp.Body) {
  270. // 解析返回response的参数
  271. }
  272. return result;
  273. }
  274. /**
  275. * 判断WPS中的文件个数是否为0,若为0则关闭WPS函数
  276. * @param {*} name
  277. */
  278. function closeWpsIfNoDocument() {
  279. var wpsApp = wps.WpsApplication();
  280. var docs = wpsApp.Documents;
  281. if (!docs || docs.Count == 0) {
  282. wps.ApiEvent.Cancel = true;
  283. //根据业务可以选择是否退出进程 wpsApp.Quit();
  284. }
  285. }
  286. function activeTab() {
  287. //启动WPS程序后,默认显示的工具栏选项卡为ribbon.xml中某一tab
  288. if (wps.ribbonUI)
  289. wps.ribbonUI.ActivateTab('WPSWorkExtTab');
  290. }
  291. function showOATab() {
  292. wps.PluginStorage.setItem("ShowOATabDocActive", pCheckIfOADoc()); //根据文件是否为OA文件来显示OA菜单
  293. wps.ribbonUI.Invalidate(); // 刷新Ribbon自定义按钮的状态
  294. }
  295. function getDemoTemplatePath() {
  296. var url = document.location.toString();
  297. url = decodeURI(url);
  298. if (url.indexOf("/") != -1) {
  299. url = url.substring(0, url.lastIndexOf("/"));
  300. }
  301. if (url.length !== 0)
  302. url = url.concat("/template/红头文件.docx");
  303. if (url.startsWith("file:///"))
  304. url = url.substr("file:///".length);
  305. return url;
  306. }
  307. function getDemoSealPath() {
  308. var url = document.location.toString();
  309. url = decodeURI(url);
  310. if (url.indexOf("/") != -1) {
  311. url = url.substring(0, url.lastIndexOf("/"));
  312. }
  313. if (url.length !== 0)
  314. url = url.concat("/template/OA模板:公章.png");
  315. if (url.startsWith("file:///"))
  316. url = url.substr("file:///".length);
  317. return url;
  318. }
  319. function pGetParamName(data, attr) {
  320. var start = data.indexOf(attr);
  321. data = data.substring(start + attr.length);
  322. return data;
  323. }
  324. /**
  325. * 从requst中获取文件名(确保请求中有filename这个参数)
  326. * @param {*} request
  327. * @param {*} url
  328. */
  329. function pGetFileName(request, url) {
  330. var disposition = request.getResponseHeader("Content-Disposition");
  331. var filename = "";
  332. if (disposition) {
  333. var matchs = pGetParamName(disposition, "filename=");
  334. if (matchs) {
  335. filename = decodeURIComponent(matchs);
  336. } else {
  337. filename = "petro" + Date.getTime();
  338. }
  339. } else {
  340. filename = url.substring(url.lastIndexOf("/") + 1);
  341. filename=filename.split("?")[0]
  342. }
  343. return filename;
  344. }
  345. function StringToUint8Array(string) {
  346. var binLen, buffer, chars, i, _i;
  347. binLen = string.length;
  348. buffer = new ArrayBuffer(binLen);
  349. chars = new Uint8Array(buffer);
  350. for (var i = 0; i < binLen; ++i) {
  351. chars[i] = String.prototype.charCodeAt.call(string, i);
  352. }
  353. return buffer;
  354. }
  355. /**
  356. * WPS下载文件到本地打开(业务系统可根据实际情况进行修改)
  357. * @param {*} url 文件流的下载路径
  358. * @param {*} callback 下载后的回调
  359. */
  360. function DownloadFile(url, callback) {
  361. var xhr = new XMLHttpRequest();
  362. xhr.onreadystatechange = function () {
  363. if (this.readyState == 4 && this.status == 200) {
  364. //需要业务系统的服务端在传递文件流时,确保请求中的参数有filename
  365. var fileName = pGetFileName(xhr, url)
  366. //落地打开模式下,WPS会将文件下载到本地的临时目录,在关闭后会进行清理
  367. var path = wps.Env.GetTempPath() + "/" + fileName
  368. var reader = new FileReader();
  369. reader.onload = function () {
  370. wps.FileSystem.writeAsBinaryString(path, reader.result);
  371. callback(path);
  372. };
  373. reader.readAsBinaryString(xhr.response);
  374. }
  375. }
  376. xhr.open('GET', url);
  377. xhr.responseType = 'blob';
  378. xhr.send();
  379. }
  380. /**
  381. * WPS上传文件到服务端(业务系统可根据实际情况进行修改,为了兼容中文,服务端约定用UTF-8编码格式)
  382. * @param {*} strFileName 上传到服务端的文件名称(包含文件后缀)
  383. * @param {*} strPath 上传文件的文件路径(文件在操作系统的绝对路径)
  384. * @param {*} uploadPath 上传文件的服务端地址
  385. * @param {*} strFieldName 业务调用方自定义的一些内容可通过此字段传递,默认赋值'file'
  386. * @param {*} OnSuccess 上传成功后的回调
  387. * @param {*} OnFail 上传失败后的回调
  388. */
  389. function UploadFile(strFileName, strPath, uploadPath, strFieldName, OnSuccess, OnFail) {
  390. var xhr = new XMLHttpRequest();
  391. xhr.open('POST', uploadPath);
  392. var fileData = wps.FileSystem.readAsBinaryString(strPath);
  393. var data = new FakeFormData();
  394. if (strFieldName == "" || typeof strFieldName == "undefined"){//如果业务方没定义,默认设置为'file'
  395. strFieldName = 'file';
  396. }
  397. data.append(strFieldName, {
  398. name: utf16ToUtf8(strFileName), //主要是考虑中文名的情况,服务端约定用utf-8来解码。
  399. type: "application/octet-stream",
  400. getAsBinary: function () {
  401. return fileData;
  402. }
  403. });
  404. xhr.onreadystatechange = function () {
  405. if (xhr.readyState == 4) {
  406. if (xhr.status == 200)
  407. OnSuccess(xhr.response)
  408. else
  409. OnFail(xhr.response);
  410. }
  411. };
  412. xhr.setRequestHeader("Cache-Control", "no-cache");
  413. xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  414. if (data.fake) {
  415. xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.boundary);
  416. var arr = StringToUint8Array(data.toString());
  417. xhr.send(arr);
  418. } else {
  419. xhr.send(data);
  420. }
  421. }
  422. /**
  423. * 打开WPS后通知到业务系统,可根据需求扩展
  424. * @param {*} p_Url 业务方接受请求的地址
  425. */
  426. function NotifyToServer(p_Url) {
  427. $.ajax({
  428. url: p_Url, // URL + '/wps/wpsCanOpen',
  429. async: true,
  430. method: "post",
  431. dataType: 'json'
  432. });
  433. }
  434. /**
  435. * 更新编辑状态
  436. * @param {*} p_Url 要传入OA端,通知业务系统,当前文档所处的编辑状态的URL地址路径
  437. * @param {*} p_OpenUrl 当前文档从业务系统打开时的入口URL,这个URL包含业务系统开发者需要传入的ID等参数
  438. * @param {*} docId 文档id
  439. * @param {*} state 0-正在编辑中 1-文件保存 2-文件关闭 状态可根据需要进行自定义扩展
  440. */
  441. function UpdateEditState(p_Url, p_OpenUrl, docId, state) {
  442. var formData = {
  443. "openUrl": p_OpenUrl,
  444. "docId": docId,
  445. "state": state
  446. };
  447. $.ajax({
  448. url: p_Url, //URL + '/document/stateMonitor',
  449. async: false,
  450. data: formData,
  451. method: "post",
  452. dataType: 'json',
  453. success: function (response) {
  454. if (response == "success") {
  455. console.log(response);
  456. }
  457. },
  458. error: function (response) {
  459. console.log(response);
  460. }
  461. });
  462. }
  463. /**
  464. * 作用:判断文档关闭后,如果系统已经没有打开的文档了,则设置回初始用户名
  465. */
  466. function pSetWPSAppUserName() {
  467. //文档全部关闭的情况下,把WPS初始启动的用户名设置回去
  468. if (wps.WpsApplication().Documents.Count == 1) {
  469. var l_strUserName = wps.PluginStorage.getItem(constStrEnum.WPSInitUserName);
  470. wps.WpsApplication().UserName = l_strUserName;
  471. }
  472. }
  473. /**
  474. * 设置文档参数的属性值
  475. * @param {*} Doc
  476. * @param {*} Key
  477. * @param {*} Value
  478. */
  479. function SetDocParamsValue(Doc, Key, Value) {
  480. if (!Doc || !Key) {
  481. return;
  482. }
  483. var l_Params = wps.PluginStorage.getItem(Doc.DocID);
  484. if (!l_Params) {
  485. return;
  486. }
  487. var l_objParams = JSON.parse(l_Params);
  488. if (!(typeof(l_objParams) == "undefined")) {
  489. l_objParams[Key] = Value;
  490. }
  491. //把属性值整体再写回原来的文档ID中
  492. wps.PluginStorage.setItem(Doc.DocID, JSON.stringify(l_objParams));
  493. }