mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2025-08-07 06:19:44 +08:00
commit
0c585ad420
@ -16,6 +16,7 @@ namespace app\admin\controller;
|
||||
|
||||
use controller\BasicAdmin;
|
||||
use service\LogService;
|
||||
use service\WechatService;
|
||||
|
||||
/**
|
||||
* 后台参数配置控制器
|
||||
|
@ -59,9 +59,10 @@ class Login extends BasicAdmin
|
||||
strlen($username) < 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('登录账号不存在,请重新输入!');
|
||||
($user['password'] !== md5($password)) && $this->error('登录密码与账号不匹配,请重新输入!');
|
||||
empty($user['is_deleted']) || $this->error('账号已经被删除,请联系管理!');
|
||||
empty($user['status']) && $this->error('账号已经被禁用,请联系管理!');
|
||||
// 更新登录信息
|
||||
$data = ['login_at' => Db::raw('now()'), 'login_num' => Db::raw('login_num+1')];
|
||||
|
@ -19,7 +19,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -35,7 +35,7 @@
|
||||
<tbody>
|
||||
<!--{foreach $list as $key=>$vo}-->
|
||||
<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'>
|
||||
</td>
|
||||
<td class='list-table-sort-td'>
|
||||
|
@ -67,7 +67,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='text-left nowrap'>操作账号</th>
|
||||
@ -81,7 +81,7 @@
|
||||
<tbody>
|
||||
<!--{foreach $list as $key=>$vo}-->
|
||||
<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'>
|
||||
</td>
|
||||
<td class='text-left nowrap'>{$vo.username}</td>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<table id="test" class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -34,7 +34,7 @@
|
||||
<tbody>
|
||||
<!--{foreach $list as $key=>$vo}-->
|
||||
<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'>
|
||||
</td>
|
||||
<td class='list-table-sort-td'>
|
||||
|
@ -45,21 +45,21 @@
|
||||
</td>
|
||||
<td class='text-left nowrap'>
|
||||
{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"> 全部加入登录控制
|
||||
</label>
|
||||
|
||||
<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"> 全部加入权限控制
|
||||
</label>
|
||||
|
||||
<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"> 全部加入菜单节点选择器
|
||||
</label>
|
||||
{/if}
|
||||
{if auth("$classuri/save") and $vo.spt eq 2}
|
||||
<span class="color-desc"> ├─ </span>
|
||||
<label class="notselect margin-right-15">
|
||||
<label class="notselect margin-right-15 think-checkbox">
|
||||
<!--{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)">
|
||||
<!--{else}-->
|
||||
@ -68,7 +68,7 @@
|
||||
加入登录控制
|
||||
</label>
|
||||
<span class="color-desc"> ├─ </span>
|
||||
<label class="notselect margin-right-15">
|
||||
<label class="notselect margin-right-15 think-checkbox">
|
||||
<!--{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'>
|
||||
<!--{else}-->
|
||||
@ -77,7 +77,7 @@
|
||||
加入权限控制
|
||||
</label>
|
||||
<span class="color-desc"> ├─ </span>
|
||||
<label class="notselect">
|
||||
<label class="notselect think-checkbox">
|
||||
<!--{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'>
|
||||
<!--{else}-->
|
||||
|
@ -61,7 +61,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='text-left nowrap'>用户名</th>
|
||||
@ -76,7 +76,7 @@
|
||||
<tbody>
|
||||
<!--{foreach $list as $key=>$vo}-->
|
||||
<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'>
|
||||
</td>
|
||||
<td class='text-left nowrap'>
|
||||
|
@ -58,7 +58,7 @@
|
||||
<table class="layui-table" lay-skin="line" lay-size="sm">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -74,7 +74,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'/>
|
||||
</td>
|
||||
<td class='list-table-sort-td'>
|
||||
|
@ -90,7 +90,7 @@
|
||||
<table class="layui-table notevent" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -114,7 +114,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'>
|
||||
</td>
|
||||
<td class='list-table-sort-td text-top'>
|
||||
|
@ -51,7 +51,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -66,7 +66,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'/>
|
||||
</td>
|
||||
<td class='list-table-sort-td'>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -34,7 +34,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'>
|
||||
</td>
|
||||
<td class='list-table-sort-td'>
|
||||
|
@ -51,7 +51,7 @@
|
||||
<table class="layui-table" lay-skin="line" lay-size="sm">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -67,7 +67,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'/>
|
||||
</td>
|
||||
<td class='list-table-sort-td text-top'>
|
||||
|
@ -182,7 +182,7 @@
|
||||
<table class="layui-table" lay-size="sm">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class="text-left">会员信息</th>
|
||||
@ -206,7 +206,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'/>
|
||||
</td>
|
||||
<td class="text-left text-top nowrap">
|
||||
|
@ -92,7 +92,7 @@ class Fans extends BasicAdmin
|
||||
{
|
||||
try {
|
||||
$openids = $this->_getActionOpenids();
|
||||
WechatService::user()->batchBlackList($openids);
|
||||
WechatService::WeChatUser()->batchBlackList($openids);
|
||||
Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '1');
|
||||
} catch (\Exception $e) {
|
||||
$this->error("设置黑名单失败,请稍候再试!");
|
||||
@ -113,7 +113,7 @@ class Fans extends BasicAdmin
|
||||
$fans = Db::name('WechatFans')->where(['id' => $fans_id])->find();
|
||||
empty($fans) && $this->error('需要操作的数据不存在!');
|
||||
try {
|
||||
$wechat = WechatService::tags();
|
||||
$wechat = WechatService::WeChatTags();
|
||||
foreach (explode(',', $fans['tagid_list']) as $tagid) {
|
||||
is_numeric($tagid) && $wechat->batchUntagging([$fans['openid']], $tagid);
|
||||
}
|
||||
@ -136,7 +136,7 @@ class Fans extends BasicAdmin
|
||||
empty($tagid) && $this->error('没有可能操作的标签ID');
|
||||
try {
|
||||
$openids = $this->_getActionOpenids();
|
||||
WechatService::tags()->batchTagging($openids, $tagid);
|
||||
WechatService::WeChatTags()->batchTagging($openids, $tagid);
|
||||
} catch (\Exception $e) {
|
||||
$this->error("设置粉丝标签失败, 请稍候再试! " . $e->getMessage());
|
||||
}
|
||||
@ -152,7 +152,7 @@ class Fans extends BasicAdmin
|
||||
empty($tagid) && $this->error('没有可能操作的标签ID');
|
||||
try {
|
||||
$openids = $this->_getActionOpenids();
|
||||
WechatService::tags()->batchUntagging($openids, $tagid);
|
||||
WechatService::WeChatTags()->batchUntagging($openids, $tagid);
|
||||
} catch (\Exception $e) {
|
||||
$this->error("删除粉丝标签失败, 请稍候再试! ");
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class FansBlock extends BasicAdmin
|
||||
{
|
||||
$openids = $this->_getActionOpenids();
|
||||
try {
|
||||
WechatService::user()->batchUnblackList($openids);
|
||||
WechatService::WeChatUser()->batchUnblackList($openids);
|
||||
Db::name($this->table)->whereIn('openid', $openids)->setField('is_black', '0');
|
||||
} catch (\Exception $e) {
|
||||
$this->error("设备黑名单失败,请稍候再试!" . $e->getMessage());
|
||||
|
@ -38,14 +38,23 @@ class Keys extends BasicAdmin
|
||||
/**
|
||||
* 显示关键字列表
|
||||
* @return array|string
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \WeChat\Exceptions\LocalCacheException
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
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']);
|
||||
return $this->_list($db->order('sort asc,id desc'));
|
||||
}
|
||||
@ -56,15 +65,13 @@ class Keys extends BasicAdmin
|
||||
*/
|
||||
protected function _index_data_filter(&$data)
|
||||
{
|
||||
$types = [
|
||||
'keys' => '关键字', 'image' => '图片', 'news' => '图文',
|
||||
'music' => '音乐', 'text' => '文字', 'video' => '视频', 'voice' => '语音',
|
||||
];
|
||||
try {
|
||||
$wechat = WechatService::qrcode();
|
||||
$types = [
|
||||
'keys' => '关键字', 'image' => '图片', 'news' => '图文',
|
||||
'music' => '音乐', 'text' => '文字', 'video' => '视频', 'voice' => '语音',
|
||||
];
|
||||
foreach ($data as &$vo) {
|
||||
$result = $wechat->create($vo['keys']);
|
||||
$vo['qrc'] = $wechat->url($result['ticket']);
|
||||
$vo['qrc'] = url('@wechat/keys/index') . "?action=qrc&keys={$vo['keys']}";
|
||||
$vo['type'] = isset($types[$vo['type']]) ? $types[$vo['type']] : $vo['type'];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
@ -91,7 +91,7 @@ class Menu extends BasicAdmin
|
||||
if (empty($post['data'])) {
|
||||
try {
|
||||
Db::name($this->table)->where('1=1')->delete();
|
||||
WechatService::menu()->delete();
|
||||
WechatService::WeChatMenu()->delete();
|
||||
} catch (\Exception $e) {
|
||||
$this->error('删除取消微信菜单失败,请稍候再试!' . $e->getMessage());
|
||||
}
|
||||
@ -121,7 +121,7 @@ class Menu extends BasicAdmin
|
||||
public function cancel()
|
||||
{
|
||||
try {
|
||||
WechatService::menu()->delete();
|
||||
WechatService::WeChatMenu()->delete();
|
||||
} catch (\Exception $e) {
|
||||
$this->error('菜单取消失败');
|
||||
}
|
||||
@ -174,7 +174,7 @@ class Menu extends BasicAdmin
|
||||
}
|
||||
unset($menu['type']);
|
||||
}
|
||||
WechatService::menu()->create(['button' => $menus]);
|
||||
WechatService::WeChatMenu()->create(['button' => $menus]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -145,7 +145,10 @@ class News extends BasicAdmin
|
||||
$id = $this->request->get('id', '');
|
||||
if ($this->request->isGet()) {
|
||||
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();
|
||||
$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['mpnews'] = ['media_id' => $newsinfo['media_id']];
|
||||
}
|
||||
if (WechatService::custom()->massSendAll($data)) {
|
||||
if (WechatService::WeChatCustom()->massSendAll($data)) {
|
||||
LogService::write('微信管理', "图文[{$news_id}]推送成功");
|
||||
$this->success('微信图文推送成功!', '');
|
||||
}
|
||||
@ -280,7 +283,7 @@ class News extends BasicAdmin
|
||||
return "<img{$matches[1]}src=\"{$src}\"{$matches[3]}/>";
|
||||
}, $article['content']);
|
||||
}
|
||||
$wechat = WechatService::media();
|
||||
$wechat = WechatService::WeChatMedia();
|
||||
// 如果已经上传过,先删除之前的历史记录
|
||||
!empty($news['media_id']) && $wechat->delMaterial($news['media_id']);
|
||||
// 上传图文到微信服务器
|
||||
|
@ -74,7 +74,7 @@ class Tags extends BasicAdmin
|
||||
if (Db::name($this->table)->where('name', $name)->count() > 0) {
|
||||
$this->error('粉丝标签标签名已经存在, 请使用其它标签名!');
|
||||
}
|
||||
$wechat = WechatService::tags();
|
||||
$wechat = WechatService::WeChatTags();
|
||||
if (false === ($result = $wechat->createTags($name)) && isset($result['tag'])) {
|
||||
$this->error("添加粉丝标签失败. ");
|
||||
}
|
||||
@ -110,7 +110,7 @@ class Tags extends BasicAdmin
|
||||
$this->error('标签已经存在, 使用其它名称再试!');
|
||||
}
|
||||
try {
|
||||
WechatService::tags()->updateTags($id, $name);
|
||||
WechatService::WeChatTags()->updateTags($id, $name);
|
||||
DataService::save($this->table, ['id' => $id, 'name' => $name], 'id');
|
||||
} catch (\Exception $e) {
|
||||
$this->error('编辑标签失败, 请稍后再试!' . $e->getMessage());
|
||||
@ -128,7 +128,7 @@ class Tags extends BasicAdmin
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
$wechat = WechatService::tags();
|
||||
$wechat = WechatService::WeChatTags();
|
||||
foreach (explode(',', $this->request->post('id', '')) as $id) {
|
||||
if ($wechat->deleteTags($id)) {
|
||||
Db::name('WechatFansTags')->where(['id' => $id])->delete();
|
||||
|
@ -74,7 +74,7 @@ class Push
|
||||
*/
|
||||
public function notify()
|
||||
{
|
||||
$wechat = WechatService::receive();
|
||||
$wechat = WechatService::WeChatReceive();
|
||||
$this->openid = $wechat->getOpenid();
|
||||
$this->receive = $wechat->getReceive();
|
||||
$this->appid = WechatService::getAppid();
|
||||
@ -251,7 +251,7 @@ class Push
|
||||
$msgData = ['touser' => $this->openid, 'msgtype' => $type, "{$type}" => $data];
|
||||
switch (strtolower(sysconf('wechat_type'))) {
|
||||
case 'api': // 参数对接,直接回复XML来实现消息回复
|
||||
$wechat = WechatService::receive();
|
||||
$wechat = WechatService::WeChatReceive();
|
||||
switch (strtolower($type)) {
|
||||
case 'text':
|
||||
return $wechat->text($data['content'])->reply([], true);
|
||||
@ -272,7 +272,7 @@ class Push
|
||||
return 'success';
|
||||
}
|
||||
case 'thr': // 第三方平台,使用客服消息来实现
|
||||
return WechatService::custom()->send($msgData);
|
||||
return WechatService::WeChatCustom()->send($msgData);
|
||||
default:
|
||||
return 'success';
|
||||
}
|
||||
@ -313,7 +313,7 @@ class Push
|
||||
protected function updateFansinfo($subscribe = true)
|
||||
{
|
||||
if ($subscribe) {
|
||||
$userInfo = WechatService::user()->getUserInfo($this->openid);
|
||||
$userInfo = WechatService::WeChatUser()->getUserInfo($this->openid);
|
||||
$userInfo['subscribe'] = intval($subscribe);
|
||||
FansService::set($userInfo);
|
||||
} else {
|
||||
|
@ -28,6 +28,7 @@ class Tools extends BasicAdmin
|
||||
/**
|
||||
* 网页授权测试
|
||||
* @return string
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
|
@ -77,7 +77,7 @@ class FansService
|
||||
*/
|
||||
public static function sync($next_openid = '')
|
||||
{
|
||||
$wechat = WechatService::user();
|
||||
$wechat = WechatService::WeChatUser();
|
||||
$result = $wechat->getUserList($next_openid);
|
||||
if (empty($result['data']['openid'])) {
|
||||
return false;
|
||||
@ -106,7 +106,7 @@ class FansService
|
||||
*/
|
||||
public static function syncBlack($next_openid = '')
|
||||
{
|
||||
$wechat = WechatService::user();
|
||||
$wechat = WechatService::WeChatUser();
|
||||
$result = $wechat->getBlackList($next_openid);
|
||||
foreach (array_chunk($result['data']['openid'], 100) as $openids) {
|
||||
$info = $wechat->getBatchUserInfo($openids);
|
||||
|
@ -67,7 +67,7 @@ class MediaService
|
||||
if (($media_url = Db::name('WechatNewsImage')->where($map)->value('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') {
|
||||
WechatService::wechat()->rmFile($local_url);
|
||||
}
|
||||
@ -93,7 +93,7 @@ class MediaService
|
||||
if (($media_id = Db::name('WechatNewsMedia')->where($map)->value('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') {
|
||||
WechatService::wechat()->rmFile($local_url);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class TagsService
|
||||
*/
|
||||
public static function syncTagsByOpenid($openid)
|
||||
{
|
||||
$tagsid = WechatService::tags()->getUserTagId($openid);
|
||||
$tagsid = WechatService::WeChatTags()->getUserTagId($openid);
|
||||
if (!is_array($tagsid)) {
|
||||
return false;
|
||||
}
|
||||
@ -55,7 +55,7 @@ class TagsService
|
||||
public static function sync()
|
||||
{
|
||||
$appid = WechatService::getAppid();
|
||||
$result = WechatService::tags()->getTags();
|
||||
$result = WechatService::WeChatTags()->getTags();
|
||||
Db::name('WechatFansTags')->where(['appid' => $appid])->delete();
|
||||
foreach (array_chunk($result['tags'], 100) as $list) {
|
||||
foreach ($list as &$vo) {
|
||||
|
@ -22,7 +22,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class='text-left'>用户昵称</th>
|
||||
@ -36,7 +36,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'/>
|
||||
</td>
|
||||
<td class='text-left nowrap'>
|
||||
|
@ -22,7 +22,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'>
|
||||
</th>
|
||||
<th class='text-left'>用户昵称</th>
|
||||
@ -36,7 +36,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'>
|
||||
</td>
|
||||
<td class='text-left nowrap'>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class='list-table-sort-td'>
|
||||
@ -38,7 +38,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'/>
|
||||
</td>
|
||||
<td class='list-table-sort-td'>
|
||||
|
@ -1,258 +1,256 @@
|
||||
{extend name='admin@public/content'}
|
||||
|
||||
{block name='content'}
|
||||
|
||||
<!--左侧图文列表 开始-->
|
||||
<div class="panel panel-default news-left">
|
||||
<div class="panel-heading">图文列表</div>
|
||||
<div class="panel-body news-box">
|
||||
{if empty($vo['articles']) eq false}
|
||||
<!--{foreach $vo.articles as $key=>$value}-->
|
||||
<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 class="upload-multiple-close layui-icon hide">ဆ</a>
|
||||
<span class="news-title">{$value.title}</span>
|
||||
<div id="NewsEditor">
|
||||
<!--左侧图文列表 开始-->
|
||||
<div class="panel panel-default news-left">
|
||||
<div class="panel-heading">图文列表</div>
|
||||
<div class="panel-body news-box">
|
||||
<div ng-if="list.length > 0" ng-repeat="x in list">
|
||||
<div class="news-item transition" ng-click="setItem($index,$event)" style="{{x.style}}" ng-class="x.active?'active':''">
|
||||
<a ng-click="delItem($index, $event)" class="upload-multiple-close layui-icon hide">ဆ</a>
|
||||
<a ng-click="dnItem($index, $event)" class="upload-multiple-close layui-icon hide"></a>
|
||||
<a ng-click="upItem($index, $event)" class="upload-multiple-close layui-icon hide"></a>
|
||||
<span class="news-title" ng-bind="x.title"></span>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
<div ng-if="list.length<1" class="news-item transition active news-image">
|
||||
<a ng-click="delItem($index, $event)" class="upload-multiple-close layui-icon hide">ဆ</a>
|
||||
<a ng-click="dnItem($index, $event)" class="upload-multiple-close layui-icon hide"></a>
|
||||
<a ng-click="upItem($index, $event)" class="upload-multiple-close layui-icon hide"></a>
|
||||
<span class="news-title"></span>
|
||||
<hr/>
|
||||
</div>
|
||||
<a class='article-add transition' ng-click="addItem()" data-text-tip="添加图文">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
<hr/>
|
||||
<!--{/foreach}-->
|
||||
{else}
|
||||
<div class="news-item transition active news-image" style="background-image:url('__STATIC__/plugs/uploader/theme/image.png')">
|
||||
<a class="upload-multiple-close layui-icon hide">ဆ</a>
|
||||
<span class="news-title"></span>
|
||||
</div>
|
||||
<hr/>
|
||||
{/if}
|
||||
<a href="javascript:void(0)" class='article-add transition' data-text-tip="添加图文">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!--左侧图文列表 结束-->
|
||||
<!--左侧图文列表 结束-->
|
||||
<!--右侧编辑区 开始-->
|
||||
<div class="panel panel-default news-right">
|
||||
<div class="panel-heading">图文内容编辑</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" role="form" name="news" onsubmit="return false;">
|
||||
|
||||
<!--右侧编辑区 开始-->
|
||||
<div class="panel panel-default news-right">
|
||||
<div class="panel-heading">图文内容编辑</div>
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" role="form" name="news" onsubmit="return false;">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">文章标题</span>
|
||||
<input maxlength="64" required title="文章的标题不能为空哦" placeholder="请在这里输入标题" name='title' class="layui-input">
|
||||
<input type="hidden" name="id">
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">文章标题</span>
|
||||
<input maxlength="64" ng-model="item.title" required title="文章的标题不能为空哦" placeholder="请在这里输入标题" name='title' class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">文章作者</span>
|
||||
<input maxlength="8" required title="文章的作者不能为空哦" placeholder="请输入作者" name='author' class="layui-input">
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">文章作者</span>
|
||||
<input maxlength="8" ng-model="item.author" required title="文章的作者不能为空哦" placeholder="请输入作者" name='author' class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div class="form-control border-radius-none" style="height:auto">
|
||||
<label class="color-desc font-s12 margin-bottom-5">图文封面大图片设置</label>
|
||||
<div class="row nowrap">
|
||||
<div class="col-xs-3" style="width:160px">
|
||||
<div class="upload-image-box transition">
|
||||
<input value="__STATIC__/plugs/uploader/theme/image.png" type="hidden" name="local_url">
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div class="form-control border-radius-none" style="height:auto">
|
||||
<label class="color-desc font-s12 margin-bottom-5">图文封面大图片设置</label>
|
||||
<div class="row nowrap">
|
||||
<div class="col-xs-3" style="width:160px">
|
||||
<div class="upload-image-box transition">
|
||||
<input ng-model="item.local_url" value="__STATIC__/plugs/uploader/theme/image.png" type="hidden" name="local_url">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6 padding-top-10">
|
||||
<button type="button" data-title="上传图片" data-file="one" data-type="jpg,png,jpeg" data-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>
|
||||
<label class="think-checkbox notselect margin-top-15">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6 padding-top-10">
|
||||
<button type="button" data-title="上传图片" data-file="one" data-type="jpg,png,jpeg" data-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>
|
||||
<label class="think-checkbox notselect margin-top-15">
|
||||
<input data-auto-none type="checkbox" value="1" name="show_cover_pic"> 在正文中显示此图片
|
||||
</label>
|
||||
</div>
|
||||
<p class="help-block margin-top-5 color-desc">封面大图片建议尺寸:900像素 * 500像素</p>
|
||||
</div>
|
||||
<p class="help-block margin-top-5 color-desc">封面大图片建议尺寸:900像素 * 500像素</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12"><textarea name='content'></textarea></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-12"><textarea ng-model="item.content" name='content'></textarea></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<label class="color-desc">摘要选填,如果不填写会默认抓取正文前54个字</label>
|
||||
<textarea name="digest" class="layui-textarea" style="height:80px;resize:none"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<label class="color-desc">原文链接<b>选填</b>,填写之后在图文左下方会出现此链接</label>
|
||||
<input maxlength="200" name='content_source_url' class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<div class="row">
|
||||
<div class="col-md-offset-4 col-md-9">
|
||||
<button data-submit type="button" class="layui-btn">保存图文</button>
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<label class="color-desc">摘要选填,如果不填写会默认抓取正文前54个字</label>
|
||||
<textarea ng-model="item.digest" name="digest" class="layui-textarea" style="height:80px;line-height:18px;resize:none"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<label class="color-desc">原文链接<b>选填</b>,填写之后在图文左下方会出现此链接</label>
|
||||
<input ng-model="item.content_source_url" maxlength="200" name='content_source_url' class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<div class="row">
|
||||
<div class="col-md-offset-4 col-md-9">
|
||||
<button ng-click="submit()" type="button" class="layui-btn">保存图文</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!--右侧编辑区 结束-->
|
||||
</div>
|
||||
<!--右侧编辑区 结束-->
|
||||
|
||||
{/block}
|
||||
|
||||
|
||||
{block name='script'}
|
||||
<textarea class="hide" id="newsdata">{$vo.articles|default=[]|json_encode=256|raw}</textarea>
|
||||
<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) {
|
||||
$('.news-item').eq(i).data('item', editDdata[i]);
|
||||
}
|
||||
var app = angular.module("NewsEditor", []).run(callback);
|
||||
angular.bootstrap(document.getElementById(app.name), [app.name]);
|
||||
|
||||
/*! 实例富文本编辑器 */
|
||||
var editor, $item, $body = $('body'), $form = $('form[name="news"]');
|
||||
function callback($rootScope) {
|
||||
$rootScope.list = [];
|
||||
$rootScope.item = {};
|
||||
|
||||
/*! 默认编辑第一篇图文 */
|
||||
editor = window.createEditor('[name="content"]');
|
||||
$form.vali();
|
||||
|
||||
/*! 上传图片 */
|
||||
$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 + ')');
|
||||
});
|
||||
|
||||
/*! 数据提交 */
|
||||
$form.find('button[data-submit]').on('click', function () {
|
||||
var data = [];
|
||||
$form.submit();
|
||||
if (!syncEditor($('.news-item.active'))) {
|
||||
editor.setData('文章内容不能留空,请输入内容!');
|
||||
return false;
|
||||
}
|
||||
$('.news-item').map(function () {
|
||||
var item = $(this).data('item');
|
||||
item.content = item.content || '文章内容不能留空,请输入内容!';
|
||||
data.push(item);
|
||||
$.form.load('{:request()->url()}', {output: 'json'}, 'get', function (ret) {
|
||||
return $rootScope.$apply(function () {
|
||||
apply((ret.data || {articles: []}).articles || []);
|
||||
}), false;
|
||||
});
|
||||
$.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 apply(data) {
|
||||
if (data.length < 1) {
|
||||
data.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')"
|
||||
});
|
||||
}
|
||||
for (var i in data) {
|
||||
data[i].active = false;
|
||||
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;
|
||||
$rootScope.item = $rootScope.list[0];
|
||||
$rootScope.setItemValue('active', true);
|
||||
setTimeout(function () {
|
||||
editor.setData($rootScope.item.content);
|
||||
}, 100);
|
||||
$form.vali();
|
||||
}
|
||||
});
|
||||
|
||||
/*! 同步编辑器 */
|
||||
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');
|
||||
$rootScope.upItem = function (index, $event) {
|
||||
$event.stopPropagation();
|
||||
var tmp = [], cur = $rootScope.list[index];
|
||||
if (index < 1) {
|
||||
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) {
|
||||
if (i !== 'content' && i !== 'show_cover_pic') {
|
||||
$form.find('[name="' + i + '"]').val(data[i]).trigger('change');
|
||||
for (var i in $rootScope.list) {
|
||||
(parseInt(i) === parseInt(index) - 1) && tmp.push(cur);
|
||||
(parseInt(i) !== parseInt(index)) && tmp.push($rootScope.list[i]);
|
||||
}
|
||||
}
|
||||
if (parseInt(data.show_cover_pic) === 1) {
|
||||
$form.find('[name="show_cover_pic"]').get(0).checked = true;
|
||||
}
|
||||
apply(tmp);
|
||||
};
|
||||
|
||||
editor.setData(htmldecode(data.content));
|
||||
$rootScope.dnItem = function (index, $event) {
|
||||
$event.stopPropagation();
|
||||
var tmp = [], cur = $rootScope.list[index];
|
||||
if (index > $rootScope.list.length - 2) {
|
||||
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);
|
||||
};
|
||||
|
||||
function htmldecode(string) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = string;
|
||||
return div.innerText || div.textContent;
|
||||
}
|
||||
$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 () {
|
||||
$form.vali();
|
||||
if ($form.find('.validate-error').size() > 0) {
|
||||
return $.msg.tips('表单验证不成功,请输入需要的内容!');
|
||||
}
|
||||
$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('click', '.news-box .article-add').on('click', '.news-box .article-add', function () {
|
||||
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">ဆ</a><span class="news-title"></span></div><hr />');
|
||||
$html.insertBefore(this).trigger('click');
|
||||
$('.news-item').size() >= 7 && $(this).hide();
|
||||
});
|
||||
|
||||
/*! 列表选择 */
|
||||
$body.off('click', '.news-item').on('click', '.news-item', function () {
|
||||
if (syncEditor($('.news-item.active'))) {
|
||||
$(this).addClass('active').siblings().removeClass('active');
|
||||
showEditor($item);
|
||||
}
|
||||
});
|
||||
|
||||
/*! 隐藏删除按钮 */
|
||||
$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>
|
||||
{/block}
|
||||
@ -279,6 +277,7 @@
|
||||
.news-left .news-item {
|
||||
width: 280px;
|
||||
height: 150px;
|
||||
cursor: pointer;
|
||||
max-width: 270px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
@ -287,6 +286,10 @@
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.news-left .news-item:hover .upload-multiple-close {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.news-left .news-item.active {
|
||||
border: 1px solid #44b549 !important;
|
||||
}
|
||||
@ -345,7 +348,7 @@
|
||||
height: 30px;
|
||||
float: right;
|
||||
margin-top: -1px;
|
||||
line-height: 30px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
margin-right: -1px;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
|
@ -39,7 +39,7 @@
|
||||
<table class="layui-table" lay-skin="line">
|
||||
<thead>
|
||||
<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'/>
|
||||
</th>
|
||||
<th class='text-center'>ID</th>
|
||||
@ -52,7 +52,7 @@
|
||||
<tbody>
|
||||
{foreach $list as $key=>$vo}
|
||||
<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'>
|
||||
</td>
|
||||
<td class='text-center'>{$vo.id|default='0'}</td>
|
||||
|
@ -118,20 +118,14 @@ class BasicAdmin extends Controller
|
||||
$query = $this->request->get();
|
||||
$page = $db->paginate($rows, $total, ['query' => $query]);
|
||||
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) {
|
||||
list($query['rows'], $query['page']) = [$num, '1'];
|
||||
$url = url('@admin') . '#' . $this->request->baseUrl() . '?' . http_build_query($query);
|
||||
$rowsHTML[] = "<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>";
|
||||
$rowHTML[] = "<option data-url='{$url}' " . ($rows === $num ? 'selected' : '') . " value='{$num}'>{$num}</option>";
|
||||
}
|
||||
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())];
|
||||
} else {
|
||||
list($result['total'], $result['list'], $result['page']) = [$totalNum, $page->all(), $page->render()];
|
||||
|
63
extend/controller/BasicApi.php
Normal file
63
extend/controller/BasicApi.php
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -32,7 +32,6 @@ class AlismsService
|
||||
*/
|
||||
private static $sdkVersion = [
|
||||
"RegionId" => "cn-hangzhou",
|
||||
"Action" => "SendBatchSms",
|
||||
"Version" => "2017-05-25",
|
||||
];
|
||||
|
||||
@ -52,6 +51,7 @@ class AlismsService
|
||||
$params["PageSize"] = $PageSize;
|
||||
$params["CurrentPage"] = $CurrentPage;
|
||||
$params["PhoneNumber"] = $PhoneNumber;
|
||||
$params['Action'] = 'QuerySendDetails';
|
||||
is_null($BizId) || $params["BizId"] = $BizId;
|
||||
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 = [])
|
||||
{
|
||||
$params = [];
|
||||
$params["Action"] = 'SendBatchSms';
|
||||
$params["TemplateCode"] = $TemplateCode;
|
||||
!empty($SmsUpExtendCodes) && $params["SmsUpExtendCodeJson"] = json_encode($SmsUpExtendCodes);
|
||||
$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)
|
||||
{
|
||||
$params = [];
|
||||
$params['Action'] = 'SendSms';
|
||||
$params["SignName"] = $SignName;
|
||||
$params["TemplateCode"] = $TemplateCode;
|
||||
$params["PhoneNumbers"] = $PhoneNumbers;
|
||||
|
@ -69,8 +69,8 @@ class FileService
|
||||
|
||||
/**
|
||||
* 获取文件当前URL地址
|
||||
* @param string $filename
|
||||
* @param string|null $storage
|
||||
* @param string $filename 文件HASH名称
|
||||
* @param string|null $storage 文件存储引擎
|
||||
* @return bool|string
|
||||
* @throws OssException
|
||||
* @throws \think\Exception
|
||||
@ -89,11 +89,11 @@ class FileService
|
||||
case 'oss':
|
||||
return self::getBaseUriOss() . $filename;
|
||||
}
|
||||
return false;
|
||||
throw new \think\Exception('未设置存储方式,无法获取到文件对应URL地址');
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置获取到七牛云文件上传目标地址
|
||||
* 根据配置获取到本地上传的目标地址
|
||||
* @return string
|
||||
*/
|
||||
public static function getUploadLocalUrl()
|
||||
@ -129,11 +129,12 @@ class FileService
|
||||
}
|
||||
return $isClient ? 'http://upload-na0.qiniup.com' : 'http://up-na0.qiniup.com';
|
||||
case '华南':
|
||||
default:
|
||||
if ($isHttps) {
|
||||
return $isClient ? 'https://upload-z2.qiniup.com' : 'https://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()
|
||||
{
|
||||
$appRoot = request()->root(true);
|
||||
$appRoot = request()->root(true); // 如果你想获取相对url地址,这里改成 false
|
||||
$uriRoot = preg_match('/\.php$/', $appRoot) ? dirname($appRoot) : $appRoot;
|
||||
return "{$uriRoot}/static/upload/";
|
||||
}
|
||||
@ -173,8 +174,10 @@ class FileService
|
||||
return 'https://' . sysconf('storage_qiniu_domain') . '/';
|
||||
case 'http':
|
||||
return 'http://' . sysconf('storage_qiniu_domain') . '/';
|
||||
default:
|
||||
case 'auto':
|
||||
return '//' . sysconf('storage_qiniu_domain') . '/';
|
||||
default:
|
||||
throw new \think\Exception('未设置七牛云文件地址协议');
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,8 +194,10 @@ class FileService
|
||||
return 'https://' . sysconf('storage_oss_domain') . '/';
|
||||
case 'http':
|
||||
return 'http://' . sysconf('storage_oss_domain') . '/';
|
||||
default:
|
||||
case 'auto':
|
||||
return '//' . sysconf('storage_oss_domain') . '/';
|
||||
default:
|
||||
throw new \think\Exception('未设置阿里云文件地址协议');
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,9 +261,9 @@ class FileService
|
||||
case 'oss':
|
||||
$ossClient = new OssClient(sysconf('storage_oss_keyid'), sysconf('storage_oss_secret'), self::getBaseUriOss(), true);
|
||||
return $ossClient->getObject(sysconf('storage_oss_bucket'), $filename);
|
||||
default:
|
||||
throw new \think\Exception('未配置读取文件的存储方法');
|
||||
}
|
||||
Log::error("通过{$storage}读取文件{$filename}的不存在!");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
namespace service;
|
||||
|
||||
use think\exception\HttpResponseException;
|
||||
use think\facade\Response;
|
||||
use think\facade\Session;
|
||||
|
||||
/**
|
||||
* 系统工具服务
|
||||
* Class ToolsService
|
||||
@ -29,11 +33,19 @@ class ToolsService
|
||||
*/
|
||||
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()) {
|
||||
header('Access-Control-Allow-Origin:*');
|
||||
header('Access-Control-Allow-Credentials:true');
|
||||
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('Access-Control-Max-Age:1728000');
|
||||
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
|
||||
* @param string $content
|
||||
|
@ -24,38 +24,79 @@ use think\Exception;
|
||||
* @author Anyon <zoujingli@qq.com>
|
||||
* @date 2017/03/22 15:32
|
||||
*
|
||||
* @method \WeChat\Card card() static 卡券管理
|
||||
* @method \WeChat\Custom custom() static 客服消息处理
|
||||
* @method \WeChat\Limit limit() static 接口调用频次限制
|
||||
* @method \WeChat\Media media() static 微信素材管理
|
||||
* @method \WeChat\Menu menu() static 微信素材管理
|
||||
* @method \WeChat\Oauth oauth() static 微信网页授权
|
||||
* @method \WeChat\Pay pay() static 微信支付商户
|
||||
* @method \WeChat\Product product() static 商店管理
|
||||
* @method \WeChat\Qrcode qrcode() static 二维码管理
|
||||
* @method \WeChat\Receive receive() static 公众号推送管理
|
||||
* @method \WeChat\Scan scan() static 扫一扫接入管理
|
||||
* @method \WeChat\Script script() static 微信前端支持
|
||||
* @method \WeChat\Shake shake() static 揺一揺周边
|
||||
* @method \WeChat\Tags tags() static 用户标签管理
|
||||
* @method \WeChat\Template template() static 模板消息
|
||||
* @method \WeChat\User user() static 微信粉丝管理
|
||||
* @method \WeChat\Wifi wifi() static 门店WIFI管理
|
||||
* @method void wechat() static 第三方微信工具
|
||||
* @method void config() static 第三方配置工具
|
||||
* ----- WeChat -----
|
||||
* @method \WeChat\Card WeChatCard() static 微信卡券管理
|
||||
* @method \WeChat\Custom WeChatCustom() static 微信客服消息
|
||||
* @method \WeChat\Limit WeChatLimit() static 接口调用频次限制
|
||||
* @method \WeChat\Media WeChatMedia() static 微信素材管理
|
||||
* @method \WeChat\Menu WeChatMenu() static 微信菜单管理
|
||||
* @method \WeChat\Oauth WeChatOauth() static 微信网页授权
|
||||
* @method \WeChat\Pay WeChatPay() static 微信支付商户
|
||||
* @method \WeChat\Product WeChatProduct() static 微信商店管理
|
||||
* @method \WeChat\Qrcode WeChatQrcode() static 微信二维码管理
|
||||
* @method \WeChat\Receive WeChatReceive() static 微信推送管理
|
||||
* @method \WeChat\Scan WeChatScan() static 微信扫一扫接入管理
|
||||
* @method \WeChat\Script WeChatScript() static 微信前端支持
|
||||
* @method \WeChat\Shake WeChatShake() static 微信揺一揺周边
|
||||
* @method \WeChat\Tags WeChatTags() static 微信用户标签管理
|
||||
* @method \WeChat\Template WeChatTemplate() static 微信模板消息
|
||||
* @method \WeChat\User WeChatUser() static 微信粉丝管理
|
||||
* @method \WeChat\Wifi WeChatWifi() static 微信门店WIFI管理
|
||||
*
|
||||
* ----- 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
|
||||
{
|
||||
|
||||
/**
|
||||
* 接口类型模式
|
||||
* @var string
|
||||
*/
|
||||
private static $type = 'WeChat';
|
||||
|
||||
/**
|
||||
* 获取微信实例ID
|
||||
* @param string $name 实例对象名称
|
||||
* @param string $type 接口实例类型
|
||||
* @return SoapService|string
|
||||
* @throws \think\Exception
|
||||
* @throws Exception
|
||||
* @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'))) {
|
||||
case 'api':
|
||||
$config = [
|
||||
@ -69,14 +110,14 @@ class WechatService
|
||||
'ssl_key' => sysconf('wechat_cert_key'),
|
||||
'cachepath' => env('cache_path') . 'wechat' . DIRECTORY_SEPARATOR,
|
||||
];
|
||||
$class = '\\WeChat\\' . ucfirst(strtolower($name));
|
||||
$class = "\\{$type}\\" . ucfirst(strtolower($name));
|
||||
if (class_exists($class)) {
|
||||
return new $class($config);
|
||||
}
|
||||
throw new Exception("Class '{$class}' not found");
|
||||
case 'thr':
|
||||
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";
|
||||
$params = ['uri' => strtolower($name), 'location' => $location, 'trace' => true];
|
||||
return new SoapService(null, $params);
|
||||
@ -99,7 +140,7 @@ class WechatService
|
||||
$signUrl = is_null($url) ? app('request')->url(true) : $url;
|
||||
switch (strtolower(sysconf('wechat_type'))) {
|
||||
case 'api':
|
||||
return WechatService::script()->getJsSign($signUrl);
|
||||
return WechatService::WeChatScript()->getJsSign($signUrl);
|
||||
case 'thr':
|
||||
return WechatService::wechat()->jsSign($signUrl);
|
||||
default:
|
||||
@ -113,6 +154,7 @@ class WechatService
|
||||
* @param int $fullMode 授权公众号模式
|
||||
* @param bool $isRedirect 是否进行跳转
|
||||
* @return array
|
||||
* @throws \WeChat\Exceptions\InvalidResponseException
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
@ -126,7 +168,7 @@ class WechatService
|
||||
}
|
||||
switch (strtolower(sysconf('wechat_type'))) {
|
||||
case 'api':
|
||||
$wechat = self::oauth();
|
||||
$wechat = self::WeChatOauth();
|
||||
if (request()->get('state') !== $appid) {
|
||||
$snsapi = empty($fullMode) ? 'snsapi_base' : 'snsapi_userinfo';
|
||||
$param = (strpos($url, '?') !== false ? '&' : '?') . 'rcode=' . encode($url);
|
||||
@ -184,14 +226,24 @@ class WechatService
|
||||
|
||||
/**
|
||||
* 魔术静态方法实现对象
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @param string $name 方法类名
|
||||
* @param array $arguments 调用参数
|
||||
* @return SoapService
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -616,7 +616,7 @@ $(function () {
|
||||
|
||||
/*! 注册 data-tips-image 事件行为 */
|
||||
$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';
|
||||
img.onload = function () {
|
||||
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,
|
||||
end: function () {
|
||||
$(img).remove();
|
||||
},
|
||||
success: function () {
|
||||
$.msg.close(index);
|
||||
}
|
||||
});
|
||||
};
|
||||
img.src = src;
|
||||
img.src = this.getAttribute('data-tips-image') || this.src;
|
||||
});
|
||||
|
||||
/*! 注册 data-tips-text 事件行为 */
|
||||
|
@ -31,6 +31,7 @@ require.config({
|
||||
'angular': ['plugs/angular/angular.min'],
|
||||
'ckeditor': ['plugs/ckeditor/ckeditor'],
|
||||
'websocket': ['plugs/socket/websocket'],
|
||||
'clipboard': ['plugs/clipboard/clipboard.min'],
|
||||
// jQuery
|
||||
'jquery.ztree': ['plugs/ztree/jquery.ztree.all.min'],
|
||||
'jquery.masonry': ['plugs/jquery/masonry.min'],
|
||||
|
10
static/plugs/ckeditor/adapters/jquery.js
vendored
10
static/plugs/ckeditor/adapters/jquery.js
vendored
@ -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);
|
2472
static/plugs/ckeditor/ckeditor.js
vendored
2472
static/plugs/ckeditor/ckeditor.js
vendored
File diff suppressed because one or more lines are too long
@ -15,7 +15,7 @@
|
||||
config.format_tags = 'p;h1;h2;h3;pre';
|
||||
config.removeButtons = 'Underline,Subscript,Superscript';
|
||||
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;
|
||||
};
|
||||
|
||||
// 自定义图片上传插件
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user