chore(addon): 新增wechat插件
84
src/addon/wechat/api/controller/Auth.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\api\controller;
|
||||
|
||||
use addon\wechat\model\Material as MaterialModel;
|
||||
use addon\wechat\model\Wechat as WechatModel;
|
||||
use app\Controller;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
|
||||
class Auth extends Controller
|
||||
{
|
||||
|
||||
public $wechat;
|
||||
public $config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$site_id = request()->siteid();
|
||||
$this->wechat = new WechatModel($site_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ************************************************************************微信公众号消息相关方法 开始******************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* 关联公众号微信unserialize
|
||||
*/
|
||||
public function relateWeixin()
|
||||
{
|
||||
Log::write('微信公众号消息');
|
||||
$this->wechat->app = $this->wechat->app();
|
||||
$this->wechat->relateWeixin();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************************************************微信公众号消息相关方法 结束******************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* 关联公众号微信unserialize
|
||||
*/
|
||||
public function wechatArticle()
|
||||
{
|
||||
$id = input('id', '');
|
||||
$index = input('i', 0);
|
||||
$material_model = new MaterialModel();
|
||||
$info = $material_model->getMaterialInfo([ 'id' => $id ]);
|
||||
if (!empty($info[ 'data' ][ 'value' ]) && json_decode($info[ 'data' ][ 'value' ], true)) {
|
||||
$info[ 'data' ][ 'value' ] = json_decode($info[ 'data' ][ 'value' ], true);
|
||||
}
|
||||
$this->assign('info', $info[ 'data' ]);
|
||||
$this->assign('index', $index);
|
||||
$replace = [
|
||||
'WECHAT_CSS' => __ROOT__ . '/addon/wechat/admin/view/public/css',
|
||||
'WECHAT_JS' => __ROOT__ . '/addon/wechat/admin/view/public/js',
|
||||
'WECHAT_IMG' => __ROOT__ . '/addon/wechat/admin/view/public/img',
|
||||
];
|
||||
return $this->fetch('wechat/article', [], $replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取授权信息
|
||||
*/
|
||||
public function getAuthInfo()
|
||||
{
|
||||
$cache_key = input("cache_key");
|
||||
$site_id = request()->siteid();
|
||||
$wechat_model = new WechatModel($site_id);
|
||||
$res = $wechat_model->authCodeToOpenid(input());
|
||||
if ($res["code"] >= 0) {
|
||||
Cache::set($cache_key, $res["data"]);
|
||||
$this->assign('result', '授权成功!');
|
||||
return $this->fetch('auth/result');
|
||||
} else {
|
||||
$this->assign('result', $res['message']);
|
||||
return $this->fetch('auth/result');
|
||||
}
|
||||
}
|
||||
}
|
||||
178
src/addon/wechat/api/controller/Wechat.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\api\controller;
|
||||
|
||||
use addon\wechat\model\Config as ConfigModel;
|
||||
use addon\wechat\model\Fans;
|
||||
use addon\wechat\model\Wechat as WechatModel;
|
||||
use app\api\controller\BaseApi;
|
||||
use app\model\member\Member as MemberModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
class Wechat extends BaseApi
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取openid
|
||||
*/
|
||||
public function authCodeToOpenid()
|
||||
{
|
||||
$weapp_model = new WechatModel($this->site_id);
|
||||
$res = $weapp_model->getAuthByCode($this->params);
|
||||
return $this->response($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网页授权code
|
||||
*/
|
||||
public function authcode()
|
||||
{
|
||||
$redirect_url = $this->params[ 'redirect_url' ] ?? '';
|
||||
$scopes = $this->params[ 'scopes' ] ?? 'snsapi_base';
|
||||
$weapp_model = new WechatModel($this->site_id);
|
||||
$res = $weapp_model->getAuthCode($redirect_url, $scopes);
|
||||
return $this->response($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取jssdk配置
|
||||
*/
|
||||
public function jssdkConfig()
|
||||
{
|
||||
$url = $this->params[ 'url' ] ?? '';
|
||||
$weapp_model = new WechatModel($this->site_id);
|
||||
$res = $weapp_model->getJssdkConfig($url);
|
||||
return $this->response($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享设置
|
||||
*/
|
||||
public function share()
|
||||
{
|
||||
$this->checkToken();
|
||||
|
||||
//页面路径
|
||||
$url = $this->params[ 'url' ] ?? '';
|
||||
$url = htmlspecialchars_decode($url);
|
||||
|
||||
//sdk配置
|
||||
$weapp_model = new WechatModel($this->site_id);
|
||||
$jssdk_config = $weapp_model->getJssdkConfig($url);
|
||||
if ($jssdk_config[ 'code' ] < 0) return $this->response($jssdk_config);
|
||||
|
||||
//分享配置
|
||||
$share_config = [];
|
||||
$share_data = event('WchatShareData', [
|
||||
'url' => $url,
|
||||
'site_id' => $this->site_id,
|
||||
'member_id' => $this->member_id,
|
||||
], true);
|
||||
if (!empty($share_data)) {
|
||||
$share_config[ 'permission' ] = $share_data[ 'permission' ];
|
||||
$share_config[ 'data' ] = $share_data[ 'data' ];
|
||||
} else {
|
||||
$share_config[ 'permission' ] = [
|
||||
'hideOptionMenu' => true,
|
||||
'hideMenuItems' => [],
|
||||
];
|
||||
$share_config[ 'data' ] = null;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'jssdk_config' => $jssdk_config[ 'data' ],
|
||||
'share_config' => $share_config,
|
||||
];
|
||||
|
||||
return $this->response($this->success($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定店铺openid
|
||||
* @return false|string
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
*/
|
||||
public function shopBindOpenid()
|
||||
{
|
||||
$key = $this->params[ "key" ];
|
||||
$weapp_model = new WechatModel($this->site_id);
|
||||
$res = $weapp_model->authCodeToOpenid($this->params);
|
||||
if ($res[ "code" ] >= 0) {
|
||||
Cache::set($key, $res[ "data" ][ "openid" ]);
|
||||
return $this->response($res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录二维码
|
||||
* @return false|string
|
||||
*/
|
||||
public function loginCode()
|
||||
{
|
||||
$key = str_replace('==', '', base64_encode(uniqid('')));
|
||||
$expire_time = 600;
|
||||
|
||||
$wechat_model = new WechatModel($this->site_id);
|
||||
$res = $wechat_model->getTempQrcode('key_' . $key, $expire_time);
|
||||
if ($res[ 'code' ] != 0) return $this->response($res);
|
||||
|
||||
Cache::set('wechat_' . $key, [ 'expire_time' => ( time() + $expire_time ) ], 3600);
|
||||
$data = $this->success([
|
||||
'key' => $key,
|
||||
'expire_time' => $expire_time,
|
||||
'qrcode' => $res[ 'data' ]
|
||||
]);
|
||||
return $this->response($data);
|
||||
}
|
||||
|
||||
/*
|
||||
* 验证公众号是否配置
|
||||
*/
|
||||
public function verificationWx()
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
$config_info = $config_model->getWechatConfig($this->site_id);
|
||||
if (!empty($config_info[ 'data' ])) {
|
||||
$config = $config_info[ 'data' ][ "value" ];
|
||||
if ($config[ 'appid' ] || $config[ 'appsecret' ]) {
|
||||
return $this->response($this->success());
|
||||
}
|
||||
}
|
||||
return $this->response($this->error());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号关注二维码
|
||||
* @return false|string
|
||||
*/
|
||||
public function followQrcode()
|
||||
{
|
||||
if (!in_array($this->params[ 'app_type' ], [ 'weapp', 'wechat' ])) return $this->response($this->error('', '该接口仅支持微信浏览器中调用'));
|
||||
|
||||
$token = $this->checkToken();
|
||||
if ($token[ 'code' ] < 0) return $this->response($token);
|
||||
|
||||
$member_model = new MemberModel();
|
||||
$member_info = $member_model->getMemberInfo([ [ 'member_id', '=', $this->member_id, [ 'site_id', '=', $this->site_id ] ] ], 'member_id,wx_openid')[ 'data' ];
|
||||
if (!empty($member_info) && !empty($member_info[ 'wx_openid' ])) {
|
||||
|
||||
$wechat_fans = ( new Fans() )->getFansInfo([ [ 'site_id', '=', $this->site_id ], [ 'openid', '=', $member_info[ 'wx_openid' ] ], [ 'is_subscribe', '=', 1 ] ], 'fans_id')[ 'data' ];
|
||||
if (!empty($wechat_fans)) return $this->response($this->success());
|
||||
|
||||
if (!empty($wechat_fans[ 'fans_id' ])) {
|
||||
$wechat_model = new WechatModel();
|
||||
$res = $wechat_model->getFollowQrcode($wechat_fans[ 'fans_id' ]);
|
||||
if ($res[ 'code' ] == 0) return $this->response($res);
|
||||
}
|
||||
}
|
||||
|
||||
// $fans_info = ( new MemberFans() )->getFansInfo([ [ 'fans_id', '=', $this->fans_id ] ], 'openid')[ 'data' ];
|
||||
// $wechat_fans = ( new Fans() )->getFansInfo([ [ 'site_id', '=', $this->site_id ], [ 'is_subscribe', '=', 1 ], [ 'openid', '=', $fans_info[ 'openid' ] ] ], 'fans_id');
|
||||
// if (!empty($wechat_fans[ 'data' ])) return $this->response($this->success());
|
||||
|
||||
$config_model = new ConfigModel();
|
||||
$config_result = $config_model->getWechatConfig($this->site_id)[ 'data' ][ 'value' ];
|
||||
|
||||
return $this->response($this->success([ 'qrcode' => $config_result[ 'qrcode' ] ]));
|
||||
}
|
||||
}
|
||||
20
src/addon/wechat/api/view/auth/result.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="referrer" content="never">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0,viewport-fit=cover"/>
|
||||
<meta http-equiv="X-UA-COMPATIBLE" content="IE=edge,chrome=1">
|
||||
<title>微信授权结果</title>
|
||||
<meta name="keywords" content="">
|
||||
<meta name="description" content="">
|
||||
</head>
|
||||
<body>
|
||||
<div class='preview-box'>
|
||||
<p style="margin-top: 20vh;text-align: center;color: orangered;font-size: 20px;">{$result}</p>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
|
||||
</script>
|
||||
</html>
|
||||
52
src/addon/wechat/api/view/wechat/article.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="referrer" content="never">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0,viewport-fit=cover"/>
|
||||
<meta http-equiv="X-UA-COMPATIBLE" content="IE=edge,chrome=1">
|
||||
<title>{$info.value[$index]['title']}</title>
|
||||
<meta name="keywords" content="">
|
||||
<meta name="description" content="">
|
||||
<link rel="stylesheet" type="text/css" href="__STATIC__/ext/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="SITEHOME_CSS/home.css">
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_preview_graphic_message.css">
|
||||
<script src="__STATIC__/js/jquery-2.2.js"></script>
|
||||
<style>
|
||||
#content p{
|
||||
width: 100%;
|
||||
word-wrap:break-word;
|
||||
word-break:normal;
|
||||
}
|
||||
#content p>img{
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='preview-box'>
|
||||
<div class='graphic-message'>
|
||||
<h1 class='title'>{$info.value[$index]['title']}</h1>
|
||||
{if condition="$info.update_time eq 0"}
|
||||
<span class='time'>{$info['create_time']|time_to_date='Y-m-d'}</span>
|
||||
{else/}
|
||||
<span class='time'>{$info['update_time']|time_to_date='Y-m-d'}</span>
|
||||
{/if}
|
||||
<span class='author'>{$info.value[$index]['autor']}</span>
|
||||
<content>
|
||||
{if condition="$info.value[$index]['show_cover_pic'] == 1"}
|
||||
<div class="rich-media-thumb" id="media" style="width: 100%">
|
||||
<img style="max-width: 100%" onerror="this.parentNode.removeChild(this)" src="{$info.value[$index]['cover']['path']}">
|
||||
</div>
|
||||
{/if}
|
||||
<div id="content">
|
||||
{:html_entity_decode($info.value[$index]['content'])}
|
||||
</div>
|
||||
</content>
|
||||
{if condition="!empty($info.value[$index]['url'])"}
|
||||
<a class='original-text' href="{$info.value[$index]['url']}">阅读原文</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
30
src/addon/wechat/config/diy_view.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
// 自定义模板页面类型,格式:[ 'title' => '页面类型名称', 'name' => '页面标识', 'path' => '页面路径', 'value' => '页面数据,json格式' ]
|
||||
'template' => [],
|
||||
|
||||
// 后台自定义组件——装修
|
||||
'util' => [],
|
||||
|
||||
// 自定义页面路径
|
||||
'link' => [],
|
||||
|
||||
// 自定义图标库
|
||||
'icon_library' => [],
|
||||
|
||||
// uni-app 组件,格式:[ 'name' => '组件名称/文件夹名称', 'path' => '文件路径/目录路径' ],多个逗号隔开,自定义组件名称前缀必须是diy-,也可以引用第三方组件
|
||||
'component' => [],
|
||||
|
||||
// uni-app 页面,多个逗号隔开
|
||||
'pages' => [],
|
||||
|
||||
// 模板信息,格式:'title' => '模板名称', 'name' => '模板标识', 'cover' => '模板封面图', 'preview' => '模板预览图', 'desc' => '模板描述'
|
||||
'info' => [],
|
||||
|
||||
// 主题风格配色,格式可以自由定义扩展,【在uni-app中通过:this.themeStyle... 获取定义的颜色字段,例如:this.themeStyle.main_color】
|
||||
'theme' => [],
|
||||
|
||||
// 自定义页面数据,格式:[ 'title' => '页面名称', 'name' => "页面标识", 'value' => [页面数据,json格式] ]
|
||||
'data' => []
|
||||
];
|
||||
17
src/addon/wechat/config/event.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
|
||||
'AddSite' => [
|
||||
'addon\wechat\event\AddSiteReplay',// 添加默认关注回复
|
||||
],
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
||||
12
src/addon/wechat/config/info.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
return [
|
||||
'name' => 'wechat',
|
||||
'title' => '微信公众号',
|
||||
'description' => '微信公众号功能',
|
||||
'type' => 'system', //插件类型 system :系统插件(自动安装), promotion:扩展营销插件 tool:工具插件
|
||||
'status' => 1,
|
||||
'author' => '',
|
||||
'version' => '5.5.2',
|
||||
'version_no' => '552250604001',
|
||||
'content' => '',
|
||||
];
|
||||
209
src/addon/wechat/config/menu_shop.php
Normal file
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
return [
|
||||
[
|
||||
'name' => 'WECHAT_ROOT',
|
||||
'title' => '微信公众号',
|
||||
'url' => 'wechat://shop/wechat/setting',
|
||||
'parent' => 'CHANNEL_ROOT',
|
||||
'picture_select' => '',
|
||||
'picture' => 'addon/wechat/shop/view/public/img/menu_icon/wechat_icon_new.png',
|
||||
'picture_selected' => 'addon/wechat/shop/view/public/img/menu_icon/wechat_icon_select.png',
|
||||
'is_show' => 1,
|
||||
'sort' => 3,
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'WCHAT_CONFIG',
|
||||
'title' => '基础配置',
|
||||
'url' => 'wechat://shop/wechat/config',
|
||||
'is_show' => 0,
|
||||
'sort' => 2,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MENU',
|
||||
'title' => '菜单管理',
|
||||
'url' => 'wechat://shop/menu/menu',
|
||||
'is_show' => 0,
|
||||
'sort' => 3,
|
||||
'type' => 'button',
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'WECHAT_MENU_EDIT',
|
||||
'title' => '编辑微信菜单',
|
||||
'url' => 'wechat://shop/menu/edit',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL',
|
||||
'title' => '消息素材',
|
||||
'url' => 'wechat://shop/material/lists',
|
||||
'is_show' => 0,
|
||||
'sort' => 4,
|
||||
'type' => 'button',
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_ADD_TEXT',
|
||||
'title' => '添加文本素材',
|
||||
'url' => 'wechat://shop/material/addTextMaterial',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_ADD',
|
||||
'title' => '添加图文',
|
||||
'url' => 'wechat://shop/material/add',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_EDIT',
|
||||
'title' => '修改图文',
|
||||
'url' => 'wechat://shop/material/edit',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_DELETE',
|
||||
'title' => '删除图文',
|
||||
'url' => 'wechat://shop/material/delete',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_ADD_TEXT',
|
||||
'title' => '添加文本',
|
||||
'url' => 'wechat://shop/material/addtextmaterial',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_EDIT_TEXT',
|
||||
'title' => '修改文本',
|
||||
'url' => 'wechat://shop/material/edittextmaterial',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MATERIAL_DELETE_TEXT',
|
||||
'title' => '删除文本',
|
||||
'url' => 'wechat://shop/material/textmaterial',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_QRCODE',
|
||||
'title' => '推广二维码管理',
|
||||
'url' => 'wechat://shop/wechat/qrcode',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'WECHAT_QRCODE_ADD',
|
||||
'title' => '推广二维码添加',
|
||||
'url' => 'wechat://shop/wechat/addqrcode',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_QRCODE_EDIT',
|
||||
'title' => '推广二维码编辑',
|
||||
'url' => 'wechat://shop/wechat/editqrcode',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_QRCODE_DELETE',
|
||||
'title' => '推广二维码删除',
|
||||
'url' => 'wechat://shop/wechat/deleteqrcode',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_QRCODE_DEFAULT',
|
||||
'title' => '设置默认推广二维码',
|
||||
'url' => 'wechat://shop/wechat/qrcodeDefault',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_SHARE',
|
||||
'title' => '分享内容',
|
||||
'url' => 'wechat://shop/wechat/share',
|
||||
'is_show' => 0,
|
||||
'sort' => 5,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_REPLAY_INDEX',
|
||||
'title' => '回复设置',
|
||||
'url' => 'wechat://shop/replay/replay',
|
||||
'is_show' => 0,
|
||||
'sort' => 6,
|
||||
'type' => 'button',
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'WECHAT_REPLAY_KEYS',
|
||||
'title' => '关键词自动回复',
|
||||
'url' => 'wechat://shop/replay/replay',
|
||||
'is_show' => 1,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_REPLAY_DEFAULT',
|
||||
'title' => '默认自动回复',
|
||||
'url' => 'wechat://shop/replay/default',
|
||||
'is_show' => 1,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_REPLAY_FOLLOW',
|
||||
'title' => '关注后自动回复',
|
||||
'url' => 'wechat://shop/replay/follow',
|
||||
'is_show' => 1,
|
||||
'type' => 'button',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MESSAGE_CONFIG',
|
||||
'title' => '模板消息',
|
||||
'url' => 'wechat://shop/message/config',
|
||||
'is_show' => 0,
|
||||
'sort' => 8,
|
||||
'type' => 'button',
|
||||
'child_list' => [
|
||||
[
|
||||
'name' => 'WECHAT_MESSAGE_EDIT',
|
||||
'parent' => 'MESSAGE_LISTS',
|
||||
'title' => '编辑消息模板',
|
||||
'url' => 'wechat://shop/message/edit',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MESSAGE_CONFIG',
|
||||
'title' => '是否需跳转到小程序',
|
||||
'url' => 'wechat://shop/message/messageConfig',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
[
|
||||
'name' => 'WECHAT_MESSAGE_SET_WECHAT_STATUS',
|
||||
'title' => '设置微信模板消息状态',
|
||||
'url' => 'wechat://shop/message/setWechatStatus',
|
||||
'is_show' => 0,
|
||||
'type' => 'button',
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
];
|
||||
174
src/addon/wechat/config/wechat_error.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
40001 => '获取 access_token 时 AppSecret 错误,或者 access_token 无效。请认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口',
|
||||
40002 => '不合法的凭证类型',
|
||||
40003 => '不合法的 OpenID ,请确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID',
|
||||
40004 => '不合法的媒体文件类型',
|
||||
40005 => '不合法的文件类型',
|
||||
40006 => '不合法的文件大小',
|
||||
40007 => '不合法的媒体文件 id',
|
||||
40008 => '不合法的消息类型',
|
||||
40009 => '不合法的图片文件大小',
|
||||
40010 => '不合法的语音文件大小',
|
||||
40011 => '不合法的视频文件大小',
|
||||
40012 => '不合法的缩略图文件大小',
|
||||
40013 => '不合法的 AppID ,请检查 AppID 的正确性,避免异常字符,注意大小写',
|
||||
40014 => '不合法的 access_token ,请认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口',
|
||||
40015 => '不合法的菜单类型',
|
||||
40016 => '不合法的按钮个数',
|
||||
40017 => '不合法的按钮类型',
|
||||
40018 => '不合法的按钮名字长度',
|
||||
40019 => '不合法的按钮 KEY 长度',
|
||||
40020 => '不合法的按钮 URL 长度',
|
||||
40021 => '不合法的菜单版本号',
|
||||
40022 => '不合法的子菜单级数',
|
||||
40023 => '不合法的子菜单按钮个数',
|
||||
40024 => '不合法的子菜单按钮类型',
|
||||
40025 => '不合法的子菜单按钮名字长度',
|
||||
40026 => '不合法的子菜单按钮 KEY 长度',
|
||||
40027 => '不合法的子菜单按钮 URL 长度',
|
||||
40028 => '不合法的自定义菜单使用用户',
|
||||
40029 => '无效的 oauth_code',
|
||||
40030 => '不合法的 refresh_token',
|
||||
40031 => '不合法的 openid 列表',
|
||||
40032 => '不合法的 openid 列表长度',
|
||||
40033 => '不合法的请求字符,不能包含 \uxxxx 格式的字符',
|
||||
40035 => '不合法的参数',
|
||||
40038 => '不合法的请求格式',
|
||||
40039 => '不合法的 URL 长度',
|
||||
40048 => '无效的url',
|
||||
40050 => '不合法的分组 id',
|
||||
40051 => '分组名字不合法',
|
||||
40060 => '删除单篇图文时,指定的 article_idx 不合法',
|
||||
40117 => '分组名字不合法',
|
||||
40118 => 'media_id 大小不合法',
|
||||
40119 => 'button 类型错误',
|
||||
40120 => '子 button 类型错误',
|
||||
40121 => '不合法的 media_id 类型',
|
||||
40125 => '无效的appsecret',
|
||||
40132 => '微信号不合法',
|
||||
40137 => '不支持的图片格式',
|
||||
40155 => '请勿添加其他公众号的主页链接',
|
||||
40163 => 'oauth_code已使用',
|
||||
40164 => 'IP:' . request()->ip() . '未加入公众号ip白名单',
|
||||
40227 => '标题为空',
|
||||
41001 => '缺少 access_token 参数',
|
||||
41002 => '缺少 appid 参数',
|
||||
41003 => '缺少 refresh_token 参数',
|
||||
41004 => '缺少 secret 参数',
|
||||
41005 => '缺少多媒体文件数据',
|
||||
41006 => '缺少 media_id 参数',
|
||||
41007 => '缺少子菜单数据',
|
||||
41008 => '缺少 oauth code',
|
||||
41009 => '缺少 openid',
|
||||
42001 => 'access_token 超时,请检查 access_token 的有效期',
|
||||
42002 => 'refresh_token 超时',
|
||||
42003 => 'oauth_code 超时',
|
||||
42007 => '用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权',
|
||||
42010 => '相同 media_id 群发过快,请重试',
|
||||
43001 => '需要 GET 请求',
|
||||
43002 => '需要 POST 请求',
|
||||
43003 => '需要 HTTPS 请求',
|
||||
43004 => '需要接收者关注',
|
||||
43005 => '需要好友关系',
|
||||
43019 => '需要将接收者从黑名单中移除',
|
||||
44001 => '多媒体文件为空',
|
||||
44002 => 'POST 的数据包为空',
|
||||
44003 => '图文消息内容为空',
|
||||
44004 => '文本消息内容为空',
|
||||
45001 => '多媒体文件大小超过限制',
|
||||
45002 => '消息内容超过限制',
|
||||
45003 => '标题字段超过限制',
|
||||
45004 => '描述字段超过限制',
|
||||
45005 => '链接字段超过限制',
|
||||
45006 => '图片链接字段超过限制',
|
||||
45007 => '语音播放时间超过限制',
|
||||
45008 => '图文消息超过限制',
|
||||
45009 => '接口调用超过限制',
|
||||
45010 => '创建菜单个数超过限制',
|
||||
45011 => 'API 调用太频繁,请稍候再试',
|
||||
45015 => '回复时间超过限制',
|
||||
45016 => '系统分组,不允许修改',
|
||||
45017 => '分组名字过长',
|
||||
45018 => '分组数量超过上限',
|
||||
45047 => '客服接口下行条数超过上限',
|
||||
45064 => '创建菜单包含未关联的小程序',
|
||||
45065 => '相同 clientmsgid 已存在群发记录,返回数据中带有已存在的群发任务的 msgid',
|
||||
45066 => '相同 clientmsgid 重试速度过快,请间隔1分钟重试',
|
||||
45067 => 'clientmsgid 长度超过限制',
|
||||
46001 => '不存在媒体数据',
|
||||
46002 => '不存在的菜单版本',
|
||||
46003 => '不存在的菜单数据',
|
||||
46004 => '不存在的用户',
|
||||
47001 => '解析 JSON/XML 内容错误',
|
||||
47003 => '参数值不符合限制要求,详情可参考参数值内容限制说明',
|
||||
48001 => 'api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 中心页中查看接口权限',
|
||||
48002 => '粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” )',
|
||||
48004 => 'api 接口被封禁,请登录 mp.weixin.qq.com 查看详情',
|
||||
48005 => 'api 禁止删除被自动回复和自定义菜单引用的素材',
|
||||
48006 => 'api 禁止清零调用次数,因为清零次数达到上限',
|
||||
48008 => '没有该类型消息的发送权限',
|
||||
50001 => '用户未授权该 api',
|
||||
50002 => '用户受限,可能是违规后接口被封禁',
|
||||
50005 => '用户未关注公众号',
|
||||
53500 => '发布功能被封禁',
|
||||
53501 => '频繁请求发布',
|
||||
53502 => 'Publish ID 无效',
|
||||
53600 => 'Article ID 无效',
|
||||
61451 => '参数错误 (invalid parameter)',
|
||||
61452 => '无效客服账号 (invalid kf_account)',
|
||||
61453 => '客服帐号已存在 (kf_account exsited)',
|
||||
61454 => '客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length)',
|
||||
61455 => '客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account)',
|
||||
61456 => '客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded)',
|
||||
61457 => '无效头像文件类型 (invalid file type)',
|
||||
61450 => '系统错误 (system error)',
|
||||
61500 => '日期格式错误',
|
||||
63001 => '部分参数为空',
|
||||
63002 => '无效的签名',
|
||||
65301 => '不存在此 menuid 对应的个性化菜单',
|
||||
65302 => '没有相应的用户',
|
||||
65303 => '没有默认菜单,不能创建个性化菜单',
|
||||
65304 => 'MatchRule 信息为空',
|
||||
65305 => '个性化菜单数量受限',
|
||||
65306 => '不支持个性化菜单的帐号',
|
||||
65307 => '个性化菜单信息为空',
|
||||
65308 => '包含没有响应类型的 button',
|
||||
65309 => '个性化菜单开关处于关闭状态',
|
||||
65310 => '填写了省份或城市信息,国家信息不能为空',
|
||||
65311 => '填写了城市信息,省份信息不能为空',
|
||||
65312 => '不合法的国家信息',
|
||||
65313 => '不合法的省份信息',
|
||||
65314 => '不合法的城市信息',
|
||||
65316 => '该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接)',
|
||||
65317 => '不合法的 URL',
|
||||
87009 => '无效的签名',
|
||||
9001001 => 'POST 数据参数不合法',
|
||||
9001002 => '远端服务不可用',
|
||||
9001003 => 'Ticket 不合法',
|
||||
9001004 => '获取摇周边用户信息失败',
|
||||
9001005 => '获取商户信息失败',
|
||||
9001006 => '获取 OpenID 失败',
|
||||
9001007 => '上传文件缺失',
|
||||
9001008 => '上传素材的文件类型不合法',
|
||||
9001009 => '上传素材的文件尺寸不合法',
|
||||
9001010 => '上传失败',
|
||||
9001020 => '帐号不合法',
|
||||
9001021 => '已有设备激活率低于 50% ,不能新增设备',
|
||||
9001022 => '设备申请数不合法,必须为大于 0 的数字',
|
||||
9001023 => '已存在审核中的设备 ID 申请',
|
||||
9001024 => '一次查询设备 ID 数量不能超过 50',
|
||||
9001025 => '设备 ID 不合法',
|
||||
9001026 => '页面 ID 不合法',
|
||||
9001027 => '页面参数不合法',
|
||||
9001028 => '一次删除页面 ID 数量不能超过 10',
|
||||
9001029 => '页面已应用在设备中,请先解除应用关系再删除',
|
||||
9001030 => '一次查询页面 ID 数量不能超过 50',
|
||||
9001031 => '时间区间不合法',
|
||||
9001032 => '保存设备与页面的绑定关系参数错误',
|
||||
9001033 => '门店 ID 不合法',
|
||||
9001034 => '设备备注信息过长',
|
||||
9001035 => '设备申请参数不合法',
|
||||
9001036 => '查询起始值 begin 不合法',
|
||||
];
|
||||
33
src/addon/wechat/event/AddSiteReplay.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\event;
|
||||
|
||||
use addon\wechat\model\Replay;
|
||||
|
||||
/**
|
||||
* 增加站点关注回复
|
||||
*/
|
||||
class AddSiteReplay
|
||||
{
|
||||
|
||||
public function handle($param)
|
||||
{
|
||||
if (!empty($param[ 'site_id' ])) {
|
||||
|
||||
$replay = new Replay();
|
||||
$data = [
|
||||
'site_id' => $param[ 'site_id' ],
|
||||
'rule_name' => '关注回复',
|
||||
'rule_type' => 'AFTER',
|
||||
'keywords_json' => '',
|
||||
'replay_json' => '[{"type":"text","reply_content":"关注回复"}]',
|
||||
'create_time' => time()
|
||||
];
|
||||
$res = $replay->addRule($data);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
19
src/addon/wechat/event/CronMessageSend.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace addon\system\Wechat\event;
|
||||
|
||||
use addon\system\Wechat\common\model\WechatMessage;
|
||||
|
||||
class CronMessageSend
|
||||
{
|
||||
/**
|
||||
* 邮箱消息延时发送
|
||||
* @param array $param
|
||||
*/
|
||||
public function handle($param = [])
|
||||
{
|
||||
$wechat_message = new WechatMessage();
|
||||
$res = $wechat_message->cronMessageSend($param);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
17
src/addon/wechat/event/Install.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace addon\Wechat\event;
|
||||
|
||||
/**
|
||||
* 应用安装
|
||||
*/
|
||||
class Install
|
||||
{
|
||||
/**
|
||||
* 执行安装
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
return success();
|
||||
}
|
||||
}
|
||||
39
src/addon/wechat/event/OAuthLogin.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace addon\system\Wechat\event;
|
||||
|
||||
use addon\wechat\model\Wechat;
|
||||
use liliuwei\think\Jump;
|
||||
|
||||
/**
|
||||
* 应用安装
|
||||
*/
|
||||
class OAuthLogin
|
||||
{
|
||||
use Jump;
|
||||
|
||||
/**
|
||||
* 授权登录
|
||||
* @param array $params
|
||||
*/
|
||||
public function handle($params = [])
|
||||
{
|
||||
if ($params[ 'name' ] == 'Wechat') {
|
||||
$wechat_model = new Wechat();
|
||||
$wechat_config = $wechat_model->getWechatConfigInfo($params[ 'site_id' ]);
|
||||
|
||||
if (empty($wechat_config[ 'data' ][ 'value' ])) {
|
||||
$this->error('站点未配置微信公众号');
|
||||
} else {
|
||||
$value = $wechat_config[ 'data' ][ 'value' ];
|
||||
if (empty($value[ 'appid' ]) || empty($value[ 'appsecret' ])) {
|
||||
$this->error('请配置您公众号的AppID和AppSecret');
|
||||
} else {
|
||||
$redirect_url = addon_url('wechat://common/login/callback', [ 'site_id' => $params[ 'site_id' ] ]);
|
||||
$get_request_code_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $value[ 'appid' ] . '&redirect_uri=' . $redirect_url . '&response_type=code&scope=snsapi_userinfo&state=niucloud#wechat_redirect';
|
||||
$this->redirect($get_request_code_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/addon/wechat/event/UnInstall.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace addon\Wechat\event;
|
||||
|
||||
/**
|
||||
* 应用卸载
|
||||
*/
|
||||
class UnInstall
|
||||
{
|
||||
/**
|
||||
* 执行卸载
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
return error('', 'System addon can not be uninstalled!');
|
||||
}
|
||||
}
|
||||
24
src/addon/wechat/event/WechatMessage.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace addon\system\Wechat\event;
|
||||
|
||||
use liliuwei\think\Jump;
|
||||
use addon\system\Wechat\common\model\WechatMessage as WechatMessageModel;
|
||||
|
||||
class WechatMessage
|
||||
{
|
||||
use Jump;
|
||||
|
||||
/**
|
||||
* 微信模板消息
|
||||
* @param array $param
|
||||
* @return array
|
||||
*/
|
||||
public function handle($param = [])
|
||||
{
|
||||
$wechat_message = new WechatMessageModel();
|
||||
$res = $wechat_message->sendMessage($param);
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
15
src/addon/wechat/event/WechatMsg.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace addon\system\Wechat\event;
|
||||
|
||||
use addon\system\Wechat\common\model\Wechat;
|
||||
|
||||
class WechatMsg
|
||||
{
|
||||
public function handle($param = [])
|
||||
{
|
||||
$wechat_config = new Wechat();
|
||||
$res = $wechat_config->sendTemplateMsg(request()->siteid(), $param);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
BIN
src/addon/wechat/icon.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
128
src/addon/wechat/model/Config.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use app\model\BaseModel;
|
||||
use app\model\upload\Upload;
|
||||
|
||||
/**
|
||||
* 微信公众号配置
|
||||
*/
|
||||
class Config extends BaseModel
|
||||
{
|
||||
/******************************************************************** 微信公众号配置 start ****************************************************************************/
|
||||
/**
|
||||
* 设置微信公众号配置
|
||||
* @param $data
|
||||
* @param $is_use
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function setWechatConfig($data, $is_use, $site_id)
|
||||
{
|
||||
$config_info = $this->getWechatConfig($site_id);
|
||||
if (!empty($config_info[ 'data' ][ 'value' ][ 'qrcode' ]) && !empty($data[ 'qrcode' ]) && $config_info[ 'data' ][ 'value' ][ 'qrcode' ] != $data[ 'qrcode' ]) {
|
||||
$upload_model = new Upload();
|
||||
$upload_model->deletePic($config_info[ 'data' ][ 'value' ][ 'qrcode' ], $site_id);
|
||||
}
|
||||
|
||||
$config = new ConfigModel();
|
||||
$res = $config->setConfig($data, '微信公众号设置', $is_use, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信公众号配置信息
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatConfig($site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_CONFIG' ] ]);
|
||||
if (empty($res[ 'data' ][ 'value' ])) {
|
||||
$res[ 'data' ][ 'value' ] = [
|
||||
'wechat_name' => '',
|
||||
'wechat_original' => '',
|
||||
'appid' => '',
|
||||
'appsecret' => '',
|
||||
'token' => '',
|
||||
'encodingaeskey' => '',
|
||||
'qrcode' => '',
|
||||
'headimg' => ''
|
||||
];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
/******************************************************************** 微信公众号配置 end ****************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************** 分享内容配置 start ****************************************************************************/
|
||||
/**
|
||||
* 设置分享内容
|
||||
* @param $data
|
||||
* @param $is_use
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function setShareConfig($data, $is_use, $site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->setConfig($data, '分享内容设置', $is_use, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_SHARE_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分享内容
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getShareConfig($site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_SHARE_CONFIG' ] ]);
|
||||
if (empty($res[ 'data' ][ 'value' ])) {
|
||||
$res[ 'data' ][ 'value' ] = [
|
||||
'goods_param_1' => '优惠价',
|
||||
'goods_param_2' => '全场正品',
|
||||
'qrcode_param_1' => '向您推荐',
|
||||
'qrcode_param_2' => '注册有优惠',
|
||||
'shop_param_1' => '欢迎打开',
|
||||
'shop_param_2' => '向您推荐',
|
||||
'shop_param_3' => '注册有优惠'
|
||||
];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
/******************************************************************** 分享内容配置 end ****************************************************************************/
|
||||
|
||||
/**
|
||||
* 设置模板消息配置
|
||||
* @param $data
|
||||
* @param $is_use
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function setTemplateMessageConfig($data, $is_use, $site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->setConfig($data, '微信模板消息设置', $is_use, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_TEMPLATE_MESSAGE_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板消息配置
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplateMessageConfig($site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_TEMPLATE_MESSAGE_CONFIG' ] ]);
|
||||
if (empty($res[ 'data' ][ 'value' ])) {
|
||||
$res[ 'data' ][ 'value' ] = [ 'is_jump_weapp' => 0 ];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
267
src/addon/wechat/model/Fans.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信粉丝
|
||||
*/
|
||||
class Fans extends BaseModel
|
||||
{
|
||||
/***************************************************************** 微信粉丝 start ***************************************************************************/
|
||||
|
||||
/**
|
||||
* 获取粉丝列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getFansList($condition = [], $field = '*', $order = '', $limit = null)
|
||||
{
|
||||
$list = model('wechat_fans')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取粉丝分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getFansPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'subscribe_time desc', $field = '*')
|
||||
{
|
||||
$list = model('wechat_fans')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为微信粉丝批量打标签
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function fansBatchTagging($data)
|
||||
{
|
||||
//调用微信接口服务器配置 修改微信端粉丝标签
|
||||
$res = model('wechat_fans')->update([ 'tagid_list' => implode(',', $data[ 'tag_id_list' ]) ], [ 'openid' => [ 'in', $data[ 'openid_list' ] ] ]);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为微信粉丝批量取消标签
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function batchUnTagging($data)
|
||||
{
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步粉丝标签
|
||||
* @param $openid_list
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function syncFans($openid_list)
|
||||
{
|
||||
$wechat_model = new Wechat();
|
||||
$select_result = $wechat_model->selectUser($openid_list);//获取多个微信粉丝信息
|
||||
if ($select_result[ "code" ] != 0)
|
||||
return $select_result;
|
||||
|
||||
$user_list = $select_result[ "data" ][ "user_info_list" ];
|
||||
$subscribe_scene_array = array (
|
||||
"ADD_SCENE_SEARCH" => "公众号搜索",
|
||||
"ADD_SCENE_ACCOUNT_MIGRATION" => "公众号迁移",
|
||||
"ADD_SCENE_PROFILE_CARD" => "名片分享",
|
||||
"ADD_SCENE_QR_CODE" => "扫描二维码",
|
||||
"ADD_SCENE_PROFILE_ LINK" => "图文页内名称点击",
|
||||
"ADD_SCENE_PROFILE_ITEM" => "图文页右上角菜单",
|
||||
"ADD_SCENE_PAID" => "支付后关注",
|
||||
"ADD_SCENE_OTHERS" => "其他",
|
||||
);
|
||||
foreach ($user_list as $user_k => $user_item) {
|
||||
$unionid = empty($user_item[ "unionid" ]) ? '' : $user_item[ "unionid" ];
|
||||
$province = base64_encode($user_item[ "province" ]);
|
||||
$city = base64_encode($user_item[ "city" ]);
|
||||
$nickname = base64_encode($user_item[ 'nickname' ]);
|
||||
$nickname_decode = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $user_item[ 'nickname' ]);
|
||||
$data = array (
|
||||
'nickname' => $nickname,
|
||||
'nickname_decode' => $nickname_decode,
|
||||
'headimgurl' => $user_item[ 'headimgurl' ],
|
||||
'sex' => $user_item[ "sex" ],
|
||||
'language' => $user_item[ "language" ],
|
||||
'country' => $user_item[ "country" ],
|
||||
'province' => $province,
|
||||
'city' => $city,
|
||||
'district' => '',
|
||||
'openid' => $user_item[ "openid" ],
|
||||
'unionid' => $unionid,
|
||||
'groupid' => $user_item[ "groupid" ],
|
||||
'is_subscribe' => $user_item[ "subscribe" ],
|
||||
'remark' => $user_item[ "remark" ],
|
||||
'update_date' => time(),
|
||||
'tagid_list' => empty($user_item[ "tagid_list" ]) ? '' : implode(',', $user_item[ "tagid_list" ]),
|
||||
'subscribe_scene' => $user_item[ "subscribe_scene" ],
|
||||
'subscribe_scene_name' => $subscribe_scene_array[ $user_item[ "subscribe_scene" ] ],
|
||||
'qr_scene' => $user_item[ "qr_scene" ],
|
||||
'qr_scene_str' => $user_item[ "qr_scene_str" ],
|
||||
'subscribe_time' => $user_item[ "subscribe_time" ],
|
||||
);
|
||||
$res = model("wechat_fans")->add($data);
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/***************************************************************** 微信粉丝 end ***************************************************************************/
|
||||
|
||||
/***************************************************************** 微信粉丝标签 start ***************************************************************************/
|
||||
|
||||
/**
|
||||
* 增加粉丝标签
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addFansTag($data)
|
||||
{
|
||||
$res = model('wechat_fans_tag')->add($data);
|
||||
if ($res === false)
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
|
||||
//同步修改微信端粉丝标签
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑粉丝标签
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editFansTag($data, $condition)
|
||||
{
|
||||
$res = model('wechat_fans_tag')->update($data, $condition);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
//同步修改微信端粉丝标签
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除标签
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteFansTag($condition)
|
||||
{
|
||||
$res = model('wechat_fans_tag')->delete($condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取粉丝列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getFansTagList($condition = [], $field = '*', $order = '', $limit = null)
|
||||
{
|
||||
$list = model('wechat_fans_tag')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信粉丝标签列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $list_rows
|
||||
* @param string $order
|
||||
* @param bool $field
|
||||
* @return array
|
||||
*/
|
||||
public function getFansTagPageList($condition = [], $page = 1, $list_rows = PAGE_LIST_ROWS, $order = '', $field = true)
|
||||
{
|
||||
$list = model('wechat_fans_tag')->pageList($condition, $field, $order, $page, $list_rows);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步粉丝标签
|
||||
* @return array
|
||||
*/
|
||||
public function syncFansTag()
|
||||
{
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/***************************************************************** 微信粉丝标签 end ***************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* 增加粉丝
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addFans($data)
|
||||
{
|
||||
$res = model('wechat_fans')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消关注
|
||||
* @param $open_id
|
||||
* @return array
|
||||
*/
|
||||
public function unfollowWechat($open_id)
|
||||
{
|
||||
$data = array (
|
||||
'is_subscribe' => 0,
|
||||
'update_date' => time(),
|
||||
'unsubscribe_time' => time()
|
||||
);
|
||||
$wechat_fans_model = model('wechat_fans');
|
||||
$res = $wechat_fans_model->update($data, [ 'openid' => $open_id ]);
|
||||
return success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 粉丝详情
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getFansInfo($condition, $field = "*")
|
||||
{
|
||||
if (!empty($cache)) {
|
||||
return $this->success($cache);
|
||||
}
|
||||
$info = model('wechat_fans')->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑粉丝
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editFans($data, $condition)
|
||||
{
|
||||
$data[ "update_date" ] = time();
|
||||
$result = model("wechat_fans")->update($data, $condition);
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
}
|
||||
88
src/addon/wechat/model/Material.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信素材管理
|
||||
*/
|
||||
class Material extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 添加微信素材
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addMaterial($data)
|
||||
{
|
||||
$res = model('wechat_media')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改微信素材
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editMaterial($data, $condition)
|
||||
{
|
||||
$res = model('wechat_media')->update($data, $condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除微信素材
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteMaterial($condition)
|
||||
{
|
||||
$res = model('wechat_media')->delete($condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信素材信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getMaterialInfo($condition, $field = '*')
|
||||
{
|
||||
$res = model('wechat_media')->getInfo($condition, $field);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信素材列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getMaterialList($condition = [], $field = '*', $order = '', $limit = null)
|
||||
{
|
||||
$res = model('wechat_media')->getList($condition, $field, $order, '', '', '', $limit);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信素材分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getMaterialPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'update_time desc', $field = '*')
|
||||
{
|
||||
$list = model('wechat_media')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
}
|
||||
40
src/addon/wechat/model/Menu.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信公众号配置
|
||||
*/
|
||||
class Menu extends BaseModel
|
||||
{
|
||||
|
||||
/******************************************************************** 微信公众号菜单配置 start ****************************************************************************/
|
||||
/**
|
||||
* 设置微信公众号配置
|
||||
* @param $data
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function setWechatMenuConfig($data, $site_id = 0)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->setConfig($data, '微信公众号设置', 1, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_MENU_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信公众号菜单配置
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatMenuConfig($site_id = 0)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WECHAT_MENU_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
/******************************************************************** 微信公众号菜单配置 end ****************************************************************************/
|
||||
}
|
||||
97
src/addon/wechat/model/Message.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use addon\weapp\model\Config as WeappConfig;
|
||||
use addon\mobileshop\model\Config as MobileShopConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 微信消息模板
|
||||
*/
|
||||
class Message extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 发送模板消息
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function sendMessage(array $param)
|
||||
{
|
||||
try {
|
||||
$site_id = $param[ 'site_id' ];
|
||||
$support_type = $param[ "support_type" ] ?? [];
|
||||
|
||||
if (!empty($support_type) && !in_array("wechat", $support_type)) return $this->success();
|
||||
|
||||
if (empty($param[ 'openid' ])) return $this->success('缺少必需参数openid');
|
||||
|
||||
$message_info = $param[ 'message_info' ];
|
||||
if ($message_info[ 'wechat_is_open' ] == 0) return $this->error('未启用模板消息');
|
||||
|
||||
$wechat_info = json_decode($message_info[ 'wechat_json' ], true);
|
||||
if (empty($message_info[ 'wechat_template_id' ])) return $this->error('未配置模板消息');
|
||||
|
||||
$template_data = [
|
||||
// 'first' => [
|
||||
// 'value' => $wechat_info[ 'headtext' ],
|
||||
// 'color' => !empty($wechat_info[ 'headtextcolor' ]) ? $wechat_info[ 'headtextcolor' ] : '#f00'
|
||||
// ],
|
||||
// 'remark' => [
|
||||
// 'value' => $wechat_info[ 'bottomtext' ],
|
||||
// 'color' => !empty($wechat_info[ 'bottomtextcolor' ]) ? $wechat_info[ 'bottomtextcolor' ] : '#333'
|
||||
// ]
|
||||
];
|
||||
if (!empty($param[ 'template_data' ])) $template_data = array_merge($template_data, $param[ 'template_data' ]);
|
||||
|
||||
|
||||
$data = [
|
||||
'openid' => $param[ 'openid' ],
|
||||
'template_id' => $message_info[ 'wechat_template_id' ],
|
||||
'data' => $template_data,
|
||||
'miniprogram' => [],
|
||||
'url' => ""
|
||||
];
|
||||
|
||||
if (!empty($param[ 'page' ])) {
|
||||
// 商家消息
|
||||
if ($message_info[ 'message_type' ] == 2 && addon_is_exit('mobileshop', $site_id)) {
|
||||
$config = new MobileShopConfig();
|
||||
$weapp_config = $config->getWeappConfig($site_id)[ 'data' ][ "value" ];
|
||||
if (!empty($weapp_config[ 'appid' ])) {
|
||||
$data[ 'miniprogram' ] = [
|
||||
'appid' => $weapp_config[ 'appid' ],
|
||||
'pagepath' => $param[ 'page' ]
|
||||
];
|
||||
}
|
||||
$mshop_config = $config->getMShopDomainName($site_id)[ 'data' ][ 'value' ];
|
||||
$data[ 'url' ] = $mshop_config[ 'domain_name_mobileshop' ] . '/' . $param[ 'page' ];
|
||||
} else {
|
||||
$template_config_model = new Config();
|
||||
$template_config = $template_config_model->getTemplateMessageConfig($site_id)[ 'data' ][ 'value' ];
|
||||
|
||||
if ($template_config[ 'is_jump_weapp' ]) {
|
||||
// 小程序配置
|
||||
$weapp_config = new WeappConfig();
|
||||
$weapp_config = $weapp_config->getWeappConfig($site_id)[ 'data' ][ "value" ];
|
||||
|
||||
if (!empty($weapp_config[ 'appid' ])) {
|
||||
$data[ 'miniprogram' ] = [
|
||||
'appid' => $weapp_config[ 'appid' ],
|
||||
'pagepath' => $param[ 'page' ]
|
||||
];
|
||||
}
|
||||
}
|
||||
$data[ 'url' ] = getH5Domain() . '/' . $param[ 'page' ];
|
||||
}
|
||||
}
|
||||
$wechat = new Wechat($site_id);
|
||||
$res = $wechat->sendTemplateMessage($data);
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', "模板消息发送失败:" . $e->getMessage() . ",File:" . $e->getFile() . ",line:" . $e->getLine());
|
||||
}
|
||||
}
|
||||
}
|
||||
121
src/addon/wechat/model/MessageRecords.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace addon\system\Wechat\common\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信模板消息消息发送记录
|
||||
*/
|
||||
class MessageRecords extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 新建微信模板消息发送记录
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addWechatMessageRecords($data)
|
||||
{
|
||||
$id = model("nc_site_message_wechat_list")->add($data);
|
||||
if ($id === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加微信模板消息发送记录
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addWechatMessageRecordsList($data)
|
||||
{
|
||||
$id = model("nc_site_message_wechat_list")->addList($data);
|
||||
if ($id === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑微信模板消息发送记录
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editWechatMessageRecords($data, $condition)
|
||||
{
|
||||
$res = model("nc_site_message_wechat_list")->update($data, $condition);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除微信模板消息发送记录
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteWechatMessageRecords($condition)
|
||||
{
|
||||
$res = model("nc_site_message_wechat_list")->delete($condition);
|
||||
if ($res === false) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询微信模板消息发送记录
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatMessageRecordsInfo($condition, $field = "*")
|
||||
{
|
||||
$res = model("nc_site_message_wechat_list")->getInfo($condition, $field);
|
||||
if (empty($res)) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询微信模板消息发送记录
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatMessageRecordsList($condition, $field = "*")
|
||||
{
|
||||
$res = model("nc_site_message_wechat_list")->getList($condition, $field);
|
||||
if (empty($res)) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询微信模板消息发送记录分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getWechatMessageRecordsPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$res = model("nc_site_message_wechat_list")->pageList($condition, $field, $order, $page, $page_size);
|
||||
if (empty($res)) {
|
||||
return $this->error('', 'UNKNOW_ERROR');
|
||||
}
|
||||
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
}
|
||||
95
src/addon/wechat/model/Qrcode.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 微信二维码
|
||||
*/
|
||||
class Qrcode extends BaseModel
|
||||
{
|
||||
/***************************************************************** 微信二维码 start ***************************************************************************/
|
||||
/**
|
||||
* 添加微信二维码
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addQrcode($data)
|
||||
{
|
||||
$data[ "update_time" ] = time();
|
||||
Cache::tag("wechat_qrcode")->clear();
|
||||
$result = model("wechat_qrcode")->add($data);
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑微信二维码
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editQrcode($data, $condition)
|
||||
{
|
||||
$data[ "update_time" ] = time();
|
||||
Cache::tag("wechat_qrcode")->clear();
|
||||
$result = model("wechat_qrcode")->update($data, $condition);
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除微信二维码
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteQrcode($condition)
|
||||
{
|
||||
Cache::tag("wechat_qrcode")->clear();
|
||||
$result = model("wechat_qrcode")->delete($condition);
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认二维码模板
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function modifyQrcodeDefault($condition)
|
||||
{
|
||||
//将全部模板设置为非默认
|
||||
Cache::tag("wechat_qrcode")->clear();
|
||||
model("wechat_qrcode")->update([ "is_default" => 0 ], [ 'is_default' => 1 ]);
|
||||
$res = model("wechat_qrcode")->update([ "is_default" => 1 ], $condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取二维码模板详情
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getQrcodeInfo($condition, $field = "*")
|
||||
{
|
||||
$info = model('wechat_qrcode')->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信二维码列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getQrcodePageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('wechat_qrcode')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/***************************************************************** 微信粉丝 end ***************************************************************************/
|
||||
}
|
||||
153
src/addon/wechat/model/Replay.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信回复
|
||||
*/
|
||||
class Replay extends BaseModel
|
||||
{
|
||||
|
||||
/*******************************************************************************微信回复开始*****************************************************/
|
||||
/**
|
||||
* 添加微信关键词回复
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addRule($data)
|
||||
{
|
||||
$res = model('wechat_replay_rule')->add($data);
|
||||
if ($res === false) {
|
||||
return $this->error($res, 'SAVE_FAIL');
|
||||
}
|
||||
return $this->success($res, 'SAVE_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改微信关键词回复
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editRule($data, $condition)
|
||||
{
|
||||
$res = model('wechat_replay_rule')->update($data, $condition);
|
||||
if ($res === false) {
|
||||
return $this->error($res, 'SAVE_FAIL');
|
||||
}
|
||||
return $this->success($res, 'SAVE_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除微信关键词回复
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteRule($condition)
|
||||
{
|
||||
$res = model('wechat_replay_rule')->delete($condition);
|
||||
if ($res === false) {
|
||||
return $this->error($res, 'DELETE_FAIL');
|
||||
}
|
||||
return $this->success($res, 'DELETE_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信关键词回复信息
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getRuleInfo($condition, $field = '*')
|
||||
{
|
||||
$info = model('wechat_replay_rule')->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取回复列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getReplayPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('wechat_replay_rule')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取站点关键字回复
|
||||
* @param $keywords
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getSiteWechatKeywordsReplay($keywords, $site_id)
|
||||
{
|
||||
|
||||
$list = model('wechat_replay_rule')->getList([['rule_type', '=', 'KEYWORDS'], ['site_id', '=', $site_id]]);
|
||||
$default_list = model('wechat_replay_rule')->getList([['rule_type', '=', 'DEFAULT'], ['site_id', '=', $site_id]]);
|
||||
$rule_list = array();
|
||||
foreach ($list as $k => $v) {
|
||||
$kewords_array = json_decode($v['keywords_json'], true);
|
||||
$replay_array = json_decode($v['replay_json'], true);
|
||||
if (!empty($kewords_array) && !empty($replay_array)) {
|
||||
foreach ($kewords_array as $k_key => $v_key) {
|
||||
if (($v_key['keywords_type'] == 0 && $v_key['keywords_name'] == $keywords) || ($v_key['keywords_type'] == 1 && (strpos($keywords, $v_key['keywords_name']) !== false))) {
|
||||
$num = rand(0, count($replay_array) - 1);
|
||||
$rule_list[] = $replay_array[$num];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($rule_list)) {
|
||||
$default_rule_list = array();
|
||||
foreach ($default_list as $kk => $vv) {
|
||||
$default_replay_array = json_decode($vv['replay_json'], true);
|
||||
if (!empty($default_replay_array)) {
|
||||
$default_rule_list[] = $default_replay_array[0];
|
||||
}
|
||||
}
|
||||
if (!empty($default_rule_list)) {
|
||||
$rule = $default_rule_list[0];
|
||||
} else {
|
||||
$rule = [];
|
||||
}
|
||||
} else {
|
||||
$rule = $rule_list[0];
|
||||
}
|
||||
return $this->success($rule);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取微信关注回复
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
function getWechatFollowReplay($site_id)
|
||||
{
|
||||
$follow_info = model('wechat_replay_rule')->getInfo([['rule_type', '=', 'AFTER'], ['site_id', '=', $site_id]]);
|
||||
$replay_content = '';
|
||||
if (!empty($follow_info['replay_json'])) {
|
||||
$replay_info = json_decode($follow_info['replay_json'], true);
|
||||
switch ($replay_info[0]['type']) {
|
||||
case 'text' :
|
||||
$replay_content = $replay_info[0]['reply_content'];
|
||||
break;
|
||||
case 'articles' :
|
||||
$replay_content = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this->success($replay_content);
|
||||
}
|
||||
|
||||
/*******************************************************************************微信回复结束*****************************************************/
|
||||
}
|
||||
273
src/addon/wechat/model/Stat.php
Normal file
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 数据统计与分析
|
||||
*/
|
||||
class Stat extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取用户增减数据, 最大时间跨度:7
|
||||
* @param $begin_date
|
||||
* @param $end_date
|
||||
* @return array
|
||||
*/
|
||||
public function userSummary($begin_date, $end_date)
|
||||
{
|
||||
$cache = Cache::get("wechat_user_summary_" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($cache))
|
||||
return $this->success($cache);
|
||||
|
||||
$wechat_model = new Wechat();
|
||||
$result = $wechat_model->userSummary($begin_date, $end_date);
|
||||
if ($result[ "code" ] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("wechat_visit")->set("wechat_user_summary_" . "_" . $begin_date . "_" . $end_date, $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取累计用户数据, 最大时间跨度:7;
|
||||
* @param $begin_date
|
||||
* @param $end_date
|
||||
* @return array
|
||||
*/
|
||||
public function userCumulate($begin_date, $end_date)
|
||||
{
|
||||
$cache = Cache::get("wechat_user_cumulate_" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($cache))
|
||||
return $this->success($cache);
|
||||
|
||||
$wechat_model = new Wechat();
|
||||
$result = $wechat_model->userCumulate($begin_date, $end_date);
|
||||
if ($result[ "code" ] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("wechat_visit")->set("wechat_user_cumulate_" . "_" . $begin_date . "_" . $end_date, $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口分析分时数据, 最大时间跨度:1;
|
||||
* @param $begin_date
|
||||
* @param $end_date
|
||||
* @return array
|
||||
*/
|
||||
public function interfaceSummaryHourly($begin_date, $end_date)
|
||||
{
|
||||
$cache = Cache::get("wechat_interface_summary_hourly_" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($cache))
|
||||
return $this->success($cache);
|
||||
|
||||
$wechat_model = new Wechat();
|
||||
$result = $wechat_model->interfaceSummaryHourly($begin_date, $end_date);
|
||||
if ($result[ "code" ] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("wechat_visit")->set("wechat_interface_summary_hourly_" . "_" . $begin_date . "_" . $end_date, $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口分析数据, 最大时间跨度:30;
|
||||
* @param $begin_date
|
||||
* @param $end_date
|
||||
* @return array
|
||||
*/
|
||||
public function interfaceSummary($begin_date, $end_date)
|
||||
{
|
||||
// $cache = Cache::get("wechat_interface_summary_" . "_" . $begin_date."_" . $end_date);
|
||||
// if (!empty($cache))
|
||||
// return $this->success($cache);
|
||||
|
||||
$wechat_model = new Wechat();
|
||||
$result = $wechat_model->interfaceSummary($begin_date, $end_date);
|
||||
if ($result[ "code" ] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("wechat_visit")->set("wechat_interface_summary_" . "_" . $begin_date . "_" . $end_date, $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信粉丝统计(以天为单位)
|
||||
* @param $begin_date
|
||||
* @param $end_date
|
||||
* @return array
|
||||
*/
|
||||
public function fans($begin_date, $end_date)
|
||||
{
|
||||
// $cache = Cache::get("wechat_fans_statistics_" . "_" . $begin_date."_" . $end_date);
|
||||
// if (!empty($cache)) {
|
||||
// return $this->success($cache);
|
||||
// }
|
||||
// $data = [ 'begin_date' => $param['begin_date'], 'end_date' => $param['end_date'] ];
|
||||
$user_summary_result = $this->userSummary($begin_date, $end_date);
|
||||
if ($user_summary_result[ "code" ] < 0) {
|
||||
return $user_summary_result;
|
||||
}
|
||||
$user_cumulate_result = $this->userCumulate($begin_date, $end_date);
|
||||
if ($user_cumulate_result[ "code" ] < 0) {
|
||||
return $user_cumulate_result;
|
||||
}
|
||||
$list = [];
|
||||
foreach ($user_cumulate_result[ "data" ] as $cumulate_k => $cumulate_v) {
|
||||
$temp_item = $cumulate_v;
|
||||
$temp_item[ 'cumulate_user' ] = empty($cumulate_v[ 'cumulate_user' ]) ? 0 : $cumulate_v[ 'cumulate_user' ];
|
||||
$new_user = 0;
|
||||
$cancel_user = 0;
|
||||
$net_growth_user = 0;
|
||||
foreach ($user_summary_result[ 'data' ] as $key => $item) {
|
||||
if ($item[ "ref_date" ] == $cumulate_v[ "ref_date" ]) {
|
||||
$new_user += $item[ 'new_user' ];
|
||||
$cancel_user += $item[ 'cancel_user' ];
|
||||
$net_growth_user += $item[ "new_user" ] - $item[ "cancel_user" ];
|
||||
}
|
||||
}
|
||||
$temp_item[ 'new_user' ] = $new_user;
|
||||
$temp_item[ 'cancel_user' ] = $cancel_user;
|
||||
$temp_item[ 'net_growth_user' ] = $net_growth_user;
|
||||
$list[] = $temp_item;
|
||||
}
|
||||
Cache::tag("wechat_visit")->set("wechat_fans_statistics_" . "_" . $begin_date . "_" . $end_date, $list);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口访问数据图
|
||||
* @param $date_type
|
||||
* @return array
|
||||
*/
|
||||
public function interfaceSummaryStatistics($date_type)
|
||||
{
|
||||
$date_data = $this->getDaterange($date_type);
|
||||
$is_error = true;
|
||||
$callback_count_data = [];
|
||||
$fail_count_data = [];
|
||||
$average_time_cost_data = [];
|
||||
$max_time_cost_data = [];
|
||||
foreach ($date_data[ "date_list" ] as $k => $v) {
|
||||
$callback_count = 0;
|
||||
$fail_count = 0;
|
||||
$average_time_cost = 0;
|
||||
$max_time_cost = 0;
|
||||
if ($is_error) {
|
||||
$temp_data = $this->interfaceSummary($v, $v);
|
||||
if (!empty($temp_data[ "data" ])) {
|
||||
$temp_date_item = $temp_data[ "data" ];
|
||||
$callback_count = $temp_date_item[ 0 ][ "callback_count" ];
|
||||
$fail_count = $temp_date_item[ 0 ][ "fail_count" ];
|
||||
$average_time_cost = $temp_date_item[ 0 ][ "total_time_cost" ] / $temp_date_item[ 0 ][ "callback_count" ];
|
||||
$max_time_cost = $temp_date_item[ 0 ][ "max_time_cost" ];
|
||||
} else {
|
||||
$is_error = false;
|
||||
}
|
||||
}
|
||||
$callback_count_data[] = $callback_count;
|
||||
$fail_count_data[] = $fail_count;
|
||||
$average_time_cost_data[] = $average_time_cost;
|
||||
$max_time_cost_data[] = $max_time_cost;
|
||||
}
|
||||
$return_data = array (
|
||||
"date" => $date_data[ "date_list" ],
|
||||
"data" => array (
|
||||
"callback_count_data" => $callback_count_data,
|
||||
"fail_count_data" => $fail_count_data,
|
||||
"average_time_cost_data" => $average_time_cost_data,
|
||||
"max_time_cost_data" => $max_time_cost_data
|
||||
)
|
||||
);
|
||||
return $this->success($return_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户访问统计图
|
||||
* @param $date_type
|
||||
* @return array
|
||||
*/
|
||||
public function userSummaryStatistics($date_type)
|
||||
{
|
||||
$is_error = true;
|
||||
$date_data = $this->getDaterange($date_type);
|
||||
$new_user_data = [];
|
||||
$cancel_user_data = [];
|
||||
$net_growth_user_data = [];
|
||||
$cumulate_user_data = [];
|
||||
foreach ($date_data[ "date_list" ] as $k => $v) {
|
||||
$new_user = 0;
|
||||
$cancel_user = 0;
|
||||
$net_growth_user = 0;
|
||||
$cumulate_user = 0;
|
||||
if ($is_error) {
|
||||
$temp_data = $this->fans($v, $v);
|
||||
if (!empty($temp_data[ "data" ])) {
|
||||
$temp_date_item = $temp_data[ "data" ];
|
||||
$new_user = $temp_date_item[ 0 ][ "new_user" ];
|
||||
$cancel_user = $temp_date_item[ 0 ][ "cancel_user" ];
|
||||
$net_growth_user = $temp_date_item[ 0 ][ "net_growth_user" ];
|
||||
$cumulate_user = $temp_date_item[ 0 ][ "cumulate_user" ];
|
||||
} else {
|
||||
$is_error = false;
|
||||
}
|
||||
}
|
||||
|
||||
$new_user_data[] = $new_user;
|
||||
$cancel_user_data[] = $cancel_user;
|
||||
$net_growth_user_data[] = $net_growth_user;
|
||||
$cumulate_user_data[] = $cumulate_user;
|
||||
}
|
||||
$return_data = array (
|
||||
"date" => $date_data[ "date_list" ],
|
||||
"data" => array (
|
||||
"new_user_data" => $new_user_data,
|
||||
"cancel_user_data" => $cancel_user_data,
|
||||
"net_growth_user_data" => $net_growth_user_data,
|
||||
"cumulate_user_data" => $cumulate_user_data
|
||||
)
|
||||
);
|
||||
return $this->success($return_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间间隔
|
||||
* @param $date_type
|
||||
* @return array
|
||||
*/
|
||||
public function getDaterange($date_type)
|
||||
{
|
||||
$yesterday = strtotime('-1 days');
|
||||
switch ( $date_type ) {
|
||||
case 'yesterday':
|
||||
$yesterday = strtotime('-1 days');
|
||||
$begin_time = $yesterday;
|
||||
$end_time = $yesterday;
|
||||
break;
|
||||
case 'week':
|
||||
$week = strtotime('-7 days');
|
||||
$begin_time = $week;
|
||||
$end_time = $yesterday;
|
||||
break;
|
||||
case 'month':
|
||||
$month = strtotime('-30 days');
|
||||
$begin_time = $month;
|
||||
$end_time = $yesterday;
|
||||
break;
|
||||
}
|
||||
$date_x = periodGroup($begin_time, $end_time, "Y-m-d");
|
||||
$begin_date = date("Ymd", $begin_time);
|
||||
$end_date = date("Ymd", $end_time);
|
||||
$data = array (
|
||||
"begin_date" => $begin_date,
|
||||
"end_date" => $end_date,
|
||||
"date_list" => $date_x,
|
||||
);
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
991
src/addon/wechat/model/Wechat.php
Normal file
@@ -0,0 +1,991 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\model;
|
||||
|
||||
use addon\wxoplatform\model\OpenPlatform;
|
||||
use addon\wxoplatform\model\Oplatform;
|
||||
use EasyWeChat\Factory;
|
||||
use EasyWeChat\Kernel\Messages\Article;
|
||||
use EasyWeChat\Kernel\Messages\Text;
|
||||
use EasyWeChat\Kernel\Messages\News;
|
||||
use EasyWeChat\Kernel\Messages\NewsItem;
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 微信公众号
|
||||
*/
|
||||
class Wechat extends BaseModel
|
||||
{
|
||||
|
||||
public $app;//微信公众对象
|
||||
private $site_id;//站点
|
||||
//公众号类型
|
||||
public $service_type = array (
|
||||
0 => "订阅号",
|
||||
1 => "由历史老帐号升级后的订阅号",
|
||||
2 => "服务号",
|
||||
);
|
||||
|
||||
//公众号认证类型
|
||||
public $verify_type = array (
|
||||
-1 => "未认证",
|
||||
0 => "微信认证",
|
||||
1 => "新浪微博认证",
|
||||
2 => "腾讯微博认证",
|
||||
3 => "已资质认证通过但还未通过名称认证",
|
||||
4 => "已资质认证通过、还未通过名称认证,但通过了新浪微博认证",
|
||||
5 => "已资质认证通过、还未通过名称认证,但通过了腾讯微博认证",
|
||||
);
|
||||
|
||||
//business_info 说明
|
||||
public $business_type = array (
|
||||
'open_store' => "是否开通微信门店功能",
|
||||
'open_scan' => "是否开通微信扫商品功能",
|
||||
'open_pay' => "是否开通微信支付功能",
|
||||
'open_card' => "是否开通微信卡券功能",
|
||||
'open_shake' => "是否开通微信摇一摇功能",
|
||||
);
|
||||
|
||||
public function __construct($site_id = 0)
|
||||
{
|
||||
$this->site_id = $site_id;
|
||||
// $response = $this->app->server->serve();
|
||||
// 将响应输出
|
||||
// $response->send();exit; // Laravel 里请使用:return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权实例
|
||||
*/
|
||||
public function app()
|
||||
{
|
||||
$config_model = new Config();
|
||||
$config_result = $config_model->getWechatConfig($this->site_id);
|
||||
$config = $config_result[ "data" ];
|
||||
if (!empty($config)) {
|
||||
$config_info = $config[ "value" ];
|
||||
}
|
||||
//授权方式 手动授权 或 自动授权(通过开放平台)
|
||||
$auth_type = $config_info[ "is_authopen" ] ?? '';
|
||||
|
||||
if ($auth_type == "1") {
|
||||
$oplatform_model = new Oplatform();
|
||||
$config_info[ 'type' ] = 'wechat';
|
||||
|
||||
$this->app = $oplatform_model->app($config_info);
|
||||
} else {
|
||||
$config = [
|
||||
'app_id' => $config_info[ "appid" ] ?? '',
|
||||
'secret' => $config_info[ "appsecret" ] ?? '',
|
||||
'token' => $config_info[ "token" ] ?? '', // Token
|
||||
'aes_key' => $config_info[ 'encodingaeskey' ] ?? '', // EncodingAESKey,兼容与安全模式下请一定要填写!!!
|
||||
// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
|
||||
'response_type' => 'array',
|
||||
/**
|
||||
* 日志配置
|
||||
*
|
||||
* level: 日志级别, 可选为:debug/info/notice/warning/error/critical/alert/emergency
|
||||
* permission:日志文件权限(可选),默认为null(若为null值,monolog会取0644)
|
||||
* file:日志文件位置(绝对路径!!!),要求可写权限
|
||||
*/
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'permission' => 0777,
|
||||
'file' => 'runtime/log/wechat/easywechat.logs',
|
||||
],
|
||||
];
|
||||
if (empty($config[ 'app_id' ]) || empty($config[ 'secret' ])) {
|
||||
throw new \Exception('商家公众号配置有误,请联系平台管理员');
|
||||
}
|
||||
|
||||
$this->app = Factory::officialAccount($config);
|
||||
}
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建微信菜单
|
||||
* @param $buttons
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function menu($buttons)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->menu->create($buttons);
|
||||
if ($result[ 'errcode' ] == 0) {
|
||||
return $this->success();
|
||||
} else {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉取粉丝列表
|
||||
* @param null $nextOpenId
|
||||
* @return array
|
||||
*/
|
||||
public function user($nextOpenId = null)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->user->list($nextOpenId); // $nextOpenId 可选
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询多个粉丝信息
|
||||
* @param $user_list
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function selectUser($user_list)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->user->select($user_list); // $nextOpenId 可选
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到粉丝信息
|
||||
* @param $openId
|
||||
* @return array
|
||||
*/
|
||||
public function getUser($openId)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->user->get($openId); // $nextOpenId 可选
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Code 获取用户 session 信息
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function authCodeToOpenid($params = [])
|
||||
{
|
||||
try {
|
||||
if (empty($_REQUEST[ "code" ])) {
|
||||
$auth_result = $this->getAuthCode(request()->url(true));
|
||||
if ($auth_result[ "code" ] >= 0) {
|
||||
header("Location: " . $auth_result[ "data" ]);
|
||||
} else {
|
||||
return $auth_result;
|
||||
}
|
||||
|
||||
}
|
||||
$user = $this->app()->oauth->user();//获取授权用户
|
||||
$data = [
|
||||
'openid' => $user->getId(),
|
||||
'userinfo' => [
|
||||
'avatarUrl' => $user->getAvatar(),
|
||||
'nickName' => $user->getNickname()
|
||||
]
|
||||
];
|
||||
return $this->success($data);
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'body')) {
|
||||
return $this->handleError($e->body[ 'errcode' ], $e->body[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code获取授权信息
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthByCode($params)
|
||||
{
|
||||
try {
|
||||
$user = $this->app()->oauth->userByCode($params[ 'code' ]);//获取授权用户
|
||||
$original = $user->getOriginal();
|
||||
$data = [
|
||||
'openid' => $original[ 'openid' ],
|
||||
'userinfo' => [
|
||||
'avatarUrl' => $original[ 'headimgurl' ] ?? '',
|
||||
'nickName' => $original[ 'nickname' ] ?? ''
|
||||
]
|
||||
];
|
||||
if (isset($original[ 'unionid' ])) {
|
||||
$data[ 'unionid' ] = $original[ 'unionid' ];
|
||||
}
|
||||
return $this->success($data);
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'body')) {
|
||||
return $this->handleError($e->body[ 'errcode' ], $e->body[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号网页授权code
|
||||
* @param $redirect
|
||||
* @param string $scopes snsapi_base:静默授权 snsapi_userinfo:用户授权
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthCode($redirect, $scopes = 'snsapi_base')
|
||||
{
|
||||
try {
|
||||
$response = $this->app()->oauth->scopes([ $scopes ])->redirect($redirect);
|
||||
return $this->success($response->getTargetUrl());
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取永久二维码
|
||||
* @param $uid
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getQrcode($uid)
|
||||
{
|
||||
$result = $this->app()->qrcode->forever($uid);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
$url = $this->app()->qrcode->url($result[ 'data' ][ 'ticket' ]);
|
||||
if (isset($url[ 'errcode' ]) && $url[ 'errcode' ] != 0) {
|
||||
return $this->error($url, $url[ "errmsg" ]);
|
||||
}
|
||||
|
||||
return $this->success($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取临时二维码
|
||||
* @param $scene
|
||||
* @param $seconds
|
||||
* @return array
|
||||
*/
|
||||
public function getTempQrcode($scene, $seconds)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->qrcode->temporary($scene, $seconds);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
$url = $this->app()->qrcode->url($result[ 'ticket' ]);
|
||||
if (isset($url[ 'errcode' ]) && $url[ 'errcode' ] != 0) {
|
||||
return $this->handleError($url[ 'errcode' ], $url[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($url);
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'body')) {
|
||||
return $this->handleError($e->body[ 'errcode' ], $e->body[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取jssdk配置
|
||||
* @param $url
|
||||
* @return array
|
||||
*/
|
||||
public function getJssdkConfig($url)
|
||||
{
|
||||
try {
|
||||
$this->app()->jssdk->setUrl($url);
|
||||
$res = $this->app->jssdk->buildConfig([], false, false, false);
|
||||
return $this->success($res);
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'body')) {
|
||||
return $this->handleError($e->body[ 'errcode' ], $e->body[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************** 数据统计与分析start *******************************************************************/
|
||||
|
||||
|
||||
/********************************************************** 数据统计与分析end *******************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************微信接口连接开始*****************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************微信接口连接结束*****************************************************/
|
||||
|
||||
|
||||
/***************************************************************** 微信公众号 统计 start *****************************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************** 微信公众号 统计 end *****************************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************** 数据统计与分析***********************************************************/
|
||||
|
||||
/**
|
||||
* 获取用户增减数据, 最大时间跨度:7;
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function userSummary($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->data_cube->userSummary($from, $to);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result[ "list" ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取累计用户数据, 最大时间跨度:7
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function userCumulate($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->data_cube->userCumulate($from, $to);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result[ "list" ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口分析分时数据, 最大时间跨度:1;
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function interfaceSummaryHourly($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->data_cube->interfaceSummaryHourly($from, $to);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result[ "list" ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口分析数据, 最大时间跨度:30;
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function interfaceSummary($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app()->data_cube->interfaceSummary($from, $to);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result[ "list" ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
/****************************************************************************** 数据统计与分析***********************************************************/
|
||||
|
||||
/****************************************************************************** 素材start***********************************************************/
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
* @param $path
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
function uploadImage($path)
|
||||
{
|
||||
$result = $this->app()->material->uploadImage($path);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传语音
|
||||
* @param $path
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
function uploadVoice($path)
|
||||
{
|
||||
$result = $this->app()->material->uploadVoice($path);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传视频
|
||||
* @param $path
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
function uploadVideo($path)
|
||||
{
|
||||
$result = $this->app()->material->uploadVideo($path);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传缩略图
|
||||
* @param $path
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
function uploadThumb($path)
|
||||
{
|
||||
$result = $this->app()->material->uploadThumb($path);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图文
|
||||
* @param $data
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function uploadArticle($data)
|
||||
{
|
||||
$article_data = [];
|
||||
foreach ($data as $k => $v) {
|
||||
$article_data[] = new Article($v);
|
||||
}
|
||||
$result = $this->app()->material->uploadArticle($article_data);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改图文
|
||||
* @param $mediaId
|
||||
* @param string $data 文章详情
|
||||
* @param int $index 多图文中的第几篇
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function updateArticle($mediaId, $data, $index = 0)
|
||||
{
|
||||
$result = $this->app()->material->updateArticle($mediaId, $data, $index);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图文消息图片
|
||||
* @param $path
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
*/
|
||||
public function uploadArticleImage($path)
|
||||
{
|
||||
$result = $this->app()->material->uploadArticleImage($path);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取永久素材
|
||||
* @param $mediaId
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function getMaterial($mediaId)
|
||||
{
|
||||
$result = $this->app()->material->get($mediaId);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除永久素材
|
||||
* @param $mediaId
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function deleteMaterial($mediaId)
|
||||
{
|
||||
$result = $this->app()->material->delete($mediaId);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/****************************************************************************** 素材end***********************************************************/
|
||||
|
||||
|
||||
/****************************************************************************** 回复start***********************************************************/
|
||||
|
||||
/**
|
||||
* 用户事件
|
||||
* @return array
|
||||
*/
|
||||
public function relateWeixin()
|
||||
{
|
||||
$server = $this->app->server;
|
||||
$message = $server->getMessage();
|
||||
if (isset($message[ 'MsgType' ])) {
|
||||
switch ( $message[ 'MsgType' ] ) {
|
||||
case 'event':
|
||||
$this->app->server->push(function($res) {
|
||||
if ($res[ 'Event' ] == 'subscribe') {
|
||||
// 关注公众号
|
||||
$Userstr = $this->getUser($res[ 'FromUserName' ]);
|
||||
//获取用户信息
|
||||
$wechat_user = $this->app->user->get($res[ 'FromUserName' ]);
|
||||
if (preg_match("/^qrscene_/", $res[ 'EventKey' ])) {
|
||||
$source_uid = substr($res[ 'EventKey' ], 8);
|
||||
$_SESSION[ 'source_uid' ] = $source_uid;
|
||||
} elseif (!empty($_SESSION[ 'source_uid' ])) {
|
||||
$source_uid = $_SESSION[ 'source_uid' ];
|
||||
} else {
|
||||
$source_uid = 0;
|
||||
}
|
||||
|
||||
if (preg_match("/^qrscene_key_/", $res[ 'EventKey' ])) {
|
||||
//新增2021.06.02
|
||||
$key = substr($res[ 'EventKey' ], 12);
|
||||
$cache = Cache::get('wechat_' . $key);
|
||||
if (!empty($cache)) {
|
||||
Cache::set('wechat_' . $key, $wechat_user);
|
||||
}
|
||||
}
|
||||
if (preg_match("/^verify_/", $res[ 'EventKey' ])) {
|
||||
$cache = Cache::get($res[ 'EventKey' ]);
|
||||
if (empty($cache)) {
|
||||
Cache::set($res[ 'EventKey' ], $wechat_user, 7200);
|
||||
}
|
||||
}
|
||||
|
||||
$nickname_decode = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $wechat_user[ 'nickname' ]);
|
||||
$headimgurl = $wechat_user[ 'headimgurl' ];
|
||||
$sex = $wechat_user[ 'sex' ];
|
||||
$language = $wechat_user[ 'language' ];
|
||||
$country = $wechat_user[ 'country' ];
|
||||
$province = $wechat_user[ 'province' ];
|
||||
$city = $wechat_user[ 'city' ];
|
||||
$district = "无";
|
||||
$openid = $wechat_user[ 'openid' ];
|
||||
$nickname = $wechat_user[ 'nickname' ];
|
||||
if (!empty($wechat_user[ 'unionid' ])) {
|
||||
$unionid = $wechat_user[ 'unionid' ];
|
||||
} else {
|
||||
$unionid = '';
|
||||
}
|
||||
$memo = $wechat_user[ 'remark' ];
|
||||
$data = array (
|
||||
'site_id' => $this->site_id,
|
||||
'nickname' => $nickname,
|
||||
'nickname_decode' => $nickname_decode,
|
||||
'headimgurl' => $headimgurl,
|
||||
'sex' => $sex,
|
||||
'language' => $language,
|
||||
'country' => $country,
|
||||
'province' => $province,
|
||||
'city' => $city,
|
||||
'district' => $district,
|
||||
'openid' => $openid,
|
||||
'unionid' => $unionid,
|
||||
'groupid' => '',
|
||||
'is_subscribe' => 1,
|
||||
'remark' => $memo,
|
||||
'subscribe_time' => $wechat_user[ 'subscribe_time' ] ?? 0,
|
||||
'subscribe_scene' => $wechat_user[ 'subscribe_scene' ] ?? 0,
|
||||
'unsubscribe_time' => $wechat_user[ 'unsubscribe_time' ] ?? 0,
|
||||
'update_date' => time()
|
||||
);
|
||||
|
||||
$fans = new Fans();
|
||||
$fans_info = $fans->getFansInfo([ [ 'openid', '=', $openid ], [ 'site_id', '=', $this->site_id ] ]);
|
||||
if (empty($fans_info[ 'data' ])) {
|
||||
$fans->addFans($data);
|
||||
} else {
|
||||
$fans->editFans($data, [ [ 'openid', '=', $openid ], [ 'site_id', '=', $this->site_id ] ]);
|
||||
}
|
||||
|
||||
//获取关注发送消息内容
|
||||
$replay = new Replay();
|
||||
$replay_content = $replay->getWechatFollowReplay($this->site_id);
|
||||
return new Text($replay_content[ 'data' ]);
|
||||
} else if ($res[ 'Event' ] == 'unsubscribe') {
|
||||
//取消关注
|
||||
$fans = new Fans();
|
||||
$openid = $res[ 'FromUserName' ];
|
||||
$fans->unfollowWechat((string) $openid);
|
||||
} else if ($res[ 'Event' ] == 'unsubscribe') {
|
||||
//取消关注
|
||||
$fans = new Fans();
|
||||
$openid = $res[ 'FromUserName' ];
|
||||
$fans->unfollowWechat((string) $openid);
|
||||
} else if ($res[ 'Event' ] == 'SCAN') {
|
||||
// SCAN事件 - 用户已关注时的事件推送 - 扫描带参数二维码事件
|
||||
$openid = $res[ 'FromUserName' ];
|
||||
$data = $res[ 'EventKey' ];
|
||||
|
||||
if (preg_match("/^key_/", $data)) {
|
||||
$key = substr($data, 4);
|
||||
$cache = Cache::get('wechat_' . $key);
|
||||
if (!empty($cache)) {
|
||||
$wechat_user = $this->app->user->get($res[ 'FromUserName' ]);
|
||||
Cache::set('wechat_' . $key, $wechat_user);
|
||||
}
|
||||
}
|
||||
if (preg_match("/^verify_/", $res[ 'EventKey' ])) {
|
||||
$cache = Cache::get($res[ 'EventKey' ]);
|
||||
if (empty($cache)) {
|
||||
$wechat_user = $this->app->user->get($res[ 'FromUserName' ]);
|
||||
Cache::set($res[ 'EventKey' ], $wechat_user, 7200);
|
||||
}
|
||||
}
|
||||
return new Text('扫码成功。');
|
||||
} else if ($res[ 'Event' ] == 'CLICK') {
|
||||
// CLICK事件 - 自定义菜单事件
|
||||
$openid = $res[ 'FromUserName' ];
|
||||
$data = $res[ 'EventKey' ];
|
||||
|
||||
if (strpos($res[ 'EventKey' ], 'MATERIAL_GRAPHIC_MESSAGE_') === 0) {
|
||||
$material_id = substr($res[ 'EventKey' ], 25);
|
||||
$material_type = 1;
|
||||
} else if (strpos($res[ 'EventKey' ], 'MATERIAL_PICTURE_') === 0) {
|
||||
$material_id = substr($res[ 'EventKey' ], 17);
|
||||
$material_type = 2;
|
||||
} else if (strpos($res[ 'EventKey' ], 'MATERIAL_TEXT_MESSAGE_') === 0) {
|
||||
$material_id = substr($res[ 'EventKey' ], 22);
|
||||
$material_type = 5;
|
||||
}
|
||||
$material = new Material();
|
||||
$media_info = $material->getMaterialInfo([ [ 'id', '=', $material_id, 'type', '=', $material_type ] ]);
|
||||
$media_info = $media_info[ 'data' ];
|
||||
if ($media_info) {
|
||||
$value = json_decode($media_info[ 'value' ], true);
|
||||
if ($material_type == 1) {
|
||||
//图文
|
||||
$url = __ROOT__;
|
||||
$url = $url . '/index.php/wechat/api/auth/wechatArticle?id=' . $media_info[ 'id' ];
|
||||
$items = [
|
||||
new NewsItem([
|
||||
'title' => $value[ 0 ][ 'title' ],
|
||||
'description' => strip_tags($value[ 0 ][ 'content' ]),
|
||||
'url' => $url,
|
||||
'image' => $value[ 0 ][ 'cover' ][ 'path' ],
|
||||
]),
|
||||
];
|
||||
return new News($items);
|
||||
|
||||
} else if ($material_type == 2) {
|
||||
//图片
|
||||
|
||||
} else if ($material_type == 5) {
|
||||
//文字
|
||||
return new Text($value[ 'content' ]);
|
||||
}
|
||||
}
|
||||
} else if ($res[ 'Event' ] == 'weapp_audit_success') {
|
||||
// 小程序审核通过 自动发布
|
||||
if (addon_is_exit('wxoplatform')) {
|
||||
$weapp_original = $res[ 'ToUserName' ];
|
||||
$site_info = model('config')->getInfo([ [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_CONFIG' ], [ 'value', 'like', '%is_authopen%' ], [ 'value', 'like', '%' . $weapp_original . '%' ] ], 'site_id');
|
||||
if (!empty($site_info)) {
|
||||
// 先将审核中的变更为审核成功
|
||||
model('weapp_audit_record')->update([ 'status' => 1, 'audit_time' => time() ], [ [ 'status', '=', 0 ], [ 'site_id', '=', $site_info[ 'site_id' ] ] ]);
|
||||
$platform = new OpenPlatform($site_info[ 'site_id' ]);
|
||||
$result = $platform->release();
|
||||
if ($result[ 'code' ] >= 0) {
|
||||
model('weapp_audit_record')->update([ 'status' => 5, 'release_time' => time() ], [ [ 'status', '=', 1 ], [ 'site_id', '=', $site_info[ 'site_id' ] ] ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$response = $this->app->server->serve();
|
||||
// 将响应输出
|
||||
return $response->send();
|
||||
|
||||
break;
|
||||
case 'text':
|
||||
$this->app->server->push(function($res) {
|
||||
$replay = new Replay();
|
||||
$rule = $replay->getSiteWechatKeywordsReplay($res[ 'Content' ], $this->site_id);
|
||||
if ($rule[ 'data' ]) {
|
||||
if ($rule[ 'data' ][ 'type' ] == 'text') {
|
||||
//文字
|
||||
return new Text($rule[ 'data' ][ 'reply_content' ]);
|
||||
} else {
|
||||
|
||||
$material = new Material();
|
||||
$media_info = $material->getMaterialInfo([ [ 'media_id', '=', $rule[ 'data' ][ 'media_id' ] ] ]);
|
||||
$media_info = $media_info[ 'data' ];
|
||||
|
||||
if ($media_info) {
|
||||
$material_type = $media_info[ 'type' ];
|
||||
$value = json_decode($media_info[ 'value' ], true);
|
||||
|
||||
if ($material_type == 1) {
|
||||
$url = __ROOT__;
|
||||
$url = $url . '/index.php/wechat/api/auth/wechatArticle?id=' . $media_info[ 'id' ];
|
||||
$items = [
|
||||
new NewsItem([
|
||||
'title' => $value[ 0 ][ 'title' ],
|
||||
'description' => strip_tags($value[ 0 ][ 'content' ]),
|
||||
'url' => $url,
|
||||
'image' => $value[ 0 ][ 'cover' ][ 'path' ],
|
||||
]),
|
||||
];
|
||||
return new News($items);
|
||||
} else if ($material_type == 2) {
|
||||
//图片
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
$response = $this->app->server->serve();
|
||||
// 将响应输出
|
||||
return $response->send();
|
||||
|
||||
break;
|
||||
case 'image':
|
||||
// return '收到图片消息';
|
||||
break;
|
||||
case 'voice':
|
||||
// return '收到语音消息';
|
||||
break;
|
||||
case 'video':
|
||||
// return '收到视频消息';
|
||||
break;
|
||||
case 'location':
|
||||
//return '收到坐标消息';
|
||||
break;
|
||||
case 'link':
|
||||
//return '收到链接消息';
|
||||
break;
|
||||
case 'file':
|
||||
///return '收到文件消息';
|
||||
// ... 其它消息
|
||||
default:
|
||||
//return '收到其它消息';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$response = $this->app->server->serve();
|
||||
return $response->send();
|
||||
}
|
||||
|
||||
/****************************************************************************** 回复end***********************************************************/
|
||||
|
||||
/****************************************************************************** 模板消息start ***********************************************************/
|
||||
|
||||
/**
|
||||
* 添加模板消息
|
||||
* @param $shortId
|
||||
* @param $keyword_name_list
|
||||
* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function getTemplateId($shortId, $keyword_name_list)
|
||||
{
|
||||
try {
|
||||
$res = $this->app()->template_message->addTemplate($shortId, $keyword_name_list);
|
||||
if (isset($res[ 'errcode' ]) && $res[ 'errcode' ] == 0) return $res;
|
||||
$errormsg = [
|
||||
'45026' => '模板数量超出限制'
|
||||
];
|
||||
return [ 'errcode' => $res[ 'errcode' ], 'errmsg' => $errormsg[ $res[ 'errcode' ] ] ?? $res[ 'errmsg' ] ];
|
||||
} catch (\Exception $e) {
|
||||
return [ 'errcode' => -1, 'errmsg' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板消息
|
||||
* @param $templateId
|
||||
* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function deleteTemplate($templateId)
|
||||
{
|
||||
try {
|
||||
$res = $this->app()->template_message->deletePrivateTemplate($templateId);
|
||||
if (isset($res[ 'errcode' ]) && $res[ 'errcode' ] == 0) return $res;
|
||||
$errormsg = [
|
||||
'45026' => '模板数量超出限制'
|
||||
];
|
||||
return [ 'errcode' => $res[ 'errcode' ], 'errmsg' => $errormsg[ $res[ 'errcode' ] ] ?? $res[ 'errmsg' ] ];
|
||||
} catch (\Exception $e) {
|
||||
return [ 'errcode' => -1, 'errmsg' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function sendTemplateMessage(array $param)
|
||||
{
|
||||
$result = $this->app()->template_message->send([
|
||||
'touser' => $param[ 'openid' ], // openid
|
||||
'template_id' => $param[ 'template_id' ],// 模板id
|
||||
'url' => $param[ 'url' ],// 跳转链接
|
||||
'miniprogram' => $param[ 'miniprogram' ], // 跳转小程序 ['appid' => 'xxxxxxx','page' => 'pages/xxx',]
|
||||
'data' => $param[ 'data' ] // 模板变量
|
||||
]);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/****************************************************************************** 模板消息end***********************************************************/
|
||||
|
||||
|
||||
/******************************************************************************* 开放平台start *************************************************************************/
|
||||
/**
|
||||
* 将公众号或小程序绑定到指定开放平台帐号下
|
||||
*/
|
||||
public function bindTo($open_appid)
|
||||
{
|
||||
try {
|
||||
$res = $this->app()->account->bindTo($open_appid);
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return [ 'errcode' => -1, 'errmsg' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将公众号/小程序从开放平台帐号下解绑
|
||||
*/
|
||||
public function unbindFrom($open_appid)
|
||||
{
|
||||
try {
|
||||
$res = $this->app()->account->unbindFrom($open_appid);
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return [ 'errcode' => -1, 'errmsg' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公众号/小程序所绑定的开放平台帐号
|
||||
*/
|
||||
public function getBinding()
|
||||
{
|
||||
try {
|
||||
$res = $this->app()->account->getBinding();
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return [ 'errcode' => -1, 'errmsg' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关注二维码
|
||||
* @param $fans_id
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getFollowQrcode($fans_id)
|
||||
{
|
||||
$cache = Cache::get('wechat_follow_qrcode_' . $fans_id);
|
||||
if ($cache) return $cache;
|
||||
|
||||
$res = $this->getTempQrcode('follow_key_' . $fans_id, 1728000);
|
||||
if ($res[ 'code' ] != 0) return $res;
|
||||
|
||||
$data = $this->success([
|
||||
'qrcode' => $res[ 'data' ],
|
||||
'site_id' => $this->site_id,
|
||||
'fans_id' => $fans_id
|
||||
]);
|
||||
Cache::set('wechat_follow_qrcode_' . $fans_id, $data, 1728000);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/******************************************************************************* 开放平台end *************************************************************************/
|
||||
|
||||
/**
|
||||
* 处理错误信息
|
||||
* @param $errcode
|
||||
* @param string $message
|
||||
* @return array
|
||||
*/
|
||||
public function handleError($errcode, $message = '')
|
||||
{
|
||||
$error = require 'addon/wechat/config/wechat_error.php';
|
||||
return $this->error([], $error[ $errcode ] ?? $message);
|
||||
}
|
||||
}
|
||||
248
src/addon/wechat/model/WechatMessage.php
Normal file
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
namespace addon\system\Wechat\common\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信公众号模板消息配置
|
||||
*/
|
||||
class WechatMessage extends BaseModel
|
||||
{
|
||||
|
||||
public $site_model;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->site_model = new Site();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
* @param $data
|
||||
*/
|
||||
public function send($param)
|
||||
{
|
||||
$message_model = new Wechat();
|
||||
$config_result = $message_model->getWechatConfigInfo($param[ "site_id" ]);
|
||||
$config_data = $config_result[ "data" ][ "value" ];
|
||||
$wechat_api = new Weixin('public');
|
||||
$wechat_api->initWechatPublicAccount($config_data[ "appid" ], $config_data[ "appsecret" ]);
|
||||
$data = array (
|
||||
"open_id" => $param[ "open_id" ],
|
||||
"template_id" => $param[ "template_id" ],
|
||||
"url" => $param[ "url" ],
|
||||
"first" => $param[ "first" ],
|
||||
"remark" => $param[ "remark" ],
|
||||
"keyword" => $param[ "keyword" ]
|
||||
);
|
||||
$res = $wechat_api->tmplmsgSend($data);
|
||||
if ($res->errcode == 0) {
|
||||
return $this->success($res);
|
||||
} else {
|
||||
return $this->error($res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有当前绑定微信公众号的模板消息
|
||||
* @param $param
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWechatTemplateList($param)
|
||||
{
|
||||
$config_result = $this->getWechatConfigInfo($param[ "site_id" ]);
|
||||
$config_data = $config_result[ "data" ][ "value" ];
|
||||
$wechat_api = new Weixin('public');
|
||||
$wechat_api->initWechatPublicAccount($config_data[ "appid" ], $config_data[ "appsecret" ]);
|
||||
|
||||
$res = $wechat_api->getWechatTemplateList();//获取微信消息模板
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信模板消息id
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function getMessageTemplateId($param)
|
||||
{
|
||||
$wechat_model = new Wechat();
|
||||
$config_result = $wechat_model->getWechatConfigInfo($param[ "site_id" ]);
|
||||
$config_data = $config_result[ "data" ][ "value" ];
|
||||
$wechat_api = new Weixin('public');
|
||||
$wechat_api->initWechatPublicAccount($config_data[ "appid" ], $config_data[ "appsecret" ]);
|
||||
$keyword = $param[ "keyword" ];//消息管理关键标识
|
||||
|
||||
//微信消息模板
|
||||
$message_model = new Message();
|
||||
$message_info_result = $message_model->getSiteWechatMessageInfo([ "keyword" => $keyword, "site_id" => $param[ "site_id" ] ]);
|
||||
$message_info = $message_info_result[ "data" ];
|
||||
if (empty($message_info))
|
||||
return $this->error([], "当前微信消息模板不存在!");
|
||||
|
||||
$message_type_model = new MessageModel();
|
||||
$message_type_info_result = $message_type_model->getMessageTypeInfo([ "keyword" => $keyword ]);
|
||||
$message_type_info = $message_type_info_result[ "data" ];
|
||||
if (empty($message_type_info[ "wechat_json" ]))
|
||||
return $this->error([], "当前微信消息模板不存在!");
|
||||
|
||||
$template_res = $wechat_api->getWechatTemplateId($message_type_info[ "wechat_json" ][ "template_no" ]);
|
||||
if ($template_res->errcode == 0) {
|
||||
//设置模板编号
|
||||
$res = $message_model->editSiteWechatMessage([ "template_id" => $template_res->template_id ], [ "keyword" => $keyword, "site_id" => $param[ "site_id" ] ]);
|
||||
return $res;
|
||||
} else {
|
||||
return $this->error($template_res, $template_res->errmsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置模板消息
|
||||
* @param $param
|
||||
* @return mixed
|
||||
*/
|
||||
public function resetMessage($param)
|
||||
{
|
||||
$wechat_model = new Wechat();
|
||||
$config_result = $wechat_model->getWechatConfigInfo($param[ "site_id" ]);
|
||||
$config_data = $config_result[ "data" ][ "value" ];
|
||||
$wechat_api = new Weixin('public');
|
||||
$wechat_api->initWechatPublicAccount($config_data[ "appid" ], $config_data[ "appsecret" ]);
|
||||
|
||||
$res = $wechat_api->getWechatTemplateList();//获取微信消息模板
|
||||
|
||||
//申請微信模板消息
|
||||
$message_model = new Message();
|
||||
$list = $message_model->getSiteWechatMessageList([ "site_id" => $param[ "site_id" ] ]);
|
||||
$res = error();
|
||||
if (!empty($list[ "data" ])) {
|
||||
foreach ($list[ "data" ] as $k => $v) {
|
||||
if (!empty($v[ "wechat_json" ])) {
|
||||
$temp_json = json_decode($v[ "wechat_json" ], true);
|
||||
if (!empty($temp_json[ "template_no" ])) {
|
||||
$res = $wechat_api->getWechatTemplateId($temp_json[ "template_no" ]);
|
||||
if ($res->errcode == 0) {
|
||||
//设置模板编号
|
||||
$message_model->editSiteWechatMessage([ "template_id" => $res->template_id ], [ "keyword" => $v[ "keyword" ], "site_id" => $param[ "site_id" ] ]);
|
||||
} else {
|
||||
return $this->error($res, $res->errmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function sendMessage($param)
|
||||
{
|
||||
$message_model = new SiteMessage();
|
||||
$type_info = $message_model->getSiteMessageTypeViewInfo([ "keyword" => $param[ "keyword" ], "site_id" => $param[ "site_id" ] ]);
|
||||
if (( ( !empty($param[ "support_type" ]) && stripos($param[ "support_type" ], "Wechat") !== false ) || empty($param[ "support_type" ]) ) && stripos($type_info[ "data" ][ "port" ], "Wechat") !== false && $type_info[ "data" ][ "wechat_is_open" ] == 1) {
|
||||
$message_model = new Message();
|
||||
$message_info = $message_model->getSiteWechatMessageInfo([ "keyword" => $param[ "keyword" ], "site_id" => $param[ "site_id" ] ]);
|
||||
if (empty($message_info[ "data" ][ "template_id" ]))
|
||||
return $this->error();
|
||||
|
||||
if (empty($message_info[ "data" ][ "headtext" ]))
|
||||
return $this->error();
|
||||
|
||||
if (empty($message_info[ "data" ][ "bottomtext" ]))
|
||||
return $this->error();
|
||||
|
||||
//模板消息字段
|
||||
if (empty($param[ "keyword_json" ]))
|
||||
return $this->error();
|
||||
|
||||
//发送的接收用户
|
||||
if (empty($param[ "open_id" ]))
|
||||
return $this->error();
|
||||
|
||||
$url = empty($param[ "url" ]) ? '' : $param[ "url" ];
|
||||
$data = array (
|
||||
"open_id" => $param[ "open_id" ],
|
||||
"template_id" => $message_info[ "data" ][ "template_id" ],
|
||||
"url" => $url,
|
||||
"first" => $message_info[ "data" ][ "headtext" ],
|
||||
"remark" => $message_info[ "data" ][ "bottomtext" ],
|
||||
"keyword" => $param[ "keyword_json" ],
|
||||
"site_id" => $param[ "site_id" ],
|
||||
);
|
||||
//添加发送记录(未即时发送的记录 发送状态为为发送)
|
||||
$message_records_model = new MessageRecords();
|
||||
$records_data = array (
|
||||
"site_id" => $param[ "site_id" ],
|
||||
"open_id" => $param[ "open_id" ],
|
||||
"keyword_json" => json_encode($param[ "keyword_json" ]),
|
||||
"keyword" => $param[ "keyword" ],
|
||||
"url" => $url,
|
||||
"create_time" => time()
|
||||
);
|
||||
//是否即时发送
|
||||
if ($type_info[ "data" ][ "is_instant" ] == 1) {
|
||||
$result = $this->send($data);
|
||||
if ($result[ "code" ] == 0) {
|
||||
$status = 1;
|
||||
$records_data[ "send_time" ] = time();
|
||||
} else {
|
||||
$status = -1;
|
||||
$records_data[ "result" ] = $result[ "data" ]->errmsg;
|
||||
}
|
||||
} else {
|
||||
$status = 0;
|
||||
}
|
||||
$records_data[ "status" ] = $status;
|
||||
$result = $message_records_model->addWechatMessageRecords($records_data);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮箱消息延时发送
|
||||
* @param array $param
|
||||
*/
|
||||
public function cronMessageSend($param = [])
|
||||
{
|
||||
$message_records_model = new MessageRecords();
|
||||
$message_records_list = $message_records_model->getWechatMessageRecordsList([ "status" => 0 ]);
|
||||
if (!empty($message_records_list[ "data" ])) {
|
||||
foreach ($message_records_list[ "data" ] as $k => $v) {
|
||||
$message_model = new Message();
|
||||
$message_info = $message_model->getSiteWechatMessageInfo([ "keyword" => $param[ "keyword" ], "site_id" => $param[ "site_id" ] ]);
|
||||
|
||||
$params = array (
|
||||
"site_id" => $v[ "site_id" ],
|
||||
"open_id" => $v[ "open_id" ],
|
||||
"keyword" => json_decode($v[ "keyword_json" ], true),
|
||||
"url" => $v[ "url" ],
|
||||
"template_id" => $message_info[ "data" ][ "template_id" ],
|
||||
"first" => $message_info[ "data" ][ "headtext" ],
|
||||
"remark" => $message_info[ "data" ][ "bottomtext" ],
|
||||
);
|
||||
$result = $this->send($params);
|
||||
|
||||
$data = array ();
|
||||
$condition = array (
|
||||
"id" => $v[ "id" ],
|
||||
"site_id" => $v[ "site_id" ]
|
||||
);
|
||||
if ($result[ "code" ] == 0) {
|
||||
$data[ "send_time" ] = time();
|
||||
$data[ "status" ] = 1;
|
||||
} else {
|
||||
$data[ "status" ] = -1;
|
||||
$data[ "result" ] = $result[ "message" ];
|
||||
}
|
||||
$message_records_model->editWechatMessageRecords($data, $condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/addon/wechat/shop/controller/BaseWechat.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use app\shop\controller\BaseShop;
|
||||
use think\App;
|
||||
|
||||
/**
|
||||
* 微信控制器基类
|
||||
*/
|
||||
class BaseWechat extends BaseShop
|
||||
{
|
||||
|
||||
public function __construct(App $app = null)
|
||||
{
|
||||
$this->replace = [
|
||||
'WECHAT_CSS' => __ROOT__ . '/addon/wechat/shop/view/public/css',
|
||||
'WECHAT_JS' => __ROOT__ . '/addon/wechat/shop/view/public/js',
|
||||
'WECHAT_IMG' => __ROOT__ . '/addon/wechat/shop/view/public/img',
|
||||
];
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
}
|
||||
297
src/addon/wechat/shop/controller/Fans.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Wechat as WechatModel;
|
||||
use addon\wechat\model\Fans as FansModel;
|
||||
|
||||
/**
|
||||
* 微信粉丝控制器
|
||||
*/
|
||||
class Fans extends BaseWechat
|
||||
{
|
||||
|
||||
/**
|
||||
* 粉丝列表
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
$fans_model = new FansModel();
|
||||
if (request()->isJson()) {
|
||||
$page = input('page', 1);
|
||||
$limit = input('page_size', PAGE_LIST_ROWS);
|
||||
$is_subscribe = input('is_subscribe', '');//关注
|
||||
$nickname = input('nickname', '');//粉丝名称
|
||||
$start_time = input('start_time', '');
|
||||
$end_time = input('end_time', '');
|
||||
$condition[] = [ 'site_id', '=', $this->site_id ];
|
||||
if ($is_subscribe !== '') {
|
||||
$condition[] = [ 'is_subscribe', "=", $is_subscribe ];
|
||||
}
|
||||
if ($nickname != '') {
|
||||
$condition[] = [ 'nickname', 'like', '%' . $nickname . '%' ];
|
||||
}
|
||||
if (!empty($start_time) && empty($end_time)) {
|
||||
$condition[] = [ "subscribe_time", ">=", date_to_time($start_time) ];
|
||||
} elseif (empty($start_time) && !empty($end_time)) {
|
||||
$condition[] = [ "subscribe_time", "<=", date_to_time($end_time) ];
|
||||
} elseif (!empty($start_time) && !empty($end_time)) {
|
||||
$condition[] = [ 'subscribe_time', 'between', [ date_to_time($start_time), date_to_time($end_time) ] ];
|
||||
}
|
||||
$fans_list = $fans_model->getFansPageList($condition, $page, $limit);
|
||||
return $fans_list;
|
||||
}
|
||||
|
||||
$tag_list = $fans_model->getFansTagList();
|
||||
$this->assign('tag_list', $tag_list[ 'data' ]);
|
||||
|
||||
return $this->fetch('fans/lists');
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新粉丝信息
|
||||
*/
|
||||
public function syncWechatFans()
|
||||
{
|
||||
$page_index = input('page', 0);
|
||||
$page_size = input('limit', PAGE_LIST_ROWS);
|
||||
$wechat_model = new WechatModel($this->site_id);
|
||||
if ($page_index == 0) {
|
||||
//建立连接,同时获取所有用户openid 拉去粉丝信息列表(一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。)
|
||||
$openid_list = [];
|
||||
$is_continue = true;
|
||||
$next_openid = null;
|
||||
do {
|
||||
$item_result = $wechat_model->user($next_openid);
|
||||
|
||||
if ($item_result[ "code" ] < 0)
|
||||
return $item_result;
|
||||
|
||||
if (empty($item_result[ 'data' ][ 'data' ])) {
|
||||
return success(0, '公众号暂无粉丝');
|
||||
}
|
||||
|
||||
$next_openid = $item_result[ "data" ][ "next_openid" ];
|
||||
$openid_item = $item_result[ "data" ][ 'data' ][ "openid" ];
|
||||
if (empty($openid_item)) {
|
||||
$is_continue = false;
|
||||
} else {
|
||||
$is_continue = false;
|
||||
foreach ($openid_item as $k => $v) {
|
||||
$openid_list[] = $v;
|
||||
}
|
||||
}
|
||||
} while ($is_continue);
|
||||
|
||||
//将粉丝列表存入session
|
||||
session('wechat_openid_list', $openid_list);
|
||||
$total = count($openid_list);
|
||||
if ($openid_list % $page_size == 0) {
|
||||
$page_count = $total / $page_size;
|
||||
} else {
|
||||
$page_count = (int) ( $total / $page_size ) + 1;
|
||||
}
|
||||
$data = array (
|
||||
'total' => $total,
|
||||
'page_count' => $page_count,
|
||||
);
|
||||
return success(0, '', $data);
|
||||
|
||||
} else {
|
||||
//对应页数更新用户粉丝信息
|
||||
$openid_list = session('wechat_openid_list');
|
||||
if (empty($openid_list)) {
|
||||
return error();
|
||||
}
|
||||
|
||||
$start = ( $page_index - 1 ) * $page_size;
|
||||
$page_fans_openid_list = array_slice($openid_list, $start, $page_size);
|
||||
|
||||
if (empty($page_fans_openid_list)) {
|
||||
return error();
|
||||
}
|
||||
|
||||
$fans_model = new FansModel();
|
||||
|
||||
$result = $wechat_model->selectUser($page_fans_openid_list);
|
||||
if ($result[ 'data' ] && $result[ 'data' ][ 'user_info_list' ]) {
|
||||
foreach ($result[ 'data' ][ 'user_info_list' ] as $k => $v) {
|
||||
$nickname_decode = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $v[ 'nickname' ]);
|
||||
$nickname = preg_replace_callback('/./u',
|
||||
function(array $match) {
|
||||
return strlen($match[ 0 ]) >= 4 ? '' : $match[ 0 ];
|
||||
},
|
||||
$v[ 'nickname' ]);
|
||||
$add_data = [
|
||||
'site_id' => $this->site_id,
|
||||
'nickname' => $nickname,
|
||||
'nickname_decode' => $nickname_decode,
|
||||
'headimgurl' => $v[ 'headimgurl' ],
|
||||
'sex' => $v[ 'sex' ],
|
||||
'language' => $v[ 'language' ],
|
||||
'country' => $v[ 'country' ],
|
||||
'province' => $v[ 'province' ],
|
||||
'city' => $v[ 'city' ],
|
||||
'openid' => $v[ 'openid' ],
|
||||
'unionid' => $v[ 'unionid' ] ?? '',
|
||||
'groupid' => '',
|
||||
'is_subscribe' => 1,
|
||||
'remark' => $v[ 'remark' ],
|
||||
'subscribe_time' => $v[ 'subscribe_time' ] ?? 0,
|
||||
'subscribe_scene' => $v[ 'subscribe_scene' ] ?? 0,
|
||||
'unsubscribe_time' => $v[ 'unsubscribe_time' ] ?? 0,
|
||||
'update_date' => time()
|
||||
];
|
||||
$info = $fans_model->getFansInfo([ 'openid' => $v[ 'openid' ], 'site_id' => $this->site_id ], 'openid');
|
||||
if (!empty($info[ 'data' ])) {
|
||||
$fans_model->editFans($add_data, [ [ 'openid', '=', $v[ 'openid' ] ], [ 'site_id', '=', $this->site_id ] ]);
|
||||
} else {
|
||||
$fans_model->addFans($add_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信粉丝标签
|
||||
*/
|
||||
public function fansTagList()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$page = input('page', 1);
|
||||
$limit = input('limit', PAGE_LIST_ROWS);
|
||||
$condition = [];
|
||||
$list = $fans_model->getFansTagPageList($condition, $page, $limit);
|
||||
return $list;
|
||||
} else {
|
||||
return $this->fetch('fans/fans_tag_list');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 为微信粉丝批量打标签
|
||||
*/
|
||||
public function fansBatchTagging()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$tagids = input('tag_id', '');
|
||||
$openids = input('openid', '');
|
||||
if (!empty($openids)) {
|
||||
$tag_id_list = explode(',', $tagids);
|
||||
$openid_list = explode(',', $openids);
|
||||
$data = [
|
||||
'tag_id_list' => $tag_id_list,
|
||||
'openid_list' => $openid_list
|
||||
];
|
||||
$res = $fans_model->fansBatchTagging($data);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为微信粉丝打标签
|
||||
*/
|
||||
public function fansTagging()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$openid = input('openid', '');
|
||||
$tagid_list = input('tagid_list', '');
|
||||
$cancel_tagid_list = input('cancel_tagid_list', '');
|
||||
if (!empty($openid)) {
|
||||
$tagid_list_arr = !empty($tagid_list) ? explode(',', $tagid_list) : [];
|
||||
$cancel_tagid_list_arr = !empty($cancel_tagid_list) ? explode(',', $cancel_tagid_list) : [];
|
||||
$data = [
|
||||
'tag_id_list' => $tagid_list_arr,
|
||||
'openid_list' => [ $openid ]
|
||||
];
|
||||
$res = $fans_model->fansBatchTagging($data);//批量增加标签
|
||||
$data[ 'tag_id_list' ] = $cancel_tagid_list_arr;
|
||||
$fans_model->batchUnTagging($data);//批量减少标签
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加标签
|
||||
* @return array
|
||||
*/
|
||||
public function addFansTag()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$tag_name = input('tag_name', '');
|
||||
if (!empty($tag_name)) {
|
||||
$data = [
|
||||
'tag_name' => $tag_name,
|
||||
];
|
||||
$data[ "tags" ] = time();
|
||||
$data[ "tag_id" ] = time();
|
||||
$res = $fans_model->addFansTag($data);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑标签
|
||||
*/
|
||||
public function editFansTag()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$id = input('id', '');
|
||||
$tag_name = input('tag_name', '');
|
||||
if (!empty($tag_name)) {
|
||||
$data = [
|
||||
'tag_name' => $tag_name,
|
||||
];
|
||||
$condition = array (
|
||||
[ "id", "=", $id ]
|
||||
);
|
||||
$res = $fans_model->editFansTag($data, $condition);
|
||||
return $res;
|
||||
} else {
|
||||
return error("", "标签名称不可为空!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除标签
|
||||
*/
|
||||
public function deleteFansTag()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$id = input('id', '');
|
||||
$condition = [
|
||||
[ 'id', "=", $id ],
|
||||
];
|
||||
$res = $fans_model->deleteFansTag($condition);
|
||||
return $res;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步粉丝标签
|
||||
*/
|
||||
public function syncFansTag()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$fans_model = new FansModel();
|
||||
$res = $fans_model->syncFansTag();
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
304
src/addon/wechat/shop/controller/Material.php
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Material as MaterialModel;
|
||||
use addon\wechat\model\Wechat as WechatModel;
|
||||
|
||||
/**
|
||||
* 微信素材控制器
|
||||
*/
|
||||
class Material extends BaseWechat
|
||||
{
|
||||
|
||||
/**
|
||||
* 素材列表--图文消息
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$type = input('type', '');
|
||||
$name = input('name', '');
|
||||
$page_index = input('page', 1);
|
||||
$page_size = input('limit', 9);
|
||||
if (!empty($type)) {
|
||||
$condition[] = [ 'type', "=", $type ];
|
||||
}
|
||||
if (!empty($name)) {
|
||||
$condition[] = array (
|
||||
'value', 'like', '%"name":"%' . $name . '%","url"%'
|
||||
);
|
||||
}
|
||||
$condition[] = [ 'site_id', '=', $this->site_id ];
|
||||
$material_model = new MaterialModel();
|
||||
$material_list = $material_model->getMaterialPageList($condition, $page_index, $page_size, 'type asc,create_time desc');
|
||||
if (!empty($material_list[ 'data' ][ 'list' ]) && is_array($material_list[ 'data' ][ 'list' ])) {
|
||||
foreach ($material_list[ 'data' ][ 'list' ] as $k => $v) {
|
||||
if (!empty($v[ 'value' ]) && json_decode($v[ 'value' ])) {
|
||||
$material_list[ 'data' ][ 'list' ][ $k ][ 'value' ] = json_decode($v[ 'value' ], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $material_list;
|
||||
} else {
|
||||
return $this->fetch('material/lists');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加图文消息
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$type = input('type', 1);
|
||||
$param[ 'value' ] = input('value', '');
|
||||
|
||||
if ($type != 1) {
|
||||
// 图片、音频、视频、缩略图素材
|
||||
$file_path = input('path', '');
|
||||
|
||||
$res = $this->uploadApi($type, [ 'path' => $file_path ]);
|
||||
if ($res[ 'code' ] != 0) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
$value[ 'file_path' ] = $file_path;
|
||||
$value[ 'url' ] = $res[ 'data' ][ 'url' ];
|
||||
$param[ 'value' ] = json_encode($value);
|
||||
$param[ 'media_id' ] = $res[ 'data' ][ 'media_id' ];
|
||||
|
||||
} else {
|
||||
$param[ 'media_id' ] = time() . 'GRAPHIC' . 'MESSAGE' . rand(1, 1000);
|
||||
}
|
||||
$param[ 'type' ] = $type;
|
||||
|
||||
$param[ 'create_time' ] = time();
|
||||
$param[ 'update_time' ] = time();
|
||||
$param[ 'site_id' ] = $this->site_id;
|
||||
$material_model = new MaterialModel();
|
||||
$res = $material_model->addMaterial($param);
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
$this->assign('material_id', '0');
|
||||
$this->assign('flag', false);
|
||||
return $this->fetch('material/edit');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改图文消息
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$condition = [];
|
||||
$condition[ 'id' ] = input('id', '');
|
||||
|
||||
$data[ 'value' ] = input('value', '');
|
||||
$data[ 'update_time' ] = time();
|
||||
|
||||
$material_model = new MaterialModel();
|
||||
$res = $material_model->editMaterial($data, $condition);
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
$material_id = input('id', '');
|
||||
$this->assign('material_id', $material_id);
|
||||
$this->assign('flag', true);
|
||||
return $this->fetch('material/edit');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加文本素材
|
||||
*/
|
||||
public function addTextMaterial()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$type = input('type', 1);
|
||||
$param[ 'value' ] = input('value', '');
|
||||
|
||||
$param[ 'type' ] = $type;
|
||||
|
||||
$param[ 'create_time' ] = time();
|
||||
$param[ 'update_time' ] = time();
|
||||
$param[ 'site_id' ] = $this->site_id;
|
||||
$material_model = new MaterialModel();
|
||||
$res = $material_model->addMaterial($param);
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
return $this->fetch('material/add_text');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改文本素材
|
||||
*/
|
||||
public function editTextMaterial()
|
||||
{
|
||||
$material_model = new MaterialModel();
|
||||
if (request()->isJson()) {
|
||||
$media_id = input("media_id", "");
|
||||
$media_id = str_replace("MATERIAL_TEXT_MESSAGE_", "", $media_id);
|
||||
|
||||
$content = input("content", "");
|
||||
$content = [ "content" => $content ];
|
||||
$content = json_encode($content, JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$condition[ 'id' ] = $media_id;
|
||||
$data[ 'value' ] = $content;
|
||||
$data[ 'update_time' ] = time();
|
||||
|
||||
$res = $material_model->editMaterial($data, $condition);
|
||||
|
||||
return $res;
|
||||
} else {
|
||||
$material_id = input('id', '');
|
||||
$data = $material_model->getMaterialInfo([ [ 'id', '=', $material_id ], [ 'site_id', '=', $this->site_id ] ]);
|
||||
if (!empty($data[ 'data' ])) {
|
||||
$data[ 'data' ][ 'value' ] = json_decode($data[ 'data' ][ 'value' ], true);
|
||||
}
|
||||
$this->assign('material_data', $data[ 'data' ]);
|
||||
return $this->fetch('material/edit_text');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览图文
|
||||
*/
|
||||
public function previewGraphicMessage()
|
||||
{
|
||||
$id = input('id', '');
|
||||
$index = input('i', '');
|
||||
$material_model = new MaterialModel();
|
||||
$info = $material_model->getMaterialInfo([ 'id' => $id ]);
|
||||
if (!empty($info[ 'data' ][ 'value' ]) && json_decode($info[ 'data' ][ 'value' ], true)) {
|
||||
$info[ 'data' ][ 'value' ] = json_decode($info[ 'data' ][ 'value' ], true);
|
||||
}
|
||||
$this->assign('info', $info[ 'data' ]);
|
||||
$this->assign('index', $index);
|
||||
return $this->fetch('material/preview_material');
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览文本
|
||||
*/
|
||||
public function previewTextMessage()
|
||||
{
|
||||
$id = input('id', '');
|
||||
$material_model = new MaterialModel();
|
||||
$info = $material_model->getMaterialInfo([ 'id' => $id ]);
|
||||
if (!empty($info[ 'data' ][ 'value' ]) && json_decode($info[ 'data' ][ 'value' ], true)) {
|
||||
$info[ 'data' ][ 'value' ] = json_decode($info[ 'data' ][ 'value' ], true);
|
||||
}
|
||||
$this->assign('info', $info[ 'data' ]);
|
||||
return $this->fetch('material/preview_text');
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传永久素材
|
||||
* @param $type
|
||||
* @param $data
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function uploadApi($type, $data)
|
||||
{
|
||||
$wechat_model = new WechatModel();
|
||||
|
||||
if ($type == 1) {
|
||||
$res = $wechat_model->uploadArticle($data);
|
||||
} else {
|
||||
if ($type == 2) {
|
||||
$type = 'image';
|
||||
$res = $wechat_model->uploadImage($data[ 'path' ]);
|
||||
} else if ($type == 3) {
|
||||
$type = 'voice';
|
||||
$res = $wechat_model->uploadVoice($data[ 'path' ]);
|
||||
} else if ($type == 4) {
|
||||
$type = 'video';
|
||||
$res = $wechat_model->uploadVideo($data[ 'path' ]);
|
||||
} else if ($type == 6) {
|
||||
$res = $wechat_model->uploadVideo($data[ 'path' ]);
|
||||
$type = 'thumb';
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除微信素材
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$id = input('id', 0);
|
||||
$material_model = new MaterialModel();
|
||||
$condition = array (
|
||||
[ "id", "=", $id ]
|
||||
);
|
||||
$res = $material_model->deleteMaterial($condition);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取素材详情
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMaterialInfo()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$material_model = new MaterialModel();
|
||||
$condition = array (
|
||||
[ 'id', '=', input('id', '') ]
|
||||
);
|
||||
$material_info = $material_model->getMaterialInfo($condition);
|
||||
if (json_decode($material_info[ 'data' ][ 'value' ])) {
|
||||
$material_info[ 'data' ][ 'value' ] = json_decode($material_info[ 'data' ][ 'value' ]);
|
||||
}
|
||||
return $material_info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 图文素材
|
||||
*/
|
||||
public function articleList()
|
||||
{
|
||||
$material_model = new MaterialModel();
|
||||
$condition = array (
|
||||
[ 'type', '=', 1 ]
|
||||
);
|
||||
$material_list = $material_model->getMaterialList($condition, '*', 'update_time desc');
|
||||
if (!empty($material_list[ 'data' ]) && is_array($material_list[ 'data' ])) {
|
||||
foreach ($material_list[ 'data' ] as $k => $v) {
|
||||
if (!empty($v[ 'value' ]) && json_decode($v[ 'value' ])) {
|
||||
$material_list[ 'data' ][ $k ][ 'value' ] = json_decode($v[ 'value' ], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->assign('material_list', $material_list);
|
||||
return $this->fetch('material/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 素材管理
|
||||
*/
|
||||
public function material()
|
||||
{
|
||||
//这这里的常量要与base中的区分,如果一致界面将无法渲染
|
||||
$type = input("type", 1);
|
||||
$this->assign("type", $type);
|
||||
// return array( 'shop/material/material' );
|
||||
return $this->fetch('material/material');
|
||||
}
|
||||
}
|
||||
58
src/addon/wechat/shop/controller/Menu.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Menu as MenuModel;
|
||||
use addon\wechat\model\Wechat as WechatModel;
|
||||
|
||||
/**
|
||||
* 微信菜单控制器
|
||||
*/
|
||||
class Menu extends BaseWechat
|
||||
{
|
||||
/**
|
||||
* 微信自定义菜单配置
|
||||
*/
|
||||
public function menu()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$menu_model = new MenuModel();
|
||||
$menu_info = $menu_model->getWechatMenuConfig($this->site_id);
|
||||
return $menu_info;
|
||||
} else {
|
||||
return $this->fetch('menu/menu');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改微信自定义菜单
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$menu_value = input('value', '');
|
||||
$menu_json = input('json_data', '');
|
||||
$menu_model = new MenuModel();
|
||||
$data = json_decode($menu_value, true);
|
||||
$res = $menu_model->setWechatMenuConfig($data, $this->site_id);
|
||||
if ($res[ 'code' ] != 0) {
|
||||
return $res;
|
||||
}
|
||||
$res = $this->sendWeixinMenu($menu_json);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 公众号同步更新微信菜单
|
||||
*/
|
||||
public function sendWeixinMenu($menu_json)
|
||||
{
|
||||
$wechat_model = new WechatModel($this->site_id);
|
||||
$menu_arr = json_decode($menu_json, true);
|
||||
$res = $wechat_model->menu($menu_arr[ 'button' ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
134
src/addon/wechat/shop/controller/Message.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Config;
|
||||
use app\model\message\Message as MessageModel;
|
||||
use app\model\message\MessageTemplate as MessageTemplateModel;
|
||||
|
||||
/**
|
||||
* 微信公众号模板消息
|
||||
*/
|
||||
class Message extends BaseWechat
|
||||
{
|
||||
/**
|
||||
* 编辑模板消息
|
||||
* @return array|mixed|string
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$message_model = new MessageModel();
|
||||
$keywords = input("keywords", "");
|
||||
$info = $message_model->getMessageInfo($this->site_id, $keywords)[ 'data' ];
|
||||
|
||||
if (empty($info))
|
||||
$this->error("不存在的模板信息!");
|
||||
|
||||
$wechat_json_array = $info[ "wechat_json_array" ];
|
||||
if (request()->isJson()) {
|
||||
|
||||
$wechat_is_open = input('wechat_is_open', 0);
|
||||
// $bottomtext = input("bottomtext", "");
|
||||
// $headtext = input("headtext", "");
|
||||
// $bottomtextcolor = input("bottomtextcolor", "");
|
||||
// $headtextcolor = input("headtextcolor", "");
|
||||
//// $wechat_json_array[ 'headtext' ] = $headtext;//头部标题
|
||||
// $wechat_json_array[ 'headtextcolor' ] = $headtextcolor;//头部标题颜色
|
||||
// $wechat_json_array[ 'bottomtext' ] = $bottomtext;//尾部描述
|
||||
// $wechat_json_array[ 'bottomtextcolor' ] = $bottomtextcolor;//尾部描述颜色
|
||||
|
||||
$data = array (
|
||||
'wechat_json' => json_encode($wechat_json_array),
|
||||
);
|
||||
$condition = array (
|
||||
[ "keywords", "=", $keywords ]
|
||||
);
|
||||
$template_model = new MessageTemplateModel();
|
||||
$res = $template_model->editMessageTemplate($data, $condition);
|
||||
if ($res[ 'code' ] == 0) {
|
||||
$res = $message_model->editMessage([ 'wechat_is_open' => $wechat_is_open, 'site_id' => $this->site_id, 'keywords' => $keywords ], [
|
||||
[ "keywords", "=", $keywords ],
|
||||
[ 'site_id', '=', $this->site_id ],
|
||||
]);
|
||||
}
|
||||
return $res;
|
||||
} else {
|
||||
$this->assign("keywords", $keywords);
|
||||
if (isset($wechat_json_array[ 'keyword_name_list' ])) {
|
||||
$wechat_json_array[ 'keyword_name_list' ] = implode(',', $wechat_json_array[ 'keyword_name_list' ]);
|
||||
}
|
||||
$this->assign("info", $wechat_json_array);
|
||||
$this->assign('wechat_is_open', $info[ 'wechat_is_open' ]);
|
||||
$this->assign('message_title', $info[ 'title' ]);
|
||||
return $this->fetch('message/edit');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板消息设置
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function config()
|
||||
{
|
||||
$message_model = new MessageModel();
|
||||
|
||||
if (request()->isJson()) {
|
||||
$page = input('page', 1);
|
||||
$page_size = input('page_size', PAGE_LIST_ROWS);
|
||||
$condition = array (
|
||||
[ "support_type", "like", '%wechat%' ],
|
||||
);
|
||||
$list = $message_model->getMessagePageList($condition, $this->site_id, $page, $page_size);
|
||||
return $list;
|
||||
} else {
|
||||
$config_model = new Config();
|
||||
$config = $config_model->getTemplateMessageConfig($this->site_id)[ 'data' ][ 'value' ];
|
||||
$this->assign('config', $config);
|
||||
return $this->fetch('message/config');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信模板消息状态设置
|
||||
*/
|
||||
public function setWechatStatus()
|
||||
{
|
||||
$message_model = new MessageModel();
|
||||
|
||||
if (request()->isJson()) {
|
||||
$keywords = input("keywords", "");
|
||||
$wechat_is_open = input('wechat_is_open', 0);
|
||||
$res = $message_model->getWechatTemplateNo($keywords, $this->site_id, $wechat_is_open);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板编号
|
||||
*/
|
||||
public function getWechatTemplateNo()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$keywords = input("keywords", "");
|
||||
$message_model = new MessageModel();
|
||||
$res = $message_model->getWechatTemplateNo($keywords, $this->site_id, -1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模板消息配置
|
||||
* @return array
|
||||
*/
|
||||
public function messageConfig()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$is_jump_weapp = input("is_jump_weapp", 0);
|
||||
$config_model = new Config();
|
||||
$res = $config_model->setTemplateMessageConfig([ 'is_jump_weapp' => $is_jump_weapp ], 1, $this->site_id);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
345
src/addon/wechat/shop/controller/Replay.php
Normal file
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Replay as ReplayModel;
|
||||
|
||||
/**
|
||||
* 微信回复控制器
|
||||
*/
|
||||
class Replay extends BaseWechat
|
||||
{
|
||||
/**
|
||||
* 回复设置--关键字自动回复
|
||||
*/
|
||||
public function replay()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$page = input('page', 1);
|
||||
$limit = input('limit', PAGE_LIST_ROWS);
|
||||
$rule_type = input('rule_type', '');
|
||||
$search_text = input('search_text', '');
|
||||
|
||||
$condition = array (
|
||||
[ 'rule_type', "=", $rule_type ],
|
||||
[ 'site_id', '=', $this->site_id ]
|
||||
);
|
||||
|
||||
$condition[] = [
|
||||
'rule_name', 'like', '%' . $search_text . '%'
|
||||
];
|
||||
|
||||
$order = 'create_time desc';
|
||||
$replay_model = new ReplayModel();
|
||||
$list = $replay_model->getReplayPageList($condition, $page, $limit, $order);
|
||||
foreach ($list[ 'data' ][ 'list' ] as $k => $v) {
|
||||
$list[ 'data' ][ 'list' ][ $k ][ 'key_list' ] = $v['keywords_json'] ? json_decode($v[ 'keywords_json' ]) : [];
|
||||
$list[ 'data' ][ 'list' ][ $k ][ 'replay_list' ] = $v['replay_json'] ? json_decode($v[ 'replay_json' ]) : [];
|
||||
}
|
||||
return $list;
|
||||
} else {
|
||||
$this->assign('link_list', []);
|
||||
return $this->fetch('replay/replay');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关键字回复
|
||||
*/
|
||||
public function addOrEditRule()
|
||||
{
|
||||
$replay_model = new ReplayModel();
|
||||
if (request()->isJson()) {
|
||||
$rule_name = input('rule_name', '');
|
||||
$rule_id = input('rule_id', 0);
|
||||
if ($rule_id > 0) {
|
||||
$data = [
|
||||
'rule_name' => $rule_name,
|
||||
'modify_time' => time()
|
||||
];
|
||||
$res = $replay_model->editRule($data, [ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
return $res;
|
||||
} else {
|
||||
$data = [
|
||||
'rule_name' => $rule_name,
|
||||
'rule_type' => 'KEYWORDS',
|
||||
'keywords_json' => '',
|
||||
'replay_json' => '',
|
||||
'create_time' => time(),
|
||||
'site_id' => $this->site_id
|
||||
];
|
||||
$res = $replay_model->addRule($data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关键词回复
|
||||
*/
|
||||
public function editKeywords()
|
||||
{
|
||||
$replay_model = new ReplayModel();
|
||||
if (request()->isJson()) {
|
||||
$rule_id = input('rule_id', '');
|
||||
$keywords_name = input('keywords_name', '');
|
||||
$keywords_type = input('keywords_type', 0);
|
||||
$key_id = input('key_id', -1);
|
||||
$info = $replay_model->getRuleInfo([ [ 'rule_id', "=", $rule_id ] ])[ 'data' ];
|
||||
if ($info[ 'keywords_json' ]) {
|
||||
$data = json_decode($info[ 'keywords_json' ]);
|
||||
if ($key_id > -1) {
|
||||
$data[ $key_id ] = [
|
||||
'keywords_name' => $keywords_name,
|
||||
'keywords_type' => $keywords_type
|
||||
];
|
||||
} else {
|
||||
$data[] = [
|
||||
'keywords_name' => $keywords_name,
|
||||
'keywords_type' => $keywords_type
|
||||
];
|
||||
}
|
||||
$data = json_encode($data);
|
||||
} else {
|
||||
$data = [
|
||||
[
|
||||
'keywords_name' => $keywords_name,
|
||||
'keywords_type' => $keywords_type
|
||||
]
|
||||
];
|
||||
$data = json_encode($data);
|
||||
}
|
||||
$data = [
|
||||
'keywords_json' => $data,
|
||||
'modify_time' => time()
|
||||
];
|
||||
$res = $replay_model->editRule($data, [ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除关键字回复
|
||||
*/
|
||||
public function deleteRule()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$rule_id = input('rule_id', 0);
|
||||
$replay_model = new ReplayModel();
|
||||
$res = $replay_model->deleteRule([ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除关键词数据
|
||||
*/
|
||||
public function deleteKeywords()
|
||||
{
|
||||
$replay_model = new ReplayModel();
|
||||
if (request()->isJson()) {
|
||||
$rule_id = input('rule_id', '');
|
||||
$key_id = input('key_id', '');
|
||||
$info_result = $replay_model->getRuleInfo([ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
$info = $info_result[ "data" ];
|
||||
$keywords_json = '';
|
||||
if ($info[ 'keywords_json' ]) {
|
||||
$keywords_json = json_decode($info[ 'keywords_json' ]);
|
||||
array_splice($keywords_json, $key_id, 1);
|
||||
$keywords_json = json_encode($keywords_json);
|
||||
}
|
||||
$data = [
|
||||
'keywords_json' => $keywords_json,
|
||||
];
|
||||
$res = $replay_model->editRule($data, [ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改回复数据
|
||||
* @return mixed
|
||||
*/
|
||||
public function editReplays()
|
||||
{
|
||||
$replay_model = new ReplayModel();
|
||||
if (request()->isJson()) {
|
||||
$rule_id = input('rule_id', '');
|
||||
$reply_content = input('reply_content', '');
|
||||
$media_id = input('media_id', '');
|
||||
$key_id = input('key_id', -1);
|
||||
$type = input('type', '');
|
||||
$replay_type = input('replay_type', '');
|
||||
$info_result = $replay_model->getRuleInfo([ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
$info = $info_result[ "data" ];
|
||||
if (!empty($rule_id)) {
|
||||
if ($info[ 'replay_json' ]) {
|
||||
$data = json_decode($info[ 'replay_json' ]);
|
||||
|
||||
if ($key_id > -1) {
|
||||
$data[ $key_id ] = [
|
||||
'reply_content' => $reply_content,
|
||||
'type' => $type,
|
||||
];
|
||||
if (!empty($media_id)) {
|
||||
$data[ $key_id ][ 'media_id' ] = $media_id;
|
||||
}
|
||||
} else {
|
||||
if (!empty($media_id)) {
|
||||
$data[] = [
|
||||
'reply_content' => $reply_content,
|
||||
'type' => $type,
|
||||
'media_id' => $media_id
|
||||
];
|
||||
} else {
|
||||
$data[] = [
|
||||
'reply_content' => $reply_content,
|
||||
'type' => $type,
|
||||
];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data = [
|
||||
[
|
||||
'reply_content' => $reply_content,
|
||||
'type' => $type,
|
||||
]
|
||||
];
|
||||
if (!empty($media_id)) {
|
||||
$data[ 0 ][ 'media_id' ] = $media_id;
|
||||
}
|
||||
}
|
||||
$data = json_encode($data);
|
||||
$data = [
|
||||
'replay_json' => $data,
|
||||
'modify_time' => time()
|
||||
];
|
||||
$res = $replay_model->editRule($data, [ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
return $res;
|
||||
} else {
|
||||
$rule_type = '';
|
||||
$rule_name = '';
|
||||
if ($replay_type == "default") {
|
||||
$rule_type = 'DEFAULT';
|
||||
$rule_name = '默认回复';
|
||||
} else if ($replay_type == "follow") {
|
||||
$rule_type = 'AFTER';
|
||||
$rule_name = '关注后回复';
|
||||
}
|
||||
$data = [
|
||||
[
|
||||
'reply_content' => $reply_content,
|
||||
'type' => $type,
|
||||
]
|
||||
];
|
||||
if (!empty($media_id)) {
|
||||
$data[ 0 ][ 'media_id' ] = $media_id;
|
||||
}
|
||||
$data = json_encode($data);
|
||||
$data = [
|
||||
'replay_json' => $data,
|
||||
'modify_time' => time(),
|
||||
'rule_name' => $rule_name,
|
||||
'rule_type' => $rule_type,
|
||||
'site_id' => $this->site_id,
|
||||
];
|
||||
$res = $replay_model->addRule($data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除回复数据
|
||||
*/
|
||||
public function deleteReply()
|
||||
{
|
||||
$replay_model = new ReplayModel();
|
||||
if (request()->isJson()) {
|
||||
$rule_id = input('rule_id', '');
|
||||
$key_id = input('key_id', '');
|
||||
$info = $replay_model->getRuleInfo([ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
$info = $info[ 'data' ];
|
||||
$replay_json = '';
|
||||
if ($info[ 'replay_json' ]) {
|
||||
$replay_json = json_decode($info[ 'replay_json' ]);
|
||||
array_splice($replay_json, $key_id, 1);
|
||||
$replay_json = json_encode($replay_json);
|
||||
}
|
||||
$data = [
|
||||
'replay_json' => $replay_json,
|
||||
];
|
||||
$res = $replay_model->editRule($data, [ [ 'rule_id', "=", $rule_id ], [ 'site_id', "=", $this->site_id ] ]);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关注后回复设置
|
||||
*/
|
||||
public function afterAttention()
|
||||
{
|
||||
return $this->fetch('replay/aterAttention');
|
||||
}
|
||||
|
||||
/**
|
||||
* 回复设置--关注后自动回复
|
||||
*/
|
||||
public function follow()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$page = input('page', 1);
|
||||
$pagesize = input('limit', PAGE_LIST_ROWS);
|
||||
$rule_type = input('rule_type', '');
|
||||
$condition = array (
|
||||
'rule_type' => $rule_type,
|
||||
'site_id' => $this->site_id
|
||||
);
|
||||
$order = 'create_time desc';
|
||||
$replay_model = new ReplayModel();
|
||||
$list = $replay_model->getReplayPageList($condition, $page, $pagesize, $order);
|
||||
foreach ($list[ 'data' ][ 'list' ] as $k => $v) {
|
||||
$list[ 'data' ][ 'list' ][ $k ][ 'key_list' ] = $v['keywords_json'] ? json_decode($v[ 'keywords_json' ]) : [];
|
||||
$list[ 'data' ][ 'list' ][ $k ][ 'replay_list' ] = $v['replay_json'] ? json_decode($v[ 'replay_json' ]) : [];
|
||||
}
|
||||
return $list;
|
||||
} else {
|
||||
$this->assign('link_list', []);//链接
|
||||
return $this->fetch('replay/follow');
|
||||
}
|
||||
}
|
||||
|
||||
public function default()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$page = input('page', 1);
|
||||
$limit = input('limit', PAGE_LIST_ROWS);
|
||||
// $rule_type = input('rule_type', '');
|
||||
$search_text = input('search_text', '');
|
||||
|
||||
$condition = array (
|
||||
[ 'rule_type', "=", 'DEFAULT' ], //只获取默认的
|
||||
[ 'site_id', '=', $this->site_id ]
|
||||
);
|
||||
|
||||
$condition[] = [
|
||||
'rule_name', 'like', '%' . $search_text . '%'
|
||||
];
|
||||
|
||||
$order = 'create_time desc';
|
||||
$replay_model = new ReplayModel();
|
||||
$list = $replay_model->getReplayPageList($condition, $page, $limit, $order);
|
||||
foreach ($list[ 'data' ][ 'list' ] as $k => $v) {
|
||||
$list[ 'data' ][ 'list' ][ $k ][ 'key_list' ] = $v['keywords_json'] ? json_decode($v[ 'keywords_json' ]) : [];
|
||||
$list[ 'data' ][ 'list' ][ $k ][ 'replay_list' ] = $v['replay_json'] ? json_decode($v[ 'replay_json' ]) : [];
|
||||
}
|
||||
return $list;
|
||||
} else {
|
||||
$this->assign('link_list', []);//链接
|
||||
return $this->fetch('replay/default');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
52
src/addon/wechat/shop/controller/Stat.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Stat as StatModel;
|
||||
|
||||
/**
|
||||
* 微信公众号基础功能
|
||||
*/
|
||||
class Stat extends BaseWechat
|
||||
{
|
||||
/**
|
||||
* 访问统计
|
||||
*/
|
||||
public function stat()
|
||||
{
|
||||
$stat_model = new StatModel();
|
||||
$yesterday = date('Y-m-d', strtotime('-1 day'));
|
||||
//昨天的用户分析数据
|
||||
$wechat_fans_result = $stat_model->fans($yesterday, $yesterday);
|
||||
$this->assign('yesterday_user_data', $wechat_fans_result[ 'data' ][ 0 ] ?? []);
|
||||
//昨天的接口分析数据
|
||||
$wechat_interface_result = $stat_model->interfaceSummary($yesterday, $yesterday);
|
||||
$this->assign('yesterday_interface_data', $wechat_interface_result[ 'data' ][ 0 ] ?? []);
|
||||
return $this->fetch('stat/stat');
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口调用统计
|
||||
* @return array
|
||||
*/
|
||||
public function interfaceSummaryStatistics()
|
||||
{
|
||||
$date_type = input("date_type", "week");
|
||||
$stat_model = new StatModel();
|
||||
$result = $stat_model->interfaceSummaryStatistics($date_type);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户访问统计
|
||||
* @return array
|
||||
*/
|
||||
public function userSummaryStatistics()
|
||||
{
|
||||
$date_type = input("date_type", "week");
|
||||
$stat_model = new StatModel();
|
||||
$result = $stat_model->userSummaryStatistics($date_type);
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
315
src/addon/wechat/shop/controller/Wechat.php
Normal file
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace addon\wechat\shop\controller;
|
||||
|
||||
use addon\wechat\model\Config as ConfigModel;
|
||||
use addon\wechat\model\Qrcode;
|
||||
use app\model\share\WchatShareBase as ShareModel;
|
||||
use app\model\system\User;
|
||||
|
||||
/**
|
||||
* 微信公众号基础功能
|
||||
*/
|
||||
class Wechat extends BaseWechat
|
||||
{
|
||||
|
||||
/**
|
||||
* 功能设置
|
||||
*/
|
||||
public function setting()
|
||||
{
|
||||
$replay_url = 'wechat://shop/replay/replay';
|
||||
if(!($this->user_info['is_admin'] == 1 || $this->group_info['is_system'] == 1)){
|
||||
$user_model = new User();
|
||||
$check_res = $user_model->checkAndGetRedirectUrl(['url' => $replay_url, 'app_module' => $this->app_module], $this->group_info);
|
||||
if($check_res['redirect_url']){
|
||||
$replay_url = $check_res[ 'redirect_url' ];
|
||||
}
|
||||
}
|
||||
$setting_arr = [
|
||||
[
|
||||
'url' => href_url('wechat://shop/wechat/config'),
|
||||
'img' => 'config_wechat_icon.png',
|
||||
'title' => '公众号管理',
|
||||
'content' => '公众号管理',
|
||||
],
|
||||
[
|
||||
'url' => href_url('wechat://shop/material/lists'),
|
||||
'img' => 'config_material_icon.png',
|
||||
'title' => '消息素材',
|
||||
'content' => '消息素材',
|
||||
],
|
||||
// [
|
||||
// 'url' => href_url('wechat://shop/fans/lists'),
|
||||
// 'img' => 'config_material_icon.png',
|
||||
// 'title' => '粉丝列表',
|
||||
// 'content' => '粉丝列表',
|
||||
// ],
|
||||
[
|
||||
'url' => href_url('wechat://shop/menu/menu'),
|
||||
'img' => 'config_menu_icon.png',
|
||||
'title' => '菜单管理',
|
||||
'content' => '菜单管理',
|
||||
],
|
||||
// [
|
||||
// 'url' => href_url('wechat://shop/wechat/qrcode'),
|
||||
// 'img' => 'config_qrcode_icon.png',
|
||||
// 'title' => '推广二维码',
|
||||
// 'content' => '推广二维码管理',
|
||||
// ],
|
||||
[
|
||||
'url' => href_url('wechat://shop/wechat/share'),
|
||||
'img' => 'config_share_icon.png',
|
||||
'title' => '分享内容设置',
|
||||
'content' => '分享内容设置',
|
||||
],
|
||||
[
|
||||
'url' => href_url($replay_url),
|
||||
'img' => 'config_replay_icon.png',
|
||||
'title' => '回复设置',
|
||||
'content' => '回复设置',
|
||||
],
|
||||
[
|
||||
'url' => href_url('wechat://shop/message/config'),
|
||||
'img' => 'config_message_icon.png',
|
||||
'title' => '模板消息',
|
||||
'content' => '模板消息设置',
|
||||
],
|
||||
];
|
||||
$this->assign('setting_arr', $setting_arr);
|
||||
return $this->fetch('wechat/setting');
|
||||
}
|
||||
|
||||
/**
|
||||
* 公众号配置
|
||||
*/
|
||||
public function config()
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
if (request()->isJson()) {
|
||||
$wechat_name = input('wechat_name', '');//公众号名称 (备注: 公众号名称,尽量与公众号平台保持一致)
|
||||
$wechat_original = input('wechat_original', '');//公众号原始id (备注: 公众号原始id,如:gh_111111111111)
|
||||
$appid = input('appid', '');//gh_845581623321AppID (备注: AppID 请注意需要与微信公众号平台保持一致,且注意信息安全,不要随意透露给第三方)
|
||||
$appsecret = input('appsecret', '');//AppSecret (备注: AppSecret密钥需要与微信公众号平台保持一致,没有特别原因不要随意修改,也不要随意透露给第三方)
|
||||
$token = input('token', 'TOKEN');//Token (备注: 自定义的Token值、确保后台与公众号平台填写的一致)
|
||||
$encodingaeskey = input('encodingaeskey', '');//EncodingAESKey (备注: 由开发者手动填写或随机生成,将用作消息体加解密密钥)
|
||||
$is_use = input('is_use', 1);//是否启用
|
||||
$qrcode = input('qrcode', '');//二维码
|
||||
$headimg = input('headimg', '');//头像
|
||||
$data = array (
|
||||
"wechat_name" => $wechat_name,
|
||||
"wechat_original" => $wechat_original,
|
||||
"appid" => $appid,
|
||||
"appsecret" => $appsecret,
|
||||
"token" => $token,
|
||||
"encodingaeskey" => $encodingaeskey,
|
||||
'qrcode' => $qrcode,
|
||||
'headimg' => $headimg,
|
||||
);
|
||||
|
||||
$res = $config_model->setWechatConfig($data, $is_use, $this->site_id);
|
||||
return $res;
|
||||
} else {
|
||||
$config_result = $config_model->getWechatConfig($this->site_id);
|
||||
$config = $config_result[ "data" ];
|
||||
$is_authopen = $config_result[ 'data' ][ 'value' ][ 'is_authopen' ] ?? 0;
|
||||
if ($is_authopen == 1) {
|
||||
$config[ 'value' ] = [];
|
||||
}
|
||||
$this->assign("config", $config);
|
||||
// 获取当前域名
|
||||
$url = __ROOT__;
|
||||
// 去除链接的http://头部
|
||||
$url_top = str_replace("https://", "", $url);
|
||||
$url_top = str_replace("http://", "", $url_top);
|
||||
// 去除链接的尾部/?s=
|
||||
$url_top = str_replace('/?s=', '', $url_top);
|
||||
$call_back_url = addon_url("wechat://api/auth/relateweixin");
|
||||
$this->assign("url", $url_top);
|
||||
$this->assign("call_back_url", $call_back_url);
|
||||
|
||||
return $this->fetch('wechat/config');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推广二维码模板
|
||||
*/
|
||||
public function qrcode()
|
||||
{
|
||||
$qrcode_model = new Qrcode();
|
||||
$template_list = $qrcode_model->getQrcodePageList([ 'is_remove' => 0 ]);
|
||||
$this->assign("template_list", $template_list[ 'data' ]);
|
||||
return $this->fetch('wechat/qrcode');
|
||||
}
|
||||
|
||||
/**
|
||||
* 推广二维码
|
||||
*/
|
||||
public function addQrcode()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$data = array (
|
||||
'background' => input("background", ''),
|
||||
'nick_font_color' => input("nick_font_color", '#000'),
|
||||
'nick_font_size' => input("nick_font_size", '12'),
|
||||
'is_logo_show' => input("is_logo_show", '1'),
|
||||
'header_left' => input("header_left", '59') . 'px',
|
||||
'header_top' => input("header_top", '15') . 'px',
|
||||
'name_left' => input("name_left", '128') . 'px',
|
||||
'name_top' => input("name_top", '23') . 'px',
|
||||
'logo_left' => input("logo_left", '60') . 'px',
|
||||
'logo_top' => input("logo_top", '200') . 'px',
|
||||
'code_left' => input("code_left", '70') . 'px',
|
||||
'code_top' => input("code_top", '300') . 'px',
|
||||
);
|
||||
$qrcode_model = new Qrcode();
|
||||
$result = $qrcode_model->addQrcode($data);
|
||||
return $result;
|
||||
} else {
|
||||
return $this->fetch('wechat/add_qrcode');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑二维码模板
|
||||
* @return mixed
|
||||
*/
|
||||
public function editQrcode()
|
||||
{
|
||||
$id = input("id", 0);
|
||||
$qrcode_model = new Qrcode();
|
||||
$condition = array (
|
||||
"id" => $id
|
||||
);
|
||||
if (request()->isJson()) {
|
||||
$data = array (
|
||||
'background' => input("background", ''),
|
||||
'nick_font_color' => input("nick_font_color", '#000'),
|
||||
'nick_font_size' => input("nick_font_size", '12'),
|
||||
'is_logo_show' => input("is_logo_show", '1'),
|
||||
'header_left' => input("header_left", '59') . 'px',
|
||||
'header_top' => input("header_top", '15') . 'px',
|
||||
'name_left' => input("name_left", '128') . 'px',
|
||||
'name_top' => input("name_top", '23') . 'px',
|
||||
'logo_left' => input("logo_left", '60') . 'px',
|
||||
'logo_top' => input("logo_top", '200') . 'px',
|
||||
'code_left' => input("code_left", '70') . 'px',
|
||||
'code_top' => input("code_top", '300') . 'px',
|
||||
);
|
||||
|
||||
$result = $qrcode_model->editQrcode($data, $condition);
|
||||
return $result;
|
||||
} else {
|
||||
$info = $qrcode_model->getQrcodeInfo($condition)[ "data" ];
|
||||
$this->assign("info", $info);
|
||||
return $this->fetch('wechat/edit_qrcode');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认推广二维码
|
||||
*/
|
||||
public function qrcodeDefault()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$id = input('id', 0);
|
||||
$qrcode_model = new Qrcode();
|
||||
$result = $qrcode_model->modifyQrcodeDefault([ 'id' => $id ]);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除默认推广二维码
|
||||
*/
|
||||
public function deleteQrcode()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$id = input('id', 0);
|
||||
$qrcode_model = new Qrcode();
|
||||
$result = $qrcode_model->deleteQrcode([ 'id' => $id ]);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享内容设置
|
||||
*/
|
||||
public function shareBack()
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
if (request()->isJson()) {
|
||||
$qrcode_param_1 = input('qrcode_param_1', '');
|
||||
$qrcode_param_2 = input('qrcode_param_2', '');
|
||||
$goods_param_1 = input('goods_param_1', '');
|
||||
$goods_param_2 = input('goods_param_2', '');
|
||||
$shop_param_1 = input('shop_param_1', '');
|
||||
$shop_param_2 = input('shop_param_2', '');
|
||||
$shop_param_3 = input('shop_param_3', '');
|
||||
|
||||
$data = array (
|
||||
'qrcode_param_1' => $qrcode_param_1,
|
||||
'qrcode_param_2' => $qrcode_param_2,
|
||||
'goods_param_1' => $goods_param_1,
|
||||
'goods_param_2' => $goods_param_2,
|
||||
'shop_param_1' => $shop_param_1,
|
||||
'shop_param_2' => $shop_param_2,
|
||||
'shop_param_3' => $shop_param_3,
|
||||
);
|
||||
|
||||
$res = $config_model->setShareConfig($data, 1, $this->site_id);
|
||||
return $res;
|
||||
} else {
|
||||
$config_result = $config_model->getShareConfig($this->site_id);
|
||||
$this->assign("info", $config_result[ "data" ][ 'value' ]);
|
||||
return $this->fetch('wechat/share_back');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享内容设置
|
||||
*/
|
||||
public function share()
|
||||
{
|
||||
if (request()->isJson()) {
|
||||
$data_json = input('data_json', '');
|
||||
$data = json_decode($data_json, true);
|
||||
$share_model = new ShareModel();
|
||||
return $share_model->setShareConfig($this->site_id, $data);
|
||||
} else {
|
||||
$share_config = event('WchatShareConfig', [ 'site_id' => $this->site_id ]);
|
||||
$config_list = [];
|
||||
foreach ($share_config as $data) {
|
||||
foreach ($data[ 'data' ] as $val) {
|
||||
$config_list[] = $val;
|
||||
}
|
||||
}
|
||||
$this->assign('config_list', $config_list);
|
||||
return $this->fetch('wechat/share');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 公众号设置
|
||||
*/
|
||||
public function configSetting()
|
||||
{
|
||||
$config_model = new ConfigModel();
|
||||
$config_result = $config_model->getWechatConfig($this->site_id);
|
||||
$config = $config_result[ "data" ];
|
||||
if (!empty($config[ "value" ])) {
|
||||
//是否是开放平台授权
|
||||
$is_authopen = $config_result[ 'data' ][ 'value' ][ 'is_authopen' ] ?? 0;
|
||||
if ($is_authopen > 0) {
|
||||
$this->redirect(addon_url("wxoplatform://shop/oplatform/wechat"));
|
||||
} else {
|
||||
$this->redirect(addon_url("wechat://shop/wechat/config"));
|
||||
}
|
||||
} else {
|
||||
$this->redirect(addon_url("wxoplatform://shop/oplatform/wechatsettled"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
158
src/addon/wechat/shop/view/fans/fans_tag_list.html
Normal file
@@ -0,0 +1,158 @@
|
||||
<style>
|
||||
.layui-table {margin: 0}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<button class="layui-btn" onclick="addOrEditTag('添加标签')">添加标签</button>
|
||||
<button class="layui-btn" onclick="syncTag()">同步标签</button>
|
||||
</div>
|
||||
<div>
|
||||
<table id="tag_list" lay-filter="tag_list" class="layui-table"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="operation">
|
||||
<a class="default" lay-event="edit">编辑</a> |
|
||||
<a class="default" lay-event="delete">删除</a> <br/>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="addOrEditTag">
|
||||
<div class="layui-form" lay-filter="otherInfo">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label sm">标签名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="tag_name" class="layui-input" value="{{d.tag_name}}" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row sm">
|
||||
<button class="layui-btn" lay-submit lay-filter="addOrEditTagSubmit">保存</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary" onclick="back()">返回</button>
|
||||
</div>
|
||||
<input type="hidden" name="id" value="{{d.id}}">
|
||||
<input type="hidden" name="tag_id" value="{{d.tag_id}}">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var form,laytpl,index,layer;
|
||||
var table = new Table({
|
||||
elem : '#tag_list',
|
||||
filter : "tag_list",
|
||||
url : "{:addon_url('wechat://shop/fans/fansTagList')}",
|
||||
cols : [
|
||||
[
|
||||
{
|
||||
type : 'checkbox',
|
||||
unresize : 'true'
|
||||
},
|
||||
{
|
||||
field: 'tag_name',
|
||||
title: '标签名称',
|
||||
unresize : 'true'
|
||||
},
|
||||
{
|
||||
title : '操作',
|
||||
toolbar : '#operation',
|
||||
width : '30%',
|
||||
align : 'right',
|
||||
unresize : 'true'
|
||||
}
|
||||
]
|
||||
]
|
||||
});
|
||||
|
||||
table.tool(function(obj){
|
||||
var data = obj.data;
|
||||
switch (obj.event) {
|
||||
case 'edit':
|
||||
addOrEditTag('编辑标签', data);
|
||||
break;
|
||||
case 'delete':
|
||||
deleteTag(data);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
layui.use([ 'form', 'laytpl'], function() {
|
||||
laytpl = layui.laytpl;
|
||||
form = layui.form;
|
||||
form.render();
|
||||
|
||||
var repeat_flag = false;//防重复标识
|
||||
form.on('submit(addOrEditTagSubmit)', function (data) {
|
||||
if (repeat_flag) return;
|
||||
repeat_flag = true;
|
||||
var url = data.field.id > 0 ? '{:addon_url("wechat://shop/fans/editFansTag")}' : '{:addon_url("wechat://shop/fans/addFansTag")}';
|
||||
$.ajax({
|
||||
type: "post",
|
||||
async: false,
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
back();
|
||||
layer.msg(res.message);
|
||||
if (res.code == 0) {
|
||||
table.reload();
|
||||
}
|
||||
repeat_flag = false;
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
function addOrEditTag(title, data) {
|
||||
var tpl_data = data == undefined ? {tag_name: '', tag_id: 0, id: 0} : data;
|
||||
laytpl($("#addOrEditTag").html()).render(tpl_data, function (html) {
|
||||
index = layer.open({
|
||||
type: 1,
|
||||
title: title,
|
||||
skin: 'layer-tips-class',
|
||||
area: ['450px'],
|
||||
content: html
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
var repeat_flag_delete = false;//防重复标识
|
||||
function deleteTag(data){
|
||||
if (repeat_flag_delete) return;
|
||||
repeat_flag_delete = true;
|
||||
layer.confirm('确定要删除该标签吗?',function (index) {
|
||||
layer.close(index);
|
||||
$.ajax({
|
||||
type : "post",
|
||||
async : false,
|
||||
url : '{:addon_url("wechat://shop/fans/deleteFansTag")}',
|
||||
dataType: 'json',
|
||||
data : data,
|
||||
success:function(res){
|
||||
layer.msg(res.message);
|
||||
if(res.code == 0){
|
||||
table.reload();
|
||||
}
|
||||
repeat_flag_delete = false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function syncTag(){
|
||||
$.ajax({
|
||||
url : '{:addon_url("wechat://shop/fans/syncFansTag")}',
|
||||
dataType: 'json',
|
||||
async : false,
|
||||
type : "post",
|
||||
beforeSend : function(){
|
||||
index = layer.load(2);
|
||||
},
|
||||
success:function(res){
|
||||
back();
|
||||
layer.msg(res.message);
|
||||
if(res.code == 0){
|
||||
table.reload();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
212
src/addon/wechat/shop/view/fans/lists.html
Normal file
@@ -0,0 +1,212 @@
|
||||
<link rel="stylesheet" type="text/css" href="SHOP_CSS/member.css" />
|
||||
<link rel="stylesheet" type="text/css" href="WECHAT_CSS/wx_fans.css" />
|
||||
<style>
|
||||
.layui-layout-admin .tips-wrap{margin-bottom: 15px;}
|
||||
</style>
|
||||
|
||||
<div class="single-filter-box">
|
||||
<button class="layui-btn btn-hide" lay-submit="" lay-filter="save" onclick="refresh()">同步粉丝信息</button>
|
||||
<div class="layui-form">
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="nickname" placeholder="请输入粉丝名称" autocomplete="off" class="layui-input">
|
||||
<button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
|
||||
<i class="layui-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示</h2>
|
||||
<div class="layui-colla-content layui-show">说明:把同步公众号上的实际粉丝数量与信息同步到商城中展示</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 列表 -->
|
||||
<table id="Fans_list" lay-filter="Fans_list"></table>
|
||||
|
||||
<!-- 批量操作 -->
|
||||
<script type="text/html" id="batchOperation">
|
||||
</script>
|
||||
|
||||
<!-- 地址 -->
|
||||
<script type="text/html" id="diqu">
|
||||
<p>{{d.country}}{{d.province}}{{d.city}}{{ d.district != '' && d.district != '无' ? d.district : '' }}</p>
|
||||
</script>
|
||||
|
||||
<!-- 操作 -->
|
||||
<script type="text/html" id="operation">
|
||||
<div class="table-btn">
|
||||
<a class="layui-btn" href="" lay-event="">查看消息</a>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- 用户信息 -->
|
||||
<script type="text/html" id="fansMessage">
|
||||
<div class='table-title'>
|
||||
<div class='title-pic'>
|
||||
{{# if(d.headimgurl){ }}
|
||||
<img layer-src src={{ns.img(d.headimgurl)}} class="head-portrait">
|
||||
{{# } }}
|
||||
</div>
|
||||
<div class='title-content'>
|
||||
<p class="layui-elip">用户名:{{d.nickname}}</p>
|
||||
{{# if(d.sex == 1){ }}
|
||||
<p class="layui-elip">性别:男</p>
|
||||
{{# }else{ }}
|
||||
<p class="layui-elip">性别:女</p>
|
||||
{{# } }}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- 用户来源 -->
|
||||
<script type="text/html" id="subscribe_scene">
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_SEARCH'){ }}
|
||||
<p>公众号搜索</p>
|
||||
{{# } }}
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_ACCOUNT_MIGRATION'){ }}
|
||||
<p>公众号迁移</p>
|
||||
{{# } }}
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_PROFILE_CARD'){ }}
|
||||
<p>名片分享</p>
|
||||
{{# } }}
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_QR_CODE'){ }}
|
||||
<p>扫描二维码</p>
|
||||
{{# } }}
|
||||
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_PROFILE_LINK'){ }}
|
||||
<p>图文页内名称点击</p>
|
||||
{{# } }}
|
||||
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_PROFILE_ITEM'){ }}
|
||||
<p>图文页右上角菜单</p>
|
||||
{{# } }}
|
||||
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_PAID'){ }}
|
||||
<p>支付后关注</p>
|
||||
{{# } }}
|
||||
|
||||
{{# if(d.subscribe_scene == 'ADD_SCENE_OTHERS '){ }}
|
||||
<p>其他</p>
|
||||
{{# } }}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="progress-layer">
|
||||
<h3>正在同步中,已完成...</h3>
|
||||
<div class="layui-progress layui-progress-big" lay-showPercent="true" lay-filter="progress">
|
||||
<div class="layui-progress-bar layui-bg-blue" lay-percent="0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['form', 'element'], function() {
|
||||
var table,
|
||||
form = layui.form;
|
||||
form.render();
|
||||
|
||||
table = new Table({
|
||||
elem: '#Fans_list',
|
||||
url: ns.url("wechat://shop/fans/lists"),
|
||||
page: true,
|
||||
cols: [
|
||||
[{
|
||||
title: '粉丝信息',
|
||||
width: '30%',
|
||||
unresize: 'false',
|
||||
templet: '#fansMessage'
|
||||
}, {
|
||||
field: 'subscribe_time',
|
||||
title: '关注时间',
|
||||
width: '20%',
|
||||
unresize: 'false',
|
||||
templet: function(data) {
|
||||
return ns.time_to_date(data.subscribe_time);
|
||||
}
|
||||
}, {
|
||||
field: 'country',
|
||||
title: '详细地址',
|
||||
width: '30%',
|
||||
unresize: 'false',
|
||||
templet:'#diqu'
|
||||
}, {
|
||||
field: 'subscribe_scene',
|
||||
title: '粉丝来源',
|
||||
width: '20%',
|
||||
unresize: 'false',
|
||||
templet:'#subscribe_scene'
|
||||
}]
|
||||
]
|
||||
});
|
||||
/**
|
||||
* 搜索功能
|
||||
*/
|
||||
form.on('submit(search)', function(data) {
|
||||
table.reload({
|
||||
page: {
|
||||
curr: 1
|
||||
},
|
||||
where: data.field
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// 更新粉丝列表
|
||||
var repeat_flag = false;//防重复标识
|
||||
var page_index = 0;
|
||||
var page_count = 0;
|
||||
var progress_element;
|
||||
layui.use('element', function(){
|
||||
progress_element = layui.element;
|
||||
});
|
||||
|
||||
function refresh() {
|
||||
if(repeat_flag) return;
|
||||
repeat_flag = true;
|
||||
$.ajax({
|
||||
type : "post",
|
||||
url : "{:addon_url('wechat://shop/fans/syncWechatFans')}",
|
||||
data : {
|
||||
"page" : page_index,
|
||||
},
|
||||
dataType : "JSON",
|
||||
beforeSend : function() {
|
||||
$(".progress-layer").fadeIn();
|
||||
},
|
||||
success : function(data) {
|
||||
repeat_flag = false;
|
||||
if (data.code != 0 && data.message != undefined && data.message != '') {
|
||||
layer.msg(data.message);
|
||||
$(".progress-layer").fadeOut();
|
||||
} else if (data.code == 0) {
|
||||
if (page_index == 0) page_count = data['data']["page_count"];
|
||||
|
||||
page_index += 1;
|
||||
if (data.data == null) {
|
||||
$(".progress-layer").fadeOut();
|
||||
}
|
||||
|
||||
if (page_index <= page_count) {
|
||||
var speed_of_progress = (page_index / page_count * 100).toFixed(2);
|
||||
progress_element.progress('progress', speed_of_progress + '%');
|
||||
}
|
||||
if (page_index <= page_count) {
|
||||
repeat_flag = false;
|
||||
refresh();
|
||||
} else {
|
||||
listenerHash(); // 刷新页面
|
||||
layer.closeAll();
|
||||
}
|
||||
} else {
|
||||
layer.msg('更新失败');
|
||||
$(".progress-layer").fadeOut();
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
layer.msg('更新失败');
|
||||
$(".progress-layer").fadeOut();
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
80
src/addon/wechat/shop/view/material/add_text.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_graphic_message.css">
|
||||
<style type="text/css">
|
||||
.layui-tab-brief{width: 800px;height: 646px}
|
||||
.input-text-hint{float:right}
|
||||
</style>
|
||||
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示<i class="layui-icon layui-colla-icon"></i></h2>
|
||||
<ul class="layui-colla-content layui-show">
|
||||
<li>由于微信公众平台的接口规范,仅提供向微信认证服务号商家。如你的公众号同时具有微信支付权限,你还可以在正文内添加超级链接。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='graphic_message'>
|
||||
<!-- 添加文本消息 -->
|
||||
<div class="layui-tab layui-tab-brief" id="add_material_text">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">添加文本消息</li>
|
||||
</ul>
|
||||
<div class="layui-form" style="margin-top: 20px;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label sm">内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" placeholder="请输入内容" id="material_text_content" class="layui-textarea" maxlength="300" lay-verify='material_text_content'></textarea>
|
||||
<span class='input-text-hint'>剩余300字</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row sm">
|
||||
<button class="layui-btn" lay-submit lay-filter="addText">保存</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary" onclick="backWechatMaterialList()">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use('form', function () {
|
||||
var form = layui.form,repeat_flag = false;
|
||||
|
||||
$('#material_text_content').on('input', function (e) {
|
||||
var num = e.target.value.length;
|
||||
num = 300 - parseInt(num);
|
||||
$('#add_material_text .input-text-hint').html('剩余' + num);
|
||||
});
|
||||
form.verify({
|
||||
'material_text_content': function (value, item) {
|
||||
if (value == '' || value == undefined) {
|
||||
return '文本内容不可为空';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
form.on('submit(addText)', function (data) {
|
||||
var value = JSON.stringify(data.field);
|
||||
if (repeat_flag) return;
|
||||
repeat_flag = true;
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: ns.url('wechat://shop/material/addTextMaterial'),
|
||||
data: {type: 5, value},
|
||||
dataType: "JSON",
|
||||
success: function (res) {
|
||||
if (res.code == 0) {
|
||||
//_self.material_id = res.data;
|
||||
location.hash = ns.hash('wechat://shop/material/lists');
|
||||
}
|
||||
repeat_flag = false;
|
||||
layer.msg(res.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function backWechatMaterialList() {
|
||||
location.hash = ns.hash("wechat://shop/material/lists");
|
||||
}
|
||||
|
||||
</script>
|
||||
163
src/addon/wechat/shop/view/material/edit.html
Normal file
@@ -0,0 +1,163 @@
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_graphic_message.css">
|
||||
<style type="text/css">
|
||||
.img-upload{margin-left: 0}
|
||||
.body-content{padding-top: 15px !important;}
|
||||
</style>
|
||||
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示<i class="layui-icon layui-colla-icon"></i></h2>
|
||||
<ul class="layui-colla-content layui-show">
|
||||
<li>由于微信公众平台的接口规范,仅提供向微信认证服务号商家。如你的公众号同时具有微信支付权限,你还可以在正文内添加超级链接。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='graphic_message'>
|
||||
<div class='graphic-message'>
|
||||
<img src='WECHAT_IMG/mobile_head.png'/>
|
||||
<ul class='graphic-message-list'>
|
||||
<template v-for="(value, index) in article_item_list">
|
||||
<li @click.stop="chooseGraphicMessage(index)" @mouseenter="moveThis(index)" @mouseleave="leaveThis(index)">
|
||||
<content>
|
||||
<template v-if="value.cover.path == ''">
|
||||
<div class='empty-img'></div>
|
||||
<span class='empty-hint'>{{index == 0 ? '封面图片' : '缩略图'}}</span>
|
||||
</template>
|
||||
<img v-else :src="value.cover.path"/>
|
||||
<div class='mask-layer'></div>
|
||||
<h4 class='title'><span>{{value.title == '' ? '标题' : value.title}}</span></h4>
|
||||
</content>
|
||||
<div class='action'>
|
||||
<template v-if="(index == 0 && index == current_msg_index) || (move_index == 0 && index == 0)">
|
||||
<span class='edit' @click.stop="chooseGraphicMessage(index)">编辑</span>
|
||||
</template>
|
||||
<template v-else-if="move_index == index || index == current_msg_index">
|
||||
<span class='edit' @click.stop="chooseGraphicMessage(index)">编辑</span>
|
||||
<span class='delete' @click.stop="deleteGraphicMessage(index)">删除</span>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<div class='add-graphic-message'>
|
||||
<h4>
|
||||
<a @click="addGraphicMessage()">新增</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div class='bottom-botton'>
|
||||
<template v-if="material_id == 0">
|
||||
<button class='layui-btn' @click="saveGraphicMessage()">保存</button>
|
||||
</template>
|
||||
<button class='layui-btn' v-else @click="editGraphicMessage()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class='editor-box' :style="'margin-top:' + editBoxTopPosition + 'px'">
|
||||
<div class='arrow'></div>
|
||||
<div class='editor-title'>
|
||||
<label>标题<span class='hint'>(必填)</span></label>
|
||||
<input class="layui-input" id="input_title" placeholder="请在这里输入标题" maxlength="64" v-model="inputTitle" max-length="70"/>
|
||||
</div>
|
||||
<div class='editor-author'>
|
||||
<label>作者<span class='hint'>(选填)</span></label>
|
||||
<input class="layui-input" id="input_autor" placeholder="请输入作者" maxlength="16" v-model="inputAutor" max-length="20"/>
|
||||
</div>
|
||||
<div class='editor-cover'>
|
||||
<label>封面<span class='hint'>(图片建议尺寸:900 x 500像素 必填)</span></label>
|
||||
<!--<div class="choose-cover">-->
|
||||
<!--<div class="choose-cover-pic">-->
|
||||
<!--<img :src="coverImg"/>-->
|
||||
<!--</div>-->
|
||||
<!--<template v-if="coverImg == ''">-->
|
||||
<!--<a class="text-color" id="uploadImg" href="javascript:;">上传图片...</a>-->
|
||||
<!--</template>-->
|
||||
<!--<template v-else>-->
|
||||
<!--<a id="uploadImg" style="margin-top: 15px;" href="javascript:;">更换封面图...</a>-->
|
||||
<!--</template>-->
|
||||
<!--</div>-->
|
||||
|
||||
<div class="layui-input-block img-upload">
|
||||
<div class="upload-img-block">
|
||||
<div class="upload-img-box hover" v-if="coverImg">
|
||||
<div class="upload-default" id="uploadImg" >
|
||||
<div id="preview_uploadImg" class="preview_img">
|
||||
<img layer-src :src="coverImg" class="img_prev" :data-img="coverImg"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<div>
|
||||
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
|
||||
<i title="删除图片" class="layui-icon layui-icon-delete js-delete"></i>
|
||||
</div>
|
||||
<div class="replace_img js-replace">点击替换</div>
|
||||
</div>
|
||||
<input type="hidden" name="logo" id="logo" :value="coverImg"/>
|
||||
</div>
|
||||
<div class="upload-img-box" v-else>
|
||||
<div class="upload-default" id="uploadImg" >
|
||||
<div class="upload">
|
||||
<i class="iconfont iconshangchuan"></i>
|
||||
<p>点击上传</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<div>
|
||||
<i title="图片预览" class="iconfont iconreview js-preview" style="margin-right: 20px;"></i>
|
||||
<i title="删除图片" class="layui-icon layui-icon-delete js-delete"></i>
|
||||
</div>
|
||||
<div class="replace_img js-replace">点击替换</div>
|
||||
</div>
|
||||
<input type="hidden" name="logo" id="logo" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label class="editor-msg-label" :class="checkShowCoverPic ? 'selected' : ''" for="check_show_cover_pic">
|
||||
<input type="checkbox" id="check_show_cover_pic" value="1" v-model="checkShowCoverPic"/>
|
||||
封面图片显示在正文中
|
||||
</label>
|
||||
</div>
|
||||
<div class='editor-content'>
|
||||
<label>正文<span class='hint'>(必填)</span></label>
|
||||
<script id="editor" type="text/plain" style="width:380px; height:300px;"></script>
|
||||
</div>
|
||||
<div class='editor-url'>
|
||||
<label>原文链接<span class='hint'>(选填)</span></label>
|
||||
<input class="layui-input" id="original_url" placeholder="例:http://www.example.com" maxlength="100" v-model="inputOriginalUrl"/>
|
||||
</div>
|
||||
</div>
|
||||
<input type='hidden' id='edit_flag' value='{$flag}'/>
|
||||
<input type='hidden' id='material_id' value='{$material_id}'/>
|
||||
<div class="loading" :class="{ show: loading }"><i class=" layui-icon layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i></div>
|
||||
</div>
|
||||
|
||||
<script src="STATIC_JS/vue.js"></script>
|
||||
<script src='WECHAT_JS/wx_graphic_message.js'></script>
|
||||
<script>
|
||||
var material_id = $("#material_id").val();
|
||||
if(material_id != 0){
|
||||
var timer_new = setInterval(function () {
|
||||
if($(".img_prev").attr('data-img') && $("#material_id").val()){
|
||||
loadImgMagnify();
|
||||
var logo_upload = new Upload({
|
||||
elem: '#uploadImg',
|
||||
callback:function (res) {
|
||||
if (res.code >= 0) {
|
||||
//成功之后将图片的路径存放再隐藏域中,便于提交使用
|
||||
// $("input[name='web_qrcode']").val(res.data.pic_path);
|
||||
vue_obj.coverImg = ns.img(res.data.pic_path);
|
||||
vue_obj.article_item_list[vue_obj.current_msg_index].cover.path = ns.img(res.data.pic_path);
|
||||
//将图片展示在页面上
|
||||
// $("#webQrcodeUpload").html("<img src=" + ns.img(res.data.pic_path) + " >");
|
||||
}
|
||||
}
|
||||
});
|
||||
clearInterval(timer_new);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
</script>
|
||||
<!-- 百度编辑器 -->
|
||||
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.config.js?time=20240614"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.all.js?time=20240614"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/lang/zh-cn/zh-cn.js"></script>
|
||||
82
src/addon/wechat/shop/view/material/edit_text.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_graphic_message.css">
|
||||
<style>
|
||||
.layui-tab-brief{width: 800px;height:646px}
|
||||
.input-text-hint{float:right}
|
||||
</style>
|
||||
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示<i class="layui-icon layui-colla-icon"></i></h2>
|
||||
<ul class="layui-colla-content layui-show">
|
||||
<li>由于微信公众平台的接口规范,仅提供向微信认证服务号商家。如你的公众号同时具有微信支付权限,你还可以在正文内添加超级链接。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='graphic_message'>
|
||||
<!-- 添加文本消息 -->
|
||||
<div class="layui-tab layui-tab-brief" id="add_material_text">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">添加文本消息</li>
|
||||
</ul>
|
||||
<div class="layui-form" style="margin-top: 20px;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label sm">内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" placeholder="请输入内容" id="material_text_content" class="layui-textarea" maxlength="300" lay-verify='material_text_content'>{$material_data.value.content}</textarea>
|
||||
<span class='input-text-hint'>剩余300字</span>
|
||||
<input type="hidden" name="media_id" id="media_id" value="{$material_data.id}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row sm">
|
||||
<button class="layui-btn" lay-submit lay-filter="addText">保存</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary" onclick="backWechatMaterialList()">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use('form', function () {
|
||||
var form = layui.form;
|
||||
|
||||
$('#material_text_content').on('input', function (e) {
|
||||
var num = e.target.value.length;
|
||||
num = 300 - parseInt(num);
|
||||
$('#add_material_text .input-text-hint').html('剩余' + num);
|
||||
});
|
||||
form.verify({
|
||||
'material_text_content': function (value, item) {
|
||||
if (value == '' || value == undefined) {
|
||||
return '文本内容不可为空';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
form.on('submit(addText)', function (data) {
|
||||
if (repeat_flag) return;
|
||||
repeat_flag = true;
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: ns.url('wechat://shop/material/editTextMaterial'),
|
||||
data: {type: 5,content: data.field.content,media_id:data.field.media_id},
|
||||
dataType: "JSON",
|
||||
success: function (res) {
|
||||
if (res.code == 0) {
|
||||
location.hash = ns.hash('wechat://shop/material/lists');
|
||||
} else {
|
||||
repeat_flag = false;
|
||||
}
|
||||
layer.msg(res.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function backWechatMaterialList() {
|
||||
location.hash = ns.hash("wechat://shop/material/lists");
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
144
src/addon/wechat/shop/view/material/lists.html
Normal file
@@ -0,0 +1,144 @@
|
||||
<style>
|
||||
.news-material>ul{display: flex;flex-wrap: wrap}
|
||||
.news-material>ul>li{border: 1px solid rgb(233, 233, 233);position: relative;margin:14px 14px 0 0 ;width: calc((100% - 16px*5)/ 5);height: 315px;}
|
||||
.news-material .add-news{text-align: center;display: flex;position: relative;}
|
||||
.news-material .add-news .add-box{margin: auto}
|
||||
.news-material .add-news .iconfont{font-size: 100px; font-weight: 800;color: #606266;}
|
||||
.news-material .add-news:hover .add-li{display: block;}
|
||||
.news-material .add-li{display: none;width: 130px;height: 60px; box-shadow:0px 0px 5px rgb(231, 231, 231) ; background: #fff; position: absolute;left: 50%;top: 85%;transform: translate(-50%,-50%)}
|
||||
.news-material .add-li li{line-height: 30px;}
|
||||
.news-material .add-li li .iconfont{font-size: 16px;}
|
||||
.news-material .add-li li:hover{background: var(--base-color)}
|
||||
.news-material .add-li li:hover span{color: #fff;cursor: pointer;}
|
||||
.news-material .add-li li:hover i{color: #fff;}
|
||||
.material-content{padding: 20px}
|
||||
.news-material .meterail-img{height:200px;text-align: center;line-height: 200px;}
|
||||
.meterail-img img{max-width: 100%; max-height: 100%;}
|
||||
.meterail-title {height: 200px;padding: 20px 40px;box-sizing: border-box;text-align: center;display: flex; overflow: hidden}
|
||||
.meterail-title .title{margin: auto ;}
|
||||
.meterail-title-text{height: 235px !important;}
|
||||
.material-content .meterail-text {overflow: hidden;height: 35px;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2; overflow:hidden; -webkit-box-orient: vertical;}
|
||||
.material-content .meterail-time{margin-top: 20px ;color: #999}
|
||||
.del-edit{position: absolute;right: 10px;top: 10px;display: none;}
|
||||
.del{margin-right: 5px;}
|
||||
.del,.edit{display: inline-block;background: #fff;height: 30px; width: 30px;text-align: center;border-radius: 50%;line-height: 30px;box-shadow:0px 0px 5px rgb(231, 231, 231) ;}
|
||||
.news-material>ul>li:hover .del-edit{display: inline-block}
|
||||
.del:hover,.edit:hover {color: var(--base-color);cursor: pointer;}
|
||||
#MaterailList{display: flex;justify-content: flex-end;margin-right: 14px;}
|
||||
</style>
|
||||
|
||||
<div class="news-material">
|
||||
<ul id="newsMaterialContent"></ul>
|
||||
<div id="MaterailList"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
//删除
|
||||
function delMaterial(id){
|
||||
$.ajax({
|
||||
url: ns.url('wechat://shop/material/delete'),
|
||||
data: {
|
||||
id,
|
||||
},
|
||||
dataType: "JSON",
|
||||
success: function(res) {
|
||||
listenerHash(); // 刷新页面
|
||||
}
|
||||
});
|
||||
}
|
||||
function add_tuwen(){
|
||||
window.open(ns.href("wechat://shop/material/add"));
|
||||
}
|
||||
function add_text(){
|
||||
window.open(ns.href("wechat://shop/material/addtextmaterial"));
|
||||
}
|
||||
var data = '';
|
||||
function getMaterailList(page){
|
||||
$.ajax({
|
||||
url: ns.url('wechat://shop/material/lists'),
|
||||
data: {
|
||||
page,
|
||||
},
|
||||
dataType: "JSON",
|
||||
success: function(res) {
|
||||
this.data = res.data.list;
|
||||
//列表渲染
|
||||
var str = ``;
|
||||
if(page == undefined || page == 1 || !page){
|
||||
str += `
|
||||
<li class="add-news">
|
||||
<div class="add-box">
|
||||
<i class="iconfont iconadd_light icon-hover"></i><br>
|
||||
<span>添加素材</span>
|
||||
<div class="add-li">
|
||||
<ul>
|
||||
<li onclick="add_tuwen()">
|
||||
<i class="iconfont icondoc_plaintext"></i> <span>添加图文</span>
|
||||
</li>
|
||||
<li onclick="add_text()">
|
||||
<i class="iconfont icontext"></i> <span>添加文字</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
|
||||
}
|
||||
$.each(this.data, function(index, item) {
|
||||
if(item.type == 1){
|
||||
str += `
|
||||
<li>
|
||||
<div class="del-edit">
|
||||
<a class="del" onclick="delMaterial(`+ item.id +`)" ><i class="iconfont iconshanchu"></i></a>
|
||||
<a href="`+ ns.href('wechat://shop/material/edit',{"id": item.id,'media_id':item.media_id,'type':item.type}) +`" target='_blank' class="edit"><i class="iconfont iconbianji-copy"></i></a>
|
||||
</div>
|
||||
<div class="meterail-img">
|
||||
<img src=" `+ item.value[0].cover.path +` " alt="">
|
||||
</div>
|
||||
<div class="material-content">
|
||||
<p class="meterail-text">`+ item.value[0].title +`</p>
|
||||
<p class="meterail-time">更新于<span>`+ ns.time_to_date(item.update_time) +`</span></p>
|
||||
</div>
|
||||
</li>
|
||||
`
|
||||
}else{
|
||||
str += `
|
||||
<li>
|
||||
<div class="del-edit">
|
||||
<a class="del" onclick="delMaterial(`+ item.id +`)"><i class="iconfont iconshanchu"></i></a>
|
||||
<a href="`+ ns.href('wechat://shop/material/edittextmaterial',{"id": item.id,'media_id':item.media_id,'type':item.type}) +`" target='_blank' class="edit"><i class="iconfont iconbianji-copy"></i></a>
|
||||
</div>
|
||||
<div class="meterail-title meterail-title-text">
|
||||
<p class="title">`+ item.value.content +`</p>
|
||||
</div>
|
||||
<div class="material-content">
|
||||
<p class="meterail-time">更新于<span>`+ ns.time_to_date(item.update_time) +`</span></p>
|
||||
</div>
|
||||
</li>
|
||||
`
|
||||
}
|
||||
|
||||
});
|
||||
$("#newsMaterialContent").html(str);
|
||||
//分页
|
||||
layui.use('laypage', function(){
|
||||
var laypage = layui.laypage;
|
||||
laypage.render({
|
||||
elem: 'MaterailList' ,
|
||||
curr: page, //当前页
|
||||
count: res.data.count,
|
||||
layout: ['count', 'prev', 'page', 'next'],
|
||||
jump: function(obj, first){
|
||||
//首次不执行
|
||||
if(!first){
|
||||
getMaterailList(obj.curr);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
getMaterailList();
|
||||
</script>
|
||||
93
src/addon/wechat/shop/view/material/material.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_menu.css">
|
||||
<script src="WECHAT_JS/common.js"></script>
|
||||
|
||||
<!-- 内容 -->
|
||||
{if $type == 1}
|
||||
<div class="layui-tab layui-tab-brief" id="marterial_graphic_message">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">图文消息</li>
|
||||
<!-- <li>高级图文</li> -->
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<table id="marterial_graphic_message_list" lay-filter="marterial_graphic_message"></table>
|
||||
<!-- 标题 -->
|
||||
<script type="text/html" id="graphic_message_title">
|
||||
<div class="layui-row grid-demo">
|
||||
{{# for (var index in d.value) { }}
|
||||
<div class="layui-col-md12 layui-clear">
|
||||
<div class="layui-col-md3 article-img" style="float:left;">
|
||||
<span style="color: #fff;padding: 2px 4px;background: #1aad19;">图文</span>
|
||||
</div>
|
||||
<div class="layui-col-md3 title" style="float:left;">
|
||||
<a href="javascript:void(0);" onclick="preview({{d.id}}, {{index}})">{{d.value[index].title}}</a>
|
||||
</div>
|
||||
</div>
|
||||
{{# } }}
|
||||
{{# if (d.value.length == 1) { }}
|
||||
<div class='layui-col-md12 read-all layui-clear' onclick="preview({{d.id}})">
|
||||
<div class='layui-col-md4' style="float:left;">阅读全文</div>
|
||||
<div class='layui-col-md4 layui-col-md-offset4'> </div>
|
||||
</div>
|
||||
{{# } }}
|
||||
</div>
|
||||
</script>
|
||||
<!-- 创建时间 -->
|
||||
<script type="text/html" id="create_time">
|
||||
<div>{{ ns.time_to_date(d.create_time) }}</div>
|
||||
</script>
|
||||
<!-- 修改时间 -->
|
||||
<script type="text/html" id="update_time">
|
||||
<div>{{ ns.time_to_date(d.update_time) }}</div>
|
||||
</script>
|
||||
<!-- 列表操作 -->
|
||||
<script type="text/html" id="operation">
|
||||
<a class="default layui-btn-sm hover_cursor text-color" style="cursor:pointer;" lay-event="choose">选取</a>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{else/}
|
||||
|
||||
<!-- 文本消息 -->
|
||||
<div class="layui-tab layui-tab-brief" id="material_text">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">文本消息</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<table id="material_text_list" lay-filter="material_text"></table>
|
||||
<!-- 内容 -->
|
||||
<script type="text/html" id="text_content">
|
||||
<div class="layui-row grid-demo">
|
||||
<div class="layui-col-md12 layui-clear">
|
||||
<div class="layui-col-md12 article-img" style="text-align: left;">
|
||||
<span style="color: #fff;padding: 2px 4px;">文本</span>
|
||||
</div>
|
||||
<div class="layui-col-md12 title line-hiding" style="float:left;">
|
||||
<a href="javascript:void(0);" onclick="previewText('{{d.value.content}}')" title="{{d.value.content}}">{{d.value.content}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<!-- 创建时间 -->
|
||||
<script type="text/html" id="create_time">
|
||||
<div>{{ ns.time_to_date(d.create_time) }}</div>
|
||||
</script>
|
||||
<!-- 修改时间 -->
|
||||
<script type="text/html" id="update_time">
|
||||
<div>{{ ns.time_to_date(d.update_time) }}</div>
|
||||
</script>
|
||||
<!-- 列表操作 -->
|
||||
<script type="text/html" id="operation">
|
||||
<a class="default layui-btn-sm hover_cursor text-color" style="cursor:pointer;" lay-event="choose">选取</a>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<script type="text/javascript" src="WECHAT_JS/wx_material_mannager.js"></script>
|
||||
<script type="text/javascript">
|
||||
loadMaterialList({$type});
|
||||
</script>
|
||||
91
src/addon/wechat/shop/view/material/material_list.html
Normal file
@@ -0,0 +1,91 @@
|
||||
<link rel="stylesheet" href="ADDON_WECHAT_CSS/wx_material.css">
|
||||
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class='mg'>
|
||||
<button class="layui-btn" onclick="window.open(ns.href('wechat://shop/material/addgraphicmessage'))">新建图文</button>
|
||||
</div>
|
||||
<div>
|
||||
<table id="graphic_message_list" lay-filter="graphic_message"></table>
|
||||
</div>
|
||||
<!-- 标题 -->
|
||||
<script type="text/html" id="title">
|
||||
<div class="layui-row grid-demo">
|
||||
{{# for (var index in d.value) { }}
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-col-md3 article-img">
|
||||
<span class="bg-color">图文</span>
|
||||
</div>
|
||||
<div class="layui-col-md8 title">
|
||||
<a class="graphic-message-title" href="javascript:void(0);" onclick="preview({{d.id}}, {{index}})">{{d.value[index].title}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{# } }}
|
||||
{{# if (d.value.length == 1) { }}
|
||||
<div class='layui-col-md12 read-all' onclick="preview({{d.id}})">
|
||||
<div class='layui-col-md4'>阅读全文</div>
|
||||
<div class='layui-col-md4 layui-col-md-offset4'> > </div>
|
||||
</div>
|
||||
{{# } }}
|
||||
</div>
|
||||
</script>
|
||||
<!-- 创建时间 -->
|
||||
<script type="text/html" id="create_time">
|
||||
<div>{{ ns.time_to_date(d.create_time) }}</div>
|
||||
</script>
|
||||
<!-- 修改时间 -->
|
||||
<script type="text/html" id="update_time">
|
||||
<div>{{ ns.time_to_date(d.update_time) }}</div>
|
||||
</script>
|
||||
<!-- 列表操作 -->
|
||||
<script type="text/html" id="operation">
|
||||
<a class="default" lay-event="edit">编辑</a>
|
||||
<a class="default" lay-event="delete">删除</a>
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<script src="ADDON_WECHAT_JS/wx_material.js"></script>
|
||||
<script>
|
||||
loadMaterialList(1);
|
||||
layui.use(['table','form'], function() {
|
||||
var table,
|
||||
form = layui.form;
|
||||
|
||||
table = new Table({
|
||||
elem: '#Fans_list',
|
||||
url: ns.url("wechat://shop/material/lists"),
|
||||
page: false,
|
||||
|
||||
cols: [
|
||||
[
|
||||
{
|
||||
field: 'title',
|
||||
title: '标题',
|
||||
unresize: 'false'
|
||||
}, {
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
unresize: 'false',
|
||||
templet: function(data) {
|
||||
return ns.time_to_date(data.create_time);
|
||||
}
|
||||
}, {
|
||||
field: 'update_time',
|
||||
title: '更新时间',
|
||||
unresize: 'false',
|
||||
templet: function(data) {
|
||||
return ns.time_to_date(data.update_time);
|
||||
}
|
||||
}, {
|
||||
title: '操作',
|
||||
toolbar: '#operation',
|
||||
align: 'right',
|
||||
unresize: 'false'
|
||||
}
|
||||
]
|
||||
],
|
||||
bottomToolbar: "#batchOperation"
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
48
src/addon/wechat/shop/view/material/preview_material.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="referrer" content="never">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0,viewport-fit=cover"/>
|
||||
<meta http-equiv="X-UA-COMPATIBLE" content="IE=edge,chrome=1">
|
||||
<title>{$info.value[$index]['title']}</title>
|
||||
<meta name="keywords" content="">
|
||||
<meta name="description" content="">
|
||||
<link rel="stylesheet" type="text/css" href="__STATIC__/ext/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="SITEHOME_CSS/home.css">
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_preview_graphic_message.css">
|
||||
<script src="__STATIC__/js/jquery-2.2.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class='preview-box'>
|
||||
<img class='head' src='WECHAT_IMG/mobile_head.png'/>
|
||||
<div class='graphic-message'>
|
||||
<h1 class='title'>{$info.value[$index]['title']}</h1>
|
||||
{if condition="$info.update_time eq 0"}
|
||||
<span class='time'>{$info['create_time']|time_to_date='Y-m-d'}</span>
|
||||
{else/}
|
||||
<span class='time'>{$info['update_time']|time_to_date='Y-m-d'}</span>
|
||||
{/if}
|
||||
<span class='author'>{$info.value[$index]['autor']}</span>
|
||||
<content>
|
||||
{if condition="$info.value[$index]['show_cover_pic'] == 1"}
|
||||
<div class="rich-media-thumb" id="media">
|
||||
<img onerror="this.parentNode.removeChild(this)" src="{$info.value[$index]['cover']['path']}">
|
||||
</div>
|
||||
{/if}
|
||||
{:html_entity_decode($info.value[$index]['content'])}
|
||||
</content>
|
||||
{if condition="!empty($info.value[$index]['url'])"}
|
||||
<a class='original-text' href="{$info.value[$index]['url']}">阅读原文</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
$(function () {
|
||||
$("img").each(function () {
|
||||
$(this).replaceWith(this);
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</html>
|
||||
32
src/addon/wechat/shop/view/material/preview_text.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="referrer" content="never">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0,viewport-fit=cover"/>
|
||||
<meta http-equiv="X-UA-COMPATIBLE" content="IE=edge,chrome=1">
|
||||
<meta name="keywords" content="">
|
||||
<meta name="description" content="">
|
||||
<link rel="stylesheet" type="text/css" href="__STATIC__/ext/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="SITEHOME_CSS/home.css">
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_preview_graphic_message.css">
|
||||
<script src="__STATIC__/js/jquery-2.2.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class='preview-box'>
|
||||
<img class='head' src='WECHAT_IMG/mobile_head.png'/>
|
||||
<div class='graphic-message'>
|
||||
<content>
|
||||
{:html_entity_decode($info.value['content'])}
|
||||
</content>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
$(function () {
|
||||
$("img").each(function () {
|
||||
$(this).replaceWith(this);
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</html>
|
||||
266
src/addon/wechat/shop/view/menu/menu.html
Normal file
@@ -0,0 +1,266 @@
|
||||
<link rel="stylesheet" href="WECHAT_CSS/wx_menu.css">
|
||||
<script src="WECHAT_JS/common.js"></script>
|
||||
|
||||
<div class='wx-menu' id='menu'>
|
||||
<div class='wx-menu-preview'>
|
||||
<div class='mobile-preview'>
|
||||
<div class='mobile-hd'>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class='mobile-bd'>
|
||||
<div class='wx-menu-list'>
|
||||
<template v-for="(item, index) in button">
|
||||
<div class="wx-menu-item-box" :class="['wx-menu-item-box-' + index]">
|
||||
<div class='wx-menu-item' :class="[index==menuIndex[0]&&-1==menuIndex[1] ? 'active' : '']" @click.stop='chooseMenu(index, -1)'>
|
||||
<template v-if="item.name == ''">
|
||||
<span>菜单名称</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>{{item.name}}</span>
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="index==menuIndex[0]">
|
||||
<div class='wx-sub-menu-list' v-if="item" :class="[button.length != undefined && button.length == 2 ? 'two' : '', button.length != undefined && button.length == 3 ? 'three' : '']">
|
||||
<div class='wx-sub-menu-item' :data="[second_index]" :class="[second_index==menuIndex[1] ? 'active' : '', 'wx-sub-menu-item-' + second_index]" v-for="(item2, second_index) in item.sub_button" @click.stop='chooseMenu(index, second_index)'>
|
||||
<template v-if="item2.name == ''">
|
||||
<span>子菜单名称</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>{{item2.name}}</span>
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="subMenuPlusShow">
|
||||
<div class='wx-sub-menu-item' @click.stop="addSubMenu(index)">+</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="button.length < 3">
|
||||
<div class='wx-menu-item-box add-menu' @click="addMenu()">+</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wx-menu-form'>
|
||||
<div class='button-list-null' v-if='menuIndex[0] == -1'>点击左侧按钮 + 添加菜单</div>
|
||||
<template v-if="menuIndex[0] != -1">
|
||||
<div class='form-editor'>
|
||||
<div class='form-hd'>
|
||||
<div class='form-hd-name'>{{name}}</div>
|
||||
<div class='form-hd-del'><a href="javascript:void(0);" class='layui-btn layui-btn-primary layui-btn-xs' @click='deleteMenu()'>删除菜单</a></div>
|
||||
</div>
|
||||
<div class='form-bd'>
|
||||
<div class='form-bd-list'>
|
||||
<div class='form-bd-item'>
|
||||
<label class='layui-form-label sm'>菜单名称</label>
|
||||
<div class='item-group'>
|
||||
<template v-if="menuIndex[1] == -1">
|
||||
<input type='text' class='input layui-input' :class="error_hint == 'name' ? 'error' : ''" value='' @keyup="checkName($event)" v-model='name' placeholder="请输入菜单名称">
|
||||
<p class="tip" :class="error_hint == 'name' ? 'error' : ''">字数不超过4个汉字或8个字母</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<input type='text' class='input layui-input' :class="error_hint == 'name' ? 'error' : ''" value='' @keyup="checkName($event, 'sub_button')" v-model='name' placeholder="请输入子菜单名称">
|
||||
<p class='tip' :class="error_hint == 'name' ? 'error' : ''">字数不超过8个汉字或16个字母</p>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-bd-item' v-if="(menuIndex[0] > -1 && (button[menuIndex[0]] == undefined || button[menuIndex[0]].sub_button == undefined || button[menuIndex[0]].sub_button[0] == undefined)) || (menuIndex[1] > -1)">
|
||||
<label class='layui-form-label sm'>菜单内容</label>
|
||||
<div class='item-group menu-type'>
|
||||
<label class='radio-label'>
|
||||
<i class='layui-icon' :class="type == 'media' ? 'layui-icon-radio' : 'layui-icon-circle'"></i>
|
||||
<input type='radio' name='type' id='type1' value='media' v-model='type'>
|
||||
<span>发送素材内容</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<i class='layui-icon' :class="type == 'view' ? 'layui-icon-radio' : 'layui-icon-circle'"></i>
|
||||
<input type='radio' name='type' id='type2' value='view' v-model='type'>
|
||||
<span>跳转到网页</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<i class='layui-icon' :class="type == 'miniprogram' ? 'layui-icon-radio' : 'layui-icon-circle'"></i>
|
||||
<input type='radio' name='type' id='type3' value='miniprogram' v-model='type'>
|
||||
<span>跳转小程序</span>
|
||||
</label>
|
||||
<label class='radio-label hide'>
|
||||
<i class='layui-icon' :class="type == 'custom_event' ? 'layui-icon-radio' : 'layui-icon-circle'"></i>
|
||||
<input type='radio' name='type' id='type4' value='custom_event' v-model='type'>
|
||||
<span>自定义事件</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='form-bd-content'>
|
||||
<div class='menu-content' v-if='type == "media"'>
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title wechat-media">
|
||||
<li :class="media_type == 'text' ? 'layui-this' : ''" @click="chooseMediaType(5)"><i class='layui-icon layui-icon-form'></i>文本消息</li>
|
||||
<li :class="media_type == 'graphic_message' ? 'layui-this' : ''" @click="chooseMediaType(1)"><i class='layui-icon layui-icon-tabs'></i>图文消息</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item" :class="media_type == 'text' ? 'layui-show' : ''">
|
||||
<template v-if="text == '' || text == undefined">
|
||||
<div class='material-library' @click="material(5)">
|
||||
<i></i>
|
||||
<span>从素材库选择</span>
|
||||
</div>
|
||||
<div class='add-material' @click="addMaterial(5)">
|
||||
<i></i>
|
||||
<span>添加文本素材</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class='text-message'>
|
||||
<div class='text-message-content'>
|
||||
<div class="material-type">
|
||||
<span>文本</span>
|
||||
</div>
|
||||
<div class="title">
|
||||
<a href="javascript:void(0);" @click="previewTexts(text)">{{text}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class='del' @click="deleteMaterial(5)">删除</span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="layui-tab-item" :class="media_type == 'graphic_message' ? 'layui-show' : ''">
|
||||
<template v-if="graphic_message[0] == undefined">
|
||||
<div class='material-library' @click="material(1)">
|
||||
<i></i>
|
||||
<span>从素材库选择</span>
|
||||
</div>
|
||||
<div class='add-material' @click="addMaterial(1)">
|
||||
<i></i>
|
||||
<span>新建图文素材</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class='graphic-message-list'>
|
||||
<template v-for="(value, index) in graphic_message">
|
||||
<div class='graphic-message-content'>
|
||||
<div class="material-type">
|
||||
<span>图文</span>
|
||||
</div>
|
||||
<div class="title">
|
||||
<a href="javascript:void(0);" @click="preview(value.id, index)">{{value.title}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="graphic_message.length == 1">
|
||||
<div class='read-all' @click="preview(value.id)">
|
||||
<div>阅读全文</div>
|
||||
<i> > </i>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<span class='del' @click="deleteMaterial(1)">删除</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='menu-content view' v-if='type == "view"'>
|
||||
<p class='tip' style="margin: 10px 0 20px 0;padding-left: 5px;">订阅者点击该子菜单会跳转到一下链接</p>
|
||||
<div class='form-bd-item'>
|
||||
<label class='layui-form-label sm'>页面地址</label>
|
||||
<div class='layui-input-inline'>
|
||||
<input type='text' class="input layui-input" value='' v-model='url' placeholder='例:http://example.com'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='menu-content menu' v-if='type == "miniprogram"'>
|
||||
<p class='tip' style="margin: 10px 0 20px 0;padding-left: 5px;">订阅者点击该子菜单会跳到以下小程序</p>
|
||||
<div class='layui-form-item'>
|
||||
<label class='layui-form-label'>备用网页</label>
|
||||
<div class='layui-input-block'>
|
||||
<input type='text' id='miniprogram_url' class="layui-input" value='' v-model='url' placeholder='例:http://example.com'>
|
||||
<p class='layui-form-mid layui-word-aux'>旧版微信客户端无法支持小程序,用户点击菜单时将会打开备用网页。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class='layui-form-item'>
|
||||
<label class='layui-form-label'>小程序APPID</label>
|
||||
<div class='layui-input-block'>
|
||||
<input type='text' class="layui-input" value='' v-model='appid'>
|
||||
<p class='layui-form-mid layui-word-aux'>小程序需要绑定当前公众号。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class='layui-form-item'>
|
||||
<label class='layui-form-label'>小程序页面路径</label>
|
||||
<div class='layui-input-inline'>
|
||||
<input type='text' class="layui-input" value='' v-model='pagepath'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='menu-content' v-if='type == "event"'>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='click' v-model='eventType'>
|
||||
<span>点击事件</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='scancode_push' v-model='eventType'>
|
||||
<span>扫码推事件</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='scancode_waitmsg' v-model='eventType'>
|
||||
<span>扫码推事件带提示</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='pic_sysphoto' v-model='eventType'>
|
||||
<span>弹出系统拍照发图</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='pic_photo_or_album' v-model='eventType'>
|
||||
<span>弹出拍照或者相册发图</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='pic_wechat' v-model='eventType'>
|
||||
<span>弹出微信相册发图器</span>
|
||||
</label>
|
||||
<label class='radio-label'>
|
||||
<input type='radio' name='eventType' value='location_select' v-model='eventType'>
|
||||
<span>弹出地理位置选择器</span>
|
||||
</label>
|
||||
<div class='form-bd-item'>
|
||||
<label class='item-label'>菜单KEY值</label>
|
||||
<div class='item-group'>
|
||||
<input type='text' class='input' value='' v-model='key'>
|
||||
<p class='tip'>旧版微信客户端无法支持小程序,用户点击菜单时将会打开备用网页。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='form-ft'>
|
||||
<button class='layui-btn' @click="saveMenu()">保存并发布</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加文本消息 -->
|
||||
<div class="layui-tab layui-tab-brief" id="add_material_text" style="display:none;">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">添加文本消息</li>
|
||||
</ul>
|
||||
<div class="layui-form" style="margin-top: 20px;">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label sm">内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" placeholder="请输入内容" id="material_text_content" class="layui-textarea" maxlength="300" lay-verify='material_text_content'></textarea>
|
||||
<span class='input-text-hint'>剩余300字</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row sm">
|
||||
<button class="layui-btn" lay-submit lay-filter="addText">保存</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary" onclick="back()">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="STATIC_JS/vue.js"></script>
|
||||
<script type="text/javascript" src="WECHAT_JS/wx_menu.js?v=1"></script>
|
||||
<script type="text/javascript" src="WECHAT_JS/wx_material_mannager.js"></script>
|
||||
211
src/addon/wechat/shop/view/message/config.html
Normal file
@@ -0,0 +1,211 @@
|
||||
<style>
|
||||
.card-common .layui-card-header{ padding-bottom: 10px; }
|
||||
</style>
|
||||
<div class="layui-collapse tips-wrap">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">操作提示</h2>
|
||||
<ul class="layui-colla-content layui-show">
|
||||
<li>注意:请将微信公众号服务类目选择为:商业服务——>软件/建站/技术开发,生活服务——>百货/超市/便利店,工具—>信息查询,所选行业不一致将会导致模板消息不可用。</li>
|
||||
<li>公众号可设置20个服务类目,每月只能修改5次,请谨慎选择。</li>
|
||||
<li>公众号最多支持25个模板消息,获取时请注意公众号剩余模板数量是否充足</li>
|
||||
<li>所需跳转到的小程序必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form">
|
||||
<div class="layui-card card-common card-brief top">
|
||||
<div class="layui-card-header">
|
||||
<span class="card-title">是否需跳转到小程序</span>
|
||||
<input type="checkbox" name="" value="1" lay-skin="switch" lay-filter="is_jump_weapp" {if $config.is_jump_weapp == 1} checked {/if} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="template_list" lay-filter="template_list"></table>
|
||||
|
||||
<script type="text/html" id="batchOperation">
|
||||
<button class="layui-btn layui-btn-primary" lay-event="open">批量开启</button>
|
||||
<button class="layui-btn layui-btn-primary" lay-event="close">批量关闭</button>
|
||||
<button class="layui-btn layui-btn-primary" lay-event="getAll">批量获取</button>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="operation">
|
||||
<div class="table-btn">
|
||||
{{# if(d.wechat_is_open == 0){ }}
|
||||
<a class="layui-btn" lay-event="open">开启</a>
|
||||
{{# }else{ }}
|
||||
<a class="layui-btn" lay-event="close">关闭</a>
|
||||
{{# } }}
|
||||
|
||||
{{# if(d.wechat_template_id != undefined && d.wechat_template_id != ''){ }}
|
||||
<a class="layui-btn" lay-event="getTemplateNo">重新获取</a>
|
||||
{{# } }}
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="message_type">
|
||||
{{ d.message_type == 1 ? '买家消息' : '卖家消息' }}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="template_no">
|
||||
{{ d.wechat_template_id ? d.wechat_template_id : '' }}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="wechat_is_open">
|
||||
{{ d.wechat_is_open == 1 ? '已启动' : '已关闭' }}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var form,table;
|
||||
layui.use(['form'], function() {
|
||||
form = layui.form;
|
||||
form.render();
|
||||
var repeat_flag = false;//防重复标识
|
||||
|
||||
form.on('switch(is_jump_weapp)', function (data) {
|
||||
data.value = data.elem.checked ? data.value : 0;
|
||||
|
||||
$.ajax({
|
||||
dataType: "JSON",
|
||||
type: "POST",
|
||||
data: {"is_jump_weapp": data.value},
|
||||
url: ns.url("wechat://shop/message/messageConfig"),
|
||||
success: function (res) {
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
table = new Table({
|
||||
elem: '#template_list',
|
||||
url: ns.url("wechat://shop/message/config"),
|
||||
cols: [
|
||||
[
|
||||
{
|
||||
width: "3%",
|
||||
type: 'checkbox',
|
||||
unresize: 'false'
|
||||
},
|
||||
{
|
||||
field: 'title',
|
||||
title: '类型',
|
||||
align: 'left'
|
||||
},
|
||||
{
|
||||
field: 'message_type',
|
||||
title: '消息类型',
|
||||
templet: '#message_type',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
field: 'wechat_is_open',
|
||||
title: '是否启用',
|
||||
templet: '#wechat_is_open',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
field: 'wechat_template_id',
|
||||
title: '编号',
|
||||
align: 'center',
|
||||
templet: '#template_no'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
toolbar: '#operation',
|
||||
align: 'right'
|
||||
}
|
||||
]
|
||||
],
|
||||
bottomToolbar: "#batchOperation"
|
||||
});
|
||||
|
||||
// 批量操作
|
||||
table.bottomToolbar(function (obj) {
|
||||
|
||||
if (obj.data.length < 1) {
|
||||
layer.msg('请选择要操作的数据');
|
||||
return;
|
||||
}
|
||||
|
||||
var keywords_array = new Array();
|
||||
for (i in obj.data) keywords_array.push(obj.data[i].keywords);
|
||||
switch (obj.event) {
|
||||
case 'open':
|
||||
// 开启
|
||||
setStatus(keywords_array.toString(), 1);
|
||||
break;
|
||||
case 'close':
|
||||
// 关闭
|
||||
setStatus(keywords_array.toString(), 0);
|
||||
break;
|
||||
case 'getAll':
|
||||
// 批量获取
|
||||
getTemplate(keywords_array.toString());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 监听工具栏操作
|
||||
*/
|
||||
table.tool(function (obj) {
|
||||
var data = obj.data;
|
||||
switch (obj.event) {
|
||||
case 'getTemplateNo': //获取模板id
|
||||
getTemplate(data.keywords);
|
||||
break;
|
||||
case 'open': //开启
|
||||
setStatus(data.keywords, 1);
|
||||
break;
|
||||
case 'close': //关闭
|
||||
setStatus(data.keywords, 0);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function setStatus(keywords, status) {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: '{:addon_url("wechat://shop/message/setWechatStatus")}',
|
||||
data: {
|
||||
"wechat_is_open": status,
|
||||
'keywords': keywords
|
||||
},
|
||||
dataType: "JSON",
|
||||
success: function (res) {
|
||||
repeat_flag = false;
|
||||
layer.msg(res.message);
|
||||
table.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getTemplate(keywords) {
|
||||
var loadLayer;
|
||||
layer.confirm('已存在的模板再次获取会导致模板重复存在,是否继续?', function (index) {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: '{:addon_url("wechat://shop/message/getWechatTemplateNo")}',
|
||||
data: {
|
||||
'keywords': keywords
|
||||
},
|
||||
dataType: "JSON",
|
||||
beforeSend: function () {
|
||||
loadLayer = layer.msg("模板获取中,请耐心等待,请勿进行其他操作!", {time: 1000 * 10000});
|
||||
},
|
||||
complete: function () {
|
||||
layer.close(loadLayer);
|
||||
},
|
||||
success: function (res) {
|
||||
repeat_flag = false;
|
||||
layer.msg(res.message);
|
||||
layer.close(index);
|
||||
table.reload();
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
84
src/addon/wechat/shop/view/message/edit.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">是否开启:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" name="wechat_is_open" value="1" {if $wechat_is_open == 1}checked{/if} lay-skin="switch">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">模板名称:</label>
|
||||
<div class="layui-input-block">
|
||||
{$message_title}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">模板消息ID:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="template_id" value="{if $info}{$info.template_id_short}{/if}" placeholder="模板消息ID" autocomplete="off" class="layui-input len-long" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">类目模板:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="keyword_name_list" value="{if $info && isset($info.keyword_name_list)}{$info.keyword_name_list}{/if}" placeholder="类目模板,多个逗号隔开" autocomplete="off" class="layui-input len-long" readonly>
|
||||
</div>
|
||||
<div class="word-aux">类目模板的关键词,多个逗号隔开</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label"><span class="required"></span>模板内容:</label>
|
||||
<div class="layui-input-inline">
|
||||
<textarea placeholder="" class="layui-textarea len-long" readonly>{if $info}{$info.content}{/if}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="keywords" value="{$keywords}" />
|
||||
|
||||
<div class="form-row">
|
||||
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary" onclick="backMessageList()">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['form', 'colorpicker'], function() {
|
||||
var form = layui.form,
|
||||
repeat_flag = false; //防重复标识
|
||||
form.render();
|
||||
|
||||
form.on('submit(save)', function(data) {
|
||||
if (repeat_flag) return;
|
||||
repeat_flag = true;
|
||||
|
||||
$.ajax({
|
||||
url: ns.url("wechat://shop/Message/edit"),
|
||||
data: data.field,
|
||||
dataType: 'JSON',
|
||||
type: 'POST',
|
||||
success: function(res) {
|
||||
repeat_flag = false;
|
||||
|
||||
if (res.code == 0) {
|
||||
layer.confirm('编辑成功', {
|
||||
title:'操作提示',
|
||||
btn: ['返回列表', '继续操作'],
|
||||
yes: function(index, layero){
|
||||
location.hash = ns.hash("shop/message/lists")
|
||||
layer.close(index);
|
||||
},
|
||||
btn2: function(index, layero) {
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
}else{
|
||||
layer.msg(res.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function backMessageList() {
|
||||
location.hash = ns.hash("shop/message/lists");
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
.access-statistics .access-api-list{display: flex;justify-content: space-between;padding: 0 15px;}
|
||||
.access-statistics .access-api-item{flex-grow: 1;text-align: center;margin-right: 10px;border: 1px solid #e5e5e5;padding-top: 25px;}
|
||||
.access-statistics .access-api-item:last-of-type{margin-right:0;}
|
||||
.access-statistics .access-api-itme-content{height: 80px; line-height: 80px; font-size: 30px;}
|
||||
.access-statistics .access-api-item-title{position: relative;}
|
||||
.access-statistics .access-api-item-title h3{display: inline-block;}
|
||||
.access-statistics .access-api-vice-content{font-size: 25px;}
|
||||
.layui-fluid .layui-tab-title{margin-top: 0;}
|
||||
.layui-tab-content-time{display: inline-block; height: 40px; margin-left: 15px; line-height: 40px;}
|
||||
101
src/addon/wechat/shop/view/public/css/wx_fans.css
Normal file
@@ -0,0 +1,101 @@
|
||||
.date-picker-btn.selected {
|
||||
background-color: var(--base-color);
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.search_form {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.search_form .reset {
|
||||
background: transparent;
|
||||
border: none;
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search_form .layui-form-mid {
|
||||
display: inline-block;
|
||||
float: unset;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.search_form .layui-btn+.layui-btn {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.layui-table {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.layui-layer-content {
|
||||
padding: 15px;
|
||||
height: auto!important;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.headimg-box {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: inline-block;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.headimg-box img{
|
||||
max-width: 50px;
|
||||
max-height: 50px;
|
||||
margin: auto;
|
||||
}
|
||||
.layui-table-cell{
|
||||
text-overflow: ellipsis;
|
||||
overflow: initial !important;
|
||||
white-space: initial;
|
||||
}
|
||||
.tag-list{
|
||||
display: inline-block;
|
||||
line-height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tag-list span{
|
||||
margin: 2px;
|
||||
padding: 2px 5px;
|
||||
border-radius: 2px;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.progress-layer {
|
||||
width: 400px;
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
box-shadow: 1px 1px 50px rgba(0,0,0,.3);
|
||||
padding: 20px 20px;
|
||||
z-index: 100;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.progress-layer h3{
|
||||
line-height: 1;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.progress-layer .layui-progress-big, .progress-layer .layui-progress-big .layui-progress-bar{
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.progress-layer .layui-progress-text{
|
||||
line-height: 14px;
|
||||
}
|
||||
742
src/addon/wechat/shop/view/public/css/wx_follow.css
Normal file
@@ -0,0 +1,742 @@
|
||||
.layui-layout-admin .layui-body .body-content{
|
||||
background: #f8f8f8;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.fourstage-nav .layui-tab-title {
|
||||
background: #fff;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.fourstage-nav .layui-tab-title li {
|
||||
line-height: 48px;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
button, input, select, textarea {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input:-moz-placeholder, textarea:-moz-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
a:-webkit-any-link {
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.reply-opts a:-webkit-any-link{
|
||||
color: var(--base-color);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.reply-opts .delet-color:-webkit-any-link {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
padding: 0 22px;
|
||||
min-width: 54px;
|
||||
line-height: 2.42857143;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.layui-body {
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-title h2 {
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.type-menu {
|
||||
text-align: left;
|
||||
height: 50px;
|
||||
line-height: 40px;
|
||||
border-bottom: 1px solid #E0E1E2;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.type-menu li {
|
||||
float: left;
|
||||
margin-right: 24px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.replay-info {
|
||||
padding: 15px 0 0;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.weixin-normal {
|
||||
position: relative;
|
||||
margin-top: 15px
|
||||
}
|
||||
|
||||
.replay-info .info {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.replay-info h3 {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.replay-info h3:last-child {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.replay-button {
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.replay-button>div {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.replay-button:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.replay-button>label {
|
||||
background-color: #1AAD19;
|
||||
border-color: #1AAD19;
|
||||
color: #FFFFFF;
|
||||
display: inline-block;
|
||||
min-width: 54px;
|
||||
line-height: 2.42857143;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.replay-button .layui-layer-page {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.replay-button .layui-form>.layui-btn {
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.replay-button label>input {
|
||||
position: absolute;
|
||||
left: -9999em;
|
||||
}
|
||||
|
||||
.replay-button .search {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: .5em;
|
||||
width: 243px;
|
||||
}
|
||||
|
||||
.replay-button .down {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.replay-button .down button {
|
||||
padding: 14px 12px 10px 12px;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.down .show-menu li a {
|
||||
color: #00A717;
|
||||
}
|
||||
|
||||
.down .show-menu li a {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.rule-group {
|
||||
position: relative;
|
||||
/* border: 1px solid #ccc; */
|
||||
margin-bottom: 20px;
|
||||
border-radius: 2px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta:hover h3 .rule-opts a {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 {
|
||||
width: 300px;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
line-height: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 .rule-opts {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -65px;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 .rule-opts a {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.rule-group .rule-body {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
margin: 0;
|
||||
/*padding-top: 5px;*/
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.rule-group .rule-body:before, .rule-group .rule-body:after {
|
||||
display: table;
|
||||
content: "";
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.rule-group .long-dashed {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
width: 100%;
|
||||
border-bottom: 1px dashed #d7d7d7;
|
||||
}
|
||||
|
||||
.weixin-normal .rule-keywords {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner {
|
||||
font-size: 12px;
|
||||
padding: 0 10px 5px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner h4 {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
margin: 0 0 5px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.rule-group .keyword-containe {
|
||||
padding-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.rule-group .info:empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.keyword-list .keyword {
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
height: 30px;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.keyword .close--circle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.keyword-list .keyword:hover .close--circle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.close--circle {
|
||||
position: absolute;
|
||||
z-index: 91;
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
font-size: 28px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.keyword .value {
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #555555;
|
||||
vertical-align: middle;
|
||||
border-radius: 4px 0 0 4px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.input-append .add-on, .input-prepend .add-on {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
height: 20px;
|
||||
min-width: 16px;
|
||||
padding: 4px 5px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -4px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.rule-group hr.dashed {
|
||||
border-bottom: 1px dashed #d7d7d7;
|
||||
border-top: none;
|
||||
margin: 0;
|
||||
background-color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.rule-group .opt {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.rule-group .opt a {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.weixin-normal .rule-replies {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner {
|
||||
font-size: 12px;
|
||||
padding: 0 10px 5px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner h4 {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
margin: 0 0 5px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.rule-group .reply-container, .keyword-container {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.rule-group .info {
|
||||
padding: 5px 0;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.rule-group .info:empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol.reply-list {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.reply-list li, .quick-dropmenu li {
|
||||
position: relative;
|
||||
padding: 8px 90px 8px 5px;
|
||||
list-style: unset;
|
||||
}
|
||||
|
||||
.reply-list .reply-opts a:hover {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.reply-cont {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.reply-summary {
|
||||
display: inline-block;
|
||||
max-width: 360px;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reply-list .reply-opts, .quick-dropmenu .reply-opts {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.reply-list li::after, .quick-dropmenu li::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
border-bottom: 1px dashed #d7d7d7;
|
||||
bottom: 0;
|
||||
left: -20px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.reply-list li:last-child::after, .quick-dropmenu li:last-child::after {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.rule-group .opt .disable-opt {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.badge-success, .label-success {
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
background: #1AAD19;
|
||||
}
|
||||
/***************************************/
|
||||
.misc {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.misc>a {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
color: var(--base-color) !important
|
||||
}
|
||||
|
||||
.others {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.others>a {
|
||||
padding: 10px;
|
||||
color: var(--base-color) !important
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
color: #ccc;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
top: 25px;
|
||||
left: 10px;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
font-size: 12px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 10px 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.dropdown-menu li {
|
||||
padding: 0 10px;
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.others:hover .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropdown-menu li:hover {
|
||||
background: var(--base-color);
|
||||
}
|
||||
|
||||
.dropdown-menu li:hover a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.complex-backdrop {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 25px;
|
||||
width: 86%;
|
||||
height: 36.5%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.complex-content {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.ng.ng-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ng {
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
width: 250px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
margin-bottom: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.picture>img {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.msg-music-thumb {
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.msg-music-thumb a {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px dashed #F2F2F2;
|
||||
display: block;
|
||||
line-height: 100px;
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
#music .layui-textarea {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.voice-player {
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
border: 1px solid #85ac4c;
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 25px;
|
||||
padding: 0 6px 0 7px;
|
||||
font-size: 12px !important;
|
||||
line-height: 25px;
|
||||
cursor: pointer;
|
||||
background: #a0ce3d;
|
||||
vertical-align: middle;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.voice-player::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -13px;
|
||||
top: 6px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-right: 6px solid #85ac4c;
|
||||
}
|
||||
|
||||
.voice-player .stop {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 1px #8ab433;
|
||||
}
|
||||
|
||||
.popover .close--circle {
|
||||
z-index: initial;
|
||||
}
|
||||
|
||||
.complex-content .close--circle ,.keyword-list .close--circle {
|
||||
position: absolute;
|
||||
z-index: 91;
|
||||
top: -9px;
|
||||
right: -9px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: rgba(153, 153, 153, 0.6);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.voice-player .second {
|
||||
display: none;
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
color: #476600;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.voice-player .play {
|
||||
display: inline-block;
|
||||
width: 17px;
|
||||
height: 20px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.voice-player::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -12px;
|
||||
top: 6px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-right: 6px solid #a0ce3d;
|
||||
}
|
||||
/*其他*/
|
||||
.ng .close--circle {
|
||||
top: -9px;
|
||||
right: -9px;
|
||||
}
|
||||
|
||||
.ng .ng-item {
|
||||
border-bottom: 1px solid #eee;
|
||||
overflow: hidden;
|
||||
padding: 5px 9px;
|
||||
}
|
||||
|
||||
.ng .label {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/*图文*/
|
||||
.ng .ng-title {
|
||||
display: inline-block !important;
|
||||
overflow: hidden !important;
|
||||
white-space: nowrap !important;
|
||||
text-overflow: ellipsis !important;
|
||||
line-height: 16px;
|
||||
min-height: 16px;
|
||||
vertical-align: middle;
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
a.new-window {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.ng .ng-item.view-more {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.ng .ng-item.view-more a {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
.rule-container {
|
||||
/*position: absolute;*/
|
||||
/*padding: 5px 10px;*/
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
/*box-shadow: 0px 1px 6px 7px rgba(0, 0, 0, 0.1);*/
|
||||
/*border: 1px solid #e5e5e5; */
|
||||
/*height: 230px;*/
|
||||
/*width: 460px;*/
|
||||
}
|
||||
|
||||
.rule-container .add_reply-top{
|
||||
position: absolute;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
line-height: 0px;/*为了防止ie下出现题型*/
|
||||
border-bottom: 10px solid #fff;
|
||||
border-left: 10px solid rgba(0,0,0,0);
|
||||
border-right: 10px solid rgba(0,0,0,0);
|
||||
right: 55px;
|
||||
top: -10px;
|
||||
}
|
||||
|
||||
.popover>.close--circle {
|
||||
top: -5px;
|
||||
right: -5px;
|
||||
}
|
||||
|
||||
.rule-container .arrow {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
top: 50%;
|
||||
left: -13px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.rule-container .arrow i {
|
||||
color: #e5e5e5;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.layui-card-body, .layui-card-header, .layui-form-label, .layui-form-mid,
|
||||
.layui-form-select, .layui-input-block, .layui-input-inline,
|
||||
.layui-textarea {
|
||||
position: unset;
|
||||
}
|
||||
|
||||
.rule-group-container {
|
||||
min-height: 165px
|
||||
}
|
||||
|
||||
.layui-layer-btn .layui-layer-btn1:hover{
|
||||
color: #333 !important;
|
||||
}
|
||||
.layui-layer-btn a:hover{
|
||||
color: #fff !important;
|
||||
}
|
||||
338
src/addon/wechat/shop/view/public/css/wx_graphic_message.css
Normal file
@@ -0,0 +1,338 @@
|
||||
#graphic_message {
|
||||
/*width: 760px;*/
|
||||
margin-bottom: 90px;
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.layui-elem-quote{
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message {
|
||||
position: relative;
|
||||
width: 320px;
|
||||
min-height: 310px;
|
||||
float: left;
|
||||
border: 1px solid #C5C5C5;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box {
|
||||
position: relative;
|
||||
margin-top: 80px;
|
||||
width: 380px;
|
||||
min-height: 400px;
|
||||
float: left;
|
||||
padding: 15px;
|
||||
margin-left: 20px;
|
||||
border: 1px solid #d1d1d1;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#graphic_message .arrow, #graphic_message .arrow::after {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 7px 7px 6px 0;
|
||||
border-color: transparent #d1d1d1 transparent transparent;
|
||||
position: absolute;
|
||||
left: -7px;
|
||||
top: 19px;
|
||||
}
|
||||
|
||||
#graphic_message .arrow::after {
|
||||
content: "";
|
||||
border-right-color: #f8f8f8;
|
||||
left: 1px;
|
||||
top: -7px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li {
|
||||
border: 1px solid #AAA;
|
||||
border-top-color: #FFF;
|
||||
border-bottom-color: #DDD;
|
||||
background: #FFF;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child {
|
||||
border-top-color: #AAA;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:last-child {
|
||||
border-bottom-color: #AAA;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li content {
|
||||
display: block;
|
||||
margin: 10px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child content {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li .title {
|
||||
padding-right: 70px;
|
||||
max-height: 48px;
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child .title {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
color: #FFF;
|
||||
z-index: 2;
|
||||
line-height: 30px;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
max-height: unset;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child .title span {
|
||||
padding: 2px 7px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li .title span {
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li .action {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#graphic_message .action span.edit, #graphic_message .action span.delete {
|
||||
background: rgba(0, 0, 0, .4);
|
||||
color: #FFF;
|
||||
font-size: 14px;
|
||||
padding: 0 5px;
|
||||
display: inline-block;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li content img {
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
border: 0;
|
||||
float: right;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li content .empty-img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
float: right;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child content img {
|
||||
width: 268px;
|
||||
height: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child content .empty-img {
|
||||
width: 268px;
|
||||
height: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li content .empty-hint {
|
||||
height: 20px;
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -5px;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
color: #AAA;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#graphic_message .graphic-message-list li:first-child content .empty-hint {
|
||||
height: 20px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 7px;
|
||||
margin: auto;
|
||||
color: #AAA;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#editor {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#graphic_message .add-graphic-message h4::before {
|
||||
top: -19px;
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
border: 8px solid transparent;
|
||||
border-bottom-width: 10px;
|
||||
border-bottom-color: #ddd;
|
||||
left: 148px;
|
||||
}
|
||||
|
||||
#graphic_message .add-graphic-message h4::after {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
border: 8px solid transparent;
|
||||
border-bottom-width: 10px;
|
||||
border-bottom-color: #f8f8f8;
|
||||
top: -16px;
|
||||
left: 148px;
|
||||
}
|
||||
|
||||
#graphic_message .add-graphic-message h4 {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
-webkit-box-shadow: 0 0 0 1px #ddd;
|
||||
box-shadow: 0 0 0 1px #ddd;
|
||||
padding: 0 6px 4px 10px;
|
||||
width: 304px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#graphic_message .add-graphic-message h4 a {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
font-weight: bold;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#graphic_message .layui-input {
|
||||
width: 270px;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box label {
|
||||
display: inline-block;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box label .hint {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box .editor-cover,
|
||||
#graphic_message .editor-box .editor-author,
|
||||
#graphic_message .editor-box .editor-title,
|
||||
#graphic_message .editor-box .editor-content {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box .editor-cover .editor-msg-label {
|
||||
position: relative;
|
||||
padding-left: 17px;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box .editor-cover #check_show_cover_pic {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 1px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box .editor-cover .choose-cover {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
#graphic_message .editor-box .editor-cover .choose-cover a {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#edui1_bottombar.edui-editor-bottomContainer.edui-default {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bottom-botton {
|
||||
position: absolute;
|
||||
padding: 20px 0;
|
||||
width: auto;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: -80px;
|
||||
text-align: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
padding-top: 20%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.loading .layui-icon {
|
||||
font-size: 39px;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block !important;
|
||||
}
|
||||
.choose-cover-pic{
|
||||
margin-bottom: 10px;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
text-align: center;
|
||||
line-height: 160px;
|
||||
}
|
||||
.choose-cover-pic img{
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
106
src/addon/wechat/shop/view/public/css/wx_leavemsg.css
Normal file
@@ -0,0 +1,106 @@
|
||||
.user_info{
|
||||
position: relative;
|
||||
/* margin-left: 80px;
|
||||
margin-right: 215px; */
|
||||
}
|
||||
.message_info{
|
||||
margin-left:80px;
|
||||
margin-right:80px;
|
||||
width:auto;
|
||||
}
|
||||
.user_info .avatar{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left:16px;
|
||||
}
|
||||
.user_info img{
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
|
||||
}
|
||||
|
||||
.layui-table .layui-table-cell{
|
||||
padding:1px;
|
||||
}
|
||||
.layui-table thead tr{
|
||||
display:none;
|
||||
}
|
||||
.message_content{
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
color: #8d8d8d;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space:normal;
|
||||
}
|
||||
.layui-icon-reply-fill:hover{
|
||||
color:#393D49 !important;
|
||||
}
|
||||
.headimg{
|
||||
width:80px;
|
||||
}
|
||||
.message_list{
|
||||
font-size:14px;
|
||||
min-height: 46px;
|
||||
/* border: 1px solid #e7e7eb;
|
||||
padding: 15px;*/
|
||||
}
|
||||
.message_time{
|
||||
margin-top: 0;
|
||||
color: #8d8d8d;
|
||||
}
|
||||
.layui-table tbody tr:hover,.layui-table-click{
|
||||
background-color:#FFF;
|
||||
}
|
||||
.layui-table tbody tr{
|
||||
border:none;
|
||||
}
|
||||
.reply-box{
|
||||
display:none;
|
||||
border-top:1px solid #e7e7eb;
|
||||
padding-top:15px;
|
||||
padding-left:80px;
|
||||
padding-right:80px;
|
||||
}
|
||||
.layui-table-header{
|
||||
border:none;
|
||||
}
|
||||
.reply-button{
|
||||
padding-top:15px;
|
||||
}
|
||||
.reply-button button{
|
||||
min-width:100px;
|
||||
}
|
||||
.userinfo-box-headimg{
|
||||
float: left;
|
||||
width: 230px;
|
||||
height: 230px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.userinfo-box-user-info{
|
||||
overflow: hidden;
|
||||
height: 230px;
|
||||
position: relative;
|
||||
}
|
||||
.userinfo-box-user-info-title{
|
||||
width:20px;
|
||||
margin-right:10px;
|
||||
color: #8d8d8d;
|
||||
}
|
||||
.userinfo-box-user-info-content{
|
||||
font-weight:normal;
|
||||
}
|
||||
.layui-layer-tips{
|
||||
width:auto !important;
|
||||
}
|
||||
.userinfo-box-user-info .layui-card-body{
|
||||
color: #333;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.userinfo-box-user-info-header-title{
|
||||
margin-right:200px;
|
||||
}
|
||||
.layui-tab-title{
|
||||
margin-bottom:15px;
|
||||
}
|
||||
280
src/addon/wechat/shop/view/public/css/wx_material.css
Normal file
@@ -0,0 +1,280 @@
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.layui-table-page {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layui-table-cell {
|
||||
height: auto;
|
||||
line-height: 28px;
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
/* ----------------------------------GRAPHIC_MESSAGE_LIST----------------------------- */
|
||||
#graphic_message_list + div .layui-table-box .layui-table td {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-row.grid-demo {
|
||||
border: 1px solid #DEDEDE;
|
||||
border-radius: 5px;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.article-img span {
|
||||
padding: 2px 4px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12 {
|
||||
padding: 2px 0;
|
||||
border-bottom: 1px solid #DEDEDE;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12.read-all {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12:first-child {
|
||||
padding: 7px 0;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3 {
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.title {
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.title a {
|
||||
color: #0d73f9;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md4 {
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md4.layui-col-md-offset4 {
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
a.graphic-message-title {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* ----------------------------------MATERIAL_GRAPHIC_MESSAGE_LIST----------------------------- */
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-row.grid-demo {
|
||||
border: 1px solid #DEDEDE;
|
||||
border-radius: 5px;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.article-img span {
|
||||
background: green;
|
||||
color: #FFF;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12 {
|
||||
padding: 2px 0;
|
||||
border-bottom: 1px solid #DEDEDE;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12.read-all {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12:first-child {
|
||||
padding: 7px 0;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3 {
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.title {
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
width: 150px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.title a {
|
||||
color: #0d73f9;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md4 {
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#marterial_graphic_message_list + div .layui-table-box .layui-table td[data-field='value'] .layui-col-md4.layui-col-md-offset4 {
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* ----------------------------------material_text----------------------------- */
|
||||
#material_text div .layui-table-box .layui-table td {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-row.grid-demo {
|
||||
border: 1px solid #DEDEDE;
|
||||
border-radius: 5px;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.article-img span {
|
||||
background: green;
|
||||
color: #FFF;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12 {
|
||||
padding: 2px 0;
|
||||
border-bottom: 1px solid #DEDEDE;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12.read-all {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12:first-child {
|
||||
padding: 7px 0;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md12:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3 {
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.title {
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
width: 150px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md3.title a {
|
||||
color: #0d73f9;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md4 {
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#material_text div .layui-table-box .layui-table td[data-field='value'] .layui-col-md4.layui-col-md-offset4 {
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* --------------------------------ADD_MATERIAL_TEXT -------------------------------------- */
|
||||
#add_material_text form.layui-form {
|
||||
padding: 15px;
|
||||
padding-right: 50px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#add_material_text .input-text-hint {
|
||||
float: right;
|
||||
color: #AAA;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* -------------------------------- MATERIAL_IMAGE -----------------------------------------*/
|
||||
#material_image .img-list {
|
||||
padding-top: 26px;
|
||||
text-align: center;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
#material_image .img-list::after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#material_image .img-list .layui-col-md2 .img {
|
||||
display: inline-block;
|
||||
background: #ccc;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
text-align: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover !important;
|
||||
background-position: 50% !important;
|
||||
}
|
||||
|
||||
#material_image .buttom-button {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 50%;
|
||||
margin-left: -66px;
|
||||
}
|
||||
|
||||
#material_image .img-list p.layui-elip {
|
||||
max-width: 110px;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
|
||||
#material_image .img-list .img-check-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 11px;
|
||||
right: 11px;
|
||||
bottom: 26px;
|
||||
line-height: 120px;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
#material_image .img-list .img-check-mask[data-show='false'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#material_image .img-list .layui-icon-ok {
|
||||
color: #FFF;
|
||||
font-size: 36px;
|
||||
}
|
||||
.article-img .bg-color {
|
||||
color: #fff;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
442
src/addon/wechat/shop/view/public/css/wx_menu.css
Normal file
@@ -0,0 +1,442 @@
|
||||
.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.wx-menu {
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.wx-menu-preview {
|
||||
width: 320px;
|
||||
height: 570px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mobile-preview {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
border: 1px solid #e7e7eb;
|
||||
}
|
||||
|
||||
.mobile-hd {
|
||||
height: 25px;
|
||||
padding-top: 35px;
|
||||
color: #FFF;
|
||||
background: #000;
|
||||
font-size: 16px;
|
||||
background-image: url(../img/mobile_head.png);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mobile-bd {
|
||||
height: 50px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-top: 1px solid #e7e7eb;
|
||||
background: transparent url(../img/mobile_foot_default.png) no-repeat 0 0;
|
||||
}
|
||||
|
||||
.wx-menu-list {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
padding-left: 43px;
|
||||
}
|
||||
|
||||
.wx-menu-item-box {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
color: #616161;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wx-menu-item-box.add-menu {
|
||||
border-left: 1px solid #e7e7eb;
|
||||
}
|
||||
|
||||
.wx-menu-item {
|
||||
border-left: 1px solid #e7e7eb;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wx-menu-item.active, .wx-sub-menu-item.active {
|
||||
border: 1px solid;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.wx-sub-menu-list {
|
||||
position: absolute;
|
||||
bottom: 62px;
|
||||
width: 136px;
|
||||
border: 1px solid #d0d0d0;
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.wx-sub-menu-list.two, .wx-sub-menu-list.three {
|
||||
width: 90.328px;
|
||||
}
|
||||
|
||||
.wx-sub-menu-list.active-second {
|
||||
left: 134.328px;
|
||||
}
|
||||
|
||||
.wx-sub-menu-list.active-third {
|
||||
left: 226.328px;
|
||||
}
|
||||
|
||||
.wx-sub-menu-item {
|
||||
border-top: 1px solid #d0d0d0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wx-menu-item, .wx-sub-menu-item {
|
||||
line-height: 50px;
|
||||
background-color: #fafafa;
|
||||
text-align: center;
|
||||
color: #616161;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wx-sub-menu-list .wx-sub-menu-item {
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.wx-menu-form {
|
||||
width: auto;
|
||||
margin-left: 340px;
|
||||
min-height: 570px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-editor {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background-color: #f4f5f9;
|
||||
border: 1px solid #e7e7eb;
|
||||
min-width: 560px;
|
||||
}
|
||||
|
||||
.form-editor .form-hd {
|
||||
padding: 10px 20px;
|
||||
border-bottom: 1px solid #e7e7eb;
|
||||
line-height: 31px;
|
||||
}
|
||||
|
||||
.form-hd-name {
|
||||
float: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.form-hd-del {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.form-editor .form-bd {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
width: 5em;
|
||||
float: left;
|
||||
margin-top: .3em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.item-group {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
float: none;
|
||||
width: auto;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.button-list-null {
|
||||
position: absolute;
|
||||
top: 37%;
|
||||
left: 30%;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.tip {
|
||||
color: #AAA;
|
||||
padding: 2px 2px 2px 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tip.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
input.error {
|
||||
border-color: red !important;
|
||||
}
|
||||
|
||||
.form-bd-content {
|
||||
background-color: #fff;
|
||||
padding: 0 15px 15px;
|
||||
min-height: 290px;
|
||||
margin: 15px 0 0;
|
||||
border-radius: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item-group.menu-type {
|
||||
padding-left: 17px;
|
||||
}
|
||||
|
||||
.form-bd-item:first-child {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.form-bd-item {
|
||||
min-height: 35px;
|
||||
line-height: 35px;
|
||||
padding-bottom: 15px
|
||||
}
|
||||
|
||||
.input.layui-input {
|
||||
display: inline-block !important;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.wechat-media i.layui-icon {
|
||||
color: #AAA;
|
||||
font-size: 16px;
|
||||
padding: 0 7px;
|
||||
}
|
||||
|
||||
.wechat-media .layui-this i.layui-icon {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.radio-label input {
|
||||
position: absolute;
|
||||
left: -500vw;
|
||||
top: -500vw;
|
||||
}
|
||||
|
||||
.radio-label i.layui-icon {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
.radio-label {
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.form-ft {
|
||||
padding-top: 20px;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-bd-list {
|
||||
background: #FFF;
|
||||
border-radius: 7px;
|
||||
padding-left: 22px;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
|
||||
.material-library, .add-material {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
padding: 50px 0;
|
||||
border: 1px dotted #CCC;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.material-library object, .add-material object {
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.material-library {
|
||||
float: left;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.material-library i, .add-material i {
|
||||
background-size: 100% 100%;
|
||||
background-color: #FFF;
|
||||
display: block;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin: auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.material-library i {
|
||||
background-image: url(../img/folder.png);
|
||||
}
|
||||
|
||||
.add-material i {
|
||||
background-image: url(../img/add.png);
|
||||
}
|
||||
|
||||
.add-material {
|
||||
float: right;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.material-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.material-img img {
|
||||
max-width: 70%;
|
||||
max-height: 180px;
|
||||
}
|
||||
|
||||
.del {
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
color: var(--base-color);
|
||||
text-decoration: solid;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-content .layui-textarea {
|
||||
height: 170px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.material-type {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.material-type span {
|
||||
background: green;
|
||||
color: #FFF;
|
||||
padding: 2px 4px;
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.graphic-message-list {
|
||||
width: 400px;
|
||||
border: 1px solid #CCC;
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.graphic-message-list .graphic-message-content {
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.graphic-message-list .graphic-message-content:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.graphic-message-list .graphic-message-content .title {
|
||||
display: inline-block;
|
||||
width: 75%;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.graphic-message-list .graphic-message-content .title a {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.graphic-message-list .read-all {
|
||||
padding: 5px 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.graphic-message-list .read-all::after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.graphic-message-list .read-all div {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.graphic-message-list .read-all i {
|
||||
float: right;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.text-message {
|
||||
width: 400px;
|
||||
border: 1px solid #CCC;
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.text-message .text-message-content {
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.text-message .text-message-content .title {
|
||||
width: 380px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
vertical-align: middle;
|
||||
border-top: 1px solid #CCC;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.text-message .text-message-content .title a {
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 4;
|
||||
-webkit-box-orient: vertical;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.text-message .text-message-content .material-type {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.wx-menu-item, .wx-menu-item span, .wx-sub-menu-item, .wx-sub-menu-item span {
|
||||
moz-user-select: -moz-none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.article-img .bg-color {
|
||||
color: #fff;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
.text-r{
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-color: #ccc;
|
||||
resize:none
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
.preview-box {
|
||||
max-width: 600px;
|
||||
height: 779px;
|
||||
background: #FFF;
|
||||
margin: 0 auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.rich-media-thumb img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.preview-box::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.preview-box::-webkit-scrollbar-track {
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
.preview-box::-webkit-scrollbar-thumb {
|
||||
background-color: #CCC;
|
||||
}
|
||||
|
||||
.preview-box::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #AAA
|
||||
}
|
||||
|
||||
.preview-box::-webkit-scrollbar-thumb:active {
|
||||
background-color: #AAA
|
||||
}
|
||||
|
||||
.preview-box > img.head {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.preview-box > .graphic-message {
|
||||
position: relative;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
padding-bottom: 150px;
|
||||
}
|
||||
|
||||
.preview-box > .graphic-message > span.time, .preview-box > .graphic-message > span.author {
|
||||
display: inline-block;
|
||||
color: #AAA;
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.preview-box > .graphic-message > content {
|
||||
display: block;
|
||||
position: relative;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.preview-box > .graphic-message > .graphic-message-content {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.preview-box > .graphic-message a.original-text {
|
||||
position: absolute;
|
||||
bottom: 50px;
|
||||
left: 0px;
|
||||
color: #607fa6;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
119
src/addon/wechat/shop/view/public/css/wx_qrcode.css
Normal file
@@ -0,0 +1,119 @@
|
||||
.qrcode-body {
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#albumList {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.input-file {
|
||||
position: absolute;
|
||||
top: -10px !important;
|
||||
right: 9px !important;
|
||||
height: 26px !important;
|
||||
width: 94px !important;
|
||||
filter: alpha(opacity:0) !important;
|
||||
opacity: 0 !important;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.qrcode_button {
|
||||
background-color: #51a351;
|
||||
border: none;
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
color: #FFF;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.check {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
right: -1px;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.check div {
|
||||
width: 60%;
|
||||
height: 30px;
|
||||
margin-left: 20%;
|
||||
border: 1px solid #fff;
|
||||
margin-top: 10%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.check div:hover {
|
||||
background: var(--base-color);
|
||||
border: 1px solid var(--base-color);
|
||||
}
|
||||
|
||||
.check div span {
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.options-btn {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#albumList li {
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
position: relative;
|
||||
float: left;
|
||||
margin-right: 1%;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
line-height: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.img-block {
|
||||
width: 100%;
|
||||
}
|
||||
.qrcode {
|
||||
width: 320px;
|
||||
height: 569px;
|
||||
background: #f5f5f5;
|
||||
position: relative;
|
||||
}
|
||||
.qrcode #imgLogo {
|
||||
max-width: 320px;
|
||||
max-height: 569px;
|
||||
}
|
||||
.tdrag-header {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
left: 59px; top: 15px;
|
||||
cursor: move;
|
||||
}
|
||||
.tdrag-logo {
|
||||
width: 43px;
|
||||
position: absolute;
|
||||
left: 60px;
|
||||
top: 210px;
|
||||
cursor: move;
|
||||
}
|
||||
.tdrag-code{
|
||||
width: 144px;
|
||||
height: 144px;
|
||||
position: absolute;
|
||||
left: 70px;
|
||||
top: 300px;
|
||||
cursor: move;
|
||||
}
|
||||
.tdrag-name{
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
position: absolute;
|
||||
left: 128px;
|
||||
top: 23px;
|
||||
cursor: move;
|
||||
}
|
||||
811
src/addon/wechat/shop/view/public/css/wx_replay.css
Normal file
@@ -0,0 +1,811 @@
|
||||
button, input, select, textarea {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input:-moz-placeholder, textarea:-moz-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.empty{width: 100%;margin-top: 15px;text-align: center;padding: 75px 0;}
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
a:-webkit-any-link {
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.reply-opts a:-webkit-any-link {
|
||||
color: var(--base-color);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.reply-opts .delet-color:-webkit-any-link {
|
||||
color: #ff3d3d;
|
||||
}
|
||||
.rule-group .rule-meta h3 .rule-opts .delet-color {
|
||||
color: #ff3d3d;
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-block;
|
||||
padding: 0 22px;
|
||||
min-width: 54px;
|
||||
line-height: 2.42857143;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.layui-body {
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-title h2 {
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.type-menu {
|
||||
text-align: left;
|
||||
height: 50px;
|
||||
line-height: 40px;
|
||||
border-bottom: 1px solid #E0E1E2;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.type-menu li {
|
||||
float: left;
|
||||
margin-right: 24px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.replay-info {
|
||||
padding: 15px 0 0;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.weixin-normal {
|
||||
margin-top: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.replay-info .info {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.replay-info h3 {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.replay-info h3:last-child {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.replay-button {
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.replay-button > div {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.replay-button:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.replay-button > label {
|
||||
background-color: #1AAD19;
|
||||
border-color: #1AAD19;
|
||||
color: #FFFFFF;
|
||||
display: inline-block;
|
||||
min-width: 54px;
|
||||
line-height: 2.42857143;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.replay-button .layui-layer-page {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.replay-button .layui-form > .layui-btn {
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.replay-button label > input {
|
||||
position: absolute;
|
||||
left: -9999em;
|
||||
}
|
||||
|
||||
.replay-button .search {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: .5em;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.replay-button .down {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.replay-button .down button {
|
||||
padding: 14px 12px 10px 12px;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.down .show-menu li a {
|
||||
color: #00A717;
|
||||
}
|
||||
|
||||
.down .show-menu li a {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.rule-group {
|
||||
border: 1px solid #e5e5e5;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 2px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.rule-group:hover {
|
||||
border: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 .rule-opts a:hover {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
line-height: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 .rule-opts {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0px;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.rule-group .rule-meta h3 .rule-opts a {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.rule-group .rule-body {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
/* margin: 0 0 10px;
|
||||
padding-top: 5px; */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.rule-group .rule-body:before, .rule-group .rule-body:after {
|
||||
display: table;
|
||||
content: "";
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
/* .rule-group .long-dashed {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
width: 100%;
|
||||
border-bottom: 1px dashed #e5e5e5;
|
||||
} */
|
||||
|
||||
.weixin-normal .rule-keywords {
|
||||
float: left;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner {
|
||||
font-size: 12px;
|
||||
padding: 0 10px 5px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner h4 {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.rule-group .keyword-containe {
|
||||
padding-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.rule-group .info:empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.rule-group .keyword-list, .reply-list {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.keyword-list .keyword {
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
height: 30px;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.keyword .close--circle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.keyword-list .keyword:hover .close--circle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.complex-content .close--circle ,.keyword-list .close--circle {
|
||||
position: absolute;
|
||||
z-index: 91;
|
||||
top: -9px;
|
||||
right: -9px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: rgba(153, 153, 153, 0.6);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.keyword .value {
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
padding: 2px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #333;
|
||||
vertical-align: middle;
|
||||
border-radius: 2px 0 0 2px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.input-append .add-on, .input-prepend .add-on {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
height: 20px;
|
||||
min-width: 16px;
|
||||
padding: 2px 7px;
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-color: #f7f7f7;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -4px;
|
||||
border-radius: 0 2px 2px 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* .rule-group hr.dashed {
|
||||
border-bottom: 1px dashed #d7d7d7;
|
||||
border-top: none;
|
||||
margin: 0;
|
||||
background-color: rgb(255, 255, 255);
|
||||
|
||||
} */
|
||||
.layui-textarea {
|
||||
resize:none
|
||||
}
|
||||
.rule-group .opt {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.rule-group .opt a {
|
||||
color: var(--base-color);
|
||||
}
|
||||
.inner-keywordbox a {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.weixin-normal .rule-replies {
|
||||
position: static;
|
||||
float: left;
|
||||
border-left: 1px solid #f7f7f7;
|
||||
padding-top: 10px;
|
||||
min-height: 115px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner {
|
||||
font-size: 12px;
|
||||
padding: 0 10px 5px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner .inner-keywordbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 15px;
|
||||
background: #f7f7f7;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.rule-group .rule-inner h4 {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.rule-group .reply-container, .keyword-container {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.rule-group .info {
|
||||
padding: 5px 0;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.rule-group .info:empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol.reply-list {
|
||||
list-style-type: decimal !important;
|
||||
}
|
||||
|
||||
.reply-list li, .quick-dropmenu li {
|
||||
position: relative;
|
||||
padding: 8px 90px 8px 5px;
|
||||
margin-left: 20px;
|
||||
list-style: unset;
|
||||
}
|
||||
|
||||
.reply-list .reply-opts a:hover {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.reply-cont {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.reply-summary {
|
||||
display: inline-block;
|
||||
max-width: 360px;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.reply-list .reply-opts, .quick-dropmenu .reply-opts {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.reply-list li::after, .quick-dropmenu li::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
border-bottom: 1px dashed #d7d7d7;
|
||||
bottom: 0;
|
||||
left: -20px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.reply-list li:last-child::after, .quick-dropmenu li:last-child::after {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.rule-group .opt .disable-opt {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.badge-success, .label-success {
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
background-color: #1AAD19;
|
||||
}
|
||||
|
||||
/***************************************/
|
||||
.misc {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.misc > a {
|
||||
display: inline-block;
|
||||
padding: 7px 10px;
|
||||
color: var(--base-color) !important;
|
||||
border-bottom: 2px solid #fff;
|
||||
}
|
||||
|
||||
.misc .active {
|
||||
color: var(--base-color)!important;
|
||||
border-color: var(--base-color);
|
||||
}
|
||||
|
||||
.others {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.others > a {
|
||||
padding: 10px;
|
||||
color: var(--base-color) !important
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
color: #ccc;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
top: 25px;
|
||||
left: 10px;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
font-size: 12px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 10px 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.dropdown-menu li {
|
||||
padding: 0 10px;
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.others:hover .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropdown-menu li:hover {
|
||||
background: var(--base-color);
|
||||
}
|
||||
|
||||
.dropdown-menu li:hover a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.complex-backdrop {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 25px;
|
||||
width: 86%;
|
||||
height: 36.5%;
|
||||
background-color: #fff;
|
||||
/* -webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.25); */
|
||||
/* border:1px solid #E6E6E6; */
|
||||
/* padding-top: 12px; */
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-body .body-content {
|
||||
background: #f8f8f8;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.fourstage-nav .layui-tab-title {
|
||||
background: #fff;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.fourstage-nav .layui-tab-title li {
|
||||
line-height: 48px;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.keyword-content {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
[lay-id=marterial_graphic_message_list] .article-img .bg-color {
|
||||
background-color: #1aad19 !important;
|
||||
}
|
||||
.layui-table-view{
|
||||
background-color: red!important;
|
||||
}
|
||||
|
||||
.complex-content {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.ng.ng-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.insert-connect {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 20px;
|
||||
color: var(--base-color) !important;
|
||||
}
|
||||
|
||||
.ng {
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
width: 250px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
margin-bottom: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.picture > img {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.msg-music-thumb {
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.msg-music-thumb a {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px dashed #F2F2F2;
|
||||
display: block;
|
||||
line-height: 100px;
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
#music .layui-textarea {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.voice-player {
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
border: 1px solid #85ac4c;
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 25px;
|
||||
padding: 0 6px 0 7px;
|
||||
font-size: 12px !important;
|
||||
line-height: 25px;
|
||||
cursor: pointer;
|
||||
background: #a0ce3d;
|
||||
vertical-align: middle;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.voice-player::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -13px;
|
||||
top: 6px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-right: 6px solid #85ac4c;
|
||||
}
|
||||
|
||||
.voice-player .stop {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 1px #8ab433;
|
||||
}
|
||||
|
||||
.popover .close--circle {
|
||||
z-index: initial;
|
||||
}
|
||||
|
||||
.close--circle {
|
||||
position: absolute;
|
||||
z-index: 91;
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
font-size: 28px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.voice-player .second {
|
||||
display: none;
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
color: #476600;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.voice-player .play {
|
||||
display: inline-block;
|
||||
width: 17px;
|
||||
height: 20px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.voice-player::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -12px;
|
||||
top: 6px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-right: 6px solid #a0ce3d;
|
||||
}
|
||||
|
||||
/*其他*/
|
||||
.ng .close--circle {
|
||||
top: -9px;
|
||||
right: -9px;
|
||||
}
|
||||
|
||||
.ng .ng-item {
|
||||
border-bottom: 1px solid #eee;
|
||||
overflow: hidden;
|
||||
padding: 5px 9px;
|
||||
}
|
||||
|
||||
.ng .label {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/*图文*/
|
||||
.ng .ng-title {
|
||||
display: inline-block !important;
|
||||
overflow: hidden !important;
|
||||
white-space: nowrap !important;
|
||||
text-overflow: ellipsis !important;
|
||||
line-height: 16px;
|
||||
min-height: 16px;
|
||||
vertical-align: middle;
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
a.new-window {
|
||||
color: var(--base-color);
|
||||
}
|
||||
|
||||
.ng .ng-item.view-more {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.ng .ng-item.view-more a {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
|
||||
.rule-container .add_reply-top{
|
||||
position: absolute;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
line-height: 0px;/*为了防止ie下出现题型*/
|
||||
border-bottom: 10px solid #fff;
|
||||
border-left: 10px solid rgba(0,0,0,0);
|
||||
border-right: 10px solid rgba(0,0,0,0);
|
||||
right: 55px;
|
||||
top: -10px;
|
||||
}
|
||||
|
||||
.popover > .close--circle {
|
||||
top: -5px;
|
||||
right: -5px;
|
||||
}
|
||||
|
||||
.rule-container .arrow {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
top: 50%;
|
||||
left: -13px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.rule-container .arrow i {
|
||||
color: #e5e5e5;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.rule-group-container {
|
||||
position: relative;
|
||||
min-height: 165px
|
||||
}
|
||||
|
||||
.search {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 1px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.layui-form-item .layui-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layui-form.hyperlink {
|
||||
padding: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.layui-form.hyperlink .layui-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.layui-layout-shop .fourstage-nav ul li.layui-this:after {
|
||||
border: none !important;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background-color: var(--base-color);
|
||||
border-radius: 30px !important;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
}
|
||||
BIN
src/addon/wechat/shop/view/public/img/add.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/addon/wechat/shop/view/public/img/administration.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/addon/wechat/shop/view/public/img/appmsg.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
src/addon/wechat/shop/view/public/img/appmsg1.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/addon/wechat/shop/view/public/img/appmsg2.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
src/addon/wechat/shop/view/public/img/arrow.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/article-msg.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/audio.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/base_icon.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
src/addon/wechat/shop/view/public/img/cart.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/addon/wechat/shop/view/public/img/check_qrcode1.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/addon/wechat/shop/view/public/img/complete.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_fans_icon.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_info.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_leavemsg_icon.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_mass_icon.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_material_icon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_menu_icon.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_message_icon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_qrcode_icon.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_replay_icon.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_share_icon.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src/addon/wechat/shop/view/public/img/config_wechat_icon.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/addon/wechat/shop/view/public/img/edition.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/addon/wechat/shop/view/public/img/flow/arrow.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/flow/complete.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/addon/wechat/shop/view/public/img/flow/config_info.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/flow/edition.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/addon/wechat/shop/view/public/img/flow/public_number.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/addon/wechat/shop/view/public/img/flow/register.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/folder.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/icon-header.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/addon/wechat/shop/view/public/img/icon.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/addon/wechat/shop/view/public/img/icon_audio_player.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/addon/wechat/shop/view/public/img/index_author.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/index_weixin.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/addon/wechat/shop/view/public/img/material_delete.png
Normal file
|
After Width: | Height: | Size: 1003 B |
BIN
src/addon/wechat/shop/view/public/img/material_download.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/addon/wechat/shop/view/public/img/material_edit.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/addon/wechat/shop/view/public/img/menu_icon/menu_wechat.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |