edit.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <?php
  2. use yii\widgets\ActiveForm;
  3. use common\enums\StatusEnum;
  4. use common\helpers\Url;
  5. use common\helpers\Html;
  6. use addons\Wechat\merchant\widgets\selector\Select;
  7. use addons\Wechat\common\enums\RuleKeywordTypeEnum;
  8. $this->title = $model->isNewRecord ? '创建' : '编辑';
  9. $this->params['breadcrumbs'][] = ['label' => '自动回复', 'url' => ['rule/index']];
  10. $this->params['breadcrumbs'][] = $this->title;
  11. ?>
  12. <?= Html::cssFile('@web/resources/css/checkbox.css'); ?>
  13. <?php $form = ActiveForm::begin([
  14. 'id' => 'ruleForm',
  15. 'enableAjaxValidation' => true,
  16. 'validationUrl' => Url::to(['edit', 'id' => $model['id']]),
  17. ]); ?>
  18. <style>
  19. .panel-default {
  20. border-color: #ddd;
  21. }
  22. .panel {
  23. margin-bottom: 20px;
  24. background-color: #fff;
  25. border: 1px solid transparent;
  26. border-radius: 4px;
  27. -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
  28. box-shadow: 0 1px 1px rgba(0,0,0,.05);
  29. }
  30. .panel-default > .panel-heading {
  31. color: #333;
  32. background-color: #f5f5f5;
  33. border-color: #ddd;
  34. }
  35. .panel-heading {
  36. padding: 10px 15px;
  37. border-bottom: 1px solid transparent;
  38. border-bottom-color: transparent;
  39. border-top-left-radius: 3px;
  40. border-top-right-radius: 3px;
  41. }
  42. .collapse.in {
  43. display: block;
  44. }
  45. .collapse {
  46. display: none;
  47. }
  48. .panel-default > .panel-heading + .panel-collapse > .panel-body {
  49. border-top-color: #ddd;
  50. }
  51. .panel-body {
  52. padding: 15px;
  53. }
  54. .panel-default {
  55. border-color: #e4eaec;
  56. }
  57. .panel {
  58. border: 1px solid #e4eaec;
  59. border-top-color: rgb(228, 234, 236);
  60. border-right-color: rgb(228, 234, 236);
  61. border-bottom-color: rgb(228, 234, 236);
  62. border-left-color: rgb(228, 234, 236);
  63. }
  64. </style>
  65. <div class="row">
  66. <div class="col-sm-12">
  67. <div class="panel panel-default">
  68. <div class="panel-heading">
  69. <span class="collapsed">回复规则</span>
  70. </div>
  71. <div id="collapseOne" class="panel-collapse collapse in" aria-expanded="true">
  72. <div class="panel-body">
  73. <div class="row">
  74. <div class="col-sm-9">
  75. <?= $form->field($model, 'name')->textInput()->hint('您可以给这条规则起一个名字, 方便下次修改和查看。') ?>
  76. <div class="setting" style="display: none">
  77. <?= $form->field($model, 'sort')->textInput()->hint('规则优先级,越大则越靠前,最大不得超过255') ?>
  78. </div>
  79. </div>
  80. <div class="col-sm-3 col-md-2 m-t-md">
  81. <div class="checkbox">
  82. <?= Html::checkbox('setting', false, [
  83. 'class' => "styled adv",
  84. 'id' => 'setting',
  85. ]); ?>
  86. <label for="setting">高级设置</label>
  87. </div>
  88. </div>
  89. </div>
  90. <div class="row">
  91. <div class="col-sm-9">
  92. <?= $form->field($model, 'keyword')->textInput(['value'=> implode(',',$ruleKeywords[RuleKeywordTypeEnum::MATCH])])->hint('多个关键字请使用逗号隔开,如天气,今日天气。')->label('关键字') ?>
  93. <div class="trigger" style="display: none">
  94. <div class="form-group">
  95. <label class="control-label">高级触发列表</label>
  96. </div>
  97. <div class="form-group well">
  98. <div class="tabs-container">
  99. <div class="tabs-top">
  100. <ul class="nav nav-tabs">
  101. <li class="nav-link active"><a data-toggle="tab" href="#tab-11" aria-expanded="true"> 包含关键字</a></li>
  102. <li class="nav-link"><a data-toggle="tab" href="#tab-12" aria-expanded="false"> 正则表达式模式匹配</a></li>
  103. <li class="nav-link"><a data-toggle="tab" href="#tab-13" aria-expanded="false"> 直接接管</a></li>
  104. </ul>
  105. <div class="tab-content ">
  106. <div id="tab-11" class="tab-pane active">
  107. <div class="panel-body">
  108. <table class="table table-hover">
  109. <tbody id="list-key-<?= RuleKeywordTypeEnum::INCLUDE?>">
  110. <?php foreach ($ruleKeywords[RuleKeywordTypeEnum::INCLUDE] as $value){ ?>
  111. <tr>
  112. <td class="saveKeywordInput">
  113. <span class="key-hint"></span>
  114. <span class="key-text"><?= $value?></span>
  115. <input type="text" class="form-control key-input" name="ruleKey[<?= RuleKeywordTypeEnum::INCLUDE ?>][]" value="<?= $value?>" style="display: none;">
  116. </td>
  117. <td type="<?= RuleKeywordTypeEnum::INCLUDE ?>">
  118. <span class="btn btn-white saveKeyword edit-Keyword">编辑</span>
  119. <span class="btn btn-white" onclick="$(this).parent().parent().remove()">删除</span>
  120. </td>
  121. </tr>
  122. <?php } ?>
  123. </tbody>
  124. </table>
  125. </div>
  126. <div class="panel-heading" type="<?= RuleKeywordTypeEnum::INCLUDE?>">
  127. <span class="btn btn-white addKeyword">添加包含关键字</span>
  128. <span class="help-block ng-binding">用户进行交谈时,对话中包含上述关键字就执行这条规则。</span>
  129. </div>
  130. </div>
  131. <div id="tab-12" class="tab-pane">
  132. <div class="panel-body">
  133. <table class="table table-hover">
  134. <tbody id="list-key-<?= RuleKeywordTypeEnum::REGULAR?>">
  135. <?php foreach ($ruleKeywords[RuleKeywordTypeEnum::REGULAR] as $value){ ?>
  136. <tr>
  137. <td class="saveKeywordInput">
  138. <span class="key-hint"></span>
  139. <span class="key-text"><?= $value?></span>
  140. <input type="text" class="form-control key-input" name="ruleKey[<?= RuleKeywordTypeEnum::REGULAR ?>][]" value="<?= $value?>" style="display: none;">
  141. </td>
  142. <td type="<?= RuleKeywordTypeEnum::REGULAR ?>">
  143. <span class="btn btn-white saveKeyword edit-Keyword">编辑</span>
  144. <span class="btn btn-white" onclick="$(this).parent().parent().remove()">删除</span>
  145. </td>
  146. </tr>
  147. <?php } ?>
  148. </tbody>
  149. </table>
  150. </div>
  151. <div class="panel-heading" type="<?= RuleKeywordTypeEnum::REGULAR?>">
  152. <span class="btn btn-white addKeyword">添加正则表达式模式</span>
  153. <span class="help-block ng-binding">
  154. 用户进行交谈时,对话内容符合述关键字中定义的模式才会执行这条规则。<br>
  155. <strong>注意:如果你不明白正则表达式的工作方式,请不要使用正则匹配</strong> <br>
  156. <strong>注意:正则匹配使用MySQL的匹配引擎,请使用MySQL的正则语法</strong> <br>
  157. <strong>示例: </strong><br>
  158. <label>^微信</label> 匹配以“微信”开头的语句<br>
  159. <label>微信$</label> 匹配以“微信”结尾的语句<br>
  160. <label>^微信$</label> 匹配等同“微信”的语句<br>
  161. <label>微信</label> 匹配包含“微信”的语句<br>
  162. <label>[0-9.-]</label> 匹配所有的数字,句号和减号<br>
  163. <label>^[a-zA-Z_]$</label> 匹配所有的字母和下划线<br>
  164. <label>^[[:alpha:]]{3}$</label> 匹配所有的3个字母的单词<br>
  165. <label>^a{4}$</label> 匹配aaaa<br>
  166. <label>^a{2,4}$</label> 匹配aa,aaa或aaaa<br>
  167. <label>^a{2,}$</label> 匹配多于两个a的字符串
  168. </span>
  169. </div>
  170. </div>
  171. <div id="tab-13" class="tab-pane">
  172. <div class="panel-body">
  173. <table class="table">
  174. <tbody id="list-key-<?= RuleKeywordTypeEnum::TAKE?>">
  175. <?php foreach ($ruleKeywords[RuleKeywordTypeEnum::TAKE] as $value){ ?>
  176. <tr>
  177. <td>
  178. <span class="key-text">符合优先级条件时, 这条回复将直接生效</span>
  179. <input type="hidden" name="ruleKey[<?= RuleKeywordTypeEnum::TAKE ?>][]" value="">
  180. </td>
  181. <td type="<?= RuleKeywordTypeEnum::TAKE ?>">
  182. <span class="btn btn-white" onclick="$(this).parent().parent().remove()">取消接管</span>
  183. </td>
  184. </tr>
  185. <?php } ?>
  186. </tbody>
  187. </table>
  188. </div>
  189. <div class="panel-heading" type="<?= RuleKeywordTypeEnum::TAKE?>">
  190. <span class="btn btn-white addKeyword">直接接管</span>
  191. <span class="help-block ng-binding">
  192. 如果没有比这条回复优先级更高的回复被触发,那么直接使用这条回复。<br>
  193. <strong>注意:如果你不明白这个机制的工作方式,请不要使用直接接管</strong>
  194. </span>
  195. </div>
  196. </div>
  197. </div>
  198. </div>
  199. </div>
  200. </div>
  201. </div>
  202. </div>
  203. <div class="col-sm-3 col-md-2 m-t-md">
  204. <div class="checkbox">
  205. <?= Html::checkbox('trigger', false, [
  206. 'class' => "styled adv",
  207. 'id' => 'trigger',
  208. ]); ?>
  209. <label for="trigger">高级设置</label>
  210. </div>
  211. </div>
  212. </div>
  213. <div class="row">
  214. <div class="col-sm-9">
  215. <?= $form->field($model, 'status')->radioList(StatusEnum::getMap())->hint('您可以临时禁用这条回复') ?>
  216. </div>
  217. </div>
  218. </div>
  219. </div>
  220. </div>
  221. </div>
  222. </div>
  223. <div class="col-sm-12">
  224. <div class="card card-primary card-outline card-outline-tabs">
  225. <div class="card-header border-bottom-0">
  226. <ul class="nav nav-tabs" id="custom-tabs-four-tab" role="tablist">
  227. <li class="nav-item"><a class="nav-link text active" data-toggle="pill" href="#custom-1" onclick="setType('text')">内容</a></li>
  228. <li class="nav-item"><a class="nav-link image" data-toggle="pill" href="#custom-2" onclick="setType('image')">图片</a></li>
  229. <li class="nav-item"><a class="nav-link news" data-toggle="pill" href="#custom-3" onclick="setType('news')">图文</a></li>
  230. <li class="nav-item"><a class="nav-link video" data-toggle="pill" href="#custom-4" onclick="setType('video')">视频</a></li>
  231. <li class="nav-item"><a class="nav-link voice" data-toggle="pill" href="#custom-5" onclick="setType('voice')">语音</a></li>
  232. <li class="nav-item"><a class="nav-link user-api" data-toggle="pill" href="#custom-6" onclick="setType('user-api')">自定义接口</a></li>
  233. </ul>
  234. </div>
  235. <div class="card-body">
  236. <div class="tab-content">
  237. <div class="tab-pane fade active show" id="custom-1">
  238. <?= $form->field($model, 'text')->textarea([
  239. 'id' => 'content'
  240. ])->label(false) ?>
  241. </div>
  242. <div class="tab-pane fade" id="custom-2">
  243. <?= $form->field($model, 'image')->widget(Select::class, [
  244. 'type' => 'image',
  245. ])->label(false) ?>
  246. </div>
  247. <div class="tab-pane fade" id="custom-3">
  248. <?= $form->field($model, 'news')->widget(Select::class, [
  249. 'type' => 'news',
  250. 'block' => '由于微信限制,自动回复只能回复一条图文信息,如果有多条图文,默认选择第一条图文',
  251. ])->label(false) ?>
  252. </div>
  253. <div class="tab-pane fade" id="custom-4">
  254. <?= $form->field($model, 'video')->widget(Select::class, [
  255. 'type' => 'video',
  256. ])->label(false) ?>
  257. </div>
  258. <div class="tab-pane fade" id="custom-5">
  259. <?= $form->field($model, 'voice')->widget(Select::class, [
  260. 'type' => 'voice',
  261. ])->label(false) ?>
  262. </div>
  263. <div class="tab-pane fade" id="custom-6">
  264. <?= $form->field($model, 'api_url')->dropDownList($apiList)->hint('1、添加此模块的规则后,只针对于单个规则定义有效,如果需要全部路由给接口处理,则修改该模块的优先级顺序<br>2、本地文件存放在当前插件文件夹内的(/addons/Wechat/common/userapis)下<br>3、文件名格式为*Api.php,例如:TestApi.php') ?>
  265. <?= $form->field($model, 'default')->textInput()->hint('当接口无回复时,则返回用户此处设置的文字信息,优先级高于“默认关键字”') ?>
  266. <?= $form->field($model, 'cache_time')->textInput()->hint('接口返回数据将缓存在系统中的时限,默认为0不缓存') ?>
  267. <?= $form->field($model, 'description')->textarea()->hint('仅作为后台备注接口的用途') ?>
  268. </div>
  269. </div>
  270. </div>
  271. </div>
  272. </div>
  273. <?= $form->field($model, 'module')->hiddenInput(['id' => 'module'])->label(false) ?>
  274. <div class="row">
  275. <div class="col-12 text-center">
  276. <span class="btn btn-primary" onclick="beforeSubmit()">保存</span>
  277. <span class="btn btn-white" onclick="history.go(-1)">返回</span>
  278. </div>
  279. </div>
  280. <?php ActiveForm::end(); ?>
  281. <!--关键字模板-->
  282. <script id="keylist" type="text/html">
  283. <tr>
  284. <td class="saveKeywordInput">
  285. <span class="key-hint"></span>
  286. <span class="key-text"></span>
  287. <input type="text" class="form-control key-input">
  288. </td>
  289. <td type="{{type}}">
  290. <span class="btn btn-white saveKeyword save-Keyword">保存</span>
  291. <span class="btn btn-white" onclick="$(this).parent().parent().remove()">删除</span>
  292. </td>
  293. </tr>
  294. </script>
  295. <!--直接授权模板-->
  296. <script id="keytask" type="text/html">
  297. <tr>
  298. <td>
  299. <span class="key-text">符合优先级条件时, 这条回复将直接生效</span>
  300. <input type="hidden" name="ruleKey[{{type}}][]" value="1">
  301. </td>
  302. <td>
  303. <span class="btn btn-white" onclick="$(this).parent().parent().remove()">取消接管</span>
  304. </td>
  305. </tr>
  306. </script>
  307. <script>
  308. var type = 'text';// 1:文字;2:图片;3:图文;4:视频;5:音频;6:自定义接口
  309. var module = '<?= $model->module; ?>';
  310. var modules = '<?= $modules; ?>';
  311. modules = JSON.parse(modules)
  312. // 设置类型
  313. function setType(num) {
  314. type = num;
  315. }
  316. function beforeSubmit() {
  317. var val = description = title = '';
  318. var id = "<?= $model['id']; ?>";
  319. $('#module').val(type);
  320. $('#ruleForm').submit();
  321. }
  322. $(document).ready(function(){
  323. if (module) {
  324. $('.' + module).trigger('click')
  325. }
  326. // 单击展开
  327. $('.adv').click(function () {
  328. var id = $(this).attr('id');
  329. if($(this).is(':checked')) {
  330. // do something
  331. $('.' + id).show();
  332. }else{
  333. $('.' + id).hide();
  334. }
  335. });
  336. // 展开高级触发
  337. if ($('#list-key-2').html().length > 121 || $('#list-key-3').html().length > 121 || $('#list-key-4').html().length > 121){
  338. $('#trigger').trigger('click');
  339. }
  340. // 添加关键字
  341. var take = "<?= RuleKeywordTypeEnum::TAKE?>";
  342. $('.addKeyword').click(function(){
  343. var self = $(this);
  344. var type = self.parent().attr('type');
  345. var data = [];
  346. data.type = type;
  347. var html = "";
  348. if(type == take){
  349. html += template('keytask', data);
  350. if($('#list-key-'+type+" tr").length < 1){
  351. $('#list-key-'+type).append(html);
  352. }
  353. }else{
  354. html += template('keylist', data);
  355. $('#list-key-'+type).append(html);
  356. }
  357. });
  358. // 保存编辑
  359. $(document).on("click",".saveKeyword",function(){
  360. var self = $(this);
  361. var val = self.parent().parent().find('.key-input').val();
  362. var type = self.parent().attr('type');
  363. if (self.hasClass("save-Keyword")){// 保存
  364. if(val){
  365. self.removeClass("save-Keyword").addClass("edit-Keyword");
  366. self.text('编辑');
  367. self.parent().parent().find('.key-text').text(val);
  368. self.parent().parent().find('.key-text').show();
  369. self.parent().parent().find('.key-input').hide();
  370. self.parent().parent().find('.key-input').attr('name','ruleKey['+type+'][]');
  371. }
  372. } else {// 编辑
  373. self.removeClass("edit-Keyword").addClass("save-Keyword");
  374. self.text('保存');
  375. self.parent().parent().find('.key-text').hide();
  376. self.parent().parent().find('.key-input').show();
  377. self.parent().parent().find('.key-input').attr('name','');
  378. }
  379. });
  380. $("input[name='SendForm[send_type]']").click(function(){
  381. var val = $(this).val();
  382. if (val == 1) {
  383. $('#send_time').addClass('hide');
  384. } else {
  385. $('#send_time').removeClass('hide');
  386. }
  387. })
  388. });
  389. </script>
粤ICP备19079148号