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');
}
}