Merge pull request #118 from zoujingli/master

合并代码到V3版本
This commit is contained in:
邹景立 2018-05-28 14:41:13 +08:00 committed by GitHub
commit 0c585ad420
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2479 changed files with 6174 additions and 14726 deletions

View File

@ -16,6 +16,7 @@ namespace app\admin\controller;
use controller\BasicAdmin; use controller\BasicAdmin;
use service\LogService; use service\LogService;
use service\WechatService;
/** /**
* 后台参数配置控制器 * 后台参数配置控制器

View File

@ -59,9 +59,10 @@ class Login extends BasicAdmin
strlen($username) < 4 && $this->error('登录账号长度不能少于4位有效字符!'); strlen($username) < 4 && $this->error('登录账号长度不能少于4位有效字符!');
strlen($password) < 4 && $this->error('登录密码长度不能少于4位有效字符!'); strlen($password) < 4 && $this->error('登录密码长度不能少于4位有效字符!');
// 用户信息验证 // 用户信息验证
$user = Db::name('SystemUser')->where('username', $username)->find(); $user = Db::name('SystemUser')->where('is_deleted', '0')->where('username', $username)->find();
empty($user) && $this->error('登录账号不存在,请重新输入!'); empty($user) && $this->error('登录账号不存在,请重新输入!');
($user['password'] !== md5($password)) && $this->error('登录密码与账号不匹配,请重新输入!'); ($user['password'] !== md5($password)) && $this->error('登录密码与账号不匹配,请重新输入!');
empty($user['is_deleted']) || $this->error('账号已经被删除,请联系管理!');
empty($user['status']) && $this->error('账号已经被禁用,请联系管理!'); empty($user['status']) && $this->error('账号已经被禁用,请联系管理!');
// 更新登录信息 // 更新登录信息
$data = ['login_at' => Db::raw('now()'), 'login_num' => Db::raw('login_num+1')]; $data = ['login_at' => Db::raw('now()'), 'login_num' => Db::raw('login_num+1')];

View File

@ -19,7 +19,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -35,7 +35,7 @@
<tbody> <tbody>
<!--{foreach $list as $key=>$vo}--> <!--{foreach $list as $key=>$vo}-->
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'> <input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td> </td>
<td class='list-table-sort-td'> <td class='list-table-sort-td'>

View File

@ -67,7 +67,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='text-left nowrap'>操作账号</th> <th class='text-left nowrap'>操作账号</th>
@ -81,7 +81,7 @@
<tbody> <tbody>
<!--{foreach $list as $key=>$vo}--> <!--{foreach $list as $key=>$vo}-->
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'> <input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td> </td>
<td class='text-left nowrap'>{$vo.username}</td> <td class='text-left nowrap'>{$vo.username}</td>

View File

@ -18,7 +18,7 @@
<table id="test" class="layui-table" lay-skin="line"> <table id="test" class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -34,7 +34,7 @@
<tbody> <tbody>
<!--{foreach $list as $key=>$vo}--> <!--{foreach $list as $key=>$vo}-->
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.ids}' type='checkbox'> <input class="list-check-box" value='{$vo.ids}' type='checkbox'>
</td> </td>
<td class='list-table-sort-td'> <td class='list-table-sort-td'>

View File

@ -45,21 +45,21 @@
</td> </td>
<td class='text-left nowrap'> <td class='text-left nowrap'>
{if auth("$classuri/save") and $vo.spt eq 1} {if auth("$classuri/save") and $vo.spt eq 1}
<label class="color-desc"> <label class="color-desc think-checkbox">
<input data-login-group="{$vo.node}" type="checkbox"> 全部加入登录控制 <input data-login-group="{$vo.node}" type="checkbox"> 全部加入登录控制
</label> </label>
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
<label class="notselect margin-left-15 color-desc"> <label class="notselect margin-left-15 color-desc think-checkbox">
<input data-auth-group="{$vo.node}" type="checkbox"> 全部加入权限控制 <input data-auth-group="{$vo.node}" type="checkbox"> 全部加入权限控制
</label> </label>
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
<label class="notselect margin-left-15 color-desc"> <label class="notselect margin-left-15 color-desc think-checkbox">
<input data-menu-group="{$vo.node}" type="checkbox"> 全部加入菜单节点选择器 <input data-menu-group="{$vo.node}" type="checkbox"> 全部加入菜单节点选择器
</label> </label>
{/if} {/if}
{if auth("$classuri/save") and $vo.spt eq 2} {if auth("$classuri/save") and $vo.spt eq 2}
<span class="color-desc">&nbsp;&nbsp;├─&nbsp;</span> <span class="color-desc">&nbsp;&nbsp;├─&nbsp;</span>
<label class="notselect margin-right-15"> <label class="notselect margin-right-15 think-checkbox">
<!--{notempty name='vo.is_login'}--> <!--{notempty name='vo.is_login'}-->
<input data-login-filter="{$vo.pnode}" checked='checked' class="check-box login_{$key}" type='checkbox' value='1' name='is_login' data-node="{$vo.node}" onclick="!this.checked && ($('.auth_{$key}')[0].checked = !!this.checked)"> <input data-login-filter="{$vo.pnode}" checked='checked' class="check-box login_{$key}" type='checkbox' value='1' name='is_login' data-node="{$vo.node}" onclick="!this.checked && ($('.auth_{$key}')[0].checked = !!this.checked)">
<!--{else}--> <!--{else}-->
@ -68,7 +68,7 @@
加入登录控制 加入登录控制
</label> </label>
<span class="color-desc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;├─&nbsp;</span> <span class="color-desc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;├─&nbsp;</span>
<label class="notselect margin-right-15"> <label class="notselect margin-right-15 think-checkbox">
<!--{notempty name='vo.is_auth'}--> <!--{notempty name='vo.is_auth'}-->
<input data-auth-filter="{$vo.pnode}" name='is_auth' data-node="{$vo.node}" checked='checked' class="check-box auth_{$key}" type='checkbox' onclick="this.checked && ($('.login_{$key}')[0].checked = !!this.checked)" value='1'> <input data-auth-filter="{$vo.pnode}" name='is_auth' data-node="{$vo.node}" checked='checked' class="check-box auth_{$key}" type='checkbox' onclick="this.checked && ($('.login_{$key}')[0].checked = !!this.checked)" value='1'>
<!--{else}--> <!--{else}-->
@ -77,7 +77,7 @@
加入权限控制 加入权限控制
</label> </label>
<span class="color-desc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;├─&nbsp;</span> <span class="color-desc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;├─&nbsp;</span>
<label class="notselect"> <label class="notselect think-checkbox">
<!--{notempty name='vo.is_menu'}--> <!--{notempty name='vo.is_menu'}-->
<input data-menu-filter="{$vo.pnode}" name='is_menu' data-node="{$vo.node}" checked='checked' class='check-box menu_{$key}' type='checkbox' value='1'> <input data-menu-filter="{$vo.pnode}" name='is_menu' data-node="{$vo.node}" checked='checked' class='check-box menu_{$key}' type='checkbox' value='1'>
<!--{else}--> <!--{else}-->

View File

@ -61,7 +61,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='text-left nowrap'>用户名</th> <th class='text-left nowrap'>用户名</th>
@ -76,7 +76,7 @@
<tbody> <tbody>
<!--{foreach $list as $key=>$vo}--> <!--{foreach $list as $key=>$vo}-->
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'> <input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td> </td>
<td class='text-left nowrap'> <td class='text-left nowrap'>

View File

@ -58,7 +58,7 @@
<table class="layui-table" lay-skin="line" lay-size="sm"> <table class="layui-table" lay-skin="line" lay-size="sm">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -74,7 +74,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/> <input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td> </td>
<td class='list-table-sort-td'> <td class='list-table-sort-td'>

View File

@ -90,7 +90,7 @@
<table class="layui-table notevent" lay-skin="line"> <table class="layui-table notevent" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -114,7 +114,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td text-top'> <td class='list-table-check-td text-top think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'> <input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td> </td>
<td class='list-table-sort-td text-top'> <td class='list-table-sort-td text-top'>

View File

@ -51,7 +51,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -66,7 +66,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/> <input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td> </td>
<td class='list-table-sort-td'> <td class='list-table-sort-td'>

View File

@ -18,7 +18,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -34,7 +34,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.ids}' type='checkbox'> <input class="list-check-box" value='{$vo.ids}' type='checkbox'>
</td> </td>
<td class='list-table-sort-td'> <td class='list-table-sort-td'>

View File

@ -51,7 +51,7 @@
<table class="layui-table" lay-skin="line" lay-size="sm"> <table class="layui-table" lay-skin="line" lay-size="sm">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -67,7 +67,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td text-top'> <td class='list-table-check-td text-top think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/> <input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td> </td>
<td class='list-table-sort-td text-top'> <td class='list-table-sort-td text-top'>

View File

@ -182,7 +182,7 @@
<table class="layui-table" lay-size="sm"> <table class="layui-table" lay-size="sm">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class="text-left">会员信息</th> <th class="text-left">会员信息</th>
@ -206,7 +206,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td text-top'> <td class='list-table-check-td text-top think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/> <input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td> </td>
<td class="text-left text-top nowrap"> <td class="text-left text-top nowrap">

View File

@ -92,7 +92,7 @@ class Fans extends BasicAdmin
{ {
try { try {
$openids = $this->_getActionOpenids(); $openids = $this->_getActionOpenids();
WechatService::user()->batchBlackList($openids); WechatService::WeChatUser()->batchBlackList($openids);
Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '1'); Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '1');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error("设置黑名单失败,请稍候再试!"); $this->error("设置黑名单失败,请稍候再试!");
@ -113,7 +113,7 @@ class Fans extends BasicAdmin
$fans = Db::name('WechatFans')->where(['id' => $fans_id])->find(); $fans = Db::name('WechatFans')->where(['id' => $fans_id])->find();
empty($fans) && $this->error('需要操作的数据不存在!'); empty($fans) && $this->error('需要操作的数据不存在!');
try { try {
$wechat = WechatService::tags(); $wechat = WechatService::WeChatTags();
foreach (explode(',', $fans['tagid_list']) as $tagid) { foreach (explode(',', $fans['tagid_list']) as $tagid) {
is_numeric($tagid) && $wechat->batchUntagging([$fans['openid']], $tagid); is_numeric($tagid) && $wechat->batchUntagging([$fans['openid']], $tagid);
} }
@ -136,7 +136,7 @@ class Fans extends BasicAdmin
empty($tagid) && $this->error('没有可能操作的标签ID'); empty($tagid) && $this->error('没有可能操作的标签ID');
try { try {
$openids = $this->_getActionOpenids(); $openids = $this->_getActionOpenids();
WechatService::tags()->batchTagging($openids, $tagid); WechatService::WeChatTags()->batchTagging($openids, $tagid);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error("设置粉丝标签失败, 请稍候再试! " . $e->getMessage()); $this->error("设置粉丝标签失败, 请稍候再试! " . $e->getMessage());
} }
@ -152,7 +152,7 @@ class Fans extends BasicAdmin
empty($tagid) && $this->error('没有可能操作的标签ID'); empty($tagid) && $this->error('没有可能操作的标签ID');
try { try {
$openids = $this->_getActionOpenids(); $openids = $this->_getActionOpenids();
WechatService::tags()->batchUntagging($openids, $tagid); WechatService::WeChatTags()->batchUntagging($openids, $tagid);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error("删除粉丝标签失败, 请稍候再试! "); $this->error("删除粉丝标签失败, 请稍候再试! ");
} }

View File

@ -89,7 +89,7 @@ class FansBlock extends BasicAdmin
{ {
$openids = $this->_getActionOpenids(); $openids = $this->_getActionOpenids();
try { try {
WechatService::user()->batchUnblackList($openids); WechatService::WeChatUser()->batchUnblackList($openids);
Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '0'); Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '0');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error("设备黑名单失败,请稍候再试!" . $e->getMessage()); $this->error("设备黑名单失败,请稍候再试!" . $e->getMessage());

View File

@ -38,14 +38,23 @@ class Keys extends BasicAdmin
/** /**
* 显示关键字列表 * 显示关键字列表
* @return array|string * @return array|string
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \WeChat\Exceptions\LocalCacheException
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException * @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException * @throws \think\exception\DbException
* @throws \think\Exception
*/ */
public function index() public function index()
{ {
$this->assign('title', '微信关键字'); // 关键字二维码显示
if ($this->request->get('action') === 'qrc') {
$wechat = WechatService::WeChatQrcode();
$result = $wechat->create($this->request->get('keys', ''));
$this->redirect($wechat->url($result['ticket']));
}
// 显示关键字列表
$this->title = '微信关键字管理';
$db = Db::name($this->table)->whereNotIn('keys', ['subscribe', 'default']); $db = Db::name($this->table)->whereNotIn('keys', ['subscribe', 'default']);
return $this->_list($db->order('sort asc,id desc')); return $this->_list($db->order('sort asc,id desc'));
} }
@ -56,15 +65,13 @@ class Keys extends BasicAdmin
*/ */
protected function _index_data_filter(&$data) protected function _index_data_filter(&$data)
{ {
try {
$types = [ $types = [
'keys' => '关键字', 'image' => '图片', 'news' => '图文', 'keys' => '关键字', 'image' => '图片', 'news' => '图文',
'music' => '音乐', 'text' => '文字', 'video' => '视频', 'voice' => '语音', 'music' => '音乐', 'text' => '文字', 'video' => '视频', 'voice' => '语音',
]; ];
try {
$wechat = WechatService::qrcode();
foreach ($data as &$vo) { foreach ($data as &$vo) {
$result = $wechat->create($vo['keys']); $vo['qrc'] = url('@wechat/keys/index') . "?action=qrc&keys={$vo['keys']}";
$vo['qrc'] = $wechat->url($result['ticket']);
$vo['type'] = isset($types[$vo['type']]) ? $types[$vo['type']] : $vo['type']; $vo['type'] = isset($types[$vo['type']]) ? $types[$vo['type']] : $vo['type'];
} }
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@ -91,7 +91,7 @@ class Menu extends BasicAdmin
if (empty($post['data'])) { if (empty($post['data'])) {
try { try {
Db::name($this->table)->where('1=1')->delete(); Db::name($this->table)->where('1=1')->delete();
WechatService::menu()->delete(); WechatService::WeChatMenu()->delete();
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error('删除取消微信菜单失败,请稍候再试!' . $e->getMessage()); $this->error('删除取消微信菜单失败,请稍候再试!' . $e->getMessage());
} }
@ -121,7 +121,7 @@ class Menu extends BasicAdmin
public function cancel() public function cancel()
{ {
try { try {
WechatService::menu()->delete(); WechatService::WeChatMenu()->delete();
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error('菜单取消失败'); $this->error('菜单取消失败');
} }
@ -174,7 +174,7 @@ class Menu extends BasicAdmin
} }
unset($menu['type']); unset($menu['type']);
} }
WechatService::menu()->create(['button' => $menus]); WechatService::WeChatMenu()->create(['button' => $menus]);
} }
} }

View File

@ -145,7 +145,10 @@ class News extends BasicAdmin
$id = $this->request->get('id', ''); $id = $this->request->get('id', '');
if ($this->request->isGet()) { if ($this->request->isGet()) {
empty($id) && $this->error('参数错误,请稍候再试!'); empty($id) && $this->error('参数错误,请稍候再试!');
return $this->fetch('form', ['title' => '编辑图文', 'vo' => MediaService::getNewsById($id)]); if ($this->request->get('output') === 'json') {
ToolsService::success('获取数据成功', MediaService::getNewsById($id));
}
return $this->fetch('form', ['title' => '编辑图文']);
} }
$data = $this->request->post(); $data = $this->request->post();
$ids = $this->_apply_news_article($data['data']); $ids = $this->_apply_news_article($data['data']);
@ -254,7 +257,7 @@ class News extends BasicAdmin
$data['filter'] = ['is_to_all' => false, 'tag_id' => join(',', $post['fans_tags'])]; $data['filter'] = ['is_to_all' => false, 'tag_id' => join(',', $post['fans_tags'])];
$data['mpnews'] = ['media_id' => $newsinfo['media_id']]; $data['mpnews'] = ['media_id' => $newsinfo['media_id']];
} }
if (WechatService::custom()->massSendAll($data)) { if (WechatService::WeChatCustom()->massSendAll($data)) {
LogService::write('微信管理', "图文[{$news_id}]推送成功"); LogService::write('微信管理', "图文[{$news_id}]推送成功");
$this->success('微信图文推送成功!', ''); $this->success('微信图文推送成功!', '');
} }
@ -280,7 +283,7 @@ class News extends BasicAdmin
return "<img{$matches[1]}src=\"{$src}\"{$matches[3]}/>"; return "<img{$matches[1]}src=\"{$src}\"{$matches[3]}/>";
}, $article['content']); }, $article['content']);
} }
$wechat = WechatService::media(); $wechat = WechatService::WeChatMedia();
// 如果已经上传过,先删除之前的历史记录 // 如果已经上传过,先删除之前的历史记录
!empty($news['media_id']) && $wechat->delMaterial($news['media_id']); !empty($news['media_id']) && $wechat->delMaterial($news['media_id']);
// 上传图文到微信服务器 // 上传图文到微信服务器

View File

@ -74,7 +74,7 @@ class Tags extends BasicAdmin
if (Db::name($this->table)->where('name', $name)->count() > 0) { if (Db::name($this->table)->where('name', $name)->count() > 0) {
$this->error('粉丝标签标签名已经存在, 请使用其它标签名!'); $this->error('粉丝标签标签名已经存在, 请使用其它标签名!');
} }
$wechat = WechatService::tags(); $wechat = WechatService::WeChatTags();
if (false === ($result = $wechat->createTags($name)) && isset($result['tag'])) { if (false === ($result = $wechat->createTags($name)) && isset($result['tag'])) {
$this->error("添加粉丝标签失败. "); $this->error("添加粉丝标签失败. ");
} }
@ -110,7 +110,7 @@ class Tags extends BasicAdmin
$this->error('标签已经存在, 使用其它名称再试!'); $this->error('标签已经存在, 使用其它名称再试!');
} }
try { try {
WechatService::tags()->updateTags($id, $name); WechatService::WeChatTags()->updateTags($id, $name);
DataService::save($this->table, ['id' => $id, 'name' => $name], 'id'); DataService::save($this->table, ['id' => $id, 'name' => $name], 'id');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error('编辑标签失败, 请稍后再试!' . $e->getMessage()); $this->error('编辑标签失败, 请稍后再试!' . $e->getMessage());
@ -128,7 +128,7 @@ class Tags extends BasicAdmin
*/ */
public function del() public function del()
{ {
$wechat = WechatService::tags(); $wechat = WechatService::WeChatTags();
foreach (explode(',', $this->request->post('id', '')) as $id) { foreach (explode(',', $this->request->post('id', '')) as $id) {
if ($wechat->deleteTags($id)) { if ($wechat->deleteTags($id)) {
Db::name('WechatFansTags')->where(['id' => $id])->delete(); Db::name('WechatFansTags')->where(['id' => $id])->delete();

View File

@ -74,7 +74,7 @@ class Push
*/ */
public function notify() public function notify()
{ {
$wechat = WechatService::receive(); $wechat = WechatService::WeChatReceive();
$this->openid = $wechat->getOpenid(); $this->openid = $wechat->getOpenid();
$this->receive = $wechat->getReceive(); $this->receive = $wechat->getReceive();
$this->appid = WechatService::getAppid(); $this->appid = WechatService::getAppid();
@ -251,7 +251,7 @@ class Push
$msgData = ['touser' => $this->openid, 'msgtype' => $type, "{$type}" => $data]; $msgData = ['touser' => $this->openid, 'msgtype' => $type, "{$type}" => $data];
switch (strtolower(sysconf('wechat_type'))) { switch (strtolower(sysconf('wechat_type'))) {
case 'api': // 参数对接直接回复XML来实现消息回复 case 'api': // 参数对接直接回复XML来实现消息回复
$wechat = WechatService::receive(); $wechat = WechatService::WeChatReceive();
switch (strtolower($type)) { switch (strtolower($type)) {
case 'text': case 'text':
return $wechat->text($data['content'])->reply([], true); return $wechat->text($data['content'])->reply([], true);
@ -272,7 +272,7 @@ class Push
return 'success'; return 'success';
} }
case 'thr': // 第三方平台,使用客服消息来实现 case 'thr': // 第三方平台,使用客服消息来实现
return WechatService::custom()->send($msgData); return WechatService::WeChatCustom()->send($msgData);
default: default:
return 'success'; return 'success';
} }
@ -313,7 +313,7 @@ class Push
protected function updateFansinfo($subscribe = true) protected function updateFansinfo($subscribe = true)
{ {
if ($subscribe) { if ($subscribe) {
$userInfo = WechatService::user()->getUserInfo($this->openid); $userInfo = WechatService::WeChatUser()->getUserInfo($this->openid);
$userInfo['subscribe'] = intval($subscribe); $userInfo['subscribe'] = intval($subscribe);
FansService::set($userInfo); FansService::set($userInfo);
} else { } else {

View File

@ -28,6 +28,7 @@ class Tools extends BasicAdmin
/** /**
* 网页授权测试 * 网页授权测试
* @return string * @return string
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \think\Exception * @throws \think\Exception
* @throws \think\exception\PDOException * @throws \think\exception\PDOException
*/ */

View File

@ -77,7 +77,7 @@ class FansService
*/ */
public static function sync($next_openid = '') public static function sync($next_openid = '')
{ {
$wechat = WechatService::user(); $wechat = WechatService::WeChatUser();
$result = $wechat->getUserList($next_openid); $result = $wechat->getUserList($next_openid);
if (empty($result['data']['openid'])) { if (empty($result['data']['openid'])) {
return false; return false;
@ -106,7 +106,7 @@ class FansService
*/ */
public static function syncBlack($next_openid = '') public static function syncBlack($next_openid = '')
{ {
$wechat = WechatService::user(); $wechat = WechatService::WeChatUser();
$result = $wechat->getBlackList($next_openid); $result = $wechat->getBlackList($next_openid);
foreach (array_chunk($result['data']['openid'], 100) as $openids) { foreach (array_chunk($result['data']['openid'], 100) as $openids) {
$info = $wechat->getBatchUserInfo($openids); $info = $wechat->getBatchUserInfo($openids);

View File

@ -67,7 +67,7 @@ class MediaService
if (($media_url = Db::name('WechatNewsImage')->where($map)->value('media_url'))) { if (($media_url = Db::name('WechatNewsImage')->where($map)->value('media_url'))) {
return $media_url; return $media_url;
} }
$info = WechatService::media()->uploadImg(self::getServerPath($local_url)); $info = WechatService::WeChatMedia()->uploadImg(self::getServerPath($local_url));
if (strtolower(sysconf('wechat_type')) === 'thr') { if (strtolower(sysconf('wechat_type')) === 'thr') {
WechatService::wechat()->rmFile($local_url); WechatService::wechat()->rmFile($local_url);
} }
@ -93,7 +93,7 @@ class MediaService
if (($media_id = Db::name('WechatNewsMedia')->where($map)->value('media_id'))) { if (($media_id = Db::name('WechatNewsMedia')->where($map)->value('media_id'))) {
return $media_id; return $media_id;
} }
$result = WechatService::media()->addMaterial(self::getServerPath($local_url), $type, $video_info); $result = WechatService::WeChatMedia()->addMaterial(self::getServerPath($local_url), $type, $video_info);
if (strtolower(sysconf('wechat_type')) === 'thr') { if (strtolower(sysconf('wechat_type')) === 'thr') {
WechatService::wechat()->rmFile($local_url); WechatService::wechat()->rmFile($local_url);
} }

View File

@ -36,7 +36,7 @@ class TagsService
*/ */
public static function syncTagsByOpenid($openid) public static function syncTagsByOpenid($openid)
{ {
$tagsid = WechatService::tags()->getUserTagId($openid); $tagsid = WechatService::WeChatTags()->getUserTagId($openid);
if (!is_array($tagsid)) { if (!is_array($tagsid)) {
return false; return false;
} }
@ -55,7 +55,7 @@ class TagsService
public static function sync() public static function sync()
{ {
$appid = WechatService::getAppid(); $appid = WechatService::getAppid();
$result = WechatService::tags()->getTags(); $result = WechatService::WeChatTags()->getTags();
Db::name('WechatFansTags')->where(['appid' => $appid])->delete(); Db::name('WechatFansTags')->where(['appid' => $appid])->delete();
foreach (array_chunk($result['tags'], 100) as $list) { foreach (array_chunk($result['tags'], 100) as $list) {
foreach ($list as &$vo) { foreach ($list as &$vo) {

View File

@ -22,7 +22,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="none" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class='text-left'>用户昵称</th> <th class='text-left'>用户昵称</th>
@ -36,7 +36,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/> <input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td> </td>
<td class='text-left nowrap'> <td class='text-left nowrap'>

View File

@ -22,7 +22,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'>
</th> </th>
<th class='text-left'>用户昵称</th> <th class='text-left'>用户昵称</th>
@ -36,7 +36,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'> <input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td> </td>
<td class='text-left nowrap'> <td class='text-left nowrap'>

View File

@ -21,7 +21,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class='list-table-sort-td'> <th class='list-table-sort-td'>
@ -38,7 +38,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'/> <input class="list-check-box" value='{$vo.id}' type='checkbox'/>
</td> </td>
<td class='list-table-sort-td'> <td class='list-table-sort-td'>

View File

@ -1,33 +1,33 @@
{extend name='admin@public/content'} {extend name='admin@public/content'}
{block name='content'} {block name='content'}
<div id="NewsEditor">
<!--左侧图文列表 开始--> <!--左侧图文列表 开始-->
<div class="panel panel-default news-left"> <div class="panel panel-default news-left">
<div class="panel-heading">图文列表</div> <div class="panel-heading">图文列表</div>
<div class="panel-body news-box"> <div class="panel-body news-box">
{if empty($vo['articles']) eq false} <div ng-if="list.length > 0" ng-repeat="x in list">
<!--{foreach $vo.articles as $key=>$value}--> <div class="news-item transition" ng-click="setItem($index,$event)" style="{{x.style}}" ng-class="x.active?'active':''">
<div class="news-item transition" data-id="{$value.id}" style="background-image:url('{$value.local_url}?imageView2/1/w/338/h/190/interlace/1')"> <a ng-click="delItem($index, $event)" class="upload-multiple-close layui-icon hide">&#x1006;</a>
<a class="upload-multiple-close layui-icon hide">&#x1006;</a> <a ng-click="dnItem($index, $event)" class="upload-multiple-close layui-icon hide">&#xe61a;</a>
<span class="news-title">{$value.title}</span> <a ng-click="upItem($index, $event)" class="upload-multiple-close layui-icon hide">&#xe619;</a>
<span class="news-title" ng-bind="x.title"></span>
</div> </div>
<hr/> <hr/>
<!--{/foreach}--> </div>
{else} <div ng-if="list.length<1" class="news-item transition active news-image">
<div class="news-item transition active news-image" style="background-image:url('__STATIC__/plugs/uploader/theme/image.png')"> <a ng-click="delItem($index, $event)" class="upload-multiple-close layui-icon hide">&#x1006;</a>
<a class="upload-multiple-close layui-icon hide">&#x1006;</a> <a ng-click="dnItem($index, $event)" class="upload-multiple-close layui-icon hide">&#xe61a;</a>
<a ng-click="upItem($index, $event)" class="upload-multiple-close layui-icon hide">&#xe619;</a>
<span class="news-title"></span> <span class="news-title"></span>
</div>
<hr/> <hr/>
{/if} </div>
<a href="javascript:void(0)" class='article-add transition' data-text-tip="添加图文"> <a class='article-add transition' ng-click="addItem()" data-text-tip="添加图文">
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
</a> </a>
</div> </div>
</div> </div>
<!--左侧图文列表 结束--> <!--左侧图文列表 结束-->
<!--右侧编辑区 开始--> <!--右侧编辑区 开始-->
<div class="panel panel-default news-right"> <div class="panel panel-default news-right">
<div class="panel-heading">图文内容编辑</div> <div class="panel-heading">图文内容编辑</div>
@ -38,8 +38,7 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">文章标题</span> <span class="input-group-addon">文章标题</span>
<input maxlength="64" required title="文章的标题不能为空哦" placeholder="请在这里输入标题" name='title' class="layui-input"> <input maxlength="64" ng-model="item.title" required title="文章的标题不能为空哦" placeholder="请在这里输入标题" name='title' class="layui-input">
<input type="hidden" name="id">
</div> </div>
</div> </div>
</div> </div>
@ -48,7 +47,7 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">文章作者</span> <span class="input-group-addon">文章作者</span>
<input maxlength="8" required title="文章的作者不能为空哦" placeholder="请输入作者" name='author' class="layui-input"> <input maxlength="8" ng-model="item.author" required title="文章的作者不能为空哦" placeholder="请输入作者" name='author' class="layui-input">
</div> </div>
</div> </div>
</div> </div>
@ -60,7 +59,7 @@
<div class="row nowrap"> <div class="row nowrap">
<div class="col-xs-3" style="width:160px"> <div class="col-xs-3" style="width:160px">
<div class="upload-image-box transition"> <div class="upload-image-box transition">
<input value="__STATIC__/plugs/uploader/theme/image.png" type="hidden" name="local_url"> <input ng-model="item.local_url" value="__STATIC__/plugs/uploader/theme/image.png" type="hidden" name="local_url">
</div> </div>
</div> </div>
<div class="col-xs-6 padding-top-10"> <div class="col-xs-6 padding-top-10">
@ -68,7 +67,7 @@
<button type="button" data-title="选择图片" data-iframe='{:url("image")}?field=local_url' class="layui-btn layui-btn-sm layui-btn-primary">选择图片</button> <button type="button" data-title="选择图片" data-iframe='{:url("image")}?field=local_url' class="layui-btn layui-btn-sm layui-btn-primary">选择图片</button>
<br> <br>
<label class="think-checkbox notselect margin-top-15"> <label class="think-checkbox notselect margin-top-15">
<input data-auto-none type="checkbox" value="1" name="show_cover_pic"> 在正文中显示此图片 <input ng-model="item.show_cover_pic" ng-checked="!!item.show_cover_pic" data-auto-none type="checkbox" value="1" name="show_cover_pic"> 在正文中显示此图片
</label> </label>
</div> </div>
</div> </div>
@ -78,25 +77,25 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-md-12"><textarea name='content'></textarea></div> <div class="col-md-12"><textarea ng-model="item.content" name='content'></textarea></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-md-12"> <div class="col-md-12">
<label class="color-desc">摘要选填如果不填写会默认抓取正文前54个字</label> <label class="color-desc">摘要选填如果不填写会默认抓取正文前54个字</label>
<textarea name="digest" class="layui-textarea" style="height:80px;resize:none"></textarea> <textarea ng-model="item.digest" name="digest" class="layui-textarea" style="height:80px;line-height:18px;resize:none"></textarea>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-md-12"> <div class="col-md-12">
<label class="color-desc">原文链接<b>选填</b>,填写之后在图文左下方会出现此链接</label> <label class="color-desc">原文链接<b>选填</b>,填写之后在图文左下方会出现此链接</label>
<input maxlength="200" name='content_source_url' class="layui-input"> <input ng-model="item.content_source_url" maxlength="200" name='content_source_url' class="layui-input">
</div> </div>
</div> </div>
<div class="form-actions"> <div class="form-actions">
<div class="row"> <div class="row">
<div class="col-md-offset-4 col-md-9"> <div class="col-md-offset-4 col-md-9">
<button data-submit type="button" class="layui-btn">保存图文</button> <button ng-click="submit()" type="button" class="layui-btn">保存图文</button>
</div> </div>
</div> </div>
</div> </div>
@ -104,155 +103,154 @@
</div> </div>
</div> </div>
<!--右侧编辑区 结束--> <!--右侧编辑区 结束-->
</div>
{/block} {/block}
{block name='script'} {block name='script'}
<textarea class="hide" id="newsdata">{$vo.articles|default=[]|json_encode=256|raw}</textarea>
<script> <script>
require(['ckeditor'], function () { require(['angular', 'ckeditor'], function () {
var editDdata = JSON.parse(document.getElementById('newsdata').innerHTML); var $form = $('form[name="news"]');
var editor = window.createEditor('[name="content"]');
for (var i in editDdata) { var app = angular.module("NewsEditor", []).run(callback);
$('.news-item').eq(i).data('item', editDdata[i]); angular.bootstrap(document.getElementById(app.name), [app.name]);
}
/*! 实例富文本编辑器 */ function callback($rootScope) {
var editor, $item, $body = $('body'), $form = $('form[name="news"]'); $rootScope.list = [];
$rootScope.item = {};
/*! 默认编辑第一篇图文 */ $.form.load('{:request()->url()}', {output: 'json'}, 'get', function (ret) {
editor = window.createEditor('[name="content"]'); return $rootScope.$apply(function () {
$form.vali(); apply((ret.data || {articles: []}).articles || []);
}), false;
/*! 上传图片 */
$body.on('change', '.upload-image-box input', function () {
$('.news-item.active').css('background-image', 'url(' + this.value + ')');
$(this).parent('.upload-image-box').css('background-image', 'url(' + this.value + ')');
}); });
/*! 数据提交 */ function apply(data) {
$form.find('button[data-submit]').on('click', function () { if (data.length < 1) {
var data = []; data.push({
$form.submit(); title: '新建图文',
if (!syncEditor($('.news-item.active'))) { local_url: '__STATIC__/plugs/uploader/theme/image.png',
editor.setData('文章内容不能留空,请输入内容!'); style: "background-image:url('__STATIC__/plugs/uploader/theme/image.png?imageView2/1/w/338/h/190/interlace/1')"
return false;
}
$('.news-item').map(function () {
var item = $(this).data('item');
item.content = item.content || '文章内容不能留空,请输入内容!';
data.push(item);
}); });
$.form.load('{:request()->url()}', {data: data}, "post");
});
/*! 输入标题显示 */
$form.find('[name="title"]').on('keyup', function () {
if ($item) {
$item.find('.news-title').html(this.value).show();
} }
});
/*! 同步编辑器 */
function syncEditor($pItem) {
// 处理上一个编辑器
if ($form && $pItem && $pItem.size() > 0) {
var data = {};
data.id = $form.find('[name=id]').val();
data.title = $form.find('[name=title]').val();
data.local_url = $form.find('[name=local_url]').val();
data.content = editor.getData() || '';
data.author = $form.find('[name=author]').val();
data.digest = $form.find('[name=digest]').val();
data.show_cover_pic = $form.find('[name="show_cover_pic"]').get(0).checked ? 1 : 0;
data.content_source_url = $form.find('[name="content_source_url"]').val();
$form.find('[name=local_url]').trigger('change');
$pItem.data('item', data), $form.submit();
if ($form.find('input.validate-error').size() > 0 || data.content.length < 1) {
((data.content || '').length < 1) && editor.setData('文章内容不能留空,请输入内容!');
$pItem.addClass('active').siblings().removeClass('active');
return false;
}
}
return true;
}
/*! 显示编辑器 */
function showEditor() {
// 读取对象数据
$item = $('.news-item.active');
this.get = function () {
var data = $item.data('item') || {};
data.id = data.id || 0;
data.title = data.title || '';
data.local_url = data.local_url || '__STATIC__/plugs/uploader/theme/image.png';
data.content = data.content || '';
data.author = data.author || '';
data.digest = data.digest || '';
data.content_source_url = data.content_source_url || '';
data.show_cover_pic = data.show_cover_pic || 0;
return data;
};
// 重置表单
$form.get(0).reset();
// 获取当前数据
var data = this.get();
for (var i in data) { for (var i in data) {
if (i !== 'content' && i !== 'show_cover_pic') { data[i].active = false;
$form.find('[name="' + i + '"]').val(data[i]).trigger('change'); data[i].style = "background-image:url('" + data[i].local_url + "?imageView2/1/w/338/h/190/interlace/1')";
data[i].show_cover_pic = !!data[i].show_cover_pic;
} }
} $rootScope.list = data;
if (parseInt(data.show_cover_pic) === 1) { $rootScope.item = $rootScope.list[0];
$form.find('[name="show_cover_pic"]').get(0).checked = true; $rootScope.setItemValue('active', true);
setTimeout(function () {
editor.setData($rootScope.item.content);
}, 100);
$form.vali();
} }
editor.setData(htmldecode(data.content)); $rootScope.upItem = function (index, $event) {
$event.stopPropagation();
function htmldecode(string) { var tmp = [], cur = $rootScope.list[index];
var div = document.createElement('div'); if (index < 1) {
div.innerHTML = string; return false;
return div.innerText || div.textContent;
} }
for (var i in $rootScope.list) {
(parseInt(i) === parseInt(index) - 1) && tmp.push(cur);
(parseInt(i) !== parseInt(index)) && tmp.push($rootScope.list[i]);
} }
apply(tmp);
};
/*! 添加新图文 */ $rootScope.dnItem = function (index, $event) {
$body.off('click', '.news-box .article-add').on('click', '.news-box .article-add', function () { $event.stopPropagation();
var $html = $('<div class="news-item transition" style="background-image:url(__STATIC__/plugs/uploader/theme/image.png)"><a class="upload-multiple-close layui-icon hide">&#x1006;</a><span class="news-title"></span></div><hr />'); var tmp = [], cur = $rootScope.list[index];
$html.insertBefore(this).trigger('click'); if (index > $rootScope.list.length - 2) {
$('.news-item').size() >= 7 && $(this).hide(); return false;
}
for (var i in $rootScope.list) {
(parseInt(i) !== parseInt(index)) && tmp.push($rootScope.list[i]);
(parseInt(i) === parseInt(index) + 1) && tmp.push(cur);
}
apply(tmp);
};
$rootScope.delItem = function (index, $event) {
$event.stopPropagation();
var list = $rootScope.list, temp = [];
for (var i in list) {
(parseInt(i) !== parseInt(index)) && temp.push(list[i]);
}
apply(temp);
};
$rootScope.setItem = function (index, $event) {
$event.stopPropagation();
$form.vali();
if ($form.find('.validate-error').size() > 0) {
return 0;
}
if (editor.getData().length < 1) {
return $.msg.tips('请输入文章内容');
}
for (var i in $rootScope.list) {
if (parseInt(i) !== parseInt(index)) {
$rootScope.list[i].active = false;
continue;
}
$rootScope.item.content = editor.getData();
$rootScope.item = $rootScope.list[i];
editor.setData($rootScope.item.content);
$rootScope.setItemValue('active', true);
}
};
$rootScope.setItemValue = function (name, value) {
$rootScope.item[name] = value;
var localUrl = $rootScope.item.local_url;
$('[name="local_url"]').parent().css('background-image', 'url(' + localUrl + ')');
$rootScope.item.style = "background-image:url('" + localUrl + "?imageView2/1/w/338/h/190/interlace/1')";
};
$rootScope.addItem = function () {
if ($rootScope.list.length > 7) {
return $.msg.tips('最多允许增加7篇文章哦');
}
$rootScope.list.push({
title: '新建图文',
local_url: '__STATIC__/plugs/uploader/theme/image.png',
style: "background-image:url('__STATIC__/plugs/uploader/theme/image.png?imageView2/1/w/338/h/190/interlace/1')"
}); });
};
/*! 列表选择 */ $rootScope.submit = function () {
$body.off('click', '.news-item').on('click', '.news-item', function () { $form.vali();
if (syncEditor($('.news-item.active'))) { if ($form.find('.validate-error').size() > 0) {
$(this).addClass('active').siblings().removeClass('active'); return $.msg.tips('表单验证不成功,请输入需要的内容!');
showEditor($item);
} }
$rootScope.item.content = editor.getData();
var data = [];
for (var i in $rootScope.list) {
data.push({
id: $rootScope.list[i].id,
title: $rootScope.list[i].title,
author: $rootScope.list[i].author,
digest: $rootScope.list[i].digest,
content: $rootScope.list[i].content,
local_url: $rootScope.list[i].local_url,
show_cover_pic: $rootScope.list[i].show_cover_pic ? 1 : 0,
content_source_url: $rootScope.list[i].content_source_url,
})
}
$.form.load('{:request()->url()}', {data: data}, "post");
};
$('body').off('change', '[name="local_url"]').on('change', '[name="local_url"]', function () {
var value = this.value;
$rootScope.$apply(function () {
$rootScope.setItemValue('local_url', value);
}); });
/*! 隐藏删除按钮 */
$body.off('mouseleave').on('mouseleave', '.news-item', function () {
$(this).find('.upload-multiple-close').addClass('hide');
}); });
}
/*! 显示删除按钮 */
$body.off('mouseenter', '.news-item').on('mouseenter', '.news-item', function () {
$('.upload-multiple-close').addClass('hide');
$(this).find('.upload-multiple-close').removeClass('hide');
});
/*! 删除操作图文 */
$body.off('click', '.upload-multiple-close').on('click', '.upload-multiple-close', function () {
var $box = $(this).parents('.news-item');
$box.add($box.next('hr')).remove();
$('.news-item').size() < 7 && $('.news-box .article-add').show();
});
/*! 默认显示第一个 */
$('.news-box .news-item:first').trigger('click');
}); });
</script> </script>
{/block} {/block}
@ -279,6 +277,7 @@
.news-left .news-item { .news-left .news-item {
width: 280px; width: 280px;
height: 150px; height: 150px;
cursor: pointer;
max-width: 270px; max-width: 270px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@ -287,6 +286,10 @@
background-position: center center; background-position: center center;
} }
.news-left .news-item:hover .upload-multiple-close {
display: inline-block !important;
}
.news-left .news-item.active { .news-left .news-item.active {
border: 1px solid #44b549 !important; border: 1px solid #44b549 !important;
} }
@ -345,7 +348,7 @@
height: 30px; height: 30px;
float: right; float: right;
margin-top: -1px; margin-top: -1px;
line-height: 30px; line-height: 34px;
text-align: center; text-align: center;
margin-right: -1px; margin-right: -1px;
background-color: rgba(0, 0, 0, .5); background-color: rgba(0, 0, 0, .5);

View File

@ -39,7 +39,7 @@
<table class="layui-table" lay-skin="line"> <table class="layui-table" lay-skin="line">
<thead> <thead>
<tr> <tr>
<th class='list-table-check-td'> <th class='list-table-check-td think-checkbox'>
<input data-auto-none="" data-check-target='.list-check-box' type='checkbox'/> <input data-auto-none="" data-check-target='.list-check-box' type='checkbox'/>
</th> </th>
<th class='text-center'>ID</th> <th class='text-center'>ID</th>
@ -52,7 +52,7 @@
<tbody> <tbody>
{foreach $list as $key=>$vo} {foreach $list as $key=>$vo}
<tr> <tr>
<td class='list-table-check-td'> <td class='list-table-check-td think-checkbox'>
<input class="list-check-box" value='{$vo.id}' type='checkbox'> <input class="list-check-box" value='{$vo.id}' type='checkbox'>
</td> </td>
<td class='text-center'>{$vo.id|default='0'}</td> <td class='text-center'>{$vo.id|default='0'}</td>

View File

@ -118,20 +118,14 @@ class BasicAdmin extends Controller
$query = $this->request->get(); $query = $this->request->get();
$page = $db->paginate($rows, $total, ['query' => $query]); $page = $db->paginate($rows, $total, ['query' => $query]);
if (($totalNum = $page->total()) > 0) { if (($totalNum = $page->total()) > 0) {
list($rowsHTML, $pageHTML, $maxNum) = [[], [], $page->lastPage()]; list($rowHTML, $curPage, $maxNum) = [[], $page->currentPage(), $page->lastPage()];
foreach ([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200] as $num) { foreach ([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200] as $num) {
list($query['rows'], $query['page']) = [$num, '1']; list($query['rows'], $query['page']) = [$num, '1'];
$url = url('@admin') . '#' . $this->request->baseUrl() . '?' . http_build_query($query); $url = url('@admin') . '#' . $this->request->baseUrl() . '?' . http_build_query($query);
$rowsHTML[] = "<option data-url='{$url}' " . ($rows === $num ? 'selected' : '') . " value='{$num}'>{$num}</option>"; $rowHTML[] = "<option data-url='{$url}' " . ($rows === $num ? 'selected' : '') . " value='{$num}'>{$num}</option>";
}
for ($i = 1; $i <= $maxNum; $i++) {
list($query['rows'], $query['page']) = [$rows, $i];
$url = url('@admin') . '#' . $this->request->baseUrl() . '?' . http_build_query($query);
$selected = $i === intval($page->currentPage()) ? 'selected' : '';
$pageHTML[] = "<option data-url='{$url}' {$selected} value='{$i}'>{$i}</option>";
} }
list($pattern, $replacement) = [['|href="(.*?)"|', '|pagination|'], ['data-open="$1"', 'pagination pull-right']]; list($pattern, $replacement) = [['|href="(.*?)"|', '|pagination|'], ['data-open="$1"', 'pagination pull-right']];
$html = "<span class='pagination-trigger nowrap'>共 {$totalNum} 条记录,每页显示 <select data-auto-none>" . join('', $rowsHTML) . "</select> 条,共 " . ceil($totalNum / $rows) . " 页当前显示第 <select>" . join('', $pageHTML) . "</select> 页。</span>"; $html = "<span class='pagination-trigger nowrap'>共 {$totalNum} 条记录,每页显示 <select data-auto-none>" . join('', $rowHTML) . "</select> 条,共 {$maxNum} 页当前显示第 {$curPage} 页。</span>";
list($result['total'], $result['list'], $result['page']) = [$totalNum, $page->all(), $html . preg_replace($pattern, $replacement, $page->render())]; list($result['total'], $result['list'], $result['page']) = [$totalNum, $page->all(), $html . preg_replace($pattern, $replacement, $page->render())];
} else { } else {
list($result['total'], $result['list'], $result['page']) = [$totalNum, $page->all(), $page->render()]; list($result['total'], $result['list'], $result['page']) = [$totalNum, $page->all(), $page->render()];

View File

@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2017 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://think.ctolog.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------
namespace controller;
use service\ToolsService;
/**
* 基础接口类
* Class BasicApi
* @package controller
*/
class BasicApi
{
/**
* 当前请求对象
* @var \think\Request
*/
protected $request;
/**
* 构造方法
* BasicApi constructor.
*/
public function __construct()
{
ToolsService::corsOptionsHandler();
$this->request = app('request');
}
/**
* 返回成功的操作
* @param string $msg 消息内容
* @param array $data 返回数据
*/
protected function success($msg, $data = [])
{
ToolsService::success($msg, $data);
}
/**
* 返回失败的请求
* @param string $msg 消息内容
* @param array $data 返回数据
*/
protected function error($msg, $data = [])
{
ToolsService::error($msg, $data);
}
}

View File

@ -32,7 +32,6 @@ class AlismsService
*/ */
private static $sdkVersion = [ private static $sdkVersion = [
"RegionId" => "cn-hangzhou", "RegionId" => "cn-hangzhou",
"Action" => "SendBatchSms",
"Version" => "2017-05-25", "Version" => "2017-05-25",
]; ];
@ -52,6 +51,7 @@ class AlismsService
$params["PageSize"] = $PageSize; $params["PageSize"] = $PageSize;
$params["CurrentPage"] = $CurrentPage; $params["CurrentPage"] = $CurrentPage;
$params["PhoneNumber"] = $PhoneNumber; $params["PhoneNumber"] = $PhoneNumber;
$params['Action'] = 'QuerySendDetails';
is_null($BizId) || $params["BizId"] = $BizId; is_null($BizId) || $params["BizId"] = $BizId;
return self::request("dysmsapi.aliyuncs.com", array_merge($params, self::$sdkVersion), true); return self::request("dysmsapi.aliyuncs.com", array_merge($params, self::$sdkVersion), true);
} }
@ -68,6 +68,7 @@ class AlismsService
public static function batchSend(array $PhoneNumbers, $TemplateCode, array $SignNames, array $TemplateParams, $SmsUpExtendCodes = []) public static function batchSend(array $PhoneNumbers, $TemplateCode, array $SignNames, array $TemplateParams, $SmsUpExtendCodes = [])
{ {
$params = []; $params = [];
$params["Action"] = 'SendBatchSms';
$params["TemplateCode"] = $TemplateCode; $params["TemplateCode"] = $TemplateCode;
!empty($SmsUpExtendCodes) && $params["SmsUpExtendCodeJson"] = json_encode($SmsUpExtendCodes); !empty($SmsUpExtendCodes) && $params["SmsUpExtendCodeJson"] = json_encode($SmsUpExtendCodes);
$params["TemplateParamJson"] = json_encode($TemplateParams, JSON_UNESCAPED_UNICODE); $params["TemplateParamJson"] = json_encode($TemplateParams, JSON_UNESCAPED_UNICODE);
@ -92,6 +93,7 @@ class AlismsService
public static function send($PhoneNumbers, $TemplateCode, $SignName, array $TemplateParam, $OutId = null, $SmsUpExtendCode = null) public static function send($PhoneNumbers, $TemplateCode, $SignName, array $TemplateParam, $OutId = null, $SmsUpExtendCode = null)
{ {
$params = []; $params = [];
$params['Action'] = 'SendSms';
$params["SignName"] = $SignName; $params["SignName"] = $SignName;
$params["TemplateCode"] = $TemplateCode; $params["TemplateCode"] = $TemplateCode;
$params["PhoneNumbers"] = $PhoneNumbers; $params["PhoneNumbers"] = $PhoneNumbers;

View File

@ -69,8 +69,8 @@ class FileService
/** /**
* 获取文件当前URL地址 * 获取文件当前URL地址
* @param string $filename * @param string $filename 文件HASH名称
* @param string|null $storage * @param string|null $storage 文件存储引擎
* @return bool|string * @return bool|string
* @throws OssException * @throws OssException
* @throws \think\Exception * @throws \think\Exception
@ -89,11 +89,11 @@ class FileService
case 'oss': case 'oss':
return self::getBaseUriOss() . $filename; return self::getBaseUriOss() . $filename;
} }
return false; throw new \think\Exception('未设置存储方式无法获取到文件对应URL地址');
} }
/** /**
* 根据配置获取到七牛云文件上传目标地址 * 根据配置获取到本地上传的目标地址
* @return string * @return string
*/ */
public static function getUploadLocalUrl() public static function getUploadLocalUrl()
@ -129,11 +129,12 @@ class FileService
} }
return $isClient ? 'http://upload-na0.qiniup.com' : 'http://up-na0.qiniup.com'; return $isClient ? 'http://upload-na0.qiniup.com' : 'http://up-na0.qiniup.com';
case '华南': case '华南':
default:
if ($isHttps) { if ($isHttps) {
return $isClient ? 'https://upload-z2.qiniup.com' : 'https://up-z2.qiniup.com'; return $isClient ? 'https://upload-z2.qiniup.com' : 'https://up-z2.qiniup.com';
} }
return $isClient ? 'http://upload-z2.qiniup.com' : 'http://up-z2.qiniup.com'; return $isClient ? 'http://upload-z2.qiniup.com' : 'http://up-z2.qiniup.com';
default:
throw new \think\Exception('未配置七牛云存储区域');
} }
} }
@ -155,7 +156,7 @@ class FileService
*/ */
public static function getBaseUriLocal() public static function getBaseUriLocal()
{ {
$appRoot = request()->root(true); $appRoot = request()->root(true); // 如果你想获取相对url地址这里改成 false
$uriRoot = preg_match('/\.php$/', $appRoot) ? dirname($appRoot) : $appRoot; $uriRoot = preg_match('/\.php$/', $appRoot) ? dirname($appRoot) : $appRoot;
return "{$uriRoot}/static/upload/"; return "{$uriRoot}/static/upload/";
} }
@ -173,8 +174,10 @@ class FileService
return 'https://' . sysconf('storage_qiniu_domain') . '/'; return 'https://' . sysconf('storage_qiniu_domain') . '/';
case 'http': case 'http':
return 'http://' . sysconf('storage_qiniu_domain') . '/'; return 'http://' . sysconf('storage_qiniu_domain') . '/';
default: case 'auto':
return '//' . sysconf('storage_qiniu_domain') . '/'; return '//' . sysconf('storage_qiniu_domain') . '/';
default:
throw new \think\Exception('未设置七牛云文件地址协议');
} }
} }
@ -191,8 +194,10 @@ class FileService
return 'https://' . sysconf('storage_oss_domain') . '/'; return 'https://' . sysconf('storage_oss_domain') . '/';
case 'http': case 'http':
return 'http://' . sysconf('storage_oss_domain') . '/'; return 'http://' . sysconf('storage_oss_domain') . '/';
default: case 'auto':
return '//' . sysconf('storage_oss_domain') . '/'; return '//' . sysconf('storage_oss_domain') . '/';
default:
throw new \think\Exception('未设置阿里云文件地址协议');
} }
} }
@ -256,9 +261,9 @@ class FileService
case 'oss': case 'oss':
$ossClient = new OssClient(sysconf('storage_oss_keyid'), sysconf('storage_oss_secret'), self::getBaseUriOss(), true); $ossClient = new OssClient(sysconf('storage_oss_keyid'), sysconf('storage_oss_secret'), self::getBaseUriOss(), true);
return $ossClient->getObject(sysconf('storage_oss_bucket'), $filename); return $ossClient->getObject(sysconf('storage_oss_bucket'), $filename);
default:
throw new \think\Exception('未配置读取文件的存储方法');
} }
Log::error("通过{$storage}读取文件{$filename}的不存在!");
return null;
} }
/** /**

View File

@ -14,6 +14,10 @@
namespace service; namespace service;
use think\exception\HttpResponseException;
use think\facade\Response;
use think\facade\Session;
/** /**
* 系统工具服务 * 系统工具服务
* Class ToolsService * Class ToolsService
@ -29,11 +33,19 @@ class ToolsService
*/ */
public static function corsOptionsHandler() public static function corsOptionsHandler()
{ {
Session::init(config('session.'));
$token = request()->header('token', '');
empty($token) && $token = request()->post('token', '');
empty($token) && $token = request()->get('token', '');
list($name, $value) = explode('=', decode($token) . '=');
if (!empty($value) && session_name() === $name) {
session_id($value);
}
if (request()->isOptions()) { if (request()->isOptions()) {
header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Credentials:true'); header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Methods:GET,POST,OPTIONS'); header('Access-Control-Allow-Methods:GET,POST,OPTIONS');
header('Access-Control-Allow-Headers:Accept,Referer,Host,Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Cookie'); header("Access-Control-Allow-Headers:Accept,Referer,Host,Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Cookie,token");
header('Content-Type:text/plain charset=UTF-8'); header('Content-Type:text/plain charset=UTF-8');
header('Access-Control-Max-Age:1728000'); header('Access-Control-Max-Age:1728000');
header('HTTP/1.0 204 No Content'); header('HTTP/1.0 204 No Content');
@ -56,6 +68,28 @@ class ToolsService
]; ];
} }
/**
* 返回成功的操作
* @param string $msg 消息内容
* @param array $data 返回数据
*/
public static function success($msg, $data = [])
{
$result = ['code' => 1, 'msg' => $msg, 'data' => $data, 'token' => encode(session_name() . '=' . session_id())];
throw new HttpResponseException(Response::create($result, 'json', 200, self::corsRequestHander()));
}
/**
* 返回失败的请求
* @param string $msg 消息内容
* @param array $data 返回数据
*/
public static function error($msg, $data = [])
{
$result = ['code' => 0, 'msg' => $msg, 'data' => $data, 'token' => encode(session_name() . '=' . session_id())];
throw new HttpResponseException(Response::create($result, 'json', 200, self::corsRequestHander()));
}
/** /**
* Emoji原形转换为String * Emoji原形转换为String
* @param string $content * @param string $content

View File

@ -24,38 +24,79 @@ use think\Exception;
* @author Anyon <zoujingli@qq.com> * @author Anyon <zoujingli@qq.com>
* @date 2017/03/22 15:32 * @date 2017/03/22 15:32
* *
* @method \WeChat\Card card() static 卡券管理 * ----- WeChat -----
* @method \WeChat\Custom custom() static 客服消息处理 * @method \WeChat\Card WeChatCard() static 微信卡券管理
* @method \WeChat\Limit limit() static 接口调用频次限制 * @method \WeChat\Custom WeChatCustom() static 微信客服消息
* @method \WeChat\Media media() static 微信素材管理 * @method \WeChat\Limit WeChatLimit() static 接口调用频次限制
* @method \WeChat\Menu menu() static 微信素材管理 * @method \WeChat\Media WeChatMedia() static 微信素材管理
* @method \WeChat\Oauth oauth() static 微信网页授权 * @method \WeChat\Menu WeChatMenu() static 微信菜单管理
* @method \WeChat\Pay pay() static 微信支付商户 * @method \WeChat\Oauth WeChatOauth() static 微信网页授权
* @method \WeChat\Product product() static 商店管理 * @method \WeChat\Pay WeChatPay() static 微信支付商户
* @method \WeChat\Qrcode qrcode() static 二维码管理 * @method \WeChat\Product WeChatProduct() static 微信商店管理
* @method \WeChat\Receive receive() static 公众号推送管理 * @method \WeChat\Qrcode WeChatQrcode() static 微信二维码管理
* @method \WeChat\Scan scan() static 扫一扫接入管理 * @method \WeChat\Receive WeChatReceive() static 微信推送管理
* @method \WeChat\Script script() static 微信前端支持 * @method \WeChat\Scan WeChatScan() static 微信扫一扫接入管理
* @method \WeChat\Shake shake() static 揺一揺周边 * @method \WeChat\Script WeChatScript() static 微信前端支持
* @method \WeChat\Tags tags() static 用户标签管理 * @method \WeChat\Shake WeChatShake() static 微信揺一揺周边
* @method \WeChat\Template template() static 模板消息 * @method \WeChat\Tags WeChatTags() static 微信用户标签管理
* @method \WeChat\User user() static 微信粉丝管理 * @method \WeChat\Template WeChatTemplate() static 微信模板消息
* @method \WeChat\Wifi wifi() static 门店WIFI管理 * @method \WeChat\User WeChatUser() static 微信粉丝管理
* @method void wechat() static 第三方微信工具 * @method \WeChat\Wifi WeChatWifi() static 微信门店WIFI管理
* @method void config() static 第三方配置工具 *
* ----- WeMini -----
* @method \WeMini\Account WeMiniAccount() static 小程序账号管理
* @method \WeMini\Basic WeMiniBasic() static 小程序基础信息设置
* @method \WeMini\Code WeMiniCode() static 小程序代码管理
* @method \WeMini\Domain WeMiniDomain() static 小程序域名管理
* @method \WeMini\Tester WeMinitester() static 小程序成员管理
* @method \WeMini\User WeMiniUser() static 小程序帐号管理
* --------------------
* @method \WeMini\Crypt WeMiniCrypt() static 小程序数据加密处理
* @method \WeMini\Plugs WeMiniPlugs() static 小程序插件管理
* @method \WeMini\Poi WeMiniPoi() static 小程序地址管理
* @method \WeMini\Qrcode WeMiniQrcode() static 小程序二维码管理
* @method \WeMini\Template WeMiniTemplate() static 小程序模板消息支持
* @method \WeMini\Total WeMiniTotal() static 小程序数据接口
*
* ----- WePay -----
* @method \WePay\Bill WePayBill() static 微信商户账单及评论
* @method \WePay\Order WePayOrder() static 微信商户订单
* @method \WePay\Refund WePayRefund() static 微信商户退款
* @method \WePay\Coupon WePayCoupon() static 微信商户代金券
* @method \WePay\Redpack WePayRedpack() static 微信红包支持
* @method \WePay\Transfers WePayTransfers() static 微信商户打款到零钱
* @method \WePay\TransfersBank WePayTransfersBank() static 微信商户打款到银行卡
*
* ----- WeOpen -----
* @method \WeOpen\Login login() static 第三方微信登录
* @method \WeOpen\Service service() static 第三方服务
*
* ----- ThinkService -----
* @method mixed wechat() static 第三方微信工具
* @method mixed config() static 第三方配置工具
*/ */
class WechatService class WechatService
{ {
/**
* 接口类型模式
* @var string
*/
private static $type = 'WeChat';
/** /**
* 获取微信实例ID * 获取微信实例ID
* @param string $name 实例对象名称 * @param string $name 实例对象名称
* @param string $type 接口实例类型
* @return SoapService|string * @return SoapService|string
* @throws \think\Exception * @throws Exception
* @throws \think\exception\PDOException * @throws \think\exception\PDOException
*/ */
public static function instance($name) public static function instance($name, $type = null)
{ {
if (!in_array($type, ['WeChat', 'WeMini'])) {
$type = self::$type;
}
switch (strtolower(sysconf('wechat_type'))) { switch (strtolower(sysconf('wechat_type'))) {
case 'api': case 'api':
$config = [ $config = [
@ -69,14 +110,14 @@ class WechatService
'ssl_key' => sysconf('wechat_cert_key'), 'ssl_key' => sysconf('wechat_cert_key'),
'cachepath' => env('cache_path') . 'wechat' . DIRECTORY_SEPARATOR, 'cachepath' => env('cache_path') . 'wechat' . DIRECTORY_SEPARATOR,
]; ];
$class = '\\WeChat\\' . ucfirst(strtolower($name)); $class = "\\{$type}\\" . ucfirst(strtolower($name));
if (class_exists($class)) { if (class_exists($class)) {
return new $class($config); return new $class($config);
} }
throw new Exception("Class '{$class}' not found"); throw new Exception("Class '{$class}' not found");
case 'thr': case 'thr':
list($appid, $appkey) = [sysconf('wechat_thr_appid'), sysconf('wechat_thr_appkey')]; list($appid, $appkey) = [sysconf('wechat_thr_appid'), sysconf('wechat_thr_appkey')];
$token = strtolower("{$name}-{$appid}-{$appkey}"); $token = strtolower("{$name}-{$appid}-{$appkey}-{$type}");
$location = config('wechat.service_url') . "/wechat/api.client/soap/{$token}.html"; $location = config('wechat.service_url') . "/wechat/api.client/soap/{$token}.html";
$params = ['uri' => strtolower($name), 'location' => $location, 'trace' => true]; $params = ['uri' => strtolower($name), 'location' => $location, 'trace' => true];
return new SoapService(null, $params); return new SoapService(null, $params);
@ -99,7 +140,7 @@ class WechatService
$signUrl = is_null($url) ? app('request')->url(true) : $url; $signUrl = is_null($url) ? app('request')->url(true) : $url;
switch (strtolower(sysconf('wechat_type'))) { switch (strtolower(sysconf('wechat_type'))) {
case 'api': case 'api':
return WechatService::script()->getJsSign($signUrl); return WechatService::WeChatScript()->getJsSign($signUrl);
case 'thr': case 'thr':
return WechatService::wechat()->jsSign($signUrl); return WechatService::wechat()->jsSign($signUrl);
default: default:
@ -113,6 +154,7 @@ class WechatService
* @param int $fullMode 授权公众号模式 * @param int $fullMode 授权公众号模式
* @param bool $isRedirect 是否进行跳转 * @param bool $isRedirect 是否进行跳转
* @return array * @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @throws \think\Exception * @throws \think\Exception
* @throws \think\exception\PDOException * @throws \think\exception\PDOException
*/ */
@ -126,7 +168,7 @@ class WechatService
} }
switch (strtolower(sysconf('wechat_type'))) { switch (strtolower(sysconf('wechat_type'))) {
case 'api': case 'api':
$wechat = self::oauth(); $wechat = self::WeChatOauth();
if (request()->get('state') !== $appid) { if (request()->get('state') !== $appid) {
$snsapi = empty($fullMode) ? 'snsapi_base' : 'snsapi_userinfo'; $snsapi = empty($fullMode) ? 'snsapi_base' : 'snsapi_userinfo';
$param = (strpos($url, '?') !== false ? '&' : '?') . 'rcode=' . encode($url); $param = (strpos($url, '?') !== false ? '&' : '?') . 'rcode=' . encode($url);
@ -184,14 +226,24 @@ class WechatService
/** /**
* 魔术静态方法实现对象 * 魔术静态方法实现对象
* @param string $name * @param string $name 方法类名
* @param array $arguments * @param array $arguments 调用参数
* @return SoapService * @return SoapService
* @throws \think\Exception * @throws \think\Exception
* @throws \think\exception\PDOException * @throws \think\exception\PDOException
*/ */
public static function __callStatic($name, $arguments) public static function __callStatic($name, $arguments)
{ {
if (substr($name, 0, 6) === 'WeMini') {
self::$type = 'WeMini';
$name = substr($name, 6);
} elseif (substr($name, 0, 6) === 'WeChat') {
self::$type = 'WeChat';
$name = substr($name, 6);
} elseif (substr($name, 0, 5) === 'WePay') {
self::$type = 'WePay';
$name = substr($name, 5);
}
return self::instance($name); return self::instance($name);
} }

View File

@ -616,7 +616,7 @@ $(function () {
/*! 注册 data-tips-image 事件行为 */ /*! 注册 data-tips-image 事件行为 */
$body.on('click', '[data-tips-image]', function () { $body.on('click', '[data-tips-image]', function () {
var img = new Image(), src = this.getAttribute('data-tips-image') || this.src; var img = new Image(), index = $.msg.loading();
var imgWidth = this.getAttribute('data-width') || '480px'; var imgWidth = this.getAttribute('data-width') || '480px';
img.onload = function () { img.onload = function () {
var $content = $(img).appendTo('body').css({background: '#fff', width: imgWidth, height: 'auto'}); var $content = $(img).appendTo('body').css({background: '#fff', width: imgWidth, height: 'auto'});
@ -625,10 +625,13 @@ $(function () {
skin: 'layui-layer-nobg', shadeClose: true, content: $content, skin: 'layui-layer-nobg', shadeClose: true, content: $content,
end: function () { end: function () {
$(img).remove(); $(img).remove();
},
success: function () {
$.msg.close(index);
} }
}); });
}; };
img.src = src; img.src = this.getAttribute('data-tips-image') || this.src;
}); });
/*! 注册 data-tips-text 事件行为 */ /*! 注册 data-tips-text 事件行为 */

View File

@ -31,6 +31,7 @@ require.config({
'angular': ['plugs/angular/angular.min'], 'angular': ['plugs/angular/angular.min'],
'ckeditor': ['plugs/ckeditor/ckeditor'], 'ckeditor': ['plugs/ckeditor/ckeditor'],
'websocket': ['plugs/socket/websocket'], 'websocket': ['plugs/socket/websocket'],
'clipboard': ['plugs/clipboard/clipboard.min'],
// jQuery // jQuery
'jquery.ztree': ['plugs/ztree/jquery.ztree.all.min'], 'jquery.ztree': ['plugs/ztree/jquery.ztree.all.min'],
'jquery.masonry': ['plugs/jquery/masonry.min'], 'jquery.masonry': ['plugs/jquery/masonry.min'],

View File

@ -1,10 +0,0 @@
/*
Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
(function(a){if("undefined"==typeof a)throw Error("jQuery should be loaded before CKEditor jQuery adapter.");if("undefined"==typeof CKEDITOR)throw Error("CKEditor should be loaded before CKEditor jQuery adapter.");CKEDITOR.config.jqueryOverrideVal="undefined"==typeof CKEDITOR.config.jqueryOverrideVal?!0:CKEDITOR.config.jqueryOverrideVal;a.extend(a.fn,{ckeditorGet:function(){var a=this.eq(0).data("ckeditorInstance");if(!a)throw"CKEditor is not initialized yet, use ckeditor() with a callback.";return a},
ckeditor:function(g,d){if(!CKEDITOR.env.isCompatible)throw Error("The environment is incompatible.");if(!a.isFunction(g)){var m=d;d=g;g=m}var k=[];d=d||{};this.each(function(){var b=a(this),c=b.data("ckeditorInstance"),f=b.data("_ckeditorInstanceLock"),h=this,l=new a.Deferred;k.push(l.promise());if(c&&!f)g&&g.apply(c,[this]),l.resolve();else if(f)c.once("instanceReady",function(){setTimeout(function(){c.element?(c.element.$==h&&g&&g.apply(c,[h]),l.resolve()):setTimeout(arguments.callee,100)},0)},
null,null,9999);else{if(d.autoUpdateElement||"undefined"==typeof d.autoUpdateElement&&CKEDITOR.config.autoUpdateElement)d.autoUpdateElementJquery=!0;d.autoUpdateElement=!1;b.data("_ckeditorInstanceLock",!0);c=a(this).is("textarea")?CKEDITOR.replace(h,d):CKEDITOR.inline(h,d);b.data("ckeditorInstance",c);c.on("instanceReady",function(d){var e=d.editor;setTimeout(function(){if(e.element){d.removeListener();e.on("dataReady",function(){b.trigger("dataReady.ckeditor",[e])});e.on("setData",function(a){b.trigger("setData.ckeditor",
[e,a.data])});e.on("getData",function(a){b.trigger("getData.ckeditor",[e,a.data])},999);e.on("destroy",function(){b.trigger("destroy.ckeditor",[e])});e.on("save",function(){a(h.form).submit();return!1},null,null,20);if(e.config.autoUpdateElementJquery&&b.is("textarea")&&a(h.form).length){var c=function(){b.ckeditor(function(){e.updateElement()})};a(h.form).submit(c);a(h.form).bind("form-pre-serialize",c);b.bind("destroy.ckeditor",function(){a(h.form).unbind("submit",c);a(h.form).unbind("form-pre-serialize",
c)})}e.on("destroy",function(){b.removeData("ckeditorInstance")});b.removeData("_ckeditorInstanceLock");b.trigger("instanceReady.ckeditor",[e]);g&&g.apply(e,[h]);l.resolve()}else setTimeout(arguments.callee,100)},0)},null,null,9999)}});var f=new a.Deferred;this.promise=f.promise();a.when.apply(this,k).then(function(){f.resolve()});this.editor=this.eq(0).data("ckeditorInstance");return this}});CKEDITOR.config.jqueryOverrideVal&&(a.fn.val=CKEDITOR.tools.override(a.fn.val,function(g){return function(d){if(arguments.length){var m=
this,k=[],f=this.each(function(){var b=a(this),c=b.data("ckeditorInstance");if(b.is("textarea")&&c){var f=new a.Deferred;c.setData(d,function(){f.resolve()});k.push(f.promise());return!0}return g.call(b,d)});if(k.length){var b=new a.Deferred;a.when.apply(this,k).done(function(){b.resolveWith(m)});return b.promise()}return f}var f=a(this).eq(0),c=f.data("ckeditorInstance");return f.is("textarea")&&c?c.getData():g.call(f)}}))})(window.jQuery);

File diff suppressed because one or more lines are too long

View File

@ -15,7 +15,7 @@
config.format_tags = 'p;h1;h2;h3;pre'; config.format_tags = 'p;h1;h2;h3;pre';
config.removeButtons = 'Underline,Subscript,Superscript'; config.removeButtons = 'Underline,Subscript,Superscript';
config.removeDialogTabs = 'image:advanced;link:advanced'; config.removeDialogTabs = 'image:advanced;link:advanced';
config.font_names = '宋体/SimSun;新宋体/NSimSun;仿宋_GB2312/FangSong_GB2312;楷体_GB2312/KaiTi_GB2312;黑体/SimHei;微软雅黑/Microsoft YaHei;' + config.font_names; config.font_names = '宋体/SimSun;新宋体/NSimSun;仿宋/FangSong;楷体/KaiTi;黑体/SimHei;微软雅黑/Microsoft YaHei;' + config.font_names;
}; };
// 自定义图片上传插件 // 自定义图片上传插件

View File

@ -1,63 +0,0 @@
Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
af.js Found: 62 Missing: 4
ar.js Found: 51 Missing: 15
bg.js Found: 58 Missing: 8
bn.js Found: 40 Missing: 26
bs.js Found: 29 Missing: 37
ca.js Found: 61 Missing: 5
cs.js Found: 66 Missing: 0
cy.js Found: 66 Missing: 0
da.js Found: 66 Missing: 0
de.js Found: 66 Missing: 0
el.js Found: 59 Missing: 7
en-au.js Found: 38 Missing: 28
en-ca.js Found: 37 Missing: 29
en-gb.js Found: 61 Missing: 5
eo.js Found: 66 Missing: 0
es.js Found: 66 Missing: 0
et.js Found: 66 Missing: 0
eu.js Found: 48 Missing: 18
fa.js Found: 66 Missing: 0
fi.js Found: 66 Missing: 0
fo.js Found: 66 Missing: 0
fr-ca.js Found: 42 Missing: 24
fr.js Found: 66 Missing: 0
gl.js Found: 40 Missing: 26
gu.js Found: 66 Missing: 0
he.js Found: 66 Missing: 0
hi.js Found: 43 Missing: 23
hr.js Found: 66 Missing: 0
hu.js Found: 63 Missing: 3
is.js Found: 41 Missing: 25
it.js Found: 66 Missing: 0
ja.js Found: 62 Missing: 4
ka.js Found: 62 Missing: 4
km.js Found: 40 Missing: 26
ko.js Found: 40 Missing: 26
lt.js Found: 66 Missing: 0
lv.js Found: 40 Missing: 26
mk.js Found: 0 Missing: 66
mn.js Found: 40 Missing: 26
ms.js Found: 39 Missing: 27
nb.js Found: 66 Missing: 0
nl.js Found: 65 Missing: 1
no.js Found: 66 Missing: 0
pl.js Found: 66 Missing: 0
pt-br.js Found: 66 Missing: 0
pt.js Found: 52 Missing: 14
ro.js Found: 61 Missing: 5
ru.js Found: 66 Missing: 0
sk.js Found: 49 Missing: 17
sl.js Found: 48 Missing: 18
sr-latn.js Found: 40 Missing: 26
sr.js Found: 40 Missing: 26
sv.js Found: 62 Missing: 4
th.js Found: 40 Missing: 26
tr.js Found: 66 Missing: 0
ug.js Found: 66 Missing: 0
uk.js Found: 66 Missing: 0
vi.js Found: 66 Missing: 0
zh-cn.js Found: 66 Missing: 0
zh.js Found: 58 Missing: 8

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More