1014 lines
32 KiB
HTML
1014 lines
32 KiB
HTML
{extend name="public/base"/}
|
|
{block name="style"}
|
|
|
|
<link rel="stylesheet" href="__PUBLIC__/plugs/tagsinput/bootstrap-tagsinput.css">
|
|
<script src="__PUBLIC__/plugs/tagsinput/bootstrap-tagsinput.js"></script>
|
|
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/plugs/webuploader/webuploader.css">
|
|
<!-- 配置文件 -->
|
|
<script type="text/javascript" src="__PUBLIC__/plugs/ueditor/ueditor.config.js"></script>
|
|
<!-- 编辑器源码文件 -->
|
|
<script type="text/javascript" src="__PUBLIC__/plugs/ueditor/ueditor.all.min.js"></script>
|
|
<!-- datepicker statr -->
|
|
<link href="__PUBLIC__/plugs/datepicker/css/foundation-datepicker.min.css" rel="stylesheet" type="text/css">
|
|
<link rel="stylesheet" href="/public/css//admin.css?v=39"/>
|
|
<script src="__PUBLIC__/plugs/datepicker/js/foundation-datepicker.js"></script>
|
|
<script src="__PUBLIC__/plugs/datepicker/js/foundation-datepicker.zh-CN.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="__PUBLIC__/plugs/board/board.min.css">
|
|
<!-- datepicker end -->
|
|
|
|
|
|
|
|
<style>
|
|
select, input {
|
|
margin-bottom: 0 !important;
|
|
}
|
|
#keyvalue {
|
|
height: auto;
|
|
}
|
|
|
|
</style>
|
|
<!-- page specific plugin styles -->
|
|
<script src='/public/js/jquery.min.js'></script>
|
|
<script src="/public/plugs/handlebars.js/4.0.10/handlebars.min.js"></script>
|
|
<script src="/public/plugs/highlight.js/9.12.0/highlight.min.js"></script>
|
|
<script src="/public/plugs/lodash.js/4.17.4/lodash.min.js"></script>
|
|
<script src="/public/plugs/moment.js/2.17.1/moment.min.js"></script>
|
|
<script src="/public/plugs/moment.js/2.17.1/locale/zh-cn.js"></script>
|
|
<script src="/public/plugs/numeral.js/2.0.6/numeral.min.js"></script>
|
|
<script src="/public/plugs/toastr.js/2.1.3/toastr.min.js"></script>
|
|
<script src="/public/plugs/Cookies.js/1.2.1/cookies.js"></script>
|
|
<script src="/public/plugs/knockout/3.4.2/knockout-min.js"></script>
|
|
<script src="/public/plugs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
|
|
<script src="/public/plugs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script>
|
|
<script src="/public/plugs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
|
|
<script src="/public/plugs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"></script>
|
|
|
|
<script src="/public/plugs/editor/admin.js?v=10"></script>
|
|
|
|
|
|
<!-- ace settings handler -->
|
|
<script src="/public/js/ace-extra.min.js"></script>
|
|
|
|
{/block}
|
|
{block name="body"}
|
|
<script>
|
|
$.get('{:url('customservice/api_check_mp_settings')}?t' + new Date().getTime(), function (result) {
|
|
|
|
if (!result.valid) {
|
|
console.log(result.valid);
|
|
$('#invalid-mp-settings-hint').show();
|
|
//$('#invalid-mp-settings-hint').slideDown();
|
|
}
|
|
});
|
|
</script>
|
|
<div id="invalid-mp-settings-hint" style="display:none;border-top: 0px; border-left: 0px; border-right: 0px; margin: 0px;" class="alert alert-warning">
|
|
<i class="fa fa-warning"></i> 您的公众号配置不完整,推广前请务必配置好公众号信息。<a href="{:url('wxmp/settings')}">立即配置</a>
|
|
</div>
|
|
<div class="main-box clearfix">
|
|
<header class="main-box-header clearfix">
|
|
<div class="pull-left">
|
|
<h2>{$meta_title}</h2>
|
|
</div>
|
|
</header>
|
|
<div class="main-box-body clearfix">
|
|
<form class="form-horizontal" id="main-form" style="margin-top:20px">
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label no-padding-right">消息类别</label>
|
|
<div class="col-sm-9">
|
|
<select class="form-control" name='type' id="type" style="width:auto;" data-val="true" data-bind="value: type">
|
|
<option value='1' selected>客服消息</option>
|
|
<!---
|
|
<option value='2'>智能推送</option>
|
|
--->
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label no-padding-right" for="seller_name">任务名称</label>
|
|
<div class="col-sm-9">
|
|
<input type="text" name="name" id="name" class="form-control "
|
|
data-val="true"
|
|
data-val-required="请输入任务名称"
|
|
data-bind="value: name" value="{$info.name|default=''}" style="width:420px;"/>
|
|
<div class="col-xs-10 no-padding-left" data-valmsg-for="name" data-valmsg-replace="true"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="col-sm-9 col-sm-offset-3">
|
|
<div style="background:#eee; padding:10px">
|
|
<div id="rich-msg-editor" class="rich-msg-editor">
|
|
<div class="msg-title">
|
|
<span data-bind="text: param.main_article.title"></span>
|
|
<i class="fa fa-edit" data-bind="click: editMainTitle" style="cursor: pointer"></i>
|
|
</div>
|
|
<div class="msg-meta">2018月09日</div>
|
|
<div class="msg-cover" style="position:relative">
|
|
<img class="msg-cover-img" data-bind="attr: { src: param.main_article.picurl }" />
|
|
<div class="msg-edit-pic-overlay">
|
|
<span class="btn-edit-pic btn btn-success btn-xs" data-bind="click: editMainPic"><i class="fa fa-edit"></i> 更换图片</span>
|
|
</div>
|
|
</div>
|
|
<div class="msg-footer" data-bind="visible: param.sub_articles().length === 0">
|
|
<i class="fa fa-chevron-right pull-right"></i> 阅读全文
|
|
</div>
|
|
|
|
<div class="msg-sub-items">
|
|
<!-- ko foreach: param.sub_articles -->
|
|
<div class="msg-sub-item clearfix">
|
|
<div class="pull-left" style="width:80%">
|
|
<span data-bind="text: title"></span>
|
|
<a href="#" data-bind="click: $root.editSubArticle" title="修改"><i class="fa fa-edit"></i></a>
|
|
<a href="#" data-bind="click: $root.removeSubArticle.bind(this, $index(), $data)" title="删除" class="text-danger"><i class="fa fa-trash-o"></i></a>
|
|
|
|
<div class="msg-sub-item-meta">
|
|
<!-- ko if: url -->
|
|
<span data-bind="text: $root.shortenUrl(url())"></span>
|
|
<!-- /ko -->
|
|
<!-- ko ifnot: url -->
|
|
<span style="color:red">链接未配置</span>
|
|
<!-- /ko -->
|
|
</div>
|
|
</div>
|
|
<div class="pull-right">
|
|
<div class="msg-sub-item-img">
|
|
<img data-bind="attr: { src: picurl }" />
|
|
<div class="msg-sub-item-img-overlay">
|
|
<a href="#" data-bind="click: $root.editSubArticlePic">更换</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- /ko -->
|
|
</div>
|
|
</div>
|
|
|
|
<div class="add-sub-item-panel" data-bind="visible: param.sub_articles().length < 7">
|
|
<a href="#" data-bind="click: addSubArticle"><i class="fa fa-plus"></i> 添加次条</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label no-padding-right">头条链接</label>
|
|
<div class="col-sm-9">
|
|
<div class="col-sm-5 col-xs-10 no-padding-left no-padding-right">
|
|
<input type="text" name="url" class="form-control" id="url-input"
|
|
data-val="true"
|
|
data-val-required="请输入原文链接"
|
|
data-bind="value: url"/>
|
|
</div>
|
|
<p class="help-block no-padding-left col-xs-10">
|
|
仅限您小说网站内部的链接
|
|
</p>
|
|
<div class="col-xs-10 no-padding-left" data-valmsg-for="url" data-valmsg-replace="true"></div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label no-padding-right">发送用户</label>
|
|
<div class="col-sm-9">
|
|
<label class="checkbox-inline">
|
|
<input type="radio" name="andience" data-bind="checked: andience" value="0"/>
|
|
<span>全部用户</span>
|
|
</label>
|
|
|
|
<label class="checkbox-inline">
|
|
<input type="radio" name="andience" data-bind="checked: andience" value="1"/>
|
|
<span>付费用户</span>
|
|
</label>
|
|
|
|
<label class="checkbox-inline">
|
|
<input type="radio" name="andience" data-bind="checked: andience" value="3"/>
|
|
<span>未付费用户</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<hr/>
|
|
<div class="form-group" id="formscheduled" >
|
|
<label class="col-sm-3 control-label no-padding-right">发送时间</label>
|
|
<div class="col-sm-9">
|
|
<div class="col-sm-5 col-xs-10 no-padding-left no-padding-right">
|
|
<input type="text" name="scheduled_at" id="scheduled_at" class="form-control"
|
|
data-val="true"
|
|
data-val-required="请设置发送时间"
|
|
data-val-regex="格式错误。示例: 2017-04-25 12:30"
|
|
data-val-regex-pattern="^\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}$"
|
|
data-bind="datetimepicker: scheduled_at, datetimepickerOptions: { minDate:31 }"/>
|
|
</div>
|
|
<div class="col-xs-10 no-padding-left" style="margin-top:10px">
|
|
<a href="#" data-bind="click: setScheduleTime.bind(this, 10, 'minutes')">10分钟后</a>
|
|
<a href="#" data-bind="click: setScheduleTime.bind(this, 1, 'hour')">1小时后</a>
|
|
<a href="#" data-bind="click: setScheduleTime.bind(this, 2, 'hours')">2小时后</a>
|
|
</div>
|
|
<div class="col-xs-10 no-padding-left" data-valmsg-for="scheduled_at" data-valmsg-replace="true"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group" id="forminterval" style="display:none">
|
|
<label class="col-sm-3 control-label no-padding-right">推送间隔</label>
|
|
<div class="col-sm-9">
|
|
<select class="form-control" name='interval' id="interval" style="width:auto;" data-val="true" data-bind="value: interval">
|
|
<option value='' selected>未选择</option>
|
|
<option value='600'>10分钟</option>
|
|
<option value='3600'>1小时</option>
|
|
<option value='43200'>12小时</option>
|
|
<option value='86400'>24小时</option>
|
|
<option value='151200'>42小时</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<hr/>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label no-padding-right">测试粉丝ID</label>
|
|
<div class="col-sm-9">
|
|
<div class="col-sm-5 col-xs-10 no-padding-left no-padding-right">
|
|
<input type="text" name="test_member_id" class="form-control " data-bind="value: test_member_id" maxlength="10"/>
|
|
</div>
|
|
<button type="button" style="margin-left:5px" class="btn btn-primary" data-bind="click: test">测试发送</button>
|
|
<div class="help-block col-xs-10 no-padding-left">
|
|
用测试粉丝帐号点公众号菜单 "粉丝导航" > "个人中心"。<a href="javascript:;" class="btn-member-id-screen">查看示例</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn btn-primary" data-bind="click: submit, disable: processing">保存</button>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="edit-title-modal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-bind="click: close" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title">设置标题</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form class="form-horizontal">
|
|
<div class="form-group">
|
|
<label class="control-label col-sm-3">标题</label>
|
|
<div class="col-sm-7">
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" name="value" placeholder="输入标题" data-bind="value: title" />
|
|
<span class="input-group-btn">
|
|
<a href="#" data-bind="click: chooseTitle" class="btn btn-default">选择</a>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" data-bind="click: submit">提交</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
|
|
var EditTitleModal = window.EditTitleModal = function () {
|
|
var self = this;
|
|
var $modal = null;
|
|
var opts = {};
|
|
var model = {
|
|
title: ko.observable(),
|
|
samples: ko.observableArray(),
|
|
chooseTitle: function () {
|
|
ChooseTitleModal.instance.open({
|
|
callbacks: {
|
|
submit: function (title) {
|
|
model.title(title);
|
|
}
|
|
}
|
|
})
|
|
},
|
|
close: function () {
|
|
self.close();
|
|
},
|
|
submit: function () {
|
|
self.submit();
|
|
}
|
|
};
|
|
|
|
this.open = function (options) {
|
|
opts = options || {};
|
|
model.title(opts.title || '');
|
|
|
|
if (!$modal) {
|
|
$modal = $('#edit-title-modal');
|
|
ko.applyBindings(model, $modal.find('.modal-content')[0]);
|
|
}
|
|
|
|
$modal.modal('show');
|
|
};
|
|
|
|
this.close = function () {
|
|
$modal.modal('hide');
|
|
};
|
|
|
|
this.value = function () {
|
|
return model.title();
|
|
};
|
|
|
|
this.load = function () {
|
|
return ChooseTitleModal.instance.load();
|
|
};
|
|
|
|
this.random = function () {
|
|
return ChooseTitleModal.instance.random();
|
|
};
|
|
|
|
this.submit = function () {
|
|
if (opts.callbacks && opts.callbacks.submit) {
|
|
opts.callbacks.submit.apply(this, [this.value()]);
|
|
}
|
|
|
|
self.close();
|
|
}
|
|
|
|
};
|
|
|
|
EditTitleModal.instance = new EditTitleModal();
|
|
|
|
})(jQuery);
|
|
</script>
|
|
<div class="modal fade" id="edit-sub-article-modal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-bind="click: close" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title" data-bind="text: subject"></h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form class="form-horizontal">
|
|
<div class="form-group">
|
|
<label class="control-label col-sm-3">标题</label>
|
|
<div class="col-sm-7">
|
|
<div class="input-group">
|
|
<input type="text" name="title" class="form-control" data-bind="value: title, disable: forbidEnterTitle" />
|
|
<span class="input-group-btn">
|
|
<a href="#" class="btn btn-default" data-bind="click: chooseTitle">选择</a>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label col-sm-3">链接地址</label>
|
|
<div class="col-sm-7">
|
|
<input type="text" name="url" class="form-control" data-bind="value: url"/>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" data-bind="click: submit">提交</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="choose-title-modal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-bind="click: close" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title">选择标题</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div style="max-height:400px;overflow:auto;">
|
|
<div class="list-group" data-bind="foreach: samples">
|
|
<div class="list-group-item" data-bind="click: $parent.selectTitle">
|
|
<a href="javascript:;" data-bind="text: title"></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="choose-pic-modal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-bind="click: close" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
<h4 class="modal-title">选择封面</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="container-fluid">
|
|
<div data-bind="foreach: pics" class="row">
|
|
<div class="col-sm-3">
|
|
<a href="javascript:;" data-bind="click: $parent.selectPic">
|
|
<img data-bind="attr: { src: cover_url }" style="max-width:100%" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" data-bind="click: submit">提交</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/block}
|
|
{block name="script"}
|
|
<script type="text/javascript" src="__PUBLIC__/plugs/webuploader/webuploader.min.js"></script>
|
|
<script type="text/javascript" src="__PUBLIC__/plugs/webuploader/webuploader.custom.js"></script>
|
|
<script type="text/javascript" src="__PUBLIC__/js/droppable.js"></script>
|
|
<script type="text/javascript" src="__PUBLIC__/plugs/board/board.min.js"></script>
|
|
|
|
<script>
|
|
(function () {
|
|
|
|
var EditSubArticleModal = window.EditSubArticleModal = function () {
|
|
var self = this;
|
|
var $modal = null;
|
|
var opts = {};
|
|
var model = {
|
|
subject: ko.observable(''),
|
|
title: ko.observable(),
|
|
url: ko.observable(),
|
|
forbidEnterTitle: ko.observable(false),
|
|
|
|
chooseTitle: function () {
|
|
ChooseTitleModal.instance.open({
|
|
callbacks: {
|
|
submit: function (title) {
|
|
model.title(title);
|
|
}
|
|
}
|
|
})
|
|
},
|
|
close: function () {
|
|
self.close();
|
|
},
|
|
submit: function () {
|
|
self.submit();
|
|
}
|
|
};
|
|
|
|
this.open = function (options) {
|
|
opts = options || {};
|
|
model.subject(opts.subject || '修改次条');
|
|
model.title(opts.title || '');
|
|
model.url(opts.url || '');
|
|
|
|
if (opts.forbidEnterTitle) {
|
|
model.forbidEnterTitle(true);
|
|
}
|
|
|
|
if (!$modal) {
|
|
$modal = $('#edit-sub-article-modal');
|
|
ko.applyBindings(model, $modal.find('.modal-content')[0]);
|
|
|
|
UIComponent.handlers['ref-link-search-box'].init([$modal.find('[name="url"]')]);
|
|
}
|
|
|
|
$modal.modal('show');
|
|
};
|
|
|
|
this.close = function () {
|
|
$modal.modal('hide');
|
|
};
|
|
|
|
this.value = function () {
|
|
return {
|
|
title: model.title(),
|
|
url: model.url()
|
|
};
|
|
};
|
|
|
|
this.submit = function () {
|
|
if (opts.callbacks && opts.callbacks.submit) {
|
|
opts.callbacks.submit.apply(this, [this.value()]);
|
|
}
|
|
|
|
self.close();
|
|
}
|
|
|
|
};
|
|
|
|
EditSubArticleModal.instance = new EditSubArticleModal();
|
|
|
|
})(jQuery);
|
|
</script>
|
|
<script>
|
|
(function () {
|
|
|
|
var ChooseTitleModal = window.ChooseTitleModal = function () {
|
|
var self = this;
|
|
var $modal = null;
|
|
var loaderPromise = null;
|
|
var opts = {};
|
|
var model = {
|
|
title: ko.observable(),
|
|
samples: ko.observableArray(),
|
|
selectTitle: function (title) {
|
|
model.title(title.title);
|
|
self.submit();
|
|
},
|
|
close: function () {
|
|
self.close();
|
|
},
|
|
submit: function () {
|
|
self.submit();
|
|
}
|
|
};
|
|
|
|
this.open = function (options) {
|
|
opts = options || {};
|
|
|
|
model.title(null);
|
|
|
|
if (!$modal) {
|
|
$modal = $('#choose-title-modal');
|
|
ko.applyBindings(model, $modal.find('.modal-content')[0]);
|
|
}
|
|
|
|
$modal.modal('show');
|
|
};
|
|
|
|
this.close = function () {
|
|
$modal.modal('hide');
|
|
};
|
|
|
|
this.value = function () {
|
|
return model.title();
|
|
};
|
|
|
|
this.load = function () {
|
|
if (loaderPromise) {
|
|
return loaderPromise;
|
|
}
|
|
|
|
var defer = $.Deferred();
|
|
if (model.samples().length > 0) {
|
|
defer.resolve();
|
|
} else {
|
|
$.get('{:url("Customservice/api_get_titles")}', {type: 2}, function (data) {
|
|
model.samples(data);
|
|
defer.resolve();
|
|
});
|
|
}
|
|
|
|
loaderPromise = defer.promise();
|
|
|
|
return loaderPromise;
|
|
};
|
|
|
|
this.random = function () {
|
|
|
|
// console.log(model.samples());
|
|
//var sample = _.sample(model.samples());
|
|
/**
|
|
var sample = JSON.parse(model.samples());
|
|
var pics = sample.length;
|
|
return sample ? sample[GetRandomNum(1,pics)].title : null;
|
|
**/
|
|
var sample = _.sample(model.samples());
|
|
return sample ? sample.title : null;
|
|
};
|
|
|
|
this.submit = function () {
|
|
if (opts.callbacks && opts.callbacks.submit) {
|
|
opts.callbacks.submit.apply(this, [this.value()]);
|
|
}
|
|
|
|
self.close();
|
|
}
|
|
|
|
};
|
|
|
|
ChooseTitleModal.instance = new ChooseTitleModal();
|
|
ChooseTitleModal.instance.load();
|
|
|
|
})(jQuery);
|
|
</script>
|
|
<script>
|
|
function GetRandomNum(Min,Max)
|
|
{
|
|
var Range = Max - Min;
|
|
var Rand = Math.random();
|
|
return(Min + Math.round(Rand * Range));
|
|
}
|
|
(function () {
|
|
|
|
var ChoosePicModal = window.ChoosePicModal = function () {
|
|
var self = this;
|
|
var opts = {};
|
|
var loaderPromise = null;
|
|
var $modal = null;
|
|
var model = {
|
|
picurl: ko.observable(),
|
|
pics: ko.observableArray(),
|
|
selectPic: function (pic) {
|
|
model.picurl(pic.cover_url);
|
|
self.submit();
|
|
},
|
|
submit: function () {
|
|
self.submit();
|
|
},
|
|
close: function () {
|
|
self.close();
|
|
}
|
|
};
|
|
|
|
this.open = function (options) {
|
|
opts = options || {};
|
|
|
|
model.picurl(opts.picurl || '');
|
|
|
|
if (model.pics().length === 0) {
|
|
load();
|
|
}
|
|
|
|
if (!$modal) {
|
|
$modal = $('#choose-pic-modal');
|
|
ko.applyBindings(model, $modal.find('.modal-content')[0]);
|
|
}
|
|
|
|
$modal.modal('show');
|
|
};
|
|
|
|
this.close = function () {
|
|
$modal.modal('hide');
|
|
};
|
|
|
|
this.value = function () {
|
|
return model.picurl();
|
|
};
|
|
|
|
this.submit = function () {
|
|
if (opts.callbacks && opts.callbacks.submit) {
|
|
opts.callbacks.submit.apply(self, [self.value()]);
|
|
}
|
|
|
|
self.close();
|
|
};
|
|
|
|
this.random = function () {
|
|
var sample = _.sample(model.pics());
|
|
return sample ? sample.cover_url : null;
|
|
};
|
|
|
|
this.load = function () {
|
|
if (loaderPromise) {
|
|
return loaderPromise;
|
|
}
|
|
|
|
var defer = $.Deferred();
|
|
if (model.pics().length > 0) {
|
|
defer.resolve();
|
|
} else {
|
|
$.get('{:url('customservice/api_get_covers')}', {type: 2}, function (data) {
|
|
model.pics(data);
|
|
defer.resolve();
|
|
});
|
|
}
|
|
|
|
loaderPromise = defer.promise();
|
|
|
|
return loaderPromise;
|
|
};
|
|
};
|
|
|
|
ChoosePicModal.instance = new ChoosePicModal();
|
|
ChoosePicModal.instance.load();
|
|
|
|
})(jQuery);
|
|
</script>
|
|
<script>
|
|
var taskId = null;
|
|
|
|
var choosePicModal = ChoosePicModal.instance;
|
|
var editTitleModal = EditTitleModal.instance;
|
|
var editSubArticleModal = EditSubArticleModal.instance;
|
|
|
|
var viewModel = {
|
|
processing: ko.observable(false),
|
|
|
|
param: {
|
|
main_article: {
|
|
title: ko.observable(),
|
|
picurl: ko.observable()
|
|
},
|
|
sub_articles: ko.observableArray()
|
|
},
|
|
|
|
id: ko.observable(taskId),
|
|
name: ko.observable(),
|
|
type: ko.observable(),
|
|
interval: ko.observable(),
|
|
url: ko.observable(),
|
|
andience: ko.observable('0'),
|
|
scheduled_at: ko.observable(),
|
|
|
|
test_member_id: ko.observable()
|
|
};
|
|
|
|
viewModel.editMainTitle = function () {
|
|
editTitleModal.open({
|
|
title: viewModel.param.main_article.title(),
|
|
callbacks: {
|
|
submit: function (title) {
|
|
viewModel.param.main_article.title(title);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
viewModel.editMainPic = function () {
|
|
choosePicModal.open({
|
|
picurl: viewModel.param.main_article.picurl(),
|
|
callbacks: {
|
|
submit: function (url) {
|
|
if (url) {
|
|
viewModel.param.main_article.picurl(url);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
viewModel.addSubArticle = function () {
|
|
viewModel.param.sub_articles.push({
|
|
title: ko.observable(editTitleModal.random()),
|
|
picurl: ko.observable(choosePicModal.random()),
|
|
url: ko.observable()
|
|
});
|
|
};
|
|
|
|
viewModel.editSubArticle = function (article) {
|
|
editSubArticleModal.open({
|
|
title: article.title(),
|
|
url: article.url(),
|
|
callbacks: {
|
|
submit: function (data) {
|
|
article.title(data.title);
|
|
article.url(data.url);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
viewModel.editSubArticlePic = function (article) {
|
|
choosePicModal.open({
|
|
picurl: article.picurl(),
|
|
callbacks: {
|
|
submit: function (url) {
|
|
if (url) {
|
|
article.picurl(url);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
viewModel.removeSubArticle = function (idx) {
|
|
viewModel.param.sub_articles.splice(idx, 1);
|
|
};
|
|
|
|
viewModel.shortenUrl = function (url) {
|
|
// http 比 https 短, 因此处理 https 即可
|
|
var index = url.indexOf('/', 'https://'.length);
|
|
return index >= 0 ? url.substr(index) : '/';
|
|
};
|
|
|
|
viewModel.setScheduleTime = function (value, unit) {
|
|
viewModel.scheduled_at(moment().add(value, unit).format('YYYY-MM-DD HH:mm'));
|
|
};
|
|
|
|
viewModel.test = function () {
|
|
if (viewModel.processing()) {
|
|
return false;
|
|
}
|
|
|
|
if (!$('#main-form').valid()) {
|
|
return false;
|
|
}
|
|
|
|
if (!viewModel.test_member_id() || !/^\d+$/.test(viewModel.test_member_id())) {
|
|
updateAlert('测试粉丝ID必须为数字','error');
|
|
return false;
|
|
}
|
|
|
|
var data = viewModel.getPostData();
|
|
data.test_member_id = viewModel.test_member_id();
|
|
|
|
$.ajax({
|
|
url: '{:url('customservice/api_test')}',
|
|
type: 'POST',
|
|
data: JSON.stringify(data),
|
|
contentType: 'application/json',
|
|
dataType: "json",
|
|
success: function(data){
|
|
if (data.code == 0) {
|
|
updateAlert("已发送","success");
|
|
}else if (data.code == 1099) {
|
|
updateAlert("该粉丝不属于你","error");
|
|
}
|
|
}
|
|
})
|
|
/**
|
|
.then(function () {
|
|
updateAlert('已发送, 如未收到,请检查各项参数是否填对', 'success');
|
|
})
|
|
.fail(handleAjaxError);
|
|
***/
|
|
};
|
|
|
|
viewModel.validate = function () {
|
|
if (!$('#main-form').valid()) {
|
|
return false;
|
|
}
|
|
|
|
var errors = [];
|
|
|
|
_.each(viewModel.param.sub_articles(), function (article, idx) {
|
|
if (!article.title()) {
|
|
errors.push('第 ' + (idx + 1) + ' 条次条缺少标题');
|
|
}
|
|
if (!article.url()) {
|
|
errors.push('第 ' + (idx + 1) + ' 条次条未设置链接');
|
|
}
|
|
});
|
|
|
|
if (errors.length > 0) {
|
|
Modal.alert({
|
|
title: '错误',
|
|
message: errors.join('<br/>')
|
|
});
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
viewModel.submit = function () {
|
|
if (viewModel.processing()) {
|
|
return false;
|
|
}
|
|
|
|
if (!viewModel.name()) {
|
|
viewModel.name(viewModel.param.main_article.title());
|
|
}
|
|
|
|
if (!viewModel.validate()) {
|
|
return false;
|
|
}
|
|
|
|
viewModel.processing(true);
|
|
|
|
$.ajax({
|
|
url: '{:url('add')}',
|
|
type: 'POST',
|
|
data: JSON.stringify(viewModel.getPostData()),
|
|
contentType: 'application/json'
|
|
})
|
|
|
|
.then(function () {
|
|
//toastr.success('保存成功');
|
|
updateAlert('保存成功', 'success');
|
|
setTimeout(function () {
|
|
location.href = '{:url('customservice/index')}';
|
|
}, 500);
|
|
})
|
|
|
|
.fail(handleAjaxError)
|
|
.always(function () {
|
|
viewModel.processing(false);
|
|
});
|
|
};
|
|
|
|
viewModel.getPostData = function () {
|
|
var articles = [ko.mapping.toJS(viewModel.param.main_article)];
|
|
|
|
_.each(viewModel.param.sub_articles(), function (it) {
|
|
articles.push(ko.mapping.toJS(it));
|
|
});
|
|
|
|
return {
|
|
id: viewModel.id(),
|
|
name: viewModel.name(),
|
|
type: viewModel.type(),
|
|
interval: viewModel.interval(),
|
|
param: {
|
|
articles: articles
|
|
},
|
|
url: viewModel.url(),
|
|
andience: viewModel.andience(),
|
|
scheduled_at: viewModel.scheduled_at()
|
|
};
|
|
};
|
|
|
|
viewModel.test_member_id.subscribe(function (value) {
|
|
window.localStorage.setItem('test_member_id', value);
|
|
});
|
|
|
|
$(function () {
|
|
$.when(
|
|
editTitleModal.load(),
|
|
choosePicModal.load()
|
|
).then(function () {
|
|
if (taskId) {
|
|
$.get('/backend/tasks/rich_msg/api_get/' + taskId, function (data) {
|
|
// 如果编辑的是一个已过期但未执行的任务, 则把时间置空, 让用户重新选择
|
|
var tsNow = new Date().getTime();
|
|
var tsScheduledAt = moment(data.scheduled_at, 'YYYY-MM-DD HH:mm:ss').valueOf();
|
|
|
|
if (tsScheduledAt < tsNow) {
|
|
data.scheduled_at = null;
|
|
}
|
|
|
|
var mainArticle = data.param.articles[0];
|
|
data.param.articles.shift();
|
|
var subArticles = data.param.articles;
|
|
|
|
data.param = {
|
|
main_article: mainArticle,
|
|
sub_articles: subArticles
|
|
};
|
|
|
|
ko.mapping.fromJS(data, {}, viewModel);
|
|
|
|
bind();
|
|
});
|
|
} else {
|
|
viewModel.param.main_article.title(editTitleModal.random());
|
|
viewModel.param.main_article.picurl(choosePicModal.random());
|
|
|
|
bind();
|
|
}
|
|
});
|
|
|
|
function bind() {
|
|
ko.applyBindings(viewModel, document.getElementById('main-form'));
|
|
|
|
UIComponent.handlers['ref-link-search-box'].init([$('#url-input')]);
|
|
|
|
viewModel.test_member_id(window.localStorage.getItem('test_member_id'));
|
|
}
|
|
});
|
|
</script>
|
|
<!-- basic scripts -->
|
|
<script src="/public/plugs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
|
<script src="/public/plugs/webui-popover/2.1.15/jquery.webui-popover.min.js"></script>
|
|
<script src="/public/plugs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>
|
|
<script src="/public/plugs/webui-popover/2.1.15/jquery.webui-popover.min.js"></script>
|
|
<link rel="stylesheet" href="/public/plugs/webui-popover/2.1.15/jquery.webui-popover.min.css">
|
|
<link rel="stylesheet" href="__PUBLIC__/plugs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css">
|
|
|
|
<link href="/public/plugs/datepicker/css/foundation-datepicker.min.css" rel="stylesheet" type="text/css">
|
|
<script src="/public/plugs/datepicker/js/foundation-datepicker.js"></script>
|
|
<script src="/public/plugs/datepicker/js/foundation-datepicker.zh-CN.js"></script>
|
|
|
|
<script>
|
|
|
|
$(function () {
|
|
/*! 默认类型事件 */
|
|
$('body').on('change', 'select[name=type]', function () {
|
|
var value = $(this).val(), $form = $(this).parents('form');
|
|
if (value==2)
|
|
{
|
|
$form.find('#forminterval').show();
|
|
$form.find('#formscheduled').hide();
|
|
|
|
}else{
|
|
$form.find('#forminterval').hide();
|
|
$form.find('#formscheduled').show();
|
|
}
|
|
//var $current = $form.find('[data-keys-type="' + value + '"]').removeClass('hide');
|
|
//$form.find('[data-keys-type]').not($current).addClass('hide');
|
|
console.log(value);
|
|
});
|
|
|
|
$('.btn-member-id-screen').webuiPopover({
|
|
html: true,
|
|
trigger: 'hover',
|
|
placement: 'top',
|
|
content: function() {
|
|
return '<div style="width:240px;min-height:430px"><img style="max-width:100%" src="/uploads/guide-user-center.jpg" /></div>';
|
|
}
|
|
});
|
|
|
|
$('#scheduled_at').fdatepicker({
|
|
format: 'yyyy-mm-dd hh:ii',
|
|
pickTime: true
|
|
});
|
|
|
|
|
|
});
|
|
</script>
|
|
|
|
{/block} |