menu.index.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. {extend name='extra@admin/content'}
  2. {block name="style"}
  3. <style>
  4. .mobile-preview {
  5. -moz-user-select: none;
  6. -webkit-user-select: none;
  7. -ms-user-select: none;
  8. -khtml-user-select: none;
  9. user-select: none;
  10. }
  11. .menu-editor {
  12. left: 317px;
  13. display: block;
  14. max-width: 500px;
  15. width: 500px;
  16. height: 580px;
  17. border-radius: 0;
  18. border-color: #e7e7eb;
  19. box-shadow: none
  20. }
  21. .menu-editor .arrow {
  22. top: auto !important;
  23. bottom: 15px
  24. }
  25. .menu-editor .popover-title {
  26. margin-top: 0
  27. }
  28. .menu-delete {
  29. font-weight: 400;
  30. font-size: 12px;
  31. }
  32. .menu-submit {
  33. margin-right: 10px
  34. }
  35. </style>
  36. {/block}
  37. {block name='content'}
  38. <div class='mobile-preview pull-left'>
  39. <div class='mobile-header'>公众号</div>
  40. <div class='mobile-body'></div>
  41. <ul class='mobile-footer'>
  42. <!--{foreach $list as $menu}-->
  43. <li class="parent-menu">
  44. <a>
  45. <i class="icon-sub hide"></i>
  46. <span data-type="{$menu.type}" data-content="{$menu.content}">{$menu.name}</span>
  47. </a>
  48. <div class="sub-menu text-center hide">
  49. <ul>
  50. <!--{if empty($menu['sub']) eq false}-->
  51. <!--{foreach $menu.sub as $submenu}-->
  52. <li>
  53. <a class="bottom-border">
  54. <span data-type="{$submenu.type}" data-content="{$submenu.content}">{$submenu.name}</span>
  55. </a>
  56. </li>
  57. <!--{/foreach}-->
  58. <!--{/if}-->
  59. <li class="menu-add"><a><i class="icon-add"></i></a></li>
  60. </ul>
  61. <i class="arrow arrow_out"></i>
  62. <i class="arrow arrow_in"></i>
  63. </div>
  64. </li>
  65. <!--{/foreach}-->
  66. <li class="parent-menu menu-add">
  67. <a><i class="icon-add"></i></a>
  68. </li>
  69. </ul>
  70. </div>
  71. <div class="pull-left" style="position:absolute">
  72. <div class="popover fade right up in menu-editor">
  73. <div class="arrow"></div>
  74. <h3 class="popover-title">
  75. 菜单名称
  76. {if auth("$classuri/edit")}
  77. <a class="pull-right menu-delete">删除</a>
  78. {/if}
  79. </h3>
  80. <div class="popover-content menu-content"></div>
  81. </div>
  82. </div>
  83. <div class="hide menu-editor-parent-tpl">
  84. <form class="form-horizontal">
  85. <p>已添加子菜单,仅可设置菜单名称。</p>
  86. <div class="form-group" style="margin-top:50px">
  87. <label class="col-xs-3 control-label">菜单名称</label>
  88. <div class="col-xs-6">
  89. <input name="menu-name" class="form-control input-sm">
  90. <span class="help-block m-b-none">字数不超过5个汉字或16个字母</span>
  91. </div>
  92. </div>
  93. </form>
  94. </div>
  95. <div class="hide menu-editor-content-tpl">
  96. <form class="form-horizontal">
  97. <div class="form-group" style="margin-top:50px">
  98. <label class="col-xs-3 control-label">菜单名称</label>
  99. <div class="col-xs-6">
  100. <input name="menu-name" class="form-control input-sm">
  101. <span class="help-block m-b-none">字数不超过13个汉字或40个字母</span>
  102. </div>
  103. </div>
  104. <div class="form-group" style="margin-top:30px">
  105. <label class="col-xs-3 control-label">菜单内容</label>
  106. <div class="col-xs-8">
  107. <div class="row">
  108. <label class="col-xs-5 font-noraml">
  109. <input class="cuci-radio" type="radio" name="menu-type" value="text"> 文字消息
  110. </label>
  111. <label class="col-xs-5 font-noraml">
  112. <input class="cuci-radio" type="radio" name="menu-type" value="keys"> 关键字
  113. </label>
  114. <label class="col-xs-5 font-noraml">
  115. <input class="cuci-radio" type="radio" name="menu-type" value="view"> 跳转网页
  116. </label>
  117. <label class="col-xs-5 font-noraml">
  118. <input class="cuci-radio" type="radio" name="menu-type" value="event"> 事件功能
  119. </label>
  120. <label class="col-xs-5 font-noraml">
  121. <input class="cuci-radio" type="radio" name="menu-type" value="miniprogram"> 小程序
  122. </label>
  123. <label class="col-xs-5 font-noraml">
  124. <input class="cuci-radio" type="radio" name="menu-type" value="customservice"> 多客服
  125. </label>
  126. </div>
  127. </div>
  128. </div>
  129. <div class="form-group" style="margin-top:30px">
  130. <div class="col-xs-10 col-xs-offset-1 editor-content-input"></div>
  131. </div>
  132. </form>
  133. </div>
  134. <div style="clear:both"></div>
  135. <div style="width:830px;padding-top:40px;text-align:center">
  136. {if auth("$classuri/edit")}
  137. <button class="layui-btn menu-submit">保存发布</button>
  138. {/if}
  139. {if auth("$classuri/cancel")}
  140. <button data-load='{:url("$classuri/cancel")}' class="layui-btn layui-btn-danger">取消发布</button>
  141. {/if}
  142. </div>
  143. {/block}
  144. {block name="script"}
  145. <script>
  146. $(function () {
  147. var menu = function () {
  148. this.$btn;
  149. this.listen();
  150. };
  151. menu.prototype.listen = function () {
  152. var self = this;
  153. $('.mobile-footer').on('click', 'li a', function () {
  154. self.$btn = $(this);
  155. self.$btn.parent('li').hasClass('menu-add') ? self.add() : self.checkShow();
  156. }).find('li:first a:first').trigger('click');
  157. $('.menu-delete').on('click', function () {
  158. var index = $.msg.confirm('删除后菜单下设置的内容将被删除!', function () {
  159. self.del(), $.msg.close(index);
  160. });
  161. });
  162. $('.menu-submit').on('click', function () {
  163. self.submit();
  164. });
  165. };
  166. menu.prototype.add = function () {
  167. var $add = this.$btn.parent('li'), $ul = $add.parent('ul');
  168. if ($ul.hasClass('mobile-footer')) { /* 添加一级菜单 */
  169. var $li = $('<li class="parent-menu"><a class="active"><i class="icon-sub hide"></i> <span>一级菜单</span></a></li>').insertBefore($add);
  170. this.$btn = $li.find('a');
  171. $('<div class="sub-menu text-center hide"><ul><li class="menu-add"><a><i class="icon-add"></i></a></li></ul><i class="arrow arrow_out"></i><i class="arrow arrow_in"></i></div>').appendTo($li);
  172. } else { /* 添加二级菜单 */
  173. this.$btn = $('<li><a class="bottom-border"><span>二级菜单</span></a></li>').prependTo($ul).find('a');
  174. }
  175. this.checkShow();
  176. };
  177. menu.prototype.checkShow = function () {
  178. var $li = this.$btn.parent('li'), $ul = $li.parent('ul');
  179. /* 选中一级菜单时显示二级菜单 */
  180. if ($li.hasClass('parent-menu')) {
  181. $('.parent-menu .sub-menu').not(this.$btn.parent('li').find('.sub-menu').removeClass('hide')).addClass('hide');
  182. }
  183. /* 一级菜单添加按钮 */
  184. var $add = $('li.parent-menu:last');
  185. $add.siblings('li').size() >= 3 ? $add.addClass('hide') : $add.removeClass('hide');
  186. /* 二级菜单添加按钮 */
  187. $add.siblings('li').map(function () {
  188. var $add = $(this).find('ul li:last');
  189. $add.siblings('li').size() >= 5 ? $add.addClass('hide') : $add.removeClass('hide');
  190. });
  191. /* 处理一级菜单 */
  192. var parentWidth = 100 / $('li.parent-menu:visible').size() + '%';
  193. $('li.parent-menu').map(function () {
  194. var $icon = $(this).find('.icon-sub');
  195. $(this).width(parentWidth).find('ul li').size() > 1 ? $icon.removeClass('hide') : $icon.addClass('hide');
  196. });
  197. /* 更新选择中状态 */
  198. $('.mobile-footer a.active').not(this.$btn.addClass('active')).removeClass('active');
  199. this.renderEdit();
  200. return $ul;
  201. };
  202. menu.prototype.del = function () {
  203. var $li = this.$btn.parent('li'), $ul = $li.parent('ul');
  204. var $default = function () {
  205. if ($li.prev('li').size() > 0) {
  206. return $li.prev('li');
  207. }
  208. if ($li.next('li').size() > 0 && !$li.next('li').hasClass('menu-add')) {
  209. return $li.next('li');
  210. }
  211. if ($ul.parents('li.parent-menu').size() > 0) {
  212. return $ul.parents('li.parent-menu');
  213. }
  214. return $('null');
  215. }.call(this);
  216. $li.remove();
  217. this.$btn = $default.find('a:first');
  218. this.checkShow();
  219. };
  220. menu.prototype.renderEdit = function () {
  221. var $span = this.$btn.find('span'), $li = this.$btn.parent('li'), $ul = $li.parent('ul'), $html = '';
  222. if ($li.find('ul li').size() > 1) { /*父菜单*/
  223. $html = $($('.menu-editor-parent-tpl').html());
  224. $html.find('input[name="menu-name"]').val($span.text()).on('change keyup', function () {
  225. $span.text(this.value || ' ');
  226. });
  227. $('.menu-editor .menu-content').html($html);
  228. } else {
  229. $html = $($('.menu-editor-content-tpl').html());
  230. $html.find('input[name="menu-name"]').val($span.text()).on('change keyup', function () {
  231. $span.text(this.value || ' ');
  232. });
  233. $('.menu-editor .menu-content').html($html);
  234. var type = $span.attr('data-type') || 'text';
  235. $html.find('input[name="menu-type"]').on('click', function () {
  236. $span.attr('data-type', this.value || 'text');
  237. var type = this.value, content = $span.data('content') || '请输入内容';
  238. var html = function () {
  239. switch (type) {
  240. case 'miniprogram':
  241. var tpl = '\
  242. <div>\
  243. <div>appid<input style="display:block;margin-bottom:10px" class="form-control input-sm" value="{appid}" name="appid"></div>\
  244. <div>url<input style="display:block;margin-bottom:10px" class="form-control input-sm" value="{url}" name="url"></div>\
  245. <div>pagepath<input style="display:block" name="pagepath" class="form-control input-sm" value={pagepath}></div>\
  246. </div>';
  247. var _appid = '', _pagepath = '', _url = '';
  248. if (content.indexOf(',') > 0) {
  249. _appid = content.split(',')[0] || '';
  250. _url = content.split(',')[1] || '';
  251. _pagepath = content.split(',')[2] || '';
  252. }
  253. $span.data('appid', _appid), $span.data('url', _url), $span.data('pagepath', _pagepath);
  254. return tpl.replace('{appid}', _appid).replace('{url}', _url).replace('{pagepath}', _pagepath);
  255. case 'customservice':
  256. case 'text':
  257. return '<div>回复内容<textarea style="resize:none;height:225px" name="content" class="form-control input-sm">{content}</textarea></div>'.replace('{content}', content);
  258. case 'view':
  259. return '<div>跳转地址<textarea style="resize:none;height:225px" name="content" class="form-control input-sm">{content}</textarea></div>'.replace('{content}', content);
  260. case 'keys':
  261. return '<div>匹配内容<textarea style="resize:none;height:225px" name="content" class="form-control input-sm">{content}</textarea></div>'.replace('{content}', content);
  262. case 'event':
  263. var options = {
  264. 'scancode_push': '扫码推事件',
  265. 'scancode_waitmsg': '扫码推事件且弹出“消息接收中”提示框',
  266. 'pic_sysphoto': '弹出系统拍照发图',
  267. 'pic_photo_or_album': '弹出拍照或者相册发图',
  268. 'pic_weixin': '弹出微信相册发图器',
  269. 'location_select': '弹出地理位置选择器'
  270. };
  271. var select = [],
  272. tpl = '<div><label class="font-noraml"><input class="cuci-radio" name="content" type="radio" {checked} value="{value}"> {title}</label></div>';
  273. if (!(options[content] || false)) {
  274. content = 'scancode_push';
  275. $span.data('content', content);
  276. }
  277. for (var i in options) {
  278. select.push(tpl.replace('{value}', i).replace('{title}', options[i]).replace('{checked}', (i === content) ? 'checked' : ''));
  279. }
  280. return select.join('');
  281. }
  282. }.call(this);
  283. var $html = $(html), $input = $html.find('input,textarea');
  284. $input.on('change keyup click', function () {
  285. // 将input值写入到span上
  286. $span.data(this.name, $(this).val() || $(this).html());
  287. // 如果是小程序,合并内容到span的content上
  288. if (type === 'miniprogram') {
  289. $span.data('content', $span.data('appid') + ',' + $span.data('url') + ',' + $span.data('pagepath'));
  290. }
  291. });
  292. $('.editor-content-input').html($html);
  293. }).filter('input[value="{type}"]'.replace('{type}', type)).trigger('click');
  294. }
  295. };
  296. menu.prototype.submit = function () {
  297. var data = [];
  298. $('li.parent-menu').map(function (index, item) {
  299. if (!$(item).hasClass('menu-add')) {
  300. var menudata = getdata($(item).find('a:first span'));
  301. menudata.index = index + 1;
  302. menudata.pindex = 0;
  303. menudata.sub = [];
  304. menudata.sort = index;
  305. data.push(menudata);
  306. $(item).find('.sub-menu ul li:not(.menu-add) span').map(function (ii, span) {
  307. var submenudata = getdata($(span));
  308. submenudata.index = (index + 1) + '' + (ii + 1);
  309. submenudata.pindex = menudata.index;
  310. submenudata.sort = ii;
  311. data.push(submenudata);
  312. });
  313. }
  314. });
  315. $.form.load('{:url("$classuri/edit")}', {data: data}, 'POST');
  316. function getdata($span) {
  317. var menudata = {};
  318. menudata.name = $span.text();
  319. menudata.type = $span.attr('data-type');
  320. menudata.content = $span.data('content') || '';
  321. return menudata;
  322. }
  323. };
  324. new menu();
  325. });
  326. </script>
  327. {/block}