templatemessage.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
  2. var issent = 0;
  3. var Controller = {
  4. index: function () {
  5. // 初始化表格参数配置
  6. Table.api.init({
  7. extend: {
  8. index_url: 'templatemessage/index',
  9. add_url: 'templatemessage/add',
  10. edit_url: 'templatemessage/edit',
  11. del_url: 'templatemessage/del',
  12. multi_url: 'templatemessage/multi',
  13. table: 'templatemessage',
  14. }
  15. });
  16. var table = $("#table");
  17. // 初始化表格
  18. table.bootstrapTable({
  19. url: $.fn.bootstrapTable.defaults.extend.index_url,
  20. pk: 'id',
  21. sortName: 'id',
  22. search: false,
  23. commonSearch: false,
  24. columns: [
  25. [
  26. {checkbox: true},
  27. {field: 'id', title: __('Id')},
  28. {field: 'title', title: __('Title')},
  29. {field: 'tpname', title: __('Tpname')},
  30. {field: 'template_id', title: __('模板ID')},
  31. {field: 'sendtime', title: __('Sendtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
  32. {field: 'statue', title: __('Statue'),visible:false,operate:false},
  33. {field: 'statue_text', title: __('Statue'), operate:false},
  34. {field: 'send_num', title: __('发送人数'), operate:false},
  35. // {field: 'success_num', title: '到达用户', operate:false},
  36. // {field: 'fail_num', title: '发送失败', operate:false},
  37. {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
  38. ]
  39. ]
  40. });
  41. // 为表格绑定事件
  42. Table.api.bindevent(table);
  43. },
  44. add: function () {
  45. Controller.api.bindevent();
  46. $('.s_time_box span:eq(1)').click();
  47. },
  48. edit: function () {
  49. Controller.api.bindevent();
  50. },
  51. api: {
  52. getStatue: function (value, row, index) {
  53. if(value == 'normal'){
  54. if (row.sendtime < Date.parse(new Date())/1000){
  55. return '<span style="color:red">发送失败</span>';
  56. }else{
  57. return '未发送';
  58. }
  59. }else{
  60. return '<span style="color:green">已发送</span>';
  61. }
  62. },
  63. bindevent: function () {
  64. /**
  65. * form表单验证
  66. */
  67. $("form[role=form]").data("validator-options", {
  68. ignore: ':hidden',
  69. beforeSubmit: function (form) {
  70. if(issent != 1){
  71. Toastr.error("请先成功测试粉丝后再保存模板消息");
  72. return false;
  73. }
  74. var sdatatime=$('#c-sendtime').val()+'';
  75. sdatatime = sdatatime.replace(/-/g,'/');
  76. sdatatime =new Date(sdatatime).getTime();
  77. if(sdatatime <= new Date().getTime()){
  78. Toastr.error("发送时间必须大于当前时间");
  79. return false;
  80. }
  81. }
  82. });
  83. Form.api.bindevent($("form[role=form]"),
  84. function (data) {
  85. Fast.api.close(data);
  86. },
  87. function (data) {
  88. console.log('error', data);
  89. }
  90. );
  91. $(document).on('click','.s_tag_li_list span',function(){
  92. var $this = $(this);
  93. $this.addClass('s_s_tag').siblings('span').removeClass('s_s_tag');
  94. var tagObj ={
  95. sex:$('#sex span.s_s_tag').data('sex'),
  96. tag:$('#ctag span.s_s_tag').data('cid'),
  97. consume:$('#consume span.s_s_tag').data('fee'),
  98. kandian: $('#kandian span.s_s_tag').data('kandian'),
  99. subscribe_time:$('#subTime span.s_s_tag').data('week'),
  100. all:"0"
  101. }
  102. var uconditon = JSON.stringify(tagObj);
  103. $('#usercondition').val(uconditon);
  104. });
  105. var ofansopen=true;
  106. //tag切换
  107. $(document).on('click','.s_tag_fans_num',function(){
  108. var $this = $(this);
  109. //防止重复点击
  110. if(!ofansopen){
  111. return false;
  112. }
  113. ofansopen = false;
  114. $('.s_tag_footer').addClass('s_tag_fans_show');
  115. var tagObj ={
  116. sex:$('#sex span.s_s_tag').data('sex'),
  117. tag:$('#ctag span.s_s_tag').data('cid'),
  118. consume:$('#consume span.s_s_tag').data('fee'),
  119. kandian: $('#kandian span.s_s_tag').data('kandian'),
  120. subscribe_time:$('#subTime span.s_s_tag').data('week'),
  121. all:"0"
  122. }
  123. var uconditon = JSON.stringify(tagObj);
  124. $('#usercondition').val(uconditon);
  125. //console.log(tagObj);
  126. $.ajax({
  127. type:'post',
  128. data:tagObj,
  129. //dataType:'json',
  130. url:'/admin/custom/ajaxcustom',
  131. success:function(data){
  132. //console.log(data);
  133. $('#mustbe').html('约'+data.ids+'人');
  134. ofansopen = true;
  135. $('.s_tag_footer').removeClass('s_tag_fans_show');
  136. },
  137. error:function(err){
  138. ofansopen = true;
  139. $('.s_tag_footer').removeClass('s_tag_fans_show');
  140. }
  141. });
  142. });
  143. //获取模板json
  144. var ontmwjson = '';
  145. function fajaxtmp(str){
  146. if(!str){
  147. str = '';
  148. }
  149. var num = 0;
  150. var nowmsg = false;
  151. $.ajax({
  152. type:'get',
  153. //dataType:'json',
  154. url:'/admin/templatemessage/ajaxtmp' + str,
  155. success:function(data){
  156. //console.log(data);
  157. if(typeof data == 'string'){
  158. data = JSON.parse(data);
  159. }
  160. if(data.error == -1){
  161. $('.ntmw_head_select ul').html("");
  162. $('.ntmw_head_select strong').html("");
  163. layer.msg(data.msg);
  164. return false;
  165. }
  166. ontmwjson = data.data;
  167. //$('#select_ntmw').val(JSON.stringify(data.data));
  168. //模板列表
  169. if($('#select_msg_id').val().length>0){
  170. var sMsgId =$.trim($('#select_ntmw_id').val());
  171. for(var k=0; k<ontmwjson.length; k++){
  172. if(ontmwjson[k].id == sMsgId){
  173. num = k;
  174. break;
  175. }
  176. }
  177. var smsghtml = $('#select_ntmw').val();
  178. ontmwjson[num]['content'] = JSON.parse($.trim(smsghtml));
  179. nowmsg = true;
  180. }
  181. var $li = '';
  182. for(var i=0; i<ontmwjson.length; i++){
  183. $li += '<li>' + ontmwjson[i].title+' -- '+ ontmwjson[i].template_id + '</li>';
  184. }
  185. $('.ntmw_head_select ul').html($li);
  186. $('.ntmw_head_select ul li:eq('+ num +')').addClass('hover');
  187. //插入html数据
  188. selectTemplate(num,nowmsg);
  189. if(str == '?w=1'){
  190. Toastr.success('刷新模板列表成功');
  191. }
  192. },
  193. error:function(err){
  194. }
  195. });
  196. }
  197. fajaxtmp();
  198. //刷新模板列表
  199. $('.ntmw_but').click(function(){
  200. fajaxtmp('?w=1');
  201. });
  202. //选择模板
  203. function selectTemplate(num,bul){
  204. var oContent = ontmwjson[num]['content'];
  205. var sLi='';
  206. $('.ntmw_head_select strong,.ntmw_main_box h3').text(ontmwjson[num].title+' -- '+ontmwjson[num].template_id);
  207. $('#select_ntmw_id').val(ontmwjson[num].id);
  208. $('#select_template_id').val(ontmwjson[num].template_id);
  209. $('#select_tpname').val(ontmwjson[num].title);
  210. $('#select_ntmw').val(JSON.stringify(oContent));
  211. //console.log(ontmwjson[num].id);
  212. //console.log(oContent);
  213. for(var i=0; i<oContent.length; i++){
  214. sLi += '<li>';
  215. for(var j=0; j<oContent[i].length; j++){
  216. if(oContent[i][j].color!=''){
  217. //console.log(oContent[i][j].color);
  218. //console.log(oContent[i][j].fieldname);
  219. if(!bul){
  220. oContent[i][j].fieldname = '';
  221. }
  222. sLi += '<i class="fa fa-edit ntmw_li_edit"></i><span style="color: '+ oContent[i][j].color +';">'+ oContent[i][j].fieldname +'</span>';
  223. }else{
  224. sLi += '<span style="color: #000000;">'+ oContent[i][j].fieldname +'</span>';
  225. }
  226. }
  227. sLi += '</li>';
  228. }
  229. $('.ntmw_main_box ul').html(sLi);
  230. }
  231. //初始化 标签
  232. $.ajax({
  233. type:'get',
  234. url:'/admin/custom/ajaxcategory',
  235. cache:false,
  236. async:false,
  237. success:function(res){
  238. data = res.data;
  239. var htmlstr = '';
  240. for(var i=0;i<data.length;i++){
  241. htmlstr+='<span data-cid="'+data[i].id+'" >'+data[i].name+'</span>';
  242. }
  243. $('#ctag').append(htmlstr);
  244. $('#mustbe').html('约'+res.ids+'人');
  245. if ($('#usercondition').val().length > 0){
  246. $tagval = JSON.parse($('#usercondition').val());
  247. $("#sex span[data-sex='"+$tagval.sex+"']").addClass('s_s_tag').siblings().removeClass('s_s_tag');
  248. $("#ctag span[data-cid='"+$tagval.tag+"']").addClass('s_s_tag').siblings().removeClass('s_s_tag');
  249. $("#consume span[data-fee='"+$tagval.consume+"']").addClass('s_s_tag').siblings().removeClass('s_s_tag');
  250. $("#kandian span[data-kandian='"+$tagval.kandian+"']").addClass('s_s_tag').siblings().removeClass('s_s_tag');
  251. $("#subTime span[data-week='"+$tagval.subscribe_time+"']").addClass('s_s_tag').siblings().removeClass('s_s_tag');
  252. }else{
  253. var tagObj1 ={
  254. sex:-1,
  255. tag:-1,
  256. consume:-1,
  257. kandian: -1,
  258. subscribe_time:-1,
  259. all:"0"
  260. };
  261. var ucon1 = JSON.stringify(tagObj1);
  262. $('#usercondition').val(ucon1);
  263. }
  264. },
  265. error:function(err){
  266. }
  267. });
  268. /**
  269. * 资源类型管理
  270. */
  271. $(document).on('click', "input[name='row[type]']", function () {
  272. var type = $(this).val();
  273. if (type=='all'){
  274. var tagObj = {
  275. all:"1"
  276. }
  277. }else{
  278. var tagObj ={
  279. sex:-1,
  280. tag:-1,
  281. consume:-1,
  282. kandian: -1,
  283. subscribe_time:-1,
  284. all:"0"
  285. }
  286. }
  287. var ucon = JSON.stringify(tagObj);
  288. $('#usercondition').val(ucon);
  289. $('.group-tag-type').addClass('hide');
  290. $('.group-tag-type input').attr('disabled');
  291. $('#group-tag-type-' + type).removeClass('hide');
  292. $('#group-tag-type-' + type+' input').removeAttr('disabled');
  293. });
  294. if ($('#usercondition').val().length > 0) {
  295. $tagval = JSON.parse($('#usercondition').val());
  296. if ($tagval.all == 1){ //选择所有用户
  297. $('#type-all').attr('checked',true);
  298. var type = 'all';
  299. $('.group-tag-type').addClass('hide');
  300. $('.group-tag-type input').attr('disabled');
  301. $('#group-tag-type-' + type).removeClass('hide');
  302. $('#group-tag-type-' + type+' input').removeAttr('disabled');
  303. }
  304. }
  305. //测试发送
  306. var flag = 0;
  307. $('.test_fans_but').click(function(){
  308. if(flag == 1){
  309. return false;
  310. }
  311. flag = 1;
  312. var $imgTxtMain = $('.img_txt_main');
  313. var reg = /^(http[s]?|ftp):\/\/[^\/\.]+?\..+\w/;
  314. //标题
  315. if($.trim($('#title').val()).length == 0){
  316. Toastr.error("标题不能为空");
  317. flag = 0;
  318. return false;
  319. }
  320. //微信模板内容
  321. if($.trim($('#select_ntmw').val()).length == 0){
  322. Toastr.error("未填写模板内容");
  323. flag = 0;
  324. return false;
  325. }
  326. //网址
  327. if($.trim($('#f_url').val()).length == 0){
  328. Toastr.error("跳转链接不能为空");
  329. flag = 0;
  330. return false;
  331. }
  332. if($.trim($('#userId').val()) == ''){
  333. Toastr.error("请填写测试粉丝ID");
  334. flag = 0;
  335. return false;
  336. }
  337. if($.trim($('#userId').val()) == ''){
  338. Toastr.error("请填写测试粉丝ID");
  339. flag = 0;
  340. return false;
  341. }
  342. var sentData = {
  343. title:$('#title').val(),
  344. admin_id:$('#admin_id').val(),
  345. user_id:$('#userId').val(),
  346. message_html:$('#select_ntmw').val(),
  347. url:$('#f_url').val(),
  348. template_id:$('#select_template_id').val(),
  349. tpid:$('#select_ntmw_id').val()
  350. };
  351. console.log(sentData);
  352. $.ajax({
  353. type:'post',
  354. url:'/admin/templatemessage/sent',
  355. data:sentData,
  356. dataType:'json',
  357. cache:false,
  358. async:false,
  359. success:function(data){
  360. console.log(data);
  361. flag = 0;
  362. if(data.errcode == 0){
  363. issent = 1;
  364. Toastr.success('已送达');
  365. }else{
  366. Toastr.error('错误码:'+data.errcode+'错误信息:'+data.errmsg);
  367. }
  368. },
  369. error:function(err){
  370. flag = 0;
  371. }
  372. })
  373. });
  374. //发送消息时间
  375. $(document).on('click','.s_time_box span',function(){
  376. var $this = $(this);
  377. var nval = parseInt($this.attr('stime'));
  378. var ntime = Date.parse(new Date());
  379. var nt = ntime + nval;
  380. $('#c-sendtime').val(GetRTime(nt));
  381. });
  382. function GetRTime(time){
  383. var stime;
  384. time = new Date(time);
  385. var year = time.getYear() + 1900;
  386. var month = time.getMonth()+1;
  387. var day = time.getDate();
  388. var hours = time.getHours();
  389. var minutes = time.getMinutes();
  390. var seconds = time.getSeconds();
  391. stime = year + '-' +
  392. (month < 10 ? '0'+month : month) + '-' +
  393. (day < 10 ? '0'+day : day) + ' ' +
  394. (hours < 10 ? '0'+hours : hours) + ':' +
  395. (minutes < 10 ? '0'+minutes : minutes) + ':' +
  396. (seconds < 10 ? '0'+seconds : seconds);
  397. return stime;
  398. }
  399. var ontmwspan = '';
  400. //选择模板
  401. $(document).on('click','.ntmw_li_edit',function(){
  402. var oThis=$(this);
  403. var oNextSpan = oThis.next('span');
  404. var sColor = oNextSpan.css('color');
  405. ontmwspan = oNextSpan;
  406. var shtml= '<div class="ntmw_pop_box">\
  407. <div class="ntmw_edit_textarea_box"><div class="ntmw_edit_textarea" contenteditable="true" style="color:#000000;">' + ontmwspan.html() + '</div></div>\
  408. <div class="ntmw_edit_color_box"><strong>字体颜色:</strong><span style="background-color:#000000"></span><span style="background-color:#ff0000"></span><span style="background-color:#ff9400"></span><span style="background-color:#0099ff"></span><span style="background-color:#ff3399"></span><span style="background-color:#999999"></span></div>\
  409. <div class="ntmw_edit_word_box"><span>占位符<i class="fa fa-question-circle" title="使用说明"></i>:</span><strong contenteditable="false" data-key="$user_nickname">用户昵称</strong><strong contenteditable="false" data-key="$user_id">用户id</strong><strong contenteditable="false" data-key="$user_vip_endtime">用户vip到期时间</strong><strong contenteditable="false" data-key="$wx_nickname">微信公众号名称</strong></div>\
  410. </div>';
  411. layer.open({
  412. type: 1,
  413. title:'',
  414. skin: 'layui-layer-rim', //加上边框
  415. btn: ['保存'],
  416. content: shtml,
  417. yes: function(index, layero){
  418. var $nuldiv = $('<div></div>');
  419. var sHtmlReg=/<[^<>]+>/g;
  420. var sNtmwEditTextarea =$('.ntmw_edit_textarea').html();
  421. $nuldiv.append(sNtmwEditTextarea);
  422. $nuldiv.find('strong[contenteditable="false"]').remove();
  423. sNtmwEditTextarea =$nuldiv.html();
  424. if(sHtmlReg.test(sNtmwEditTextarea)){
  425. Toastr.error("您输入的内容包含特殊字符,请重新输入");
  426. return false;
  427. }
  428. layer.close(index);
  429. var sTextareaColor = $('.ntmw_edit_textarea').css('color');
  430. var sTextareaContent = $.trim($('.ntmw_edit_textarea').html());
  431. oNextSpan.css('color',sTextareaColor).html(sTextareaContent);
  432. var $li = $('.ntmw_main_box ul li');
  433. var sVal =JSON.parse($.trim($('#select_ntmw').val()));
  434. for(var i=0; i<$li.length; i++){
  435. var aLi = sVal[i];
  436. $lispan = $li.eq(i).find('span');
  437. for(var j=0; j<$lispan.length; j++){
  438. var $prev = $lispan.eq(j).prev();
  439. if($prev.is('i')){
  440. aLi[j].color = colorRGB2Hex($lispan.eq(j).css('color'));
  441. }
  442. aLi[j].fieldname = $lispan.eq(j).html();
  443. }
  444. }
  445. $('#select_ntmw').val(JSON.stringify(sVal));
  446. }
  447. });
  448. //默认字体颜色
  449. var $span = $('.ntmw_edit_color_box span');
  450. for(var i=0; i<$span.length; i++){
  451. var sNowSpanColor = $span.eq(i).css('backgroundColor');
  452. if(sColor == sNowSpanColor){
  453. $span.eq(i).addClass('active').siblings('span').removeClass('active');
  454. break;
  455. }
  456. if(sColor == $span.eq(0).css('backgroundColor')){
  457. $span.eq(0).addClass('active').siblings('span').removeClass('active');
  458. break;
  459. }
  460. }
  461. $('.ntmw_edit_textarea').css('color',sColor);
  462. $('.ntmw_edit_textarea').append('\r');
  463. $('.ntmw_edit_textarea').focus();
  464. keepLastIndex($('.ntmw_edit_textarea').get(0));
  465. });
  466. //rgb转换未16进制
  467. function colorRGB2Hex(color) {
  468. if(!/#/.test(color)){
  469. var rgb = color.split(',');
  470. var r = parseInt(rgb[0].split('(')[1]);
  471. var g = parseInt(rgb[1]);
  472. var b = parseInt(rgb[2].split(')')[0]);
  473. var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  474. return hex;
  475. }
  476. return color;
  477. }
  478. //修改字体颜色
  479. $(document).on('click','.ntmw_edit_color_box span',function(){
  480. var $this = $(this);
  481. var sColor = $this.css('backgroundColor');
  482. $this.addClass('active').siblings('span').removeClass('active');
  483. $('.ntmw_edit_textarea').css('color',sColor);
  484. });
  485. //添加占位符
  486. var lastEditRange;
  487. $(document).on('click','.ntmw_edit_word_box strong',function(){
  488. var $this = $(this);
  489. var sHtml = $this.prop("outerHTML");
  490. var sTATxt = $.trim($('.ntmw_edit_textarea').html()) + '&nbsp;' + sHtml + '&nbsp;\r';
  491. var txtFocus = $('.ntmw_edit_textarea').get(0);
  492. var sTATxtLen = sTATxt.length - 1;
  493. $('.ntmw_edit_textarea').html(sTATxt);
  494. $this.blur();
  495. keepLastIndex(txtFocus);
  496. });
  497. //将光标放到最后面
  498. function keepLastIndex(obj) {
  499. if(window.getSelection) {//ie11 10 9 ff safari
  500. obj.focus(); //解决ff不获取焦点无法定位问题
  501. var range = window.getSelection();//创建range
  502. range.selectAllChildren(obj);//range 选择obj下所有子内容
  503. range.collapseToEnd();//光标移至最后
  504. }else if(document.selection) {//ie10 9 8 7 6 5
  505. var range = document.selection.createRange();//创建选择对象
  506. //var range = document.body.createTextRange();
  507. range.moveToElementText(obj);//range定位到obj
  508. range.collapse(false);//光标移至最后
  509. range.select();
  510. }
  511. }
  512. //选择模板下拉切换
  513. $(document).on('click','.ntmw_head_select li',function(){
  514. var $this=$(this);
  515. var sTxt = $this.text();
  516. var nIndex = $this.index();
  517. $this.addClass('hover').siblings('li').removeClass('hover');
  518. $('.ntmw_head_select strong').data('value',nIndex);
  519. $('.ntmw_head_select strong').text(sTxt);
  520. selectTemplate(nIndex);
  521. });
  522. $(document).on('click','.ntmw_edit_word_box i',function(){
  523. layer.open({
  524. type: 1,
  525. title:'',
  526. skin: 'layui-layer-rim', //加上边框
  527. btn: ['知道了'],
  528. content: '<div class="ntmw_question_box">\
  529. <div class="ntmw_question_li">模板:亲爱的<span>用户昵称</span>, 您的年费到期时间为<span>用户vip到期时间</span></div>\
  530. <div class="ntmw_question_li">效果:亲爱的宁静致远,您的年费到期时间为2018-12-29 17:28</span></div>\
  531. </div>',
  532. yes: function(index, layero){
  533. layer.close(index);
  534. }
  535. });
  536. })
  537. //修改url
  538. $(document).on('click','.img_txt_edit_url',function(){
  539. var $this=$(this);
  540. Fast.api.open('referral/referral/select?one=1', '选择', {
  541. callback: function (data) {
  542. var data = data[0];
  543. // console.log('展示title回调', data);
  544. $this.parent().siblings('input').val(data.source_url);
  545. }
  546. });
  547. });
  548. //修改book
  549. $(document).on('click','.img_txt_edit_book',function(){
  550. var $this=$(this);
  551. Fast.api.open('book.book/select?one=1', '选择', {
  552. callback: function (data) {
  553. var data = data[0];
  554. $this.parent().siblings('input').val(data.current_book_url);
  555. }
  556. });
  557. });
  558. }
  559. }
  560. };
  561. return Controller;
  562. });