addons.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. define([], function () {
  2. require.config({
  3. paths: {
  4. 'jquery-colorpicker': '../addons/ask/js/jquery.colorpicker.min',
  5. },
  6. shim: {
  7. 'jquery-colorpicker': {
  8. deps: ['jquery'],
  9. exports: '$.fn.extend'
  10. },
  11. }
  12. });
  13. require.config({
  14. paths: {
  15. 'jquery-colorpicker': '../addons/cms/js/jquery.colorpicker.min',
  16. 'jquery-autocomplete': '../addons/cms/js/jquery.autocomplete',
  17. 'jquery-tagsinput': '../addons/cms/js/jquery.tagsinput',
  18. 'clipboard': '../addons/cms/js/clipboard.min',
  19. },
  20. shim: {
  21. 'jquery-colorpicker': {
  22. deps: ['jquery'],
  23. exports: '$.fn.extend'
  24. },
  25. 'jquery-autocomplete': {
  26. deps: ['jquery'],
  27. exports: '$.fn.extend'
  28. },
  29. 'jquery-tagsinput': {
  30. deps: ['jquery', 'jquery-autocomplete', 'css!../addons/cms/css/jquery.tagsinput.min.css'],
  31. exports: '$.fn.extend'
  32. }
  33. }
  34. });
  35. require.config({
  36. paths: {
  37. 'nkeditor': '../addons/nkeditor/js/customplugin',
  38. 'nkeditor-core': '../addons/nkeditor/nkeditor.min',
  39. 'nkeditor-lang': '../addons/nkeditor/lang/zh-CN',
  40. },
  41. shim: {
  42. 'nkeditor': {
  43. deps: [
  44. 'nkeditor-core',
  45. 'nkeditor-lang'
  46. ]
  47. },
  48. 'nkeditor-core': {
  49. deps: [
  50. 'css!../addons/nkeditor/themes/black/editor.min.css',
  51. 'css!../addons/nkeditor/css/common.css'
  52. ],
  53. exports: 'window.KindEditor'
  54. },
  55. 'nkeditor-lang': {
  56. deps: [
  57. 'nkeditor-core'
  58. ]
  59. }
  60. }
  61. });
  62. require(['form'], function (Form) {
  63. var _bindevent = Form.events.bindevent;
  64. Form.events.bindevent = function (form) {
  65. _bindevent.apply(this, [form]);
  66. if ($(".editor", form).size() > 0) {
  67. require(['nkeditor', 'upload'], function (Nkeditor, Upload) {
  68. var getImageFromClipboard, getImageFromDrop, getFileFromBase64;
  69. getImageFromClipboard = function (data) {
  70. var i, item;
  71. i = 0;
  72. while (i < data.clipboardData.items.length) {
  73. item = data.clipboardData.items[i];
  74. if (item.type.indexOf("image") !== -1) {
  75. return item.getAsFile() || false;
  76. }
  77. i++;
  78. }
  79. return false;
  80. };
  81. getImageFromDrop = function (data) {
  82. var i, item, images;
  83. i = 0;
  84. images = [];
  85. while (i < data.dataTransfer.files.length) {
  86. item = data.dataTransfer.files[i];
  87. if (item.type.indexOf("image") !== -1) {
  88. images.push(item);
  89. }
  90. i++;
  91. }
  92. return images;
  93. };
  94. getFileFromBase64 = function (data, url) {
  95. var arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],
  96. bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  97. while (n--) {
  98. u8arr[n] = bstr.charCodeAt(n);
  99. }
  100. var filename, suffix;
  101. if (typeof url != 'undefined') {
  102. var urlArr = url.split('.');
  103. filename = url.substr(url.lastIndexOf('/') + 1);
  104. suffix = urlArr.pop();
  105. } else {
  106. filename = Math.random().toString(36).substring(5, 15);
  107. }
  108. if (!suffix) {
  109. suffix = data.substring("data:image/".length, data.indexOf(";base64"));
  110. }
  111. var exp = new RegExp("\\." + suffix + "$", "i");
  112. filename = exp.test(filename) ? filename : filename + "." + suffix;
  113. var file = new File([u8arr], filename, {type: mime});
  114. return file;
  115. };
  116. var getImageFromUrl = function (url, callback, outputFormat) {
  117. var canvas = document.createElement('CANVAS'),
  118. ctx = canvas.getContext('2d'),
  119. img = new Image;
  120. img.crossOrigin = 'Anonymous';
  121. img.onload = function () {
  122. var urlArr = url.split('.');
  123. var suffix = urlArr.pop();
  124. suffix = suffix.match(/^(jpg|png|gif|bmp|jpeg)$/i) ? suffix : 'png';
  125. try {
  126. canvas.height = img.height;
  127. canvas.width = img.width;
  128. ctx.drawImage(img, 0, 0);
  129. var dataURL = canvas.toDataURL(outputFormat || 'image/' + suffix);
  130. var file = getFileFromBase64(dataURL, url);
  131. } catch (e) {
  132. callback.call(this, null);
  133. }
  134. callback.call(this, file);
  135. canvas = null;
  136. };
  137. img.onerror = function (e) {
  138. callback.call(this, null);
  139. };
  140. img.src = Fast.api.fixurl("/addons/nkeditor/index/download") + "?url=" + encodeURIComponent(url);
  141. };
  142. //上传Word图片
  143. Nkeditor.uploadwordimage = function (index, image) {
  144. var that = this;
  145. (function () {
  146. var file = getFileFromBase64(image);
  147. var placeholder = new RegExp("##" + index + "##", "g");
  148. Upload.api.send(file, function (data) {
  149. that.html(that.html().replace(placeholder, Fast.api.cdnurl(data.url)));
  150. }, function (data) {
  151. that.html(that.html().replace(placeholder, ""));
  152. });
  153. }(index, image));
  154. };
  155. Nkeditor.lang({
  156. remoteimage: '下载远程图片'
  157. });
  158. //远程下载图片
  159. Nkeditor.plugin('remoteimage', function (K) {
  160. var editor = this, name = 'remoteimage';
  161. editor.plugin.remoteimage = {
  162. download: function (e) {
  163. var that = this;
  164. var html = that.html();
  165. var staging = {}, orgined = {}, index = 0, images = 0, completed = 0, failured = 0;
  166. var checkrestore = function () {
  167. if (completed + failured >= images) {
  168. $.each(staging, function (i, j) {
  169. that.html(that.html().replace("<code>" + i + "</code>", j));
  170. });
  171. }
  172. };
  173. html.replace(/<code>([\s\S]*?)<\/code>/g, function (code) {
  174. staging[index] = code;
  175. return "<code>" + index + "</code>";
  176. }
  177. );
  178. html = html.replace(/<img([\s\S]*?)\ssrc\s*=\s*('|")((http(s?):)([\s\S]*?))('|")([\s\S]*?)[\/]?>/g, function () {
  179. images++;
  180. var url = arguments[3];
  181. var placeholder = '<img src="' + Fast.api.cdnurl("/assets/addons/nkeditor/img/downloading.png") + '" data-index="' + index + '" />';
  182. //如果是云存储的链接,则忽略
  183. if (Config.upload.cdnurl && url.indexOf(Config.upload.cdnurl) > -1) {
  184. completed++;
  185. return arguments[0];
  186. } else {
  187. orgined[index] = arguments[0];
  188. }
  189. //下载远程图片
  190. (function (index, url, placeholder) {
  191. getImageFromUrl(url, function (file) {
  192. if (!file) {
  193. failured++;
  194. that.html(that.html().replace(placeholder, orgined[index]));
  195. checkrestore();
  196. } else {
  197. Upload.api.send(file, function (data) {
  198. completed++;
  199. that.html(that.html().replace(placeholder, '<img src="' + Fast.api.cdnurl(data.url) + '" />'));
  200. checkrestore();
  201. }, function (data) {
  202. failured++;
  203. that.html(that.html().replace(placeholder, orgined[index]));
  204. checkrestore();
  205. });
  206. }
  207. });
  208. })(index, url, placeholder);
  209. index++;
  210. return placeholder;
  211. });
  212. if (index > 0) {
  213. that.html(html);
  214. } else {
  215. Toastr.info("没有需要下载的远程图片");
  216. }
  217. }
  218. };
  219. // 点击图标时执行
  220. editor.clickToolbar(name, editor.plugin.remoteimage.download);
  221. });
  222. $(".editor", form).each(function () {
  223. var that = this;
  224. Nkeditor.create(that, {
  225. width: '100%',
  226. filterMode: false,
  227. wellFormatMode: false,
  228. allowMediaUpload: true, //是否允许媒体上传
  229. allowFileManager: true,
  230. allowImageUpload: true,
  231. fontSizeTable: ['9px', '10px', '12px', '14px', '16px', '18px', '21px', '24px', '32px'],
  232. wordImageServer: typeof Config.nkeditor != 'undefined' && Config.nkeditor.wordimageserver ? "127.0.0.1:10101" : "", //word图片替换服务器的IP和端口
  233. cssPath: Fast.api.cdnurl('/assets/addons/nkeditor/plugins/code/prism.css'),
  234. cssData: "body {font-size: 13px}",
  235. fillDescAfterUploadImage: false, //是否在上传后继续添加描述信息
  236. themeType: typeof Config.nkeditor != 'undefined' ? Config.nkeditor.theme : 'black', //编辑器皮肤,这个值从后台获取
  237. fileManagerJson: Fast.api.fixurl("/addons/nkeditor/index/attachment/module/" + Config.modulename),
  238. items: [
  239. 'source', 'undo', 'redo', 'preview', 'print', 'template', 'code', 'quote', 'cut', 'copy', 'paste',
  240. 'plainpaste', 'wordpaste', 'justifyleft', 'justifycenter', 'justifyright',
  241. 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
  242. 'superscript', 'clearhtml', 'quickformat', 'selectall',
  243. 'formatblock', 'fontname', 'fontsize', 'forecolor', 'hilitecolor', 'bold',
  244. 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', 'image', 'multiimage', 'graft',
  245. 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
  246. 'anchor', 'link', 'unlink', 'remoteimage', 'about', 'fullscreen'
  247. ],
  248. afterCreate: function () {
  249. var self = this;
  250. //Ctrl+回车提交
  251. Nkeditor.ctrl(document, 13, function () {
  252. self.sync();
  253. $(that).closest("form").submit();
  254. });
  255. Nkeditor.ctrl(self.edit.doc, 13, function () {
  256. self.sync();
  257. $(that).closest("form").submit();
  258. });
  259. //粘贴上传
  260. $("body", self.edit.doc).bind('paste', function (event) {
  261. var image, pasteEvent;
  262. pasteEvent = event.originalEvent;
  263. if (pasteEvent.clipboardData && pasteEvent.clipboardData.items) {
  264. image = getImageFromClipboard(pasteEvent);
  265. if (image) {
  266. event.preventDefault();
  267. Upload.api.send(image, function (data) {
  268. self.exec("insertimage", Fast.api.cdnurl(data.url));
  269. });
  270. }
  271. }
  272. });
  273. //挺拽上传
  274. $("body", self.edit.doc).bind('drop', function (event) {
  275. var image, pasteEvent;
  276. pasteEvent = event.originalEvent;
  277. if (pasteEvent.dataTransfer && pasteEvent.dataTransfer.files) {
  278. images = getImageFromDrop(pasteEvent);
  279. if (images.length > 0) {
  280. event.preventDefault();
  281. $.each(images, function (i, image) {
  282. Upload.api.send(image, function (data) {
  283. self.exec("insertimage", Fast.api.cdnurl(data.url));
  284. });
  285. });
  286. }
  287. }
  288. });
  289. },
  290. //FastAdmin自定义处理
  291. beforeUpload: function (callback, file) {
  292. var file = file ? file : $("input.ke-upload-file", this.form).prop('files')[0];
  293. Upload.api.send(file, function (data) {
  294. var data = {code: '000', data: {url: Fast.api.cdnurl(data.url)}, title: '', width: '', height: '', border: '', align: ''};
  295. callback(data);
  296. });
  297. },
  298. //错误处理 handler
  299. errorMsgHandler: function (message, type) {
  300. try {
  301. console.log(message, type);
  302. } catch (Error) {
  303. alert(message);
  304. }
  305. }
  306. });
  307. });
  308. });
  309. }
  310. }
  311. });
  312. if (Config.modulename == 'admin' && Config.controllername == 'index' && Config.actionname == 'index') {
  313. require.config({
  314. paths: {
  315. 'vue': "../addons/shopro/libs/vue",
  316. 'moment': "../addons/shopro/libs/moment",
  317. 'text': "../addons/shopro/libs/require-text",
  318. 'chat': '../addons/shopro/libs/chat',
  319. 'ELEMENT': '../addons/shopro/libs/element/element',
  320. },
  321. shim: {
  322. 'ELEMENT': {
  323. deps: ['css!../addons/shopro/libs/element/element.css']
  324. },
  325. },
  326. });
  327. require(['vue', 'jquery', 'chat', 'text!../addons/shopro/chat.html', 'ELEMENT', 'moment'], function (Vue, $, Chat, ChatTemp, ELEMENT, Moment) {
  328. Vue.use(ELEMENT);
  329. var wsUri;
  330. Fast.api.ajax({
  331. url: 'shopro/chat/index/init',
  332. loading: false,
  333. type: 'GET'
  334. }, function (ret, res) {
  335. if (res.data.config.type == 'shopro') {
  336. let wg = 'ws';
  337. if (res.data.config.system.is_ssl == 1) {
  338. wg = 'wss';
  339. }
  340. wsUri = wg + '://' + window.location.hostname + ':' + res.data.config.system.gateway_port;
  341. // 反向代理
  342. if (res.data.config.system.is_ssl == 1 && res.data.config.system.ssl_type == 'reverse_proxy') {
  343. wsUri = wg + '://' + window.location.hostname + '/websocket/';
  344. }
  345. $("body").append(`<div id="chatTemplateContainer" style="display:none"></div>
  346. <div id="chatService"><Chat :passvalue="obj"></Chat></div>`);
  347. $("#chatTemplateContainer").append(ChatTemp);
  348. new Vue({
  349. el: "#chatService",
  350. data() {
  351. return {
  352. obj: {
  353. commonWordsList: res.data.fast_reply,
  354. token: res.data.token,
  355. wsUri: wsUri,
  356. expire_time: res.data.expire_time,
  357. customer_service_id: res.data.customer_service.id,
  358. adminData: res.data,
  359. emoji_list: res.data.emoji
  360. }
  361. }
  362. }
  363. });
  364. }
  365. return false;
  366. }, function (ret, res) {
  367. if (res.msg == '') {
  368. return false;
  369. }
  370. })
  371. });
  372. }
  373. });