Subscribe.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. <?php
  2. namespace app\admin\controller\wechat;
  3. use app\common\constants\Message;
  4. use app\common\controller\Backend;
  5. use app\common\library\Redis;
  6. use app\main\constants\WechatSubscribeConstants;
  7. use app\main\service\AdminService;
  8. use app\main\service\UrlService;
  9. use think\Exception;
  10. /**
  11. * 被关注回复配置管理
  12. *
  13. * @icon fa fa-circle-o
  14. */
  15. class Subscribe extends Backend
  16. {
  17. protected $gzhName = null;
  18. public $noNeedRight = ['getkandian','getlist','del'];
  19. /**
  20. * WechatSubscribeConfig模型对象
  21. */
  22. protected $model = null;
  23. public function _initialize()
  24. {
  25. parent::_initialize();
  26. //公众号名称
  27. $wxJson = model("AdminConfig")
  28. ->where('admin_id', $this->auth->id)
  29. ->value('json');
  30. if (!empty($wxJson)) {
  31. $wxInfo = json_decode($wxJson, true);
  32. $this->gzhName = $wxInfo['authorizer_info']['nick_name'];
  33. }
  34. $this->model = model('WechatSubscribeConfig');
  35. }
  36. /**
  37. * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个方法
  38. * 因此在当前控制器中可不用编写增删改查的代码,如果需要自己控制这部分逻辑
  39. * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
  40. */
  41. /**
  42. * 被关注回复设置
  43. *
  44. * @return string|\think\response\Json
  45. * @throws \think\Exception
  46. */
  47. public function index()
  48. {
  49. $this->request->filter(['strip_tags']);
  50. if($this->request->isPost()){
  51. $data = [
  52. 'status'=>1,
  53. 'type'=>1
  54. ];
  55. $switch = model('WechatSubscribeSwitch')->where('admin_id','eq',$this->auth->id)->find();
  56. if(!empty($switch)){
  57. $data['status'] = $switch['status'];
  58. $data['type'] = $switch['type'];
  59. }
  60. return json($data);
  61. }
  62. return $this->view->fetch();
  63. }
  64. /**
  65. * 设置开启/关闭状态
  66. *
  67. * @return string|\think\response\Json
  68. */
  69. public function operate()
  70. {
  71. $enabled = $this->request->param('enabled');
  72. $type = $this->request->param('type');
  73. $updateData = [];
  74. if ($enabled == 1) {
  75. //开启
  76. $updateData['status'] = 1;
  77. } elseif ($enabled == 2) {
  78. //关闭
  79. $updateData['status'] = 2;
  80. } else {
  81. //异常状态
  82. $this->error('参数错误');
  83. }
  84. $updateData['type'] = $type;
  85. $updateData['updatetime'] = time();
  86. $config = model('WechatSubscribeSwitch')->where('admin_id', 'eq', $this->auth->id)->find();
  87. if ($config) {//编辑
  88. $result = $config->save($updateData);
  89. } else {
  90. // switch
  91. $switch['admin_id'] = $this->auth->id;
  92. $switch['status'] = $updateData['status'];
  93. $switch['type'] = $updateData['type'];
  94. $switch['createtime'] = time();
  95. $switch['updatetime'] = time();
  96. model('WechatSubscribeSwitch')->save($switch);
  97. }
  98. Redis::instance()->del('OSSC:' . $this->auth->id);
  99. Redis::instance()->del('OSCC:' . $this->auth->id);
  100. Redis::instance()->del('OSCCT:' . $this->auth->id);
  101. if ($result !== false) {
  102. $this->success();
  103. } else {
  104. $this->error($this->model->getError());
  105. }
  106. }
  107. /**
  108. * 保存设置
  109. * @return string|\think\response\Json *
  110. */
  111. public function save()
  112. {
  113. if ($this->request->isPost()) {
  114. //签到方式 $sign_type 1=> 回复签到; 2 => 自动签到
  115. $data = json_decode($this->request->post('data'), true);
  116. $timeChecker = $this->timeChecker(strtotime($data['starttime']),strtotime($data['endtime']),$data['id']);
  117. if($timeChecker['code'] == 0){
  118. $this->error($timeChecker['msg']);
  119. }
  120. $sign_type = $data["sign_type"]??'';
  121. //签到文案
  122. $sign_txt = $data["sign_txt"]??'';
  123. $newsContent = $data["news_content"]??'[]';
  124. $textContent = $data["text_content"]??'[]';
  125. $subType = $data["sub_type"]??'';
  126. //文本每一二条之间的提示语
  127. $text_split = $data["text_split"]??'';
  128. $text_tip = $data["text_tip"]??'';
  129. $text_tip = str_replace('<br>',"\r\n", $text_tip);
  130. $text_tip_word = json_encode([
  131. 'text_split' => $text_split,
  132. 'text_tip' => $text_tip,
  133. ],JSON_UNESCAPED_UNICODE);
  134. $tmp = $subType;
  135. $content = '';
  136. if ($subType == 'news') {
  137. $content = json_encode($newsContent, JSON_UNESCAPED_UNICODE);
  138. } elseif ($subType == 'text') {
  139. $content = json_encode($textContent, JSON_UNESCAPED_UNICODE);
  140. }
  141. //替换域名
  142. if ($content) {
  143. $content = UrlService::instance()->replaceReferralHost($this->getCurrentAccountChannelId(), $content)->data;
  144. }
  145. try {
  146. $isNew = false;
  147. $config = $this->model
  148. ->where('id', 'eq', $data['id'])
  149. ->find();
  150. if (empty($data['id']) || !isset($data['id'])) {
  151. //新增设置
  152. $configData['admin_id'] = $this->auth->id;
  153. if($subType == 'news'){
  154. $configData['type'] = 'news';
  155. $configData['news_content'] = $content;
  156. $configData['text_content'] = '';
  157. }else{
  158. $configData['type'] = 'text';
  159. $configData['text_content'] = $content;
  160. $configData['news_content'] = '';
  161. }
  162. $configData['event_keys'] = json_encode([
  163. 'text' => '',
  164. 'news' => ''
  165. ], JSON_UNESCAPED_UNICODE);
  166. $configData['sign_type'] = $sign_type;
  167. $configData['sign_txt'] = $sign_txt;
  168. $configData['title'] = $data['title'];
  169. $configData['starttime'] = strtotime($data['starttime']);
  170. $configData['endtime'] = strtotime($data['endtime']);
  171. $configData['status'] = $data['show_type'];
  172. $result = $this->model->allowField(true)->save($configData);
  173. if ($result == false) {
  174. throw new Exception($this->model->getError());
  175. }
  176. $isNew = true;
  177. $updateConfigData = [
  178. 'event_keys' => [
  179. 'text' => '',
  180. 'news' => '',
  181. ],
  182. 'text_content' => '',
  183. 'news_content' => '',
  184. 'text_tip_word' => $text_tip_word,
  185. ];
  186. }
  187. else {
  188. $updateConfigData = [
  189. 'event_keys' => json_decode($config->event_keys, true),
  190. 'type' => $subType,
  191. 'text_tip_word' => $text_tip_word,
  192. 'sign_type' => $sign_type,
  193. 'sign_txt' => $sign_type == WechatSubscribeConstants::SUBCRIBE_SIGN_TYPE_TWO ? $sign_txt : ''
  194. ];
  195. }
  196. $updateConfigData['title'] = $data['title'];
  197. $updateConfigData['starttime'] = strtotime($data['starttime']);
  198. $updateConfigData['endtime'] = strtotime($data['endtime']);
  199. $updateConfigData['status'] = $data['show_type'];
  200. if($subType == 'news'){
  201. $updateConfigData['type'] = 'news';
  202. $updateConfigData['news_content'] = $content;
  203. $updateConfigData['text_content'] = '';
  204. }else{
  205. $updateConfigData['type'] = 'text';
  206. $updateConfigData['text_content'] = $content;
  207. $updateConfigData['news_content'] = '';
  208. }
  209. $replyEventkey = '';
  210. //走更新路线
  211. if (!$isNew && !empty($config->event_keys)) {
  212. $eventKeys = json_decode($config->event_keys, true);
  213. if (isset($eventKeys[$tmp])) {
  214. $replyEventkey = $eventKeys[$tmp];
  215. $resourceModel = model("WechatResponse")
  216. ->where('eventkey', 'eq', $replyEventkey)
  217. ->find();
  218. if (empty($resourceModel)) {
  219. $isNew = true;
  220. }
  221. } else {
  222. $isNew = true;
  223. }
  224. }
  225. if ($isNew) {
  226. //新建资源
  227. $resourceData = [
  228. 'admin_id' => $this->auth->id,
  229. 'title' => '',
  230. 'eventkey' => $this->auth->id . '_' . uniqid(),
  231. 'type' => $tmp,
  232. 'content' => '',
  233. 'status' => 'normal',
  234. 'is_subscribe' => '1'
  235. ];
  236. //先创建
  237. $resourceResult = model("WechatResponse")
  238. ->allowField(true)
  239. ->save($resourceData);
  240. if ($resourceResult !== false) {
  241. $replyEventkey = $resourceData['eventkey'];
  242. } else {
  243. throw new Exception('创建回复资源失败');
  244. }
  245. }
  246. switch ($tmp) {
  247. case WechatSubscribeConstants::SUBCRIBE_TYPE_TEXT:
  248. //组织内容
  249. if($sign_type == WechatSubscribeConstants::SUBCRIBE_SIGN_TYPE_TWO ){
  250. $temp = WechatSubscribeConstants::SUBCRIBE_TEXT_SIGN_TEMPLATE;
  251. }else{
  252. $temp = WechatSubscribeConstants::SUBCRIBE_TEXT_TEMPLATE;
  253. }
  254. $bookTemp = WechatSubscribeConstants::SUBCRIBE_TEXT_BOOK_TEMPLATE;
  255. $bookSets = json_decode($content, true);
  256. $contentStr = [];
  257. $resourceContent = '';
  258. if (is_array($bookSets)) {
  259. foreach ($bookSets as $index=>$bookSet) {
  260. if ($index == 1 && $text_split) {
  261. $contentStr[] = $text_split;
  262. }
  263. $url = $bookSet['url'];
  264. $title = $bookSet['title'];
  265. $contentStr[] = str_replace(['{URL}', '{TITLE}'], [$url, $title], $bookTemp);
  266. }
  267. $resourceContent = str_replace(['{TEXT_TIP}', '$gzh_name', '{CONTENT}'], [$text_tip, $this->gzhName, implode("\r\n\r\n", $contentStr)], $temp);
  268. }
  269. if($sign_type == WechatSubscribeConstants::SUBCRIBE_SIGN_TYPE_TWO){
  270. $sign_str = "<a href='weixin://bizmsgmenu?msgmenucontent=" . Message::MESSAGE_KEYWORD . "&msgmenuid={{" . time() . "}}\"'>{$sign_txt}</a>";
  271. $resourceContent = str_replace('{SIGNTXT}', $sign_str, $resourceContent);
  272. }
  273. $newResourceData = [
  274. 'type' => 'text',
  275. 'title' => '文字类型回复',
  276. 'content' => $resourceContent,
  277. ];
  278. $updateConfigData['event_keys']['text'] = $replyEventkey;
  279. $updateConfigData['text_content'] = $content;
  280. break;
  281. case WechatSubscribeConstants::SUBCRIBE_TYPE_NEWS:
  282. $newResourceData = [
  283. 'type' => 'news',
  284. 'title' => '图文类型回复',
  285. 'content' => $content,
  286. ];
  287. $updateConfigData['event_keys']['news'] = $replyEventkey;
  288. $updateConfigData['news_content'] = $content;
  289. break;
  290. }
  291. //更新资源
  292. $resourceResult = model("WechatResponse")
  293. ->allowField(true)
  294. ->save($newResourceData, ['eventkey'=>$replyEventkey]);
  295. if ($resourceResult == false) {
  296. throw new Exception('创建回复资源失败');
  297. }
  298. //创建成功后替换关键字回复的event_key
  299. $maps = [
  300. 'admin_id' => ['eq', $this->auth->id],
  301. 'text' => ['eq', 'subscribe']
  302. ];
  303. $replyModel = model("WechatAutoreply")->where($maps)->find();
  304. if (empty($replyModel)) {
  305. //新增
  306. $replyModel = model("WechatAutoreply")->allowField(true)
  307. ->save(
  308. [
  309. 'admin_id' => $this->auth->id,
  310. 'title' => 'subscribe',
  311. 'text' => 'subscribe',
  312. 'eventkey' => $replyEventkey,
  313. 'status' => 'normal'
  314. ]
  315. );
  316. if ($replyModel === false) {
  317. throw new Exception('创建关键字回复失败');
  318. }
  319. } else {
  320. //更新
  321. $replyModel->save(['eventkey' => $replyEventkey]);
  322. }
  323. $updateConfigData['event_keys'] = json_encode($updateConfigData['event_keys'], JSON_UNESCAPED_UNICODE);
  324. //更新设置
  325. $result = $this->model->allowField(true)->save($updateConfigData, ['id' => $data['id']]);
  326. if ($result !== false) {
  327. Redis::instance()->del('OSCC:' . $this->auth->id);
  328. Redis::instance()->del('OSCC:' . $this->auth->id);
  329. Redis::instance()->del('OSCCT:' . $this->auth->id);
  330. $this->success();
  331. } else {
  332. $this->error($this->model->getError());
  333. }
  334. } catch (\think\exception\PDOException $e) {
  335. $this->error($e->getMessage());
  336. } catch (Exception $e) {
  337. $this->error($e->getMessage());
  338. }
  339. } else {
  340. $this->error(__('Parameter %s can not be empty', ''));
  341. }
  342. }
  343. /**
  344. * 列表
  345. */
  346. public function getlist()
  347. {
  348. //设置过滤方法
  349. $this->request->filter(['strip_tags']);
  350. if ($this->request->isPost())
  351. {
  352. $pageSize = $this->request->post("pageSize", 20);
  353. $pageNo = $this->request->post("pageNo", 1);
  354. $where['admin_id'] = ['eq',$this->auth->id];
  355. $total = $this->model->where($where)->order('id','desc')->count();
  356. $list = $this->model->where($where)->order('id','desc')->paginate($pageSize,false,['page'=>$pageNo]);
  357. $rows = [];
  358. if(!empty($list)){
  359. foreach($list as $key=>$li){
  360. $rows[$key]['id'] = $li['id'];
  361. $rows[$key]['title'] = $li['title'];
  362. $rows[$key]['type'] = $li['type'];
  363. $rows[$key]['sign_type'] = $li['sign_type'];
  364. $rows[$key]['sign_txt'] = $li['sign_txt'];
  365. $rows[$key]['text_tip_word'] = $li['text_tip_word'];
  366. $rows[$key]['type_text'] = $li['type'] == 'news' ? '图文形式' : '文字形式';
  367. $rows[$key]['text_content'] = $li['text_content'];
  368. $rows[$key]['news_content'] = $li['news_content'];
  369. $rows[$key]['status'] = $li['status'] == 'normal' ? 1 : 2;
  370. $rows[$key]['status_text'] = $li['status'] == 'normal' ? '生效' : '失效';
  371. if(empty($li['title'])){
  372. $rows[$key]['title'] = '老数据';
  373. }
  374. $rows[$key]['updatetime'] = date('Y-m-d H:i:s',$li['updatetime']);
  375. $rows[$key]['starttime'] = empty($li['starttime']) ? '-' : date('Y-m-d H:i:s',$li['starttime']);
  376. $rows[$key]['endtime'] = empty($li['endtime']) ? '-' : date('Y-m-d H:i:s',$li['endtime']);
  377. $rows[$key]['kandian'] = \think\Config::get('site.kandian_sign');
  378. }
  379. }
  380. $result = array("total" => $total, "rows" => $rows);
  381. return json($result);
  382. }
  383. return $this->view->fetch();
  384. }
  385. private function timeChecker($starttime,$endtime,$id){
  386. $result = ['code'=>1,'msg'=>''];
  387. if(empty($starttime) && empty($endtime)){
  388. $result = ['code'=>0,'msg'=>'起止时间不能为空'];
  389. }
  390. if(!empty($starttime) && $starttime >= $endtime){
  391. $result = ['code'=>0,'msg'=>'结束时间要晚于开始时间'];
  392. }
  393. if((!empty($starttime) && empty($endtime)) || (empty($starttime) && !empty($endtime))){
  394. $result = ['code'=>0,'msg'=>'起止时间不能为空'];
  395. }
  396. $maps = [
  397. 'admin_id' => $this->auth->id,
  398. 'status' => 'normal'
  399. ];
  400. if($id){
  401. $maps['id'] = ['neq',$id];
  402. }
  403. $rows = $this->model->where($maps)->field('id,starttime,endtime')->select();
  404. if(!empty($rows)){
  405. foreach($rows as $row){
  406. if($starttime >= $row['starttime'] && $row['endtime'] >= $starttime){
  407. $result = ['code'=>0,'msg'=>'设置的起止时间有重复'];
  408. break;
  409. }
  410. if($endtime >= $row['starttime'] && $row['endtime'] >= $endtime){
  411. $result = ['code'=>0,'msg'=>'设置的起止时间有重复'];
  412. break;
  413. }
  414. if($endtime == $row['starttime'] && $row['endtime'] == $endtime){
  415. $result = ['code'=>0,'msg'=>'设置的起止时间有重复'];
  416. break;
  417. }
  418. }
  419. }
  420. return $result;
  421. }
  422. public function getkandian(){
  423. $kandian = config('site.kandian_sign');
  424. return ['kandian'=>$kandian];
  425. }
  426. }