diy.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. (function () {
  2. // 解决火狐浏览器拖动新增tab
  3. document.body.ondrop = function (event) {
  4. event.preventDefault();
  5. event.stopPropagation();
  6. };
  7. // 默认数据
  8. var defaultData = {};
  9. // umeditor 实例
  10. var $umeditor = {};
  11. /***
  12. * 前端可视化diy
  13. * @constructor
  14. */
  15. function diyPhone(initalData, diyData, opts) {
  16. defaultData = initalData;
  17. this.init(diyData, opts);
  18. }
  19. diyPhone.prototype = {
  20. init: function (data, opts) {
  21. // 实例化Vue
  22. new Vue({
  23. el: '#app',
  24. data: {
  25. // diy数据
  26. diyData: data,
  27. // 当前选中的元素(下标)
  28. selectedIndex: -1,
  29. // 当前选中的diy元素
  30. curItem: {},
  31. // 外部数据
  32. opts: opts
  33. },
  34. error: '',
  35. methods: {
  36. /**
  37. * 新增Diy组件
  38. * @param key
  39. */
  40. onAddItem: function (key) {
  41. // 验证新增Diy组件
  42. if (!this.onCheckAddItem(key)) {
  43. return false;
  44. }
  45. // 复制默认diy组件数据
  46. var data = $.extend(true, {}, defaultData[key]);
  47. // 新增到diy列表数据
  48. this.diyData.items.push(data);
  49. // 编辑当前选中的元素
  50. this.onEditer(this.diyData.items.length - 1);
  51. },
  52. /**
  53. * 验证新增Diy组件
  54. * @param key
  55. */
  56. onCheckAddItem: function (key) {
  57. // 验证关注公众号组件只能存在一个
  58. if (key === 'officialAccount') {
  59. for (var index in this.diyData.items) {
  60. if (this.diyData.items.hasOwnProperty(index)) {
  61. var item = this.diyData.items[index];
  62. if (item.type === 'officialAccount') {
  63. layer.msg('该组件最多存在一个', {anim: 6});
  64. return false;
  65. }
  66. }
  67. }
  68. }
  69. return true;
  70. },
  71. /**
  72. * 拖动diy元素更新当前索引
  73. * @param e
  74. */
  75. onDragItemEnd: function (e) {
  76. this.onEditer(e.newIndex);
  77. },
  78. /**
  79. * 编辑当前选中的Diy元素
  80. * @param index
  81. */
  82. onEditer: function (index) {
  83. // 记录当前选中元素的索引
  84. this.selectedIndex = index;
  85. // 当前选中的元素数据
  86. this.curItem = this.selectedIndex === 'page' ? this.diyData.page
  87. : this.diyData.items[this.selectedIndex];
  88. // 注册编辑器事件
  89. this.initEditor();
  90. },
  91. /**
  92. * 删除diy元素
  93. * @param index
  94. */
  95. onDeleleItem: function (index) {
  96. var _this = this;
  97. layer.confirm('确定要删除吗?', function (layIdx) {
  98. _this.diyData.items.splice(index, 1);
  99. _this.selectedIndex = -1;
  100. layer.close(layIdx);
  101. });
  102. },
  103. /**
  104. * 编辑器:选择图片
  105. * @param source
  106. * @param index
  107. */
  108. onEditorSelectImage: function (source, index) {
  109. $.fileLibrary({
  110. type: 'image',
  111. done: function (images) {
  112. source[index] = images[0]['file_path'];
  113. }
  114. });
  115. },
  116. /**
  117. * 编辑器:重置颜色
  118. * @param holder
  119. * @param attribute
  120. * @param color
  121. */
  122. onEditorResetColor: function (holder, attribute, color) {
  123. holder[attribute] = color;
  124. },
  125. /**
  126. * 编辑器:删除data元素
  127. * @param index
  128. * @param selectedIndex
  129. */
  130. onEditorDeleleData: function (index, selectedIndex) {
  131. if (this.diyData.items[selectedIndex].data.length <= 1) {
  132. layer.msg('至少保留一个', {anim: 6});
  133. return false;
  134. }
  135. this.diyData.items[selectedIndex].data.splice(index, 1);
  136. },
  137. /**
  138. * 编辑器:添加data元素
  139. */
  140. onEditorAddData: function () {
  141. // 新增data数据
  142. var newDataItem = $.extend(true, {}, defaultData[this.curItem.type].data[0]);
  143. this.curItem.data.push(newDataItem);
  144. },
  145. /**
  146. * 注册编辑器事件
  147. */
  148. initEditor: function () {
  149. // 注册dom事件
  150. this.$nextTick(function () {
  151. // 销毁 umeditor 组件
  152. if ($umeditor.hasOwnProperty('key')) {
  153. $umeditor.destroy();
  154. }
  155. // 注册html组件
  156. this.editorHtmlComponent();
  157. // 富文本事件
  158. if (this.curItem.type === 'richText') {
  159. this.onRichText(this.curItem);
  160. }
  161. });
  162. },
  163. /**
  164. * 编辑器事件:html组件
  165. */
  166. editorHtmlComponent: function () {
  167. var $editor = $(this.$refs['diy-editor']);
  168. // 单/多选框
  169. $editor.find('input[type=checkbox], input[type=radio]').uCheck();
  170. // select组件
  171. // $editor.find('select').selected();
  172. },
  173. /**
  174. * 编辑器事件:拼团商品选择
  175. * @param item
  176. */
  177. onSelectGoods: function (item) {
  178. var uris = {
  179. goods: 'goods/lists&status=10',
  180. sharingGoods: 'sharing.goods/lists&status=10',
  181. bargainGoods: 'bargain.goods/lists&status=10',
  182. sharpGoods: 'sharp.goods/lists&status=10'
  183. };
  184. $.selectData({
  185. title: '选择商品',
  186. uri: uris[item.type],
  187. duplicate: false,
  188. dataIndex: 'goods_id',
  189. done: function (data) {
  190. data.forEach(function (itm) {
  191. item.data.push(itm)
  192. });
  193. },
  194. getExistData: function () {
  195. var existData = [];
  196. item.data.forEach(function (goods) {
  197. if (goods.hasOwnProperty('goods_id')) {
  198. existData.push(goods.goods_id);
  199. }
  200. });
  201. return existData;
  202. }
  203. });
  204. },
  205. /**
  206. * 选择线下门店
  207. * @param item
  208. */
  209. onSelectShop: function (item) {
  210. $.selectData({
  211. title: '选择门店',
  212. uri: 'shop/lists&status=1',
  213. duplicate: false,
  214. dataIndex: 'shop_id',
  215. done: function (data) {
  216. data.forEach(function (itm) {
  217. item.data.push(itm)
  218. });
  219. },
  220. getExistData: function () {
  221. var existData = [];
  222. item.data.forEach(function (shop) {
  223. if (shop.hasOwnProperty('shop_id')) {
  224. existData.push(shop.shop_id);
  225. }
  226. });
  227. return existData;
  228. }
  229. });
  230. },
  231. /**
  232. * 编辑器事件:富文本
  233. */
  234. onRichText: function (item) {
  235. $umeditor = UM.getEditor('ume-editor', {
  236. initialFrameWidth: 375,
  237. initialFrameHeight: 400
  238. });
  239. $umeditor.ready(function () {
  240. // 写入编辑器内容
  241. $umeditor.setContent(item.params.content);
  242. $umeditor.addListener('contentChange', function () {
  243. item.params.content = $umeditor.getContent();
  244. });
  245. });
  246. },
  247. /**
  248. * 提交后端保存
  249. * @returns {boolean}
  250. */
  251. onSubmit: function () {
  252. if (this.diyData.items.length <= 0) {
  253. layer.msg('至少存在一个组件', {anim: 6});
  254. return false;
  255. }
  256. $.post('', {data: JSON.stringify(this.diyData)}, function (result) {
  257. result.code === 1 ? $.show_success(result.msg, result.url)
  258. : $.show_error(result.msg);
  259. });
  260. }
  261. }
  262. });
  263. }
  264. };
  265. window.diyPhone = diyPhone;
  266. })(window);