Initial project files: BESCMS full source

This commit is contained in:
bes
2026-08-13 23:37:46 +08:00
parent fa6cddb540
commit 2e26f85723
2166 changed files with 396625 additions and 0 deletions
@@ -0,0 +1,87 @@
<?php namespace Phpcmf\Controllers\Admin;
class Account extends \Phpcmf\Common
{
public function __construct() {
parent::__construct();
if (IS_ADMIN && SITE_ID > 1) {
$this->_admin_msg(0, '请登录主站账号管理微信插件');
}
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME. '账号接入' => [APP_DIR.'/account/index', 'fa fa-weixin'],
'help' => [808],
]
));
}
public function gz_index() {
$rt = weixin_get_access_token();
if ($rt['code']) {
$access_token = $rt['msg'];
$param = [
'expire_seconds' => 2592000,
'action_name' => 'QR_STR_SCENE',
'action_info' => array(
'scene' => array(
'scene_str' => 'login-guanzhu',
),
)
];
$rt = wx_post_https_json_data(
'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $access_token,
$param
);
if (!$rt['code']) {
$this->_admin_msg(0, '生成二维码失败');
}
$url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $rt['data']['ticket'];
echo '<div style="text-align: center"><img src="'.$url.'"></div>';exit;
} else {
$this->_admin_msg(0, $rt['msg']);
}
}
public function index() {
$page = intval(\Phpcmf\Service::L('Input')->get('page'));
$data = \Phpcmf\Service::M('Weixin', 'Weixin')->get_config('account');
if (IS_AJAX_POST) {
$post = \Phpcmf\Service::L('Input')->post('data');
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->save_config('account', $post);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
\Phpcmf\Service::M('Weixin', 'Weixin')->cache();
$rt = weixin_get_access_token($post);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, dr_lang('操作成功'));
}
$rt = weixin_get_access_token();
$access_tocken = $rt['code'] ? '': $rt['msg'];
\Phpcmf\Service::V()->assign([
'data' => $data,
'page' => $page,
'form' => dr_form_hidden(['page' => $page]),
'access_tocken' => $access_tocken,
]);
\Phpcmf\Service::V()->display('account_index.html');
}
}
@@ -0,0 +1,59 @@
<?php namespace Phpcmf\Controllers\Admin;
class Api extends \Phpcmf\Common
{
/**
* 生成安全码
*/
public function token() {
echo 'PHPCMF'.strtoupper(substr((md5(SYS_TIME)), rand(0, 10), 13));exit;
}
/**
* 生成来路随机字符
*/
public function asckey() {
$s = strtoupper(base64_encode(md5(SYS_TIME).md5(rand(0, 2015).md5(rand(0, 2015)))).md5(rand(0, 2009)));
echo substr('PHPCMF'.str_replace('=', '', $s), 0, 43);exit;
}
// 选择素材
public function content() {
// 强制将模板设置为后台
\Phpcmf\Service::V()->admin();
// 登陆判断
!$this->uid && $this->_json(0, dr_lang('会话超时,请重新登录'));
$builder = \Phpcmf\Service::M()->db->table(weixin_wxtable('content'));
// 搜索结果显示条数
$limit = (int)$_GET['limit'];
$limit = $limit ? $limit : 20;
$data = $_GET;
if ($data['search'] && isset($data['keyword']) && $data['keyword']) {
$builder->like('title', urldecode($data['keyword']));
}
$list = $builder->limit($limit)->orderBy('inputtime DESC')->get()->getResultArray();
\Phpcmf\Service::V()->assign(array(
'list' => $list,
'param' => $data,
'search' => dr_form_search_hidden(['search' => 1, 'limit' => $limit]),
'content_type' => [
'index' => '图文',
'image' => '图片',
'voice' => '语音',
'video' => '视频',
],
));
\Phpcmf\Service::V()->display('api_content.html');exit;
}
}
@@ -0,0 +1,36 @@
<?php namespace Phpcmf\Controllers\Admin;
// 已发布内容
class Article extends \Phpcmf\Common
{
public function __construct() {
parent::__construct();
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'已发布内容' => [APP_DIR.'/article/index', 'fa fa-envelope-o'],
]
));
}
public function index() {
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_admin_msg(0, $rt['msg']);
}
$access_token = $rt['msg'];
$rt = wx_post_https_json_data(
'https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token='.$access_token,
[
'offset' => 0,
'count' => 2,
'no_content' => 0,
]
);
var_dump($rt);
}
}
@@ -0,0 +1,53 @@
<?php namespace Phpcmf\Controllers\Admin;
class Config extends \Phpcmf\Common
{
public function __construct() {
parent::__construct();
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'系统配置' => [APP_DIR.'/config/index', 'fa fa-cog'],
]
));
}
public function index() {
$page = intval(\Phpcmf\Service::L('Input')->get('page'));
$data = \Phpcmf\Service::M('Weixin', 'Weixin')->get_config('config');
if (IS_AJAX_POST) {
$post = \Phpcmf\Service::L('Input')->post('data');
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->save_config('config', $post);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, dr_lang('操作成功'));
}
$module = [];
$local = dr_dir_map(APPSPATH, 1); // 搜索本地模块
foreach ($local as $dir) {
if (is_file(APPSPATH.$dir.'/Config/App.php')) {
$key = strtolower($dir);
$cfg = require APPSPATH.$dir.'/Config/App.php';
if ($cfg['type'] == 'module') {
$cfg['dirname'] = $key;
$module[$key] = $cfg;
}
}
}
\Phpcmf\Service::V()->assign([
'data' => $data,
'page' => $page,
'form' => dr_form_hidden(['page' => $page]),
'module' => $module,
]);
\Phpcmf\Service::V()->display('config_index.html');
}
}
@@ -0,0 +1,321 @@
<?php namespace Phpcmf\Controllers\Admin;
// 草稿箱
class Content extends \Phpcmf\Table
{
private $tid;
public function __construct()
{
parent::__construct();
// 支持附表存储
$this->is_data = 0;
// 表单显示名称
$this->name = dr_lang('内容库');
// 字段划分
$j = 0;
$field = [];
for ($i = 1; $i<=9; $i++) {
$field['title_'.$i] = array(
'ismain' => 0,
'displayorder' => $j,
'name' => dr_lang('标题'),
'fieldname' => 'title_'.$i,
'fieldtype' => 'Text',
'setting' => array(
'option' => array(
'width' => '100%',
),
'validate' => array(
'formattr' => ' onblur="dr_wx_show_title('.$i.');"',
)
)
);
$j++;
$field['author_'.$i] = array(
'ismain' => 0,
'displayorder' => $j,
'name' => dr_lang('作者'),
'fieldname' => 'author_'.$i,
'fieldtype' => 'Text',
'setting' => array(
'option' => array(
'width' => 200,
)
)
);
$j++;
$field['thumb_'.$i] = array(
'ismain' => 0,
'displayorder' => $j,
'name' => dr_lang('封面'),
'fieldtype' => 'File',
'fieldname' => 'thumb_'.$i,
'setting' => array(
'option' => array(
'ext' => 'jpg,png,jpeg,gif',
'size' => 20,
),
)
);
$j++;
$field['description_'.$i] = array(
'ismain' => 0,
'displayorder' => $j,
'name' => dr_lang('描述'),
'fieldname' => 'description_'.$i,
'fieldtype' => 'Textarea',
'setting' => array(
'option' => array(
'width' => '90%',
'height' => 70,
),
'validate' => array(
'xss' => 1,
),
)
);
$j++;
$field['content_'.$i] = array(
'ismain' => 0,
'displayorder' => $j,
'name' => dr_lang('内容'),
'fieldtype' => 'Ueditor',
'fieldname' => 'content_'.$i,
'setting' => array(
'option' => array(
'mode' => 1,
'height' => 300,
'width' => '100%',
'mini' => 1,
),
'validate' => [
'tips' => '内容中的图片一定不要太大,否则无法同步到微信服务器'
]
)
);
$j++;
$field['url_'.$i] = array(
'ismain' => 0,
'displayorder' => $j,
'name' => dr_lang('原文地址'),
'fieldname' => 'url_'.$i,
'fieldtype' => 'Text',
'setting' => array(
'option' => array(
'width' => '100%',
)
)
);
}
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('content'),
'field' => $field,
'order_by' => 'inputtime desc',
'date_field' => 'inputtime',
]);
\Phpcmf\Service::V()->assign([
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'内容库' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-th-list'],
'添加' => [''.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
'修改' => ['hide:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-plus'],
'清空附件media_id' => ['ajax:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/clear_del', 'fa fa-file'],
]
),
'myfieldinfo' => $field,
'zt' => [
0 => '发布成功',
1 => '发布中',
2 => '原创失败',
3 => '常规失败',
4 => '平台审核不通过',
5 => '成功后用户删除所有文章',
6 => '成功后系统封禁所有文章',
]
]);
}
public function clear_del() {
\Phpcmf\Service::M()->table(weixin_wxtable('media_id'))->clear_all();
$this->_json(1, '全部附件media_id记录被清空');
}
public function index() {
$where = (string)$_GET['keyword'] ? '`title` LIKE "%'.$_GET['keyword'].'%"' : '';
\Phpcmf\Service::M()->set_where_list($where);
list($tpl) = $this->_list();
\Phpcmf\Service::V()->display($tpl);
}
public function add() {
list($tpl) = $this->_Post();
\Phpcmf\Service::V()->display($tpl);
}
public function edit() {
list($tpl) = $this->_Post(intval(\Phpcmf\Service::L('Input')->get('id')));
\Phpcmf\Service::V()->display($tpl);
}
// 转存素材库
public function module_add() {
$mid = dr_safe_filename($_GET['mid']);
$row = \Phpcmf\Service::M('Module')->table('module')->where('dirname', $mid)->getRow();
if (!$row) {
$this->_json(0, dr_lang('此模块[%s]未安装', $mid));
}
$this->_module_init($mid);
$ids = \Phpcmf\Service::L('input')->get('ids');
if (!$ids) {
$this->_json(0, dr_lang('所选内容不存在'));
} elseif (dr_count($ids) > 9) {
$this->_json(0, dr_lang('微信素材超过9条数据'));
}
$n = 1;
$save = [
'tid' => 'index',
'title' => 'index',
'content' => [],
'media_id' => '',
'inputtime' => SYS_TIME,
];
$save['media_id'] = '';
$save['publish_id'] = '';
$save['article_id'] = '';
$save['status'] = 1;
foreach ($ids as $id) {
$data = $this->content_model->get_data($id);
if ($data) {
$save['content']['title_'.$n] = $data['title'];
$save['content']['thumb_'.$n] = $data['thumb'];
$save['content']['author_'.$n] = $data['author'];
$save['content']['content_'.$n] = $data['content'];
$save['content']['description_'.$n] = $data['description'];
$save['content']['url_'.$n] = dr_url_prefix($data['url'], $mid);
$n++;
}
}
$save['nums'] = $n;
$save['title'] = $save['content']['title_1'];
$save['content'] = dr_array2string($save['content']);
\Phpcmf\Service::M()->table(weixin_wxtable('content'))->insert($save);
$this->_json(1, '存储成功,请到微信草稿中编辑发布');
}
/**
* 获取内容
* */
protected function _Data($id = 0) {
$data = parent::_Data($id);
if (!$data) {
return [];
}
$value = dr_string2array($data['content']);
return $value;
}
// 格式化保存数据
protected function _Format_Data($id, $data, $old) {
!$data[0]['title_1'] && $this->_json(0, '第一个标题不能为空', ['field' => 'title_1']);
!$data[0]['content_1'] && $this->_json(0, '第一个内容不能为空', ['field' => 'content_1']);
$nums = 0;
for ($i = 1; $i<=9; $i++) {
if ($data[0]['title_'.$i]) {
$nums++;
} else {
break;
}
}
$save = [
'tid' => '',
'nums' => $nums,
'title' => $data[0]['title_1'],
'content' => dr_array2string($data[0]),
'inputtime' => SYS_TIME,
];
// 每次修改媒体id重置
$save['media_id'] = '';
$save['publish_id'] = '';
$save['article_id'] = '';
$save['status'] = 1;
return $save;
}
// 保存后
protected function _Save($id = 0, $data = [], $old = [], $before = null, $after = null) {
return parent::_Save($id, $data, $old, $before, function($id, $data, $old) {
$content = dr_string2array($data['content']);
for ($i = 1; $i <=9; $i++) {
if (!$content['url_'.$i]) {
$content['url_'.$i] = SITE_URL.'index.php?s=weixin&c=show&id='.$id.'&p='.$i;
}
}
\Phpcmf\Service::M()->table(weixin_wxtable('content'))->update($id, [
'content' => dr_array2string($content),
]);
});
}
//
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
null,
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
//
public function sync_add() {
$ids = \Phpcmf\Service::L('Input')->get_post_ids();
if (!$ids) {
$this->_json(0, dr_lang('所选数据不存在'));
}
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$access_token = $rt['msg'];
$rows = \Phpcmf\Service::M()->init($this->init)->where_in('id', $ids)->getAll();
if (!$rows) {
$this->_json(0, dr_lang('所选数据不存在'));
}
foreach ($rows as $t) {
if (!$t['article_id']) {
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->sync_content($access_token, $t);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
}
}
$this->_json(1, '提交成功,等待平台审核');
}
}
@@ -0,0 +1,117 @@
<?php namespace Phpcmf\Controllers\Admin;
// 粉丝组
class Group extends \Phpcmf\Table
{
public function __construct()
{
parent::__construct();
\Phpcmf\Service::V()->assign([
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'用户标签' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-users'],
'添加' => ['add:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus', null, '33%'],
'从服务端获取分组' => ['ajax:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/down_add', 'fa fa-refresh'],
]
),
]);
// 支持附表存储
$this->is_data = 0;
// 表单显示名称
$this->name = dr_lang('微信用户标签');
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('group'),
'order_by' => 'id asc',
]);
}
public function down_add() {
$rt = \Phpcmf\Service::M('User', 'weixin')->down_group();
$rt['code'] ? $this->_json(1, '操作成功') : $this->_json(0, $rt['msg']);
}
public function index() {
$this->_list([], -1);
\Phpcmf\Service::V()->display('group_index.html');
}
public function add() {
$this->_Post();
\Phpcmf\Service::V()->display('group_add.html');exit;
}
public function edit() {
$this->_Post(intval(\Phpcmf\Service::L('Input')->get('id')));
\Phpcmf\Service::V()->display('group_add.html');exit;
}
// 删除个性菜单
public function menu_del() {
$gid = intval($_GET['gid']);
!$gid && $this->_json(0, '参数未定义');
$menu = \Phpcmf\Service::M()->table(weixin_wxtable('menu'))->where('gid', $gid)->getRow();
!$menu && $this->_json(0, '菜单不存在');
$at = weixin_get_access_token();
if (!$at['code']) {
$this->_json(0, $at['msg']);
}
$data = array('menuid'=> $menu['menuid']);
$rt = wx_post_https_json_data('https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token='.$at['msg'], $data);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
\Phpcmf\Service::M()->db->table(weixin_wxtable('menu'))->where('gid', $gid)->delete();
$this->_json(1, '操作成功');
}
// 格式化保存数据
protected function _Format_Data($id, $data, $old) {
$data['count'] = intval($old['count']);
!$data['name'] && $this->_json(0, '用户标签名称必须填写', ['field' => 'name']);
if ($id) {
// 修改标签
if ($data['name'] != $old['name'] && $old['tag']) {
$rt = \Phpcmf\Service::M('User', 'weixin')->edit_group($data['tag'], $data['name']);
!$rt['code'] && $this->_json(0, $rt['msg']);
}
unset($data['tag']);
} else {
// 创建标签
$rt = \Phpcmf\Service::M('User', 'weixin')->add_group($data['name']);
!$rt['code'] && $this->_json(0, $rt['msg']);
$data['tag'] = $rt['code'];
}
$data['groupid'] = intval($data['groupid']);
return $data;
}
// 后台删除表单内容
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
function ($rows) {
foreach ($rows as $t) {
$rt = \Phpcmf\Service::M('User', 'weixin')->delete_group($t['id']);
!$rt['code'] && $this->_json(0, $rt['msg']);
}
return dr_return_data(1, 'ok');
},
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
}
@@ -0,0 +1,41 @@
<?php namespace Phpcmf\Controllers\Admin;
class Home extends \Phpcmf\Common
{
public function __construct() {
parent::__construct();
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'微信公众号' => [APP_DIR.'/home/index', 'fa fa-area-chart'],
]
));
}
public function index() {
$data = [];
$fans = \Phpcmf\Service::M('Weixin', 'Weixin')->update_count_fans();
if ($fans) {
foreach ($fans as $d => $t) {
$data[] = [
'country' => substr($t['date'], 0, 4).'-'.substr($t['date'], 4, 2).'-'.substr($t['date'], 6, 2),
'year2004' => $t['new'],
'year2005' => $t['cumulate'],
];
}
}
\Phpcmf\Service::V()->assign([
'fans' => $fans,
'today' => date('Ymd'),
'yesterday' => date('Ymd', strtotime('-1 days')),
'data_tj' => json_encode($data),
'usercount' => \Phpcmf\Service::M()->table(weixin_wxtable('user'))->counts(),
'msgcount' => \Phpcmf\Service::M()->table(weixin_wxtable('message'))->where('DATEDIFF(from_unixtime(inputtime),now())=0')->counts(),
]);
\Phpcmf\Service::V()->display('weixin_index.html');
}
}
@@ -0,0 +1,36 @@
<?php namespace Phpcmf\Controllers\Admin;
class Log extends \Phpcmf\Common {
public function index() {
$file = WRITEPATH.'app/weixin.log';
if (!$file) {
$this->_admin_msg(0, '文件不存在:'.$file);
}
if (filesize($file) > 1024*1024*2) {
$this->_admin_msg(0, '此日志文件大于2MB,请使用Ftp等工具查看此文件:'.$file);
}
\Phpcmf\Service::V()->assign([
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
'请求日志' => ['weixin/log/index', 'fa fa-shield'],
]
),
'code' => file_get_contents($file),
'islog' => isset($this->weixin['account']['log']) && $this->weixin['account']['log'],
]);
\Phpcmf\Service::V()->display('log.html');
}
public function del() {
$file = WRITEPATH.'app/weixin.log';
unlink($file);
$this->_json(1, dr_lang('操作成功'));
}
}
@@ -0,0 +1,195 @@
<?php namespace Phpcmf\Controllers\Admin;
// 自定义菜单
class Menu extends \Phpcmf\Table
{
private $menu_type;
private $gid;
private $plugin;
public function __construct()
{
parent::__construct();
// 支持附表存储
$this->is_data = 0;
// 表单显示名称
$this->name = dr_lang('微信自定义菜单');
$this->gid = intval($_GET['gid']);
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('menu'),
'where_list' => 'gid='.$this->gid,
'order_by' => 'displayorder asc,id asc',
]);
$this->menu_type = [
'view' => '网页地址',
'login' => '登录认证',
'click' => '小插件',
'miniprogram' => '小程序',
'article_view_limited' => '跳转图文',
];
$local = dr_dir_map(APPPATH.'Plugins', 1);
$this->plugin = [];
if ($local) {
foreach ($local as $dir) {
if (is_file(APPPATH.'Plugins/'.$dir.'/App.php')) {
$key = strtolower($dir);
$cfg = require APPPATH.'Plugins/'.$dir.'/App.php';
$this->plugin[$key] = [
'name' => $cfg['name'],
'value' => 'App::'.$key,
];
}
}
}
$menu = [
WEIXIN_MORE_NAME.'自定义菜单' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index{gid='.$this->gid.'}', 'fa fa-list'],
'添加' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add{gid='.$this->gid.'}', 'fa fa-plus', null, '33%'],
'修改' => ['hide:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/edit{gid='.$this->gid.'}', 'fa fa-edit'],
];
if (!$this->gid) {
$menu['从服务端获取菜单'] = ['ajax:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/down_add', 'fa fa-refresh'];
}
\Phpcmf\Service::V()->assign([
'gid' => $this->gid,
'menu' => \Phpcmf\Service::M('auth')->_admin_menu($menu),
'plugin' => $this->plugin,
'menu_type' => $this->menu_type,
'menu_top' => \Phpcmf\Service::M('User', APP_DIR)->top_menu(),
]);
}
public function down_add() {
$rt = \Phpcmf\Service::M('User', APP_DIR)->down_menu();
$rt['code'] ? $this->_json(1, '操作成功') : $this->_json(0, $rt['msg']);
}
public function sync_index() {
$rt = \Phpcmf\Service::M('User', APP_DIR)->sync_menu();
$rt['code'] ? $this->_json(1, '操作成功') : $this->_json(0, $rt['msg']);
}
public function displayorder_edit() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$row = \Phpcmf\Service::M()->table(weixin_wxtable('menu'))->get($id);
if (!$row) {
$this->_json(0, dr_lang('数据#%s不存在', $id));
}
$value = (int)\Phpcmf\Service::L('Input')->get('value');
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('menu'))->save($id, 'displayorder', $value);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, dr_lang('操作成功'));
}
public function index() {
list($tpl, $data) = $this->_list([], -1);
$list = [];
if ($data['list']) {
foreach ($data['list'] as $t) {
if ($t['pid'] == 0) {
$list[$t['id']] = $t;
foreach ($data['list'] as $tt) {
if ($tt['pid'] == $t['id']) {
$list[$tt['id']] = $tt;
}
}
}
}
}
\Phpcmf\Service::V()->assign('list', $list);
\Phpcmf\Service::V()->assign('is_ajax', 0);
\Phpcmf\Service::V()->display($tpl);
}
public function add() {
list($tpl) = $this->_Post();
\Phpcmf\Service::V()->assign('pid', $_GET['pid']);
$this->_get_data();
\Phpcmf\Service::V()->display($tpl);exit;
}
public function edit() {
$id = intval(\Phpcmf\Service::L('Input')->get('id'));
list($tpl, $data) = $this->_Post($id);
if (!$data) {
$this->_admin_msg(0, dr_lang('菜单#%s不存在', $id));
}
if (!$data['pid'] && !$data['type']) {
$tpl = 'menu_post_ajax.html';
}
if ($this->gid != $data['gid']) {
$this->_admin_msg(0, dr_lang('菜单#%s不属于当前组', $id));
}
$this->_get_data();
\Phpcmf\Service::V()->display($tpl);exit;
}
private function _get_data() {
\Phpcmf\Service::V()->assign([
'view_url' => [
[
'name' => '用户中心',
'value' => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode(SITE_URL.'index.php?s=weixin&c=member').'&response_type=code&scope=snsapi_base&state=member#wechat_redirect',
],
],
'twsc' => \Phpcmf\Service::M()->table(weixin_wxtable('content'))->where('article_id<>""')->order_by('inputtime desc')->getAll(50),
]);
}
// 格式化保存数据
protected function _Format_Data($id, $data, $old) {
if (!$data['name']) {
$this->_json(0, '菜单名称必须填写', ['field' => 'name']);
}
$data['name'] = dr_emoji2html($data['name']);
$data['value'] = is_array($_POST['value_'.$data['type']]) ? dr_array2string($_POST['value_'.$data['type']]) : (string)$_POST['value_'.$data['type']];
if (!$id) {
$data['menuid'] = 0;
$data['displayorder'] = 0;
}
$data['gid'] = $this->gid;
return $data;
}
/**
* 获取内容
* $id 内容id,新增为0
* */
protected function _Data($id = 0) {
$data = parent::_Data($id);
if ($data['type'] == 'miniprogram') {
$data['value'] = dr_string2array($data['value']);
}
return $data;
}
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
null,
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
}
@@ -0,0 +1,154 @@
<?php namespace Phpcmf\Controllers\Admin;
// 消息
class Message extends \Phpcmf\Table
{
public function __construct()
{
parent::__construct();
// 支持附表存储
$this->is_data = 0;
$this->tpl_prefix = 'message_';
// 表单显示名称
$this->name = dr_lang('微信消息');
$this->my_field = array(
'nickname' => array(
'ismain' => 1,
'name' => '昵称',
'isemoji' => 1,
'fieldname' => 'nickname',
),
'content' => array(
'ismain' => 1,
'name' => '内容',
'fieldname' => 'content',
),
);
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('message'),
'order_by' => 'inputtime desc',
'date_field' => 'inputtime',
'field' => $this->my_field,
]);
\Phpcmf\Service::V()->assign([
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME. '消息管理' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-user'],
'更新消息状态' => ['ajax:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/update_add', 'fa fa-refresh'],
]
),
'field' => $this->my_field,
]);
}
public function update_add() {
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$access_token = $rt['msg'];
$error = 0;
$data = \Phpcmf\Service::M()->table(weixin_wxtable('message'))->where('status', 0)->getAll();
if ($data) {
foreach ($data as $t) {
$user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('openid', $t['openid'])->getRow();
if (!$user) {
//$this->_json(0, '此用户已经取消关注,消息Id'.$t['id']);
$error++;
continue;
}
// 需要下载资源
$file = '';
$value = dr_string2array($t['content']);
if ($value['MediaId'] && in_array($t['tid'], ['image', 'voice', 'video', 'shortvideo'])) {
$file = 'http://file.api.weixin.qq.com/cgi-bin/media/get?access_token='.$access_token.
'&media_id='.$value['MediaId'];
}
\Phpcmf\Service::M()->table(weixin_wxtable('message'))->update($t['id'], [
'status' => 1,
'headimgurl' => $user['headimgurl'],
'nickname' => $user['nickname'],
'userid' => $user['id'],
'file' => $file,
]);
}
}
$this->_json(1, '更新完成,失败'.$error.'条');
}
public function index() {
list($tpl, $data) = $this->_List();
if ($data['list']) {
$list = [];
foreach ($data['list'] as $t) {
$value = dr_string2array($t['content']);
switch ($t['tid']) {
case 'text':
# 文本消息
$t['tid_name'] = '<span class="label label-success"> 文本 </span>';
$t['content'] = $value['Content'];
break;
case 'image':
# 图片消息
$t['tid_name'] = '<span class="label label-danger"> 图片 </span>';
break;
case 'voice':
# 语音消息
$t['tid_name'] = '<span class="label label-default"> 语音 </span>';
break;
case 'video':
# 视频消息
$t['tid_name'] = '<span class="label label-warning"> 视频 </span>';
break;
case 'shortvideo':
# 小视频消息
$t['tid_name'] = '<span class="label label-warning"> 小视频 </span>';
break;
case 'link':
# 链接消息
$t['tid_name'] = '<span class="label label-info"> 链接 </span>';
$t['content'] = '<a href="'.$value['Url'].'" target="_blank">'.$value['Url'].'</a>';
break;
default:
$t['tid_name'] = '未知';
break;
}
$t['status_name'] = $t['status'] ? '<span class="label label-success"> 已更新 </span>' : '<span class="label label-danger"> 未更新 </span>';
$list[] = $t;
}
}
\Phpcmf\Service::V()->assign('list', $list);
\Phpcmf\Service::V()->display($tpl);
}
public function show() {
\Phpcmf\Service::V()->assign('tid', \Phpcmf\Service::L('Input')->get('tid'));
\Phpcmf\Service::V()->assign('url', SYS_UPLOAD_URL.\Phpcmf\Service::L('Input')->get('file'));
\Phpcmf\Service::V()->display('message_show.html');exit;
}
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
function ($rows) {
foreach ($rows as $t) {
if ($t['file']) {
@unlink(SYS_UPLOAD_PATH.$t['file']);
}
}
return dr_return_data(1, 'ok');
},
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
}
@@ -0,0 +1,146 @@
<?php namespace Phpcmf\Controllers\Admin;
class More extends \Phpcmf\Table
{
public function __construct() {
parent::__construct();
if (IS_ADMIN && SITE_ID > 1) {
$this->_admin_msg(0, '请登录主站账号管理微信插件');
}
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
'多公众号管理' => [APP_DIR.'/more/index', 'fa fa-user'],
'添加' => ['add:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus', null, '200px'],
]
));
// 支持附表存储
$this->is_data = 0;
// 表单显示名称
$this->name = dr_lang('多公众号');
// 初始化数据表
$this->_init([
'table' => 'app_weixin',
'order_by' => 'id asc',
]);
}
public function index() {
$this->_list([], -1);
\Phpcmf\Service::V()->display('more_list.html');
}
public function add() {
$this->_Post();
\Phpcmf\Service::V()->display('more_post.html');exit;
}
public function edit() {
$this->_Post(intval(\Phpcmf\Service::L('Input')->get('id')));
\Phpcmf\Service::V()->display('more_post.html');exit;
}
public function go_index() {
$id = intval(\Phpcmf\Service::L('Input')->get('id'));
$data = \Phpcmf\Service::M()->table('app_weixin')->get($id);
if (!$data) {
$this->_msg(0, '公众号不存在');
}
\Phpcmf\Service::L('cache')->set_auth_data('more_weixin', $id, 1);
$this->_msg(1, '切换到公众号:'.$data['name'], dr_url('weixin/account/index'));
}
protected function _Save($id = 0, $data = [], $old = [], $func = null, $func2 = null) {
return parent::_Save($id, $data, $old, function($id, $data, $old){
// 保存之前执行的函数,并返回新的数据
return dr_return_data(1, null, $data);
}, function ($id, $data, $old) {
// 保存之后执行的动作
if (!$old) {
// 生成新表
$this->_create_table($id);
}
});
}
private function _create_table($id) {
$sql = file_get_contents(APPPATH.'Config/Install.sql');
$sql = str_replace('{dbprefix}', \Phpcmf\Service::M()->dbprefix('more_'.$id.'_'), $sql);
$sql_data = explode(';SQL_FINECMS_EOL', trim(str_replace(array(PHP_EOL, chr(13), chr(10)), 'SQL_FINECMS_EOL', $sql)));
foreach($sql_data as $query){
if (!$query) {
continue;
}
$ret = '';
$queries = explode('SQL_FINECMS_EOL', trim($query));
foreach($queries as $query) {
$ret.= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query;
}
if (!$ret) {
continue;
}
if (!\Phpcmf\Service::M()->db->simpleQuery(dr_format_create_sql($ret))) {
$rt = \Phpcmf\Service::M()->db->error();
return $ret.': '.$rt['message'];
}
}
return 0;
}
private function _delete_table($id) {
$sql = file_get_contents(APPPATH.'Config/Install.sql');
$sql = str_replace('{dbprefix}', \Phpcmf\Service::M()->dbprefix('more_'.$id.'_'), $sql);
$sql_data = explode(';SQL_FINECMS_EOL', trim(str_replace(array(PHP_EOL, chr(13), chr(10)), 'SQL_FINECMS_EOL', $sql)));
foreach($sql_data as $query){
if (!$query) {
continue;
}
$ret = '';
$queries = explode('SQL_FINECMS_EOL', trim($query));
foreach($queries as $query) {
$ret.= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query;
}
if (!$ret) {
continue;
} elseif (strpos($ret, 'DROP TABLE') === false) {
continue;
}
if (!\Phpcmf\Service::M()->db->simpleQuery(($ret))) {
$rt = \Phpcmf\Service::M()->db->error();
return $ret.': '.$rt['message'];
}
}
return 0;
}
// 后台删除表单内容
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
function ($rows) {
foreach ($rows as $t) {
if ($t['id'] == 1) {
$this->_json(0, '默认公众号不能删除');
}
$this->_delete_table($t['id']);
}
return dr_return_data(1, 'ok');
},
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
}
@@ -0,0 +1,118 @@
<?php namespace Phpcmf\Controllers\Admin;
// 微信自动回复内容
class Reply extends \Phpcmf\Table
{
public function __construct()
{
parent::__construct();
// 支持附表存储
$this->is_data = 0;
// 表单显示名称
$this->name = dr_lang('微信回复内容');
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('reply'),
'order_by' => '`displayorder` desc,`id` desc',
'date_field' => 'updatetime',
]);
\Phpcmf\Service::V()->assign([
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'自动回复' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-comments'],
'添加' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
'修改' => ['hide:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-plus'],
]
),
]);
}
public function index() {
$where = (string)$_GET['keyword'] ? '`keyword` LIKE "%'.$_GET['keyword'].'%"' : '';
$where && \Phpcmf\Service::M()->set_where_list($where);
list($tpl) = $this->_list();
\Phpcmf\Service::V()->display($tpl);
}
public function add() {
list($tpl) = $this->_Post();
\Phpcmf\Service::V()->display($tpl);
}
public function edit() {
list($tpl) = $this->_Post(intval(\Phpcmf\Service::L('Input')->get('id')));
\Phpcmf\Service::V()->display($tpl);
}
public function displayorder_edit() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$row = \Phpcmf\Service::M()->table(weixin_wxtable('reply'))->get($id);
if (!$row) {
$this->_json(0, dr_lang('数据#%s不存在', $id));
}
$value = (int)\Phpcmf\Service::L('Input')->get('value');
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('reply'))->save($id, 'displayorder', $value);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
\Phpcmf\Service::M('weixin', 'weixin')->cache();
$this->_json(1, dr_lang('操作成功'));
}
/**
* 获取内容
* */
protected function _Data($id = 0) {
$data = parent::_Data($id);
if (!$data) {
return [];
}
return $data;
}
// 格式化保存数据
protected function _Format_Data($id, $data, $old) {
$data['content'] = (string)$_POST['value'][$data['tid']];
$data['displayorder'] = (int)$data['displayorder'];
if (!$id) {
$data['counts'] = 0;
$data['updatetime'] = 0;
}
return $data;
}
/**
* 保存内容
* $id 内容id,新增为0
* $data 提交内容数组,留空为自动获取
* $func 格式化提交的数据
* */
protected function _Save($id = 0, $data = [], $old = [], $func = null, $func2 = null) {
return parent::_Save($id, $data, $old,
null,
function ($id, $data, $old) {
// 保存之后
\Phpcmf\Service::M('weixin', 'weixin')->cache();
}
);
}
// 删除时
public function del() {
$this->_Del(\Phpcmf\Service::L('Input')->get_post_ids(), null, function($data){
\Phpcmf\Service::M('weixin', 'weixin')->cache();
});
}
}
@@ -0,0 +1,137 @@
<?php namespace Phpcmf\Controllers\Admin;
// 微信客服群发
class Send extends \Phpcmf\Common
{
public function __construct() {
parent::__construct();
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME. '客服群发' => [APP_DIR.'/send/index', 'fa fa-envelope-o'],
]
));
}
// 来自cms的群发
public function show_add() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$mid = dr_safe_filename(\Phpcmf\Service::L('Input')->get('mid'));
if (!$id || !$mid) {
$this->_html_msg(0, '参数不能为空');
}
$data = \Phpcmf\Service::M()->table_site($mid)->get($id);
if (!$data) {
$this->_html_msg(0, '内容不存在');
}
$data['tid'] = 'index';
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->send_for_content(0, $data);
!$rt['code'] && $this->_html_msg(0, $rt['msg']);
$this->_html_msg(1, '发送命令提交成功,即将自动发布', dr_url('weixin/send/add', ['id' => $rt['code']]));
}
public function add() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$send_table = weixin_wxtable('send');
$data = \Phpcmf\Service::M()->table($send_table)->where('cid', $id)->where('status', 0)->getAll(20);
if (!$data) {
$msg = '发送结果:成功'. \Phpcmf\Service::M()->table($send_table)->where('cid', $id)->where('status', 1)->counts().'个,失败'. \Phpcmf\Service::M()->table($send_table)->where('cid', $id)->where('status', 2)->counts().'个';
\Phpcmf\Service::M()->db->table($send_table)->where('cid', $id)->delete();
$this->_admin_msg(1, $msg);
}
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_admin_msg(0, $rt['msg']);
}
$access_token = $rt['msg'];
foreach ($data as $t) {
$param = dr_string2array($t['content']);
$param['touser'] = $t['openid'];
$rt = wx_post_https_json_data(
'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token,
$param
);
if (!$rt['code']) {
\Phpcmf\Service::M()->table($send_table)->update($t['id'], [
'status' => 2,
]);
} else {
// 发送成功
\Phpcmf\Service::M()->table($send_table)->update($t['id'], [
'status' => 1,
]);
}
}
$this->_admin_msg(2, '正在发送中...', FC_NOW_URL, 0);
}
public function index() {
if ($_GET['ac'] == 'send' && IS_AJAX_POST) {
// 发送群发
$data = \Phpcmf\Service::L('Input')->post('data');
$data['type'] = (int)$data['type'];
!$data['content'][$data['type']] && $this->_json(0, '没有选择内容');
if ($data['type']) {
$content = \Phpcmf\Service::M()->table(weixin_wxtable('content'))->get($data['content'][$data['type']]);
!$content && $this->_json(0, '素材内容不存在');
//!$content['media_id'] && $this->_json(0, '素材内容未同步');
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->send_for_content($data['groupid'], $content);
} else {
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->send_for_text($data['groupid'], $data['content'][0]);
}
!$rt['code'] && $this->_json(0, $rt['msg']);
$this->_json(1, '发送命令提交成功,即将自动发布', ['url' =>\Phpcmf\Service::L('Router')->url('weixin/send/add', ['id' => $rt['code']])]);
exit;
}
$db = \Phpcmf\Service::M()->table(weixin_wxtable('content'))->where('article_id<>""');
if (IS_POST) {
$param = \Phpcmf\Service::L('Input')->post('search');
$param['keyword'] && $db->where('`title` LIKE "%'.$param['keyword'].'%"');
}
$list = $db->order_by('inputtime desc')->getAll(30);
$uuid = 0;
$group = \Phpcmf\Service::M('User', APP_DIR)->get_group_data();
if (isset($_GET['uid']) && $_GET['uid']) {
$user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->get($_GET['uid']);
$uuid = $user['openid'];
if ($user && $uuid) {
$group[$uuid] = [
'id' => $uuid,
'tag' => $uuid,
'name' => '指定粉丝',
'count' => dr_html2emoji($user['nickname']),
];
}
}
\Phpcmf\Service::V()->assign([
'form' => dr_form_hidden(),
'list' => $list,
'uuid' => $uuid,
'param' => $param,
'group' => $group,
'ucount' => \Phpcmf\Service::M()->table(weixin_wxtable('user'))->counts(),
'content_type' => [
//'index' => '图文',
//'image' => '图片',
//'//voice' => '语音',
//'video' => '视频',
],
]);
\Phpcmf\Service::V()->display('send_index.html');
}
}
@@ -0,0 +1,59 @@
<?php namespace Phpcmf\Controllers\Admin;
// 微信群发
class Sendall extends \Phpcmf\Table
{
public function __construct() {
parent::__construct();
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME. '高级群发' => [APP_DIR.'/sendall/index', 'fa fa-volume-up'],
]
));
}
public function index() {
if ($_GET['ac'] == 'send' && IS_AJAX_POST) {
// 发送群发
$data = \Phpcmf\Service::L('Input')->post('data');
!$data['content'] && $this->_json(0, '没有选择素材内容');
$content = \Phpcmf\Service::M()->table(weixin_wxtable('content'))->get($data['content']);
!$content && $this->_json(0, '素材内容不存在');
!$content['article_id'] && $this->_json(0, '素材内容未同步');
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->sendall($data['groupid'], $content);
!$rt['code'] && $this->_json(0, $rt['msg']);
$this->_json(1, '发送提交成功');
exit;
}
$db = \Phpcmf\Service::M()->table(weixin_wxtable('content'))->where('article_id<>""');
if (IS_POST) {
$param = \Phpcmf\Service::L('Input')->post('search');
$param['tid'] && $db->where('tid', $param['tid']);
$param['keyword'] && $db->where('`title` LIKE "%'.$param['keyword'].'%"');
}
$list = $db->order_by('inputtime desc')->getAll(30);
\Phpcmf\Service::V()->assign([
'form' => dr_form_hidden(),
'list' => $list,
'param' => $param,
'group' => \Phpcmf\Service::M('User', APP_DIR)->get_group_data(),
'ucount' => \Phpcmf\Service::M()->table(weixin_wxtable('user'))->counts(),
'content_type' => [
//'index' => '图文',
//'image' => '图片',
//'voice' => '语音',
// 'video' => '视频',
],
]);
\Phpcmf\Service::V()->display('sendall_index.html');
}
}
@@ -0,0 +1,119 @@
<?php namespace Phpcmf\Controllers\Admin;
// 优速贡献代码
class Sendtpl extends \Phpcmf\App
{
// 来自cms的群发
public function show_add() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$mid = dr_safe_filename(\Phpcmf\Service::L('Input')->get('mid'));
if (!$id || !$mid) {
$this->_json(0, '参数不能为空');
}
$this->_module_init($mid);
$data = $this->content_model->get_data($id);
if (!$data) {
$this->_json(0, '内容不存在');
}
$file = WRITEPATH.'config/weixin_sendtpl.php';
$config = [];
if (is_file($file)) {
$config = require $file;
}
if (!isset($config[$mid])) {
$this->_json(0, '微信插件-内容模板群发设置-没有设置本模块参数');
} elseif (!isset($config[$mid]['use']) || !$config[$mid]['use']) {
$this->_json(0, '微信插件-内容模板群发设置-没有开启本模块');
} elseif (!isset($config[$mid]['id']) || !$config[$mid]['id']) {
$this->_json(0, '微信插件-内容模板群发设置-没有设置本模块参数');
} elseif (!isset($config[$mid]['content']) || !$config[$mid]['content']) {
$this->_json(0, '微信插件-内容模板群发设置-没有设置本模块参数');
}
$cache = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->getAll();
if (!$cache) {
$this->_json(0, dr_lang('没有可用粉丝'));
}
// 生成模板
$template = [];
foreach ($config[$mid]['content'] as $t) {
if ($t['name']) {
$value = $t['value'];
$tpl = $this->replace($data, $value);
$template[$t['name']] = [
'value' => $tpl ? $tpl : $value,
'color' => $t['color'],
];
}
}
if (!$template) {
$this->_json(0, dr_lang('模板内容解析后不存在'));
}
$data['template'] = $config[$mid]['id'];
$data['color'] = $config[$mid]['color'];
$data['url'] = dr_url_prefix($data['url'], $mid);
// 存储文件
\Phpcmf\Service::L('cache')->set_auth_data('app-weixin-template-send', [
'data' => $data,
'template' => $template,
'users' => dr_save_bfb_data($cache)
]);
$this->_json(1, 'ok', ['url' => dr_url('weixin/template/show_index', ['counts'=> count($cache)])]);
}
// 查看列表
public function index() {
$file = WRITEPATH.'config/weixin_sendtpl.php';
$module = \Phpcmf\Service::L('cache')->get('module-'.SITE_ID.'-content');
if (IS_POST) {
$post = \Phpcmf\Service::L('input')->post('data');
\Phpcmf\Service::L('Config')->file($file, '微信模板群发', 32)->to_require($post);
$this->_json(1, '操作成功');
}
$one = reset($module);
$page = \Phpcmf\Service::L('input')->get('page');
if (!$page) {
$page = $one['dirname'];
}
\Phpcmf\Service::V()->assign([
'page' => $page,
'data' => is_file($file) ? require $file : [],
'form' => dr_form_hidden(),
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'模块内容群发' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-edit'],
'help' => [1127],
]),
'module' => $module,
]);
\Phpcmf\Service::V()->display('sendtpl.html');
}
// 替换全部
private function replace($data, $value) {
$rep = new \php5replace($data);
$value = preg_replace_callback('#{([A-Z_]+)}#U', array($rep, 'php55_replace_var'), $value);
$value = preg_replace_callback('#{([a-z_0-9]+)}#U', array($rep, 'php55_replace_data'), $value);
$value = preg_replace_callback('#{\$([a-z_0-9]+)}#U', array($rep, 'php55_replace_data'), $value);
$value = preg_replace_callback('#{([a-z_0-9]+)\((.*)\)}#Ui', array($rep, 'php55_replace_function'), $value);
return $value;
}
}
@@ -0,0 +1,347 @@
<?php namespace Phpcmf\Controllers\Admin;
class Template extends \Phpcmf\Table
{
public function __construct()
{
parent::__construct();
// 表单显示名称
$this->name = dr_lang('模板消息');
// 模板前缀(避免混淆)
$this->tpl_prefix = 'template_';
// 用于表储存的字段,后台可修改的表字段
$field = array(
'title' => array(
'name' => dr_lang('主题'),
'fieldname' => 'title', // 这是字段名称必须和主键相同
),
'template' => array(
'name' => dr_lang('模板ID'),
'fieldname' => 'template', // 这是字段名称必须和主键相同
),
'url' => array(
'name' => dr_lang('消息URL'),
'fieldname' => 'url', // 这是字段名称必须和主键相同
),
);
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('template'),
'field' => $field, // 可查询的字段
'order_by' => 'inputtime desc', // 列表排序
'date_field' => 'inputtime', // 按时间段搜索字段
]);
// 把公共变量传入模板
\Phpcmf\Service::V()->assign([
// 搜索字段
'field' => $field,
// 后台的菜单
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME. $this->name => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-edit'],
'创建' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
'修改' => ['hide:'.APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-edit'],
]),
'group' => \Phpcmf\Service::M('User', APP_DIR)->get_group_data(),
'ucount' => \Phpcmf\Service::M()->table(weixin_wxtable('user'))->counts(),
]);
}
// 来自cms的群发
public function show_add() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$mid = dr_safe_filename(\Phpcmf\Service::L('Input')->get('mid'));
if (!$id || !$mid) {
$this->_json(0, '参数不能为空');
}
$data = \Phpcmf\Service::M()->table_site($mid)->get($id);
if (!$data) {
$this->_json(0, '内容不存在');
}
$cache = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->getAll();
if (!$cache) {
$this->_json(0, dr_lang('没有可用粉丝'));
}
$tpl = [];
// 生成模板
$template = [];
foreach ($tpl['content'] as $t) {
if ($t['name']) {
$template[$t['name']] = [
'value' => $t['value'],
'color' => $t['color'],
];
}
}
if (!$template) {
$this->_json(0, dr_lang('模板内容解析后不存在'));
}
// 存储文件
\Phpcmf\Service::L('cache')->set_auth_data('app-weixin-template-send', [
'data' => $data,
'template' => $template,
'users' => dr_save_bfb_data($cache)
], 3600);
$this->_json(1, 'ok', ['url' => dr_url('weixin/template/show_index', ['counts'=> count($cache)])]);
}
// 查看列表
public function index() {
list($tpl) = $this->_List();
\Phpcmf\Service::V()->display($tpl);
}
// 添加内容
public function add() {
list($tpl) =$this->_Post(0);
\Phpcmf\Service::V()->display($tpl);
}
// 修改内容
public function edit() {
$id = intval(\Phpcmf\Service::L('Input')->get('id'));
list($tpl) = $this->_Post($id);
\Phpcmf\Service::V()->display($tpl);
}
// 删除内容
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
null,
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
// 内容处理
public function todo_add() {
$id = \Phpcmf\Service::L('input')->get('id');
$data = \Phpcmf\Service::M()->table($this->init['table'])->get($id);
if (!$data) {
$this->_json(0, dr_lang('模板内容不存在'));
} elseif (!$data['content']) {
$this->_json(0, dr_lang('内容参数不存在'));
} elseif (!$data['template']) {
$this->_json(0, dr_lang('模板ID不存在'));
}
$data['content'] = dr_string2array($data['content']);
if ($data['groupid'] < 0) {
$gid = abs($data['groupid']);
$where = 'uid in (select uid from '.\Phpcmf\Service::M()->dbprefix('member_group_index').' where gid='.$gid.')';
$cache = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where($where)->getAll();
} elseif ($data['groupid'] > 0) {
$cache = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('groupids LIKE "%\"'.\Phpcmf\Service::M()->db->escapeString($data['groupid'], true).'\"%"')->getAll();
} else {
$cache = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->getAll();
}
if (!$cache) {
$this->_json(0, dr_lang('没有可用粉丝'));
}
// 生成模板
$template = [];
foreach ($data['content'] as $t) {
if ($t['name']) {
$template[$t['name']] = [
'value' => $t['value'],
'color' => $t['color'],
];
}
}
if (!$template) {
$this->_json(0, dr_lang('模板内容解析后不存在'));
}
// 存储文件
\Phpcmf\Service::L('cache')->set_auth_data('app-weixin-template-send', [
'data' => $data,
'template' => $template,
'users' => $this->_save_bfb_data($cache),
]);
$this->_json(1, 'ok', ['url' => dr_url('weixin/template/show_index', ['counts'=> count($cache)])]);
}
function _save_bfb_data($data) {
$cache = [];
$count = dr_count($data);
$num = ceil($count/10);
if ($count > $num) {
$pagesize = ceil($count/$num);
for ($i = 1; $i <= $num; $i ++) {
$cache[$i] = array_slice($data, ($i - 1) * $pagesize, $pagesize);
}
} else {
for ($i = 1; $i <= $count; $i ++) {
$cache[$i] = array_slice($data, ($i - 1), 1);
}
}
return $cache;
}
// 内容处理
public function show_index() {
\Phpcmf\Service::V()->assign([
'menu' => '',
'hidebtn' => 1,
'todo_url' => dr_url('weixin/template/send_add'),
'count_url' => dr_url('weixin/template/show_count_index'),
]);
\Phpcmf\Service::V()->display('bfb.html');exit;
}
// 内容数量统计
public function show_count_index() {
$data = \Phpcmf\Service::L('cache')->get_auth_data('app-weixin-template-send');
!dr_count($data) && $this->_json(0, dr_lang('无可用数据,缓存已失效'));
$this->_json(count($data['users']), 'ok');
}
public function send_add() {
$page = max(1, intval($_GET['pp']));
$cache = \Phpcmf\Service::L('cache')->get_auth_data('app-weixin-template-send');
!$cache && $this->_json(0, dr_lang('缓存不存在'));
$data = $cache['users'][$page];
$cts = count($cache['users']);
if ($data) {
$html = '';
foreach ($data as $user) {
$rt = $this->_send_template($user['openid'], $cache['data']['template'], $cache['template'], $cache['data']['url'], $cache['data']['color']);
if (!$rt['code']) {
$ok = "<span class='error'>".$rt['msg']."</span>";
$class = ' p_error';
} else {
$ok = "<span class='ok'>".dr_lang('发送成功')."</span>";
\Phpcmf\Service::M()->db->table($this->init['table'])
->where('id', intval($cache['data']['id']))
->increment('counts', 1);
}
$html.= '<p class="'.$class.'"><label class="rleft">'.dr_html2emoji($user['nickname']).'</label><label class="rright">'.$ok.'</label></p>';
}
$this->_json($page + 1, $html, [
'msg' => '正在执行第'.$page.'页/共'.$cts.'页',
'bfb' => round($page/$cts * 100, 2),
]);
}
// 完成
\Phpcmf\Service::L('cache')->del_auth_data('app-weixin-template-send');
$this->_json($cts, 'ok');
}
/**
* 获取微信 access token
*/
public function _weixin_template_access_token() {
$cache_data = \Phpcmf\Service::L('cache')->init('file')->get('access_token');
if (isset($cache_data['time']) && $cache_data['access_token']) {
$access_token = $cache_data['access_token'];
} else {
$weixin = \Phpcmf\Service::C()->get_cache('weixin');
$result = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$weixin['account']['appid'].'&secret='.$weixin['account']['appsecret']);
if (!$result['code']) {
return dr_return_data(0, 'AccessToken'.$result['msg']);
}
\Phpcmf\Service::L('cache')->init('file')->save('access_token', $result['data'], 3600);
$access_token = $result['data']['access_token'];
}
return dr_return_data(1, 'ok', ['access_token' => $access_token]);
}
private function _send_template($oid, $id, $data, $url = '', $color = '') {
$rt = $this->_weixin_template_access_token();
if (!$rt['code']) {
return dr_return_data(0, $rt['msg']);
}
$p = [
'touser' => $oid,
'template_id' => $id,
'url' => $url,
'topcolor' => $color,
'data' => $data,
];
$rt = wx_post_https_json_data('https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$rt['data']['access_token'], $p);
return $rt;
}
// 复制
public function copy_edit() {
$id = intval(\Phpcmf\Service::L('input')->get('id'));
$data = \Phpcmf\Service::M()->db->table(weixin_wxtable('template'))->where('id', $id)->get()->getRowArray();
if (!$data) {
$this->_json(0, dr_lang('数据#%s不存在', $id));
}
unset($data['id']);
$data['title'].= '_copy';
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('template'))->insert($data);
if (!$rt['code']) {
$this->_json(0, dr_lang($rt['msg']));
}
$this->_json(1, dr_lang('复制成功'));
}
/**
* 获取内容
* $id 内容id,新增为0
* */
protected function _Data($id = 0) {
$data = parent::_Data($id);
if (!$data) {
return [];
}
$data['content'] = dr_string2array($data['content']);
return $data;
}
// 格式化保存数据
protected function _Format_Data($id, $data, $old) {
$data[1] = \Phpcmf\Service::L('input')->post('data');
$data[1]['content'] = dr_array2string($data[1]['content']);
if (!$id) {
// 当提交新数据时,把当前时间插入进去
$data[1]['counts'] = 0;
$data[1]['inputtime'] = SYS_TIME;
}
return $data;
}
}
@@ -0,0 +1,275 @@
<?php namespace Phpcmf\Controllers\Admin;
// 粉丝
class User extends \Phpcmf\Table
{
public function __construct()
{
parent::__construct();
// 支持附表存储
$this->is_data = 0;
$this->tpl_prefix = 'user_';
// 表单显示名称
$this->name = dr_lang('微信用户');
$this->my_field = array(
'nickname' => array(
'ismain' => 1,
'name' => '昵称',
'isemoji' => 1,
'fieldname' => 'nickname',
),
'username' => array(
'ismain' => 1,
'name' => '账号',
'fieldname' => 'username',
),
'openid' => array(
'ismain' => 1,
'name' => 'openid(OID)',
'fieldname' => 'openid',
),
);
// 初始化数据表
$this->_init([
'table' => weixin_wxtable('user'),
'order_by' => 'subscribe_time desc,uid asc',
'date_field' => 'subscribe_time',
'field' => $this->my_field,
]);
\Phpcmf\Service::V()->assign([
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME.'粉丝管理' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-user'],
'从服务端获取粉丝' => [APP_DIR.'/'.\Phpcmf\Service::L('Router')->class.'/down_add', 'fa fa-plus'],
]
),
'field' => $this->my_field,
'group' => \Phpcmf\Service::M('User', APP_DIR)->get_group_data(),
]);
}
public function down_add() {
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_admin_msg(0, $rt['msg']);
}
$access_token = $rt['msg'];
$action = \Phpcmf\Service::L('Input')->get('action');
if (!$action) {
$url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token='.$access_token.'&next_openid='.\Phpcmf\Service::L('Input')->get('next_openid');
$rt = wx_get_https_json_data($url);
if (!$rt['code']) {
$this->_admin_msg(0, $rt['msg']);
} elseif (!isset($rt['data']['count']) || $rt['data']['count'] == 0) {
// 拉取完毕 全部设置为0状态
\Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->update(array(
'status' => 0,
));
\Phpcmf\Service::M()->table(weixin_wxtable('user'))->clear_all();
$this->_admin_msg(1, '同步用户数据中,请勿关闭',\Phpcmf\Service::L('Router')->url('weixin/user/down_add', array('action'=>'user')), 0);
}
// 查询并入库
$res = \Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->whereIn('openid', $rt['data']['data']['openid'])->get()->getResultArray();
if (count($res) != $rt['data'] ['count']) {
// 更新的数量不一致,可能有增加的用户openid
$openids = array();
if ($res) {
foreach ($res as $t) {
$openids[] = $t['openid'];
}
}
$diff = array_diff ( $rt['data'] ['data'] ['openid'], $openids );
if (! empty ( $diff )) {
foreach ( $diff as $id ) {
$save = array();
$save ['openid'] = $id;
$save ['uid'] = 0;
$save ['status'] = 0;
\Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->insert($save);
}
}
}
$this->_admin_msg(1, '同步用户OpenID中,请勿关闭',\Phpcmf\Service::L('Router')->url('weixin/user/down_add', array('next_openid'=>$rt['data']['next_openid'])), 0);
} elseif ($action == 'user') {
// 开始更新会员资料
$list = \Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->where('status', 0)->orderBy('id desc')->limit(50)->get()->getResultArray();
if (empty ($list)) {
$this->_admin_msg(1, '同步用户完成',\Phpcmf\Service::L('Router')->url('weixin/user/index') , 0);
}
$param = $openids = $uids = array();
foreach ( $list as $vo ) {
$param['user_list'][] = array (
'openid' => $vo ['openid'],
'lang' => 'zh-CN'
);
$openids[] = $vo ['openid'];
$uids [$vo ['openid']] = $vo ['uid'];
}
$rt = wx_post_https_json_data(
'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=' . $access_token,
$param
);
if (!$rt['code']) {
$this->_admin_msg(0, $rt['msg']);
}
$ok = 0;
$update = array();
foreach ($rt['data']['user_info_list'] as $u ) {
if ($u['subscribe'] == 0) {
continue;
}
$rt = \Phpcmf\Service::M('User', APP_DIR)->insert_user($u);
// 更新关注表状态
if ($rt) {
$ok++;
\Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->where('openid', $u['openid'])->update(array(
'status' => 1,
'uid' => $rt['id'],
));
}
$update[] = $u['openid'];
}
// 判断没获取到的
foreach ($list as $t) {
if (!dr_in_array($t['openid'], $update)) {
\Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->where('openid', $t['openid'])->update(array(
'status' => 1,
'uid' => 0,
));
}
}
$this->_admin_msg(1, '每次同步50个,本次成功'.$ok.'个,请勿关闭',\Phpcmf\Service::L('Router')->url('weixin/user/down_add', array('action'=>'user')), 0);
}
}
public function index() {
$groupid = (int)\Phpcmf\Service::L('Input')->request('groupid');
$groupid && \Phpcmf\Service::M()->set_where_list('`groupids` LIKE "%'.str_replace('\\', '\\\\\\', json_encode($groupid)).'%"');
list($tpl) = $this->_List(['groupid' => $groupid]);
\Phpcmf\Service::V()->display($tpl);
}
// 分组设置
public function move_edit() {
$ids = \Phpcmf\Service::L('Input')->get_post_ids();
!$ids && $this->_json(0, dr_lang('所选数据不存在'));
$rows = \Phpcmf\Service::M()->init($this->init)->where_in('id', $ids)->getAll();
!$rows && $this->_json(0, dr_lang('所选数据不存在'));
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$access_token = $rt['msg'];
$groupid = (int)\Phpcmf\Service::L('Input')->post('groupid');
if (!$groupid) {
$this->_json(0, '未选择标签组');
}
$openid = [];
foreach ($rows as $t) {
$openid[] = $t['openid'];
$groupids = dr_string2array($t['groupids']);
if (!dr_in_array($groupid, $groupids)) {
$groupids[] = (string)$groupid;
}
// 更改本地库
\Phpcmf\Service::M()->db->table(weixin_wxtable('user'))->where('id', $t['id'])->update(array(
'groupids' => dr_array2string($groupids),
));
}
$param = [
'openid_list' => $openid,
'tagid' => $groupid,
];
$rt = wx_post_https_json_data(
'https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token=' . $access_token,
$param
);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, dr_lang('操作成功'));
}
// 分组取消
public function move_del() {
$ids = \Phpcmf\Service::L('Input')->get_post_ids();
!$ids && $this->_json(0, dr_lang('所选数据不存在'));
$rows = \Phpcmf\Service::M()->init($this->init)->where_in('id', $ids)->getAll();
!$rows && $this->_json(0, dr_lang('所选数据不存在'));
$rt = weixin_get_access_token();
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$access_token = $rt['msg'];
$groupid = (int)\Phpcmf\Service::L('Input')->post('groupid');
if (!$groupid) {
$this->_json(0, '未选择标签组');
}
$openid = [];
foreach ($rows as $t) {
$openid[] = $t['openid'];
$groupids = dr_string2array($t['groupids']);
if ($groupids && dr_in_array($groupid, $groupids)) {
foreach ($groupids as $i => $v) {
if ($v == $groupid) {
unset($groupids[$i]);
}
}
// 更改本地库
\Phpcmf\Service::M()->db->table(weixin_wxtable('user'))->where('id', $t['id'])->update(array(
'groupids' => dr_array2string($groupids),
));
}
}
$param = [
'openid_list' => $openid,
'tagid' => $groupid,
];
$rt = wx_post_https_json_data(
'https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token=' . $access_token,
$param
);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, dr_lang('操作成功'));
}
//
public function del() {
$this->_Del(
\Phpcmf\Service::L('Input')->get_post_ids(),
null,
null,
\Phpcmf\Service::M()->dbprefix($this->init['table'])
);
}
}
@@ -0,0 +1,36 @@
<?php namespace Phpcmf\Controllers\Admin;
class Xcx extends \Phpcmf\Common
{
public function index() {
$page = intval(\Phpcmf\Service::L('Input')->get('page'));
$data = \Phpcmf\Service::M('Weixin', 'Weixin')->get_config('xcx');
if (IS_AJAX_POST) {
$post = \Phpcmf\Service::L('Input')->post('data');
$rt = \Phpcmf\Service::M('Weixin', 'Weixin')->save_config('xcx', $post);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
\Phpcmf\Service::M('Weixin', 'Weixin')->cache();
$this->_json(1, dr_lang('操作成功'));
}
\Phpcmf\Service::V()->assign([
'data' => $data,
'page' => $page,
'form' => dr_form_hidden(['page' => $page]),
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
[
WEIXIN_MORE_NAME. '小程序' => [APP_DIR.'/xcx/index', 'fa fa-cog'],
'help' => [416],
]
),
]);
\Phpcmf\Service::V()->display('xcx_index.html');
}
}
+16
View File
@@ -0,0 +1,16 @@
<?php namespace Phpcmf\Controllers;
class Api extends \Phpcmf\Common {
// 从微信菜单中进入授权
public function xcx_access_token() {
$rts = xcx_get_access_token();
if (!$rts['code']) {
$this->_json(0, $rts['msg']);
}
$this->_json(1, $rts['msg']);
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php namespace Phpcmf\Controllers;
// 登录跳转
class Go extends \Phpcmf\Common {
// 从微信菜单中进入授权
// 公众号内自动登陆
public function index() {
$url = (!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=weixin&c=member&m=login';
if ($_GET['url']) {
$burl = urlencode($_GET['url']);
} else {
$burl = urlencode((!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=member');
}
dr_redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode($url).'&response_type=code&scope=snsapi_userinfo&state='.($burl).'#wechat_redirect');
}
// 静默授权获取openidsnsapi_base
public function check() {
$code = \Phpcmf\Service::L('input')->get('code');
$burl = $_GET['url'] ? $_GET['url'] : FC_NOW_URL;
if ($code) {
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->weixin['account']['appid'].'&secret='.$this->weixin['account']['appsecret'].'&code='.$code.'&grant_type=authorization_code';
$rt = wx_get_https_json_data($url);
if (!$rt['code']) {
$this->_msg(0, $rt['msg']);
} elseif ($rt['data']['openid']) {
\Phpcmf\Service::L('input')->set_cookie('weixin_gzh_openid', $rt['data']['openid'], 86400 * 30);
}
dr_redirect($burl);
}
$redirect_uri = (!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=weixin&c=go&m=check&url='.urlencode($burl);
dr_redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode($redirect_uri).'&response_type=code&scope=snsapi_base&state=check#wechat_redirect');
}
}
+652
View File
@@ -0,0 +1,652 @@
<?php namespace Phpcmf\Controllers;
class Home extends \Phpcmf\Common {
private $token;
private $data;
private $access_token;
public function index() {
if (!isset($this->weixin['account']['appid']) || !$this->weixin['account']['appid']) {
exit('插件AppId未配置(如果后台已经配置,请更新缓存后,才会生效)');
} elseif (!isset($this->weixin['account']['token']) || !$this->weixin['account']['token']) {
exit('插件Token未配置(如果后台已经配置,请更新缓存后,才会生效)');
} elseif ($this->checkSignature()) {
// 判读是不是只是验证
$echostr = \Phpcmf\Service::L('Input')->get('echostr', true);
if ($echostr) {
echo $echostr;exit;
} else {
// 实际处理用户消息
$content = file_get_contents('php://input');
if (isset($this->weixin['account']['log']) && $this->weixin['account']['log']) {
file_put_contents(WRITEPATH.'app/weixin.log', dr_date(SYS_TIME, 'Y-m-d H:i:s').' - '.$content.PHP_EOL.'==================================='.PHP_EOL, FILE_APPEND);
}
//file_put_contents(APPPATH."wx.txt", var_export($content, true));
if ($content) {
// 解析微信传过来的 XML 内容 转化为数组
$this->data = dr_object2array(simplexml_load_string($content, 'SimpleXMLElement', LIBXML_NOCDATA));
if (!$this->data['EventKey']) {
$this->data['EventKey'] = '';
}
$this->token = $this->data['ToUserName'];
$rt = weixin_get_access_token();
$rt['code'] && $this->access_token = $rt['msg'];
// 微信消息钩子
\Phpcmf\Hooks::trigger('weixin_msg', $this);
// 存储和分析请求
switch ($this->data['MsgType']) {
case 'text':
# 文本消息
// 初始化用户 将其加入到粉丝组里面
$this->_init_user();
\Phpcmf\Service::M('Weixin', 'Weixin')->save_message($this->data);
//
// 搜索自定义回复
$kws = $this->get_cache('weixin-kws'.(WEIXIN_MORE_ID > 1 ? '_more_'.WEIXIN_MORE_ID : ''));
if ($kws) {
foreach ($kws as $kw => $id) {
if (strpos($this->data['Content'], (string)$kw) !== false) {
$data = \Phpcmf\Service::M()->table(weixin_wxtable('reply'))->get($id);
if ($data) {
// 记录
\Phpcmf\Service::M()->table(weixin_wxtable('reply'))->update($data['id'], [
'counts' => $data['counts'] + 1,
'updatetime' => SYS_TIME,
]);
if ($data['tid']) {
// 回复素材
return $this->_to_weixin_content($data['content']);
} else {
// 回复文本
return $this->_to_weixin_text($data['content']);
}
break;
}
}
}
}
// 用于自定义开发回复
if (is_file(APPPATH.'Plugins/AutoReply/Run.php')) {
require APPPATH.'Plugins/AutoReply/Run.php';
}
// 搜索模块内容回复
if ($this->weixin['config']['ss']) {
// 搜索模块内容回复
if ($this->weixin['config']['ss_dir']) {
// 搜索模块内容
foreach ($this->weixin['config']['ss_dir'] as $dirname) {
foreach ($this->site as $siteid) {
$table = dr_module_table_prefix($dirname, $siteid);
// 判断是否存在表
if (!\Phpcmf\Service::M()->is_table_exists($table)) {
continue;
}
// 查询 关键 词
$kw = dr_safe_replace($this->data['Content']);
$data = \Phpcmf\Service::M()->db->table($table)->where('`title` LIKE "%'.$kw.'%"')->orderBy('id desc')->limit(1)->get()->getResultArray();
#log_message('error', ''.\Phpcmf\Service::M()->get_sql_query());
if ($data) {
// 查询成功,回复他们
$cdata = [
'tid' => 'index',
'content' => [],
];
foreach ($data as $ii => $t) {
$i = 10 + $ii;
$cdata['content'][$i] = [
'title_'.$i => $t['title'],
'author_'.$i => $t['author'],
'thumb_'.$i => $t['thumb'] ? dr_get_file($t['thumb']) : SITE_LOGO,
'description_'.$i => $t['description'],
'url_'.$i => dr_url_prefix($t['url']),
];
if ($t['thumb'] && !isset($cdata['content'][1])) {
$cdata['content'][1] = [
'title_1' => $t['title'],
'author_1' => $t['author'],
'thumb_1' => dr_get_file($t['thumb']),
'description_1' => $t['description'],
'url_1' => dr_url_prefix($t['url']),
];
unset($cdata['content'][$i]);
}
}
ksort($cdata['content']);
// 回复内容
return $this->_to_weixin_content_data($cdata);
}
}
}
}
// 没有找到回复内容
if ($this->weixin['config']['ss_type']) {
// 回复素材
return $this->_to_weixin_content($this->weixin['config']['ss_value_1']);
} else {
// 回复文本
return $this->_to_weixin_text($this->weixin['config']['ss_value_0']);
}
}
break;
case 'image':
# 图片消息
case 'voice':
# 语音消息
case 'video':
# 视频消息
case 'shortvideo':
# 小视频消息
case 'link':
# 链接消息
// 初始化用户 将其加入到粉丝组里面
$this->_init_user();
\Phpcmf\Service::M('Weixin', 'Weixin')->save_message($this->data);
break;
case 'location':
# 地理位置消息
break;
case 'event':
# 事件推送
switch ($this->data['Event']) {
case 'PUBLISHJOBFINISH':
// 发布内容推送
\Phpcmf\Service::M()->table(weixin_wxtable('content'))
->where('publish_id', $this->data['PublishEventInfo']['publish_id'])->update(0, [
'status' => $this->data['PublishEventInfo']['publish_status'],
'article_id' => $this->data['PublishEventInfo']['article_id'],
]);
break;
case 'subscribe':
// 关注时
// 统计数据
/*
$fans = \Phpcmf\Service::M()->table(weixin_wxtable('count_fans'))->where('date', date('Ymd'))->getRow();
if (!$fans) {
// 今日新关注
$usercount = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->counts();
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('count_fans'))->insert([
'new' => 1,
'cancel' => 0,
'cumulate' => $usercount,
'date' => date('Ymd'),
]);
} else {
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('count_fans'))->update($fans['id'], [
'new' => $fans['new'] + 1,
'cumulate' => $fans['cumulate'] + 1,
]);
}*/
if (strpos($this->data['EventKey'], 'qrscene_bang-') === 0) {
// 表示通过扫描二维码关注微信公众号
$this->_gz_bang_user();
} else {
// 初始化用户 将其加入到粉丝组里面
$user = $this->_init_user();
$this->_gz_login_user();
// 回复关注信息
if ($this->weixin['config']['gz']) {
if ($this->weixin['config']['gz_type']) {
// 回复素材
if ($this->weixin['config']['gz_value_1']) {
$this->_to_weixin_content($this->weixin['config']['gz_value_1']);
}
} else {
// 回复文本
if ($this->weixin['config']['gz_value_0']) {
$this->_to_weixin_text($this->_gz_msg($this->weixin['config']['gz_value_0'], $user));
}
}
}
}
break;
case 'unsubscribe':
// 取消关注时
/*
$fans = \Phpcmf\Service::M()->table(weixin_wxtable('count_fans'))->where('date', date('Ymd'))->getRow();
if (!$fans) {
// 今日新取消关注
$usercount = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->counts();
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('count_fans'))->insert([
'new' => 0,
'cancel' => 1,
'cumulate' => $usercount,
'date' => date('Ymd'),
]);
} else {
$rt = \Phpcmf\Service::M()->table(weixin_wxtable('count_fans'))->update($fans['id'], [
'cancel' => $fans['new'] + 1,
'cumulate' => max(0, $fans['cumulate'] - 1),
]);
}*/
// 删除各种记录
\Phpcmf\Service::M()->db->table(weixin_wxtable('user'))->where('openid', $this->data['FromUserName'])->delete();
\Phpcmf\Service::M()->db->table(weixin_wxtable('follow'))->where('openid', $this->data['FromUserName'])->delete();
\Phpcmf\Service::M()->db->table(weixin_wxtable('message'))->where('openid', $this->data['FromUserName'])->delete();
\Phpcmf\Service::M()->db->table('member_oauth')->where('oauth', 'wechat')->where('oid', $this->data['FromUserName'])->delete();
break;
default:
if (strpos($this->data['EventKey'], 'App::') === 0) {
// 表示执行插件控制器
$file = APPPATH.'Plugins/'.ucfirst(substr($this->data['EventKey'], 5)).'/Run.php';
if (!is_file($file)) {
log_message('error', '微信小插件运行程序不存在:'.$file);
} else {
require $file;
}
// 初始化用户 将其加入到粉丝组里面
$this->_init_user();
} elseif (strpos($this->data['EventKey'], 'bang-') === 0 || strpos($this->data['EventKey'], 'qrscene_bang-') === 0) {
// 表示通过扫描二维码关注微信公众号
$this->_gz_bang_user();
} elseif (strpos($this->data['EventKey'], 'login-') === 0 || strpos($this->data['EventKey'], 'qrscene_login-') === 0) {
// 表示通过扫描二维码关注微信公众号
$this->_gz_login_user();
}
break;
}
break;
default:
# code...
// 初始化用户 将其加入到粉丝组里面
$this->_init_user();
break;
}
}
}
}
exit;
}
// 表示通过扫描二维码关注微信公众号
private function _gz_bang_user() {
list($s, $uid) = explode('-', $this->data['EventKey']);
$member = $uid ? dr_member_info($uid) : [];
if ($member) {
// 绑定账号
$rt = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->access_token.'&openid='.$this->data['FromUserName']);
if (!$rt['code']) {
return;
} elseif (!$rt['data']['openid']) {
return;
}
\Phpcmf\Service::M('member')->insert_oauth($uid, 'login', [
'oid' => $rt['data']['openid'],
'oauth' => 'wechat',
'avatar' => (string)$rt['data']['headimgurl'],
'unionid' => (string)$rt['data']['unionid'],
'nickname' => dr_emoji2html($rt['data']['nickname']?$rt['data']['nickname']:'微信用户'),
'expire_at' => SYS_TIME,
'access_token' => 0,
'refresh_token' => 0,
], '');
\Phpcmf\Service::M()->db->table(weixin_wxtable('user'))->where('openid', $this->data['FromUserName'])->update([
'uid' => (int)$member['uid'],
'username' => (string)$member['username'],
]);
if ( $this->weixin['config']['gz']) {
if ($this->weixin['config']['gz_type']) {
// 回复素材
$this->_to_weixin_content($this->weixin['config']['gz_value_1']);
} else {
// 回复文本
$this->_to_weixin_text($this->_gz_msg($this->weixin['config']['gz_value_0'], $member));
}
}
}
}
// 表示通过扫描二维码关注微信公众号
private function _gz_login_user() {
list($s, $ep) = explode('-', $this->data['EventKey']);
if ($ep) {
// 登录或注册账号
$rt = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->access_token.'&openid='.$this->data['FromUserName']);
if (!$rt['code']) {
return;
}
$user = \Phpcmf\Service::M()->table('member_oauth')->where('oid', $rt['data']['openid'])->where('oauth', 'wechat')->getRow();
if (!$user && isset($rt['data']['unionid']) && $rt['data']['unionid']) {
$user = \Phpcmf\Service::M()->table('member_oauth')->where('unionid', $rt['data']['unionid'])->getRow();
}
if ($user['uid']) {
// 已经关注,就登录
\Phpcmf\Service::M()->table('member_oauth')->update($user['id'], [
'refresh_token' => 'login-'.$ep,
]);
if ($this->weixin['config']['gz_login']) {
$user = dr_member_info($user['uid']);
$this->_to_weixin_text(str_replace(['{user}', '{time}', '{name}'], [$user['username'], dr_date(SYS_TIME), $user['name']], $this->weixin['config']['gz_login']));
} else {
$this->_to_weixin_text('通过扫描二维码在PC登录成功');
}
return;
}
if ($this->member_cache['oauth']['login']) {
// 直接注册
$oauth = [
'oid' => $rt['data']['openid'],
'oauth' => 'wechat',
'avatar' => $rt['data']['headimgurl'],
'unionid' => (string)$rt['data']['unionid'],
'nickname' => dr_emoji2html($rt['data']['nickname']?$rt['data']['nickname']:'微信用户'),
'expire_at' => SYS_TIME,
'access_token' => 0,
'refresh_token' => 'login-'.$ep,
];
$rt2 = \Phpcmf\Service::M('member')->insert_oauth(0, 'register', $oauth, '');
if (!$rt2['code']) {
$this->_to_weixin_text($rt2['msg']);
}
$oauth['id'] = $rt2['code'];
$groupid = (int)$this->member_cache['register']['groupid'];
if (!$groupid) {
$this->_to_weixin_text('系统没有设置默认注册的用户组');
}
$rt = \Phpcmf\Service::M('member')->register_oauth($groupid, $oauth);
if ($rt['code']) {
// 登录成功
if ($this->weixin['config']['gz_reg']) {
$user = $rt['data']['member'];
$this->_to_weixin_text(str_replace(['{user}', '{time}', '{name}'], [$user['username'], dr_date(SYS_TIME), $user['name']], $this->weixin['config']['gz_reg']));
} else {
$this->_to_weixin_text('通过扫描二维码在PC注册成功,随机账号为:'.$rt['data']['member']['username']);
}
} else {
$this->_to_weixin_text($rt['msg']);
}
} else {
// 绑定账号
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode(SITE_URL.'index.php?s=weixin&c=member&ep=login-'.$ep).'&response_type=code&scope=snsapi_base&state=member#wechat_redirect';
$txt = $this->weixin['config']['bang_text'] ? $this->weixin['config']['bang_text'] : '您还没有绑定本站账号,点我立即绑定账号';
$this->_to_weixin_text('<a href="'.$url.'">'.$txt.'</a>');
}
}
}
// 替换返回值
private function _gz_msg($tpl, $user) {
if (!isset($user['username']) || !$user['username']) {
$user['username'] = $user['nickname'];
}
return str_replace('{username}', $user['username'], (string)$tpl);
}
// 初始化用户情况
private function _init_user() {
$rt = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->access_token.'&openid='.$this->data['FromUserName']);
if (!$rt['code']) {
return;
}
$user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('openid', $this->data['FromUserName'])->getRow();
if (!$user) {
// 入库粉丝表
$user = \Phpcmf\Service::M('User', APP_DIR)->insert_user($rt['data']);
} else {
// 更新
$user = \Phpcmf\Service::M('User', APP_DIR)->update_user($user, $rt['data']);;
}
// 判断当用户没有绑定会员的情况时
if (!$user['uid']) {
// 判断是否绑定过公众号
$bang = \Phpcmf\Service::M()->table('member_oauth')->where('oauth', 'wechat')->where('oid', $this->data['FromUserName'])->getRow();
if (!$bang && isset($user['unionid']) && $user['unionid']) {
$bang = \Phpcmf\Service::M()->table('member_oauth')->where('unionid', $user['unionid'])->getRow();
}
if ($bang && $bang['uid']) {
$member = dr_member_info($bang['uid']);
\Phpcmf\Service::M()->table(weixin_wxtable('user'))->update($user['id'], [
'uid' => (int)$bang['uid'],
'username' => (string)$member['username'],
]);
} else {
if ($this->weixin['config']['bang']) {
// 提醒用户绑定会员
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode(SITE_URL.'index.php?s=weixin&c=member').'&response_type=code&scope=snsapi_base&state=member#wechat_redirect';
$txt = $this->weixin['config']['bang_text'] ? $this->weixin['config']['bang_text'] : '您还没有绑定本站账号,点我立即绑定账号';
$this->_to_weixin_text('<a href="'.$url.'">'.$txt.'</a>');
}
return $user;
}
}
// 存储cookie
$this->uid = $user['uid'];
$this->member = \Phpcmf\Service::M('member')->get_member($this->uid);
\Phpcmf\Service::M('member')->save_cookie($this->member);
return $this->member;
}
// 验证微信请求
private function checkSignature() {
$nonce = (string)$_GET["nonce"];
$signature = (string)$_GET["signature"];
$timestamp = (string)$_GET["timestamp"];
$token = $this->weixin['account']['token'];
$tmpArr = [$token, $timestamp, $nonce];
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if ($tmpStr == $signature){
return true;
} else{
return false;
}
}
// ================================================
// 回复文本
public function _to_weixin_text($text) {
if (!$text) {
return;
}
echo '<xml>
<ToUserName><![CDATA['.$this->data['FromUserName'].']]></ToUserName>
<FromUserName><![CDATA['.$this->data['ToUserName'].']]></FromUserName>
<CreateTime>'.(SYS_TIME+2).'</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA['.$text.']]></Content>
</xml>';exit;
}
// 回复素材
public function _to_weixin_content($id) {
$id = (int)substr($id, 5);
if (!$id) {
return;
}
// 查询内容
$data = \Phpcmf\Service::M()->table(weixin_wxtable('content'))->get($id);
if (!$data) {
return;
}
$value = dr_string2array($data['content']);
$data['content'] = [];
if ($value) {
for ($i = 1; $i<=9; $i++) {
if (!$value['thumb_'.$i] || !$value['title_'.$i]) {
break;
}
$data['content'][$i] = [
"title_".$i => $value['title_'.$i],
"thumb_".$i => dr_get_file($value['thumb_'.$i]),
"description_".$i => $value['description_'.$i],
"url_".$i => html_entity_decode(dr_url_prefix($value['url_'.$i]))
];
}
}
#file_put_contents(WRITEPATH."weixin/wx.txt", var_export($data, true));
return $this->_to_weixin_content_data($data);
}
// 开始回复
public function _to_weixin_content_data($cdata) {
if (!$cdata['tid']) {
$cdata['tid'] = 'index';
}
switch ($cdata['tid']) {
case 'index':
// 回复图文
$count = 0;
$text = '';
foreach ($cdata['content'] as $i => $t) {
if ($t['title_'.$i]) {
$count ++;
$text.= '<item>
<Title><![CDATA['.$t['title_'.$i].']]></Title>
<Description><![CDATA['.$t['description_'.$i].']]></Description>
<PicUrl><![CDATA['.$t['thumb_'.$i].']]></PicUrl>
<Url><![CDATA['.$t['url_'.$i].']]></Url>
</item>';
}
}
if (!$count) {
$this->_to_weixin_text('没有找到相关内容');
return;
}
exit('
<xml>
<ToUserName><![CDATA['.$this->data['FromUserName'].']]></ToUserName>
<FromUserName><![CDATA['.$this->data['ToUserName'].']]></FromUserName>
<CreateTime>'.(SYS_TIME+2).'</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>'.$count.'</ArticleCount>
<Articles>
'.$text.'
</Articles>
</xml>
');
break;
case 'image':
if (!$cdata['media_id']) {
$this->_to_weixin_text('没有找到相关内容');
return;
}
exit('<xml>
<ToUserName><![CDATA['.$this->data['FromUserName'].']]></ToUserName>
<FromUserName><![CDATA['.$this->data['ToUserName'].']]></FromUserName>
<CreateTime>'.(SYS_TIME+2).'</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA['.$cdata['media_id'].']]></MediaId>
</Image>
</xml>');
break;
case 'voice':
if (!$cdata['media_id']) {
$this->_to_weixin_text('没有找到相关内容');
return;
}
exit('<xml>
<ToUserName><![CDATA['.$this->data['FromUserName'].']]></ToUserName>
<FromUserName><![CDATA['.$this->data['ToUserName'].']]></FromUserName>
<CreateTime>'.(SYS_TIME+2).'</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Image>
<MediaId><![CDATA['.$cdata['media_id'].']]></MediaId>
</Image>
</xml>');
break;
case 'video':
if (!$cdata['media_id']) {
$this->_to_weixin_text('没有找到相关内容');
return;
}
exit('<xml>
<ToUserName><![CDATA['.$this->data['FromUserName'].']]></ToUserName>
<FromUserName><![CDATA['.$this->data['ToUserName'].']]></FromUserName>
<CreateTime>'.(SYS_TIME+2).'</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Image>
<MediaId><![CDATA['.$cdata['media_id'].']]></MediaId>
</Image>
</xml>');
break;
case 'link':
exit('<xml>
<ToUserName><![CDATA['.$this->data['FromUserName'].']]></ToUserName>
<FromUserName><![CDATA['.$this->data['ToUserName'].']]></FromUserName>
<CreateTime>'.(SYS_TIME+2).'</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<Title><![CDATA['.$cdata['title'].']]></Title>
<Description><![CDATA['.$cdata['description'].']]></Description>
<Url><![CDATA['.$cdata['url'].']]></Url>
</xml>');
break;
}
$this->_to_weixin_text('没有找到相关内容');
}
/* 组装xml数据 */
private function _data2xml($xml, $data, $item = 'item') {
foreach ( $data as $key => $value ) {
is_numeric ( $key ) && ($key = $item);
if (is_array ( $value ) || is_object ( $value )) {
$child = $xml->addChild ( $key );
$this->_data2xml ( $child, $value, $item );
} else {
if (is_numeric ( $value )) {
$child = $xml->addChild ( $key, $value );
} else {
$child = $xml->addChild ( $key );
$node = dom_import_simplexml ( $child );
$node->appendChild ( $node->ownerDocument->createCDATASection ( $value ) );
}
}
}
}
}
+408
View File
@@ -0,0 +1,408 @@
<?php namespace Phpcmf\Controllers;
// 绑定账号
class Member extends \Phpcmf\Common {
private $access_token;
// 从微信菜单中进入授权
public function index() {
$code = \Phpcmf\Service::L('input')->get('code');
$state = \Phpcmf\Service::L('input')->get('state');
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->weixin['account']['appid'].'&secret='.$this->weixin['account']['appsecret'].'&code='.$code.'&state='.$state.'&grant_type=authorization_code';
$rt = wx_get_https_json_data($url);
if (!$rt['code']) {
$this->_msg(0, $rt['msg']);
}
$user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('openid', $rt['data']['openid'])->getRow();
if (!$user) {
$rts = weixin_get_access_token();
$rts['code'] && $this->access_token = $rts['msg'];
$rts = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->access_token.'&openid='.$rt['data']['openid']);
if (!$rts['code']) {
$this->_msg(0, $rts['msg']);
} elseif (!$rts['data']['nickname']) {
//$this->_msg(0, '未获取到微信用户昵称');
}
$user = \Phpcmf\Service::M('User', APP_DIR)->insert_user($rts['data']);
}
$oid = $rt['data']['openid'];
$user['uid'] = (int)$user['uid'];
$rt = \Phpcmf\Service::M('member')->insert_oauth($user['uid'], 'login', [
'oid' => $oid,
'oauth' => 'wechat',
'avatar' => $user['headimgurl'],
'unionid' => (string)$user['unionid'],
'nickname' => dr_emoji2html($user['nickname']?$user['nickname']:'微信用户'),
'expire_at' => SYS_TIME,
'access_token' => 0,
'refresh_token' => 0,
], $state);
if (!$rt['code']) {
$this->_msg(0, $rt['msg']);
exit;
} else {
if ($user['uid']) {
// 验证是否存在
$member = \Phpcmf\Service::M('member')->member_info($user['uid']);
if (!$member) {
\Phpcmf\Service::M()->db->table('weixin_user')->where('uid', $user['uid'])->delete();
}
}
dr_redirect($rt['msg']);
}
exit;
}
// 小程序读取手机号
public function xcx_phone()
{
if (IS_POST) {
if (!$_POST['js_code']) {
$this->_json(0, 'js_code数据获取失败');
}
$rts = xcx_get_access_token();
if (!$rts['code']) {
$this->_json(0, $rts['msg']);
}
$url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $rts['msg'];
$rt = wx_post_https_json_data(($url), [
'code' => $_POST['js_code']
]);
$token = $rt['data'];
if (!$token) {
$this->_json(0, '手机号获取失败');
} elseif (isset($token['errcode']) && $token['errcode']) {
$this->_json(0, '手机号错误代码(' . $token['errcode'] . '):' . $token['errmsg'] . ' appid=' . $this->weixin['xcx']['appid'] . '&secret=' . $this->weixin['xcx']['appsecret'] . '');
}
$this->_json(1, 'ok', $token['phone_info']['phoneNumber']);
}
}
// 小程序登录
public function xcx() {
if (IS_POST) {
$json = json_decode($_POST['json'], true);
if (!$json) {
$this->_json(0, 'POST数据解析失败');
} elseif (!$_POST['js_code']) {
$this->_json(0, 'js_code数据获取失败');
}
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$this->weixin['xcx']['appid'].'&secret='.$this->weixin['xcx']['appsecret'].'&js_code='.$_POST['js_code'].'&grant_type=authorization_code';
$token = json_decode(dr_catcher_data($url), true);
if (!$token) {
$this->_json(0, 'jscode2session获取失败');
} elseif (isset($token['errcode']) && $token['errcode']) {
$this->_json(0, 'jscode2session错误代码('.$token['errcode'].'):'.$token['errmsg'].' appid='.$this->weixin['xcx']['appid'].'&secret='.$this->weixin['xcx']['appsecret'].'');
} elseif (!$token['openid']) {
$this->_json(0, 'jscode2session:openid获取失败');
}
$rt = \Phpcmf\Service::M('member')->insert_oauth(0, 'login', [
'oid' => $token['openid'],
'oauth' => 'wxxcx',
'avatar' => $json['avatarUrl'],
'unionid' => (string)$token['unionid'],
//'nickname' => dr_emoji2html($json['nickName']),
'nickname' => dr_emoji2html($user['nickName']?$user['nickName']:'微信用户'),
'expire_at' => SYS_TIME,
'access_token' => $token['session_key'],
'refresh_token' => '',
]);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$oauth = \Phpcmf\Service::M()->table('member_oauth')->get($rt['code']);
if (!$oauth) {
$this->_json(0, '服务端储存用户失败');
} elseif ($oauth['uid']) {
$rt = \Phpcmf\Service::M('member')->login_uid($oauth, $oauth['uid']);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, 'login', $rt['data']);
}
if ($this->weixin['xcx']['login']) {
// 直接登录
$rt = \Phpcmf\Service::M('member')->register_oauth(0, $oauth);
if ($rt['code']) {
// 登录成功
$this->_json(1, 'login', $rt['data']);
} else {
$this->_json(0, $rt['msg']);
}
} else {
// 提示注册
$oauth['nickname'] = dr_html2emoji($oauth['nickname']?$oauth['nickname']:'微信用户');
$this->_json(1, 'register', $oauth);
}
} else {
$this->_json(0, '非POST提交');
}
exit;
}
// 小程序绑定账号
public function xcx_bang() {
if (IS_POST) {
$oid = (int)\Phpcmf\Service::L('Input')->post('oid');
$post = \Phpcmf\Service::L('Input')->post('data', true);
if (!$post) {
$this->_json(0, 'POST数据解析失败');
} elseif (!$oid) {
$this->_json(0, '小程序OpenId为空');
}
$oauth = \Phpcmf\Service::M()->table('member_oauth')->get($oid);
if (!$oauth) {
$this->_json(0, '服务端用户不存在');
} elseif ($oauth['uid']) {
$rt = \Phpcmf\Service::M('member')->login_uid($oauth, $oauth['uid']);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, 'ok', $rt['data']);
}
// 登录绑定
if (empty($post['username']) || empty($post['password'])) {
$this->_json(0, dr_lang('账号或密码必须填写'));
} else {
$rt = \Phpcmf\Service::M('member')->login($post['username'], $post['password']);
if ($rt['code']) {
// 登录成功
\Phpcmf\Service::M()->db->table('member_oauth')->where('id', $oid)->update(['uid' => $rt['data']['member']['id']]);
$this->_json(1, 'ok', $rt['data']);
} else {
$this->_json(0, $rt['msg']);
}
}
} else {
$this->_json(0, '非POST提交');
}
}
// 小程序注册账号
public function xcx_reg() {
if (IS_POST) {
$oid = (int)\Phpcmf\Service::L('Input')->post('oid');
$post = \Phpcmf\Service::L('Input')->post('data', true);
if (!$post) {
$this->_json(0, 'POST数据解析失败');
} elseif (!$oid) {
$this->_json(0, '小程序OpenId为空');
}
$oauth = \Phpcmf\Service::M()->table('member_oauth')->get($oid);
if (!$oauth) {
$this->_json(0, '服务端用户不存在');
} elseif ($oauth['uid']) {
$rt = \Phpcmf\Service::M('member')->login_uid($oauth, $oauth['uid']);
if (!$rt['code']) {
$this->_json(0, $rt['msg']);
}
$this->_json(1, 'ok', $rt['data']);
}
// 注册
if (empty($post['password'])) {
$this->_json(0, dr_lang('密码必须填写'), ['field' => 'password']);
} elseif ($post['password'] != $post['password2']) {
$this->_json(0, dr_lang('确认密码不一致'), ['field' => 'password2']);
} else {
$rt = \Phpcmf\Service::M('member')->register_oauth_bang($oauth, 0, [
'username' => (string)$post['username'],
'phone' => (string)$post['phone'],
'email' => (string)$post['email'],
'password' => dr_safe_password($post['password']),
'name' => dr_safe_replace($post['name']),
]);
if ($rt['code']) {
// 注册绑定成功
$this->_json(1, 'ok', $rt['data']);
} else {
$this->_json(0, $rt['msg'], ['field' => $rt['data']['field']]);
}
}
} else {
$this->_json(0, '非POST提交');
}
}
// 公众号浏览url弹出登录
//
// 公众号内自动登陆
public function login() {
$code = \Phpcmf\Service::L('input')->get('code');
$state = \Phpcmf\Service::L('input')->get('state');
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->weixin['account']['appid'].'&secret='.$this->weixin['account']['appsecret'].'&code='.$code.'&state='.$state.'&grant_type=authorization_code';
$rt = wx_get_https_json_data($url);
if (!$rt['code']) {
$this->_msg(0, $rt['msg']);
}
// 刷新
$rs = wx_get_https_json_data('https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.$this->weixin['account']['appid'].'&grant_type=refresh_token&refresh_token='.$rt['data']['refresh_token']);
if (!$rs['code']) {
$this->_msg(0, $rs['msg']);
}
$rts = wx_get_https_json_data('https://api.weixin.qq.com/sns/userinfo?access_token='.$rs['data']['access_token'].'&openid='.$rt['data']['openid'].'&lang=zh_CN');
if (!$rts['code']) {
$this->_msg(0, $rts['msg']);
} elseif (!$rts['data']['nickname']) {
//$this->_msg(0, '未获取到微信用户昵称');
}
$user = \Phpcmf\Service::M()->table(weixin_wxtable('user'))->where('openid', $rt['data']['openid'])->getRow();
if (!$user) {
$user = \Phpcmf\Service::M('User', APP_DIR)->insert_user($rts['data']);
$user['uid'] = 0;
} else {
$user = \Phpcmf\Service::M('User', APP_DIR)->update_user($user, $rts['data']);
}
// $rt = \Phpcmf\Service::M('member')->register_oauth($groupid, $oauth);
$oid = $rt['data']['openid'];
$rt = \Phpcmf\Service::M('member')->insert_oauth($user['uid'], 'login', [
'oid' => $oid,
'oauth' => 'wechat',
'avatar' => $user['headimgurl'],
'unionid' => (string)$user['unionid'],
'nickname' => dr_emoji2html($user['nickname']),
'expire_at' => SYS_TIME,
'access_token' => 0,
'refresh_token' => 0,
], $state);
if (!$rt['code']) {
$this->_msg(0, $rt['msg']);
exit;
} else {
if ($user['uid'] && $state) {
// 存储cookie
$member = \Phpcmf\Service::M('member')->member_info($user['uid']);
if (!$member) {
\Phpcmf\Service::M()->db->table('weixin_user')->where('uid', $user['uid'])->delete();
dr_redirect($rt['msg']);
exit;
}
\Phpcmf\Service::M('member')->save_cookie($member, 1);
$goto_url = urldecode($state);
if (strpos($goto_url, 'is_admin_call')) {
// 存储后台回话
\Phpcmf\Service::M('auth')->save_login_auth('wechat', $user['uid']);
$goto_url.= '&uid='.$user['uid'];
} elseif (strpos($state, DOMAIN_NAME) === false) {
// 域名不同的情况下
$rt = \Phpcmf\Service::M('member')->sso($member, 1);
$sso = '';
foreach ($rt as $url) {
$sso.= '<script src="'.$url.'"></script>';
}
$this->_msg(1, dr_lang('%s,欢迎回来', dr_html2emoji($user['nickname'])).$sso, $goto_url, 0);exit;
}
dr_redirect($goto_url);
} else {
dr_redirect($rt['msg']);
}
}
}
// 微信公众号绑定
public function wxbang() {
if (!$this->uid) {
$ep = dr_safe_replace(\Phpcmf\Service::L('input')->get('ep'));
$rt = \Phpcmf\Service::M()->table('member_oauth')->where('refresh_token', $ep)->where('uid>0')->where('oauth', 'wechat')->getRow();
if ($rt) {
// 为他登录
// 存储cookie
$this->uid = $rt['uid'];
$this->member = \Phpcmf\Service::M('member')->get_member($this->uid);
$sso = \Phpcmf\Service::M('member')->login_oauth('wechat', $this->member);
// 存储后台回话
if (isset($_GET['is_admin_call'])) {
\Phpcmf\Service::M('auth')->save_login_auth('wechat', $this->uid);
$this->_json(1, 'ok', [
'url' => urldecode($_GET['is_admin_call']).'&uid='.$this->uid,
'sso' => $sso,
]);
} else {
$this->_json(1, 'ok', [
'sso' => $sso,
]);
}
}
} else {
$rt = \Phpcmf\Service::M()->table('member_oauth')->where('uid', $this->uid)->where('oauth', 'wechat')->getRow();
}
if (!$rt) {
$this->_json(0, '');
} else {
// 绑定成功更新头像
list($cache_path) = dr_avatar_path();
$path = $cache_path.dr_avatar_dir($this->uid);
$file = $path.$this->uid.'.jpg';
if (!is_file($file)) {
// 没有头像下载头像
$img = dr_catcher_data($rt['avatar']);
if (strlen($img) > 20) {
if (!is_dir($path)) {
dr_mkdirs($path);
}
file_put_contents($file, $img);
}
}
// 存储后台回话
if (isset($_GET['is_admin_call'])) {
\Phpcmf\Service::M('auth')->save_login_auth('wechat', $this->uid);
$this->_json($rt['access_token'] ? 0 : 1, 'ok', [
'url' => urldecode($_GET['is_admin_call']).'&uid='.$this->uid,
'sso' => \Phpcmf\Service::M('member')->sso($this->member, 1),
]);
} else {
$this->_json($rt['access_token'] ? 0 : 1, 'ok', $rt);
}
}
}
// 公众号浏览url弹出登录 url
public function login_url() {
$url = (!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=weixin&c=member&m=login';
if ($_GET['back'] && strpos($_GET['back'], 'c=member&m=login') === false) {
$burl = $_GET['back'];
} else {
$burl = (!$this->is_mobile ? SITE_URL : SITE_MURL).'index.php?s=member';
}
dr_redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->weixin['account']['appid'].'&redirect_uri='.urlencode($url).'&response_type=code&scope=snsapi_userinfo&state='.urlencode($burl).'#wechat_redirect');
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php namespace Phpcmf\Controllers;
// 素材内容显示
class Show extends \Phpcmf\Common {
public function index() {
$id = (int)\Phpcmf\Service::L('Input')->get('id');
$p = (int)\Phpcmf\Service::L('Input')->get('p');
$data = \Phpcmf\Service::M()->table(weixin_wxtable('content'))->get($id);
if (!$data) {
$this->_msg(0, '微信素材内容不存在');
} elseif ($data['tid'] != 'index') {
$this->_msg(0, '素材内容不正确');
}
$content = dr_string2array($data['content']);
if (!$content['title_'.$p] || !$content['content_'.$p]) {
$this->_msg(0, '素材内容不完整');
}
$share = \Phpcmf\Service::L('jssdk', 'weixin');
\Phpcmf\Service::V()->assign([
'title' => $content['title_'.$p],
'thumb' => $content['thumb_'.$p],
'author' => $content['author_'.$p],
'content' => htmlspecialchars_decode($content['content_'.$p]),
'inputtime' => dr_date($data['inputtime']),
'_inputtime' => $data['inputtime'],
'description' => $content['description_'.$p],
'signPackage' => $share->GetSignPackage(),
]);
\Phpcmf\Service::V()->display('show.html');exit;
}
}