初始上传
This commit is contained in:
126
addon/weapp/model/Config.php
Executable file
126
addon/weapp/model/Config.php
Executable file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\weapp\model;
|
||||
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
use app\model\upload\Upload;
|
||||
|
||||
/**
|
||||
* 微信小程序配置
|
||||
*/
|
||||
class Config extends BaseModel
|
||||
{
|
||||
/******************************************************************** 微信小程序配置 start ****************************************************************************/
|
||||
/**
|
||||
* 设置微信小程序配置
|
||||
* @return multitype:string mixed
|
||||
*/
|
||||
public function setWeappConfig($data, $is_use, $site_id = 0)
|
||||
{
|
||||
$config_info = $this->getWeappConfig($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', '=', 'WEAPP_CONFIG' ] ]);
|
||||
if ($res && $data[ 'qrcode' ]) {
|
||||
copy($data[ 'qrcode' ], 'public/static/img/default_img/wxewm.png');
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信小程序配置信息
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getWeappConfig($site_id = 0)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_CONFIG' ] ]);
|
||||
return $res;
|
||||
}
|
||||
/******************************************************************** 微信小程序配置 end ****************************************************************************/
|
||||
|
||||
/**
|
||||
* 设置小程序版本信息
|
||||
* @param $data
|
||||
* @param $is_use
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function setWeappVersion($data, $is_use, $site_id = 0)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->setConfig($data, '小程序版本', $is_use, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_VERSION' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序版本信息
|
||||
* @param int $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getWeappVersion($site_id = 0)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_VERSION' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除小程序版本信息
|
||||
*/
|
||||
public function clearWeappVersion()
|
||||
{
|
||||
model('config')->update([ 'value' => '' ], [ [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'WEAPP_VERSION' ] ]);
|
||||
Cache::tag('config')->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置小程序分享
|
||||
* @param $site_id
|
||||
* @param $app_module
|
||||
* @param $key
|
||||
* @param $value
|
||||
*/
|
||||
public function setShareConfig($site_id, $app_module, $key, $value)
|
||||
{
|
||||
$config = model('config')->getInfo([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', 'WEAPP_SHARE' ] ], 'value');
|
||||
if (!empty($config) && !empty($config[ 'value' ])) $data = json_decode($config[ 'value' ], true);
|
||||
|
||||
if (!empty($data[ $key ][ 'path' ]) && !empty($value[ 'path' ]) && $data[ $key ][ 'path' ] != $value[ 'path' ]) {
|
||||
$upload_model = new Upload();
|
||||
$upload_model->deletePic($data[ $key ][ 'path' ], $site_id);
|
||||
}
|
||||
|
||||
$data[ $key ] = $value;
|
||||
$model = new ConfigModel();
|
||||
$res = $model->setConfig($data, '小程序分享', 1, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', 'WEAPP_SHARE' ] ]);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序分享配置
|
||||
* @param $site_id
|
||||
* @param $app_module\
|
||||
*/
|
||||
public function getShareConfig($site_id, $app_module)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', $app_module ], [ 'config_key', '=', 'WEAPP_SHARE' ] ]);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
174
addon/weapp/model/Message.php
Executable file
174
addon/weapp/model/Message.php
Executable file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\weapp\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 微信小程序订阅消息
|
||||
*/
|
||||
class Message extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 消息分页列表
|
||||
* @param array $condition
|
||||
* @param int $site_id
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @return array
|
||||
*/
|
||||
public function getMessagePageList($condition = [], $site_id = 0, $page = 1, $page_size = PAGE_LIST_ROWS, $order = '')
|
||||
{
|
||||
$list = model('message_template')->pageList($condition, 'id,keywords,title,message_type,weapp_json', $order, $page, $page_size);
|
||||
if ($site_id > 0) {
|
||||
if (!empty($list[ 'list' ])) {
|
||||
foreach ($list[ 'list' ] as $k => $v) {
|
||||
$list[ 'list' ][ $k ]['message_info'] = json_decode($v['weapp_json'], true);
|
||||
$message_info = model('message')->getInfo([ [ "keywords", "=", $v[ 'keywords' ] ], [ 'site_id', '=', $site_id ] ], 'weapp_is_open,weapp_template_id');
|
||||
$list[ 'list' ][ $k ][ 'weapp_is_open' ] = $message_info == null ? 0 : $message_info[ 'weapp_is_open' ];
|
||||
$list[ 'list' ][ $k ][ 'weapp_template_id' ] = $message_info == null ? 0 : $message_info[ 'weapp_template_id' ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取微信模板消息id
|
||||
* @param string $keywords
|
||||
* todo 批量获取模板消息
|
||||
*/
|
||||
public function getWeappTemplateNo(string $keywords, $site_id, $weapp_is_open = 0)
|
||||
{
|
||||
$keyword = explode(',', $keywords);
|
||||
$wechat = new Weapp($site_id);
|
||||
|
||||
if ($weapp_is_open == 1) {
|
||||
// 启用
|
||||
foreach ($keyword as $item) {
|
||||
$shop_message = model('message')->getInfo([ [ 'keywords', '=', $item ], [ "site_id", "=", $site_id ] ], 'weapp_template_id');
|
||||
$data = [
|
||||
'weapp_is_open' => $weapp_is_open,
|
||||
'site_id' => $site_id,
|
||||
'keywords' => $item,
|
||||
];
|
||||
// 开启时没有模板则进行添加
|
||||
if (!empty($shop_message)) {
|
||||
if (empty($shop_message[ 'weapp_template_id' ])) {
|
||||
$template_info = model('message_template')->getInfo([ [ 'keywords', '=', $item ], [ 'weapp_json', '<>', '' ] ], 'weapp_json');
|
||||
if (!empty($template_info)) {
|
||||
$template = json_decode($template_info[ 'weapp_json' ], true);
|
||||
$res = $wechat->getTemplateId($template);
|
||||
if (isset($res[ 'errcode' ]) && $res[ 'errcode' ] == 0) {
|
||||
$data[ 'weapp_template_id' ] = $res[ 'priTmplId' ];
|
||||
} else {
|
||||
return $this->error($res, $res[ 'errmsg' ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
model('message')->update($data, [ [ 'keywords', '=', $item ], [ "site_id", "=", $site_id ] ]);
|
||||
} else {
|
||||
$template_info = model('message_template')->getInfo([ [ 'keywords', '=', $item ], [ 'weapp_json', '<>', '' ] ], 'weapp_json');
|
||||
if (!empty($template_info)) {
|
||||
$template = json_decode($template_info[ 'weapp_json' ], true);
|
||||
$res = $wechat->getTemplateId($template);
|
||||
if (isset($res[ 'errcode' ]) && $res[ 'errcode' ] == 0) {
|
||||
$data[ 'weapp_template_id' ] = $res[ 'priTmplId' ];
|
||||
} else {
|
||||
return $this->error($res, $res[ 'errmsg' ]);
|
||||
}
|
||||
}
|
||||
model('message')->add($data);
|
||||
}
|
||||
}
|
||||
} else if ($weapp_is_open == 0) {
|
||||
// 关闭
|
||||
foreach ($keyword as $item) {
|
||||
$shop_message = model('message')->getInfo([ [ 'keywords', '=', $item ], [ "site_id", "=", $site_id ] ], 'weapp_template_id');
|
||||
if (!empty($shop_message)) {
|
||||
model('message')->update([ 'weapp_is_open' => $weapp_is_open ], [ [ 'keywords', '=', $item ], [ "site_id", "=", $site_id ] ]);
|
||||
} else {
|
||||
model('message')->add([
|
||||
'site_id' => $site_id,
|
||||
'keywords' => $item,
|
||||
'weapp_is_open' => $weapp_is_open
|
||||
]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 获取
|
||||
$list = model('message_template')->getList([ [ 'keywords', 'in', $keyword ], [ 'weapp_json', '<>', '' ] ], 'keywords,weapp_json');
|
||||
if (!empty($list)) {
|
||||
foreach ($list as $item) {
|
||||
$template = json_decode($item[ 'weapp_json' ], true);
|
||||
$res = $wechat->getTemplateId($template);
|
||||
if (isset($res[ 'errcode' ]) && $res[ 'errcode' ] != 0) return $this->error($res, $res[ 'errmsg' ]);
|
||||
|
||||
$shop_message = model('message')->getInfo([ [ 'keywords', '=', $item[ 'keywords' ] ], [ "site_id", "=", $site_id ] ], 'weapp_template_id');
|
||||
|
||||
if (!empty($shop_message)) {
|
||||
model('message')->update([ 'weapp_template_id' => $res[ 'priTmplId' ] ], [ [ 'keywords', '=', $item[ 'keywords' ] ], [ "site_id", "=", $site_id ] ]);
|
||||
} else {
|
||||
model('message')->add([
|
||||
'site_id' => $site_id,
|
||||
'keywords' => $item[ 'keywords' ],
|
||||
'weapp_template_id' => $res[ 'priTmplId' ]
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送订阅消息
|
||||
* @param array $param
|
||||
*/
|
||||
public function sendMessage(array $param)
|
||||
{
|
||||
try {
|
||||
|
||||
$site_id = $param['site_id'] ?: 1;
|
||||
$support_type = $param['message_info']["support_type"] ?? [];
|
||||
if (empty($support_type) || strpos($support_type, "weapp") === false) return $this->success();
|
||||
|
||||
if (empty($param['openid'])) return $this->success('缺少必需参数openid');
|
||||
$message_info = $param['message_info'];
|
||||
if ($message_info['weapp_is_open'] == 0) return $this->error('未启用模板消息');
|
||||
if (empty($message_info['weapp_template_id'])) return $this->error('未配置模板消息');
|
||||
$data = [
|
||||
'openid' => $param['openid'],
|
||||
'template_id' => $message_info['weapp_template_id'],
|
||||
'data' => $param['template_data'],
|
||||
'page' => $param['page'] ?? ''
|
||||
];
|
||||
$weapp = new Weapp($site_id);
|
||||
$res = $weapp->sendTemplateMessage($data);
|
||||
|
||||
return $res;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('', "消息发送失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订阅消息模板id集合
|
||||
* @param $site_id
|
||||
* @param $keywords
|
||||
*/
|
||||
public function getMessageTmplIds($site_id, $keywords){
|
||||
$data = model('message')->getColumn([ ['weapp_is_open', '=', 1], ['weapp_template_id', '<>', ''], ['site_id', '=', $site_id], ['keywords', 'in', explode(',', $keywords) ] ], 'weapp_template_id');
|
||||
return $this->success($data);
|
||||
}
|
||||
}
|
||||
199
addon/weapp/model/Stat.php
Executable file
199
addon/weapp/model/Stat.php
Executable file
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\weapp\model;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 微信小程序数据统计与分析
|
||||
*/
|
||||
class Stat extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 小程序 访问日趋势
|
||||
* @param $from
|
||||
* @param $to
|
||||
*/
|
||||
public function dailyVisitTrend($begin_date, $end_date)
|
||||
{
|
||||
$info = Cache::get("weapp_daily_visit_trend" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($info)) {
|
||||
return success($info);
|
||||
}
|
||||
$wepp_model = new Weapp();
|
||||
$result = $wepp_model->dailyVisitTrend($begin_date, $end_date);
|
||||
if ($result["code"] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("weapp_visit")->set("weapp_daily_visit_trend" . "_" . $begin_date . "_" . $end_date, $result["data"]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序 访问周趋势
|
||||
* @param $from
|
||||
* @param $to
|
||||
*/
|
||||
public function weeklyVisitTrend($begin_date, $end_date)
|
||||
{
|
||||
$info = Cache::get("weapp_weekly_visit_trend" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($info)) {
|
||||
return success($info);
|
||||
}
|
||||
$wepp_model = new Weapp();
|
||||
$result = $wepp_model->weeklyVisitTrend($begin_date, $end_date);
|
||||
if ($result["code"] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("weapp_visit")->set("weapp_weekly_visit_trend" . "_" . $begin_date . "_" . $end_date, $result["data"]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序 访问月趋势
|
||||
* @param $from
|
||||
* @param $to
|
||||
*/
|
||||
public function monthlyVisitTrend($begin_date, $end_date)
|
||||
{
|
||||
$info = Cache::get("weapp_monthly_visit_trend" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($info)) {
|
||||
return success($info);
|
||||
}
|
||||
$wepp_model = new Weapp();
|
||||
$result = $wepp_model->monthlyVisitTrend($begin_date, $end_date);
|
||||
if ($result["code"] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("weapp_visit")->set("weapp_monthly_visit_trend" . "_" . $begin_date . "_" . $end_date, $result["data"]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序 访问日趋势
|
||||
* @param $from
|
||||
* @param $to
|
||||
*/
|
||||
public function visitPage($begin_date, $end_date)
|
||||
{
|
||||
$info = Cache::get("weapp_visit_page" . "_" . $begin_date . "_" . $end_date);
|
||||
if (!empty($info)) {
|
||||
return success($info);
|
||||
}
|
||||
$wepp_model = new Weapp();
|
||||
$result = $wepp_model->dailyVisitTrend($begin_date, $end_date);
|
||||
if ($result["code"] < 0)
|
||||
return $result;
|
||||
|
||||
Cache::tag("weapp_visit")->set("weapp_visit_page" . "_" . $begin_date . "_" . $end_date, $result["data"]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询微信小程序访问数据
|
||||
* @param $date_type
|
||||
* @param $daterange
|
||||
*/
|
||||
public function visitData($date_type)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
switch ($date_type) {
|
||||
case 'yesterday':
|
||||
$begin_date = date('Ymd', strtotime('-1 days'));
|
||||
$end_date = date('Ymd', strtotime('-1 days'));
|
||||
$result = $this->dailyVisitTrend($begin_date, $end_date);
|
||||
break;
|
||||
case 'month':
|
||||
$begin_date = date('Y-m-d', strtotime(date('Y-m-01') . ' -1 month'));
|
||||
$end_date = date('Y-m-d', strtotime(date('Y-m-01') . ' -1 day'));
|
||||
$result = $this->monthlyVisitTrend($begin_date, $end_date);
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信小程序 数据分析统计
|
||||
*/
|
||||
public function visitStatistics($daterange)
|
||||
{
|
||||
if (empty($daterange))
|
||||
return $this->success([]);
|
||||
|
||||
$is_error = true;
|
||||
$daterange_array = explode(" 至 ", $daterange);
|
||||
$start_date = date_format(date_create($daterange_array[0]), "Ymd");
|
||||
$end_date = date_format(date_create($daterange_array[1]), "Ymd");
|
||||
$date_x = periodGroup(strtotime($start_date), strtotime($end_date));
|
||||
$session_cnt_data = [];//打开次数
|
||||
$visit_pv_data = [];//访问次数
|
||||
$visit_uv_data = [];//访问人数
|
||||
$visit_uv_new_data = [];//新用户数
|
||||
$stay_time_uv_data = [];//人均停留时长 (浮点型,单位:秒)
|
||||
$stay_time_session_data = [];//次均停留时长 (浮点型,单位:秒)
|
||||
$visit_depth_data = [];//平均访问深度 (浮点型)
|
||||
foreach ($date_x as $k => $v) {
|
||||
$session_cnt = 0;//打开次数
|
||||
$visit_pv = 0;//访问次数
|
||||
$visit_uv = 0;//访问人数
|
||||
$visit_uv_new = 0;//新用户数
|
||||
$stay_time_uv = 0;//人均停留时长 (浮点型,单位:秒)
|
||||
$stay_time_session = 0;//次均停留时长 (浮点型,单位:秒)
|
||||
$visit_depth = 0;//平均访问深度 (浮点型)
|
||||
if ($is_error) {
|
||||
// $temp_daterange = array(
|
||||
// "begin_date" => $v,
|
||||
// "end_date" => $v,
|
||||
// "site_id" => $site_id
|
||||
// );
|
||||
$result = $this->dailyVisitTrend($v, $v);
|
||||
$temp_data = $result["data"];
|
||||
if (!empty($temp_data)) {
|
||||
$session_cnt = $temp_data["session_cnt"];//打开次数
|
||||
$visit_pv = $temp_data["visit_pv"];//访问次数
|
||||
$visit_uv = $temp_data["visit_uv"];//访问人数
|
||||
$visit_uv_new = $temp_data["visit_uv_new"];//新用户数
|
||||
$stay_time_uv = $temp_data["stay_time_uv"];//人均停留时长 (浮点型,单位:秒)
|
||||
$stay_time_session = $temp_data["stay_time_session"];//次均停留时长 (浮点型,单位:秒)
|
||||
$visit_depth = $temp_data["visit_depth"];//平均访问深度 (浮点型)
|
||||
} else {
|
||||
$is_error = false;
|
||||
}
|
||||
}
|
||||
|
||||
$session_cnt_data[] = $session_cnt;//打开次数
|
||||
$visit_pv_data[] = $visit_pv;//访问次数
|
||||
$visit_uv_data[] = $visit_uv;//访问人数
|
||||
$visit_uv_new_data[] = $visit_uv_new;//新用户数
|
||||
$stay_time_uv_data[] = $stay_time_uv;//人均停留时长 (浮点型,单位:秒)
|
||||
$stay_time_session_data[] = $stay_time_session;//次均停留时长 (浮点型,单位:秒)
|
||||
$visit_depth_data[] = $visit_depth;//平均访问深度 (浮点型)
|
||||
}
|
||||
|
||||
$statistics_data = array(
|
||||
"date" => $date_x,
|
||||
"data" => array(
|
||||
"session_cnt_data" => $session_cnt_data,
|
||||
"visit_pv_data" => $visit_pv_data,
|
||||
"visit_uv_data" => $visit_uv_data,
|
||||
"visit_uv_new_data" => $visit_uv_new_data,
|
||||
"stay_time_uv_data" => $stay_time_uv_data,
|
||||
"stay_time_session_data" => $stay_time_session_data,
|
||||
"visit_depth_data" => $visit_depth_data,
|
||||
)
|
||||
);
|
||||
return $this->success($statistics_data);
|
||||
}
|
||||
}
|
||||
873
addon/weapp/model/Weapp.php
Executable file
873
addon/weapp/model/Weapp.php
Executable file
@@ -0,0 +1,873 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\weapp\model;
|
||||
|
||||
use addon\wechatpay\model\Config as WechatPayModel;
|
||||
use app\model\BaseModel;
|
||||
use app\model\order\Order;
|
||||
use app\model\shop\Shop as ShopModel;
|
||||
use app\model\system\Api;
|
||||
use app\model\system\Config as ConfigModel;
|
||||
use EasyWeChat\Factory;
|
||||
use think\facade\Cache;
|
||||
use addon\weapp\model\Config as WeappConfigModel;
|
||||
use addon\wxoplatform\model\Config as WxOplatformConfigModel;
|
||||
use app\model\web\Config as WebConfig;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 微信小程序配置
|
||||
*/
|
||||
class Weapp extends BaseModel
|
||||
{
|
||||
private $app;//微信模型
|
||||
|
||||
//小程序类型
|
||||
public $service_type = array (
|
||||
0 => "小程序",
|
||||
);
|
||||
|
||||
//小程序认证类型
|
||||
public $verify_type = array (
|
||||
-1 => "未认证",
|
||||
0 => "微信认证",
|
||||
);
|
||||
|
||||
//business_info 说明
|
||||
public $business_type = array (
|
||||
'open_store' => "是否开通微信门店功能",
|
||||
'open_scan' => "是否开通微信扫商品功能",
|
||||
'open_pay' => "是否开通微信支付功能",
|
||||
'open_card' => "是否开通微信卡券功能",
|
||||
'open_shake' => "是否开通微信摇一摇功能",
|
||||
);
|
||||
|
||||
// 站点ID
|
||||
private $site_id;
|
||||
|
||||
public function __construct($site_id = 0)
|
||||
{
|
||||
$this->site_id = $site_id;
|
||||
//微信小程序配置
|
||||
$weapp_config_model = new WeappConfigModel();
|
||||
$weapp_config = $weapp_config_model->getWeappConfig($site_id)[ "data" ][ "value" ];
|
||||
|
||||
if (isset($weapp_config[ 'is_authopen' ]) && addon_is_exit('wxoplatform')) {
|
||||
$plateform_config_model = new WxOplatformConfigModel();
|
||||
$plateform_config = $plateform_config_model->getOplatformConfig()[ "data" ][ "value" ];
|
||||
|
||||
$config = [
|
||||
'app_id' => $plateform_config[ "appid" ] ?? '',
|
||||
'secret' => $plateform_config[ "secret" ] ?? '',
|
||||
'token' => $plateform_config[ "token" ] ?? '',
|
||||
'aes_key' => $plateform_config[ "aes_key" ] ?? '',
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'permission' => 0777,
|
||||
'file' => 'runtime/log/wechat/oplatform.logs',
|
||||
],
|
||||
];
|
||||
$open_platform = Factory::openPlatform($config);
|
||||
$this->app = $open_platform->miniProgram($weapp_config[ 'authorizer_appid' ], $weapp_config[ 'authorizer_refresh_token' ]);
|
||||
} else {
|
||||
$config = [
|
||||
'app_id' => $weapp_config[ "appid" ] ?? '',
|
||||
'secret' => $weapp_config[ "appsecret" ] ?? '',
|
||||
'response_type' => 'array',
|
||||
'log' => [
|
||||
'level' => 'debug',
|
||||
'permission' => 0777,
|
||||
'file' => 'runtime/log/wechat/easywechat.logs',
|
||||
],
|
||||
];
|
||||
if(!empty($weapp_config[ "appid" ]) && !empty($weapp_config[ "appsecret" ])){
|
||||
$this->app = Factory::miniProgram($config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* 根据 jsCode 获取用户 session 信息
|
||||
* @param $param
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
*/
|
||||
public function authCodeToOpenid($param)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->auth->session($param[ 'code' ]);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->handleError($result[ 'errcode' ], $result[ 'errmsg' ]);
|
||||
} else {
|
||||
Cache::set('weapp_' . $result[ 'openid' ], $result);
|
||||
unset($result[ 'session_key' ]);
|
||||
return $this->success($result);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'formattedResponse')) {
|
||||
return $this->handleError($e->formattedResponse[ 'errcode' ], $e->formattedResponse[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
* @param unknown $param
|
||||
*/
|
||||
public function createQrcode($param)
|
||||
{
|
||||
try {
|
||||
$checkpath_result = $this->checkPath($param[ 'qrcode_path' ]);
|
||||
if ($checkpath_result[ "code" ] != 0) return $checkpath_result;
|
||||
|
||||
// scene:场景值最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~
|
||||
$scene = '';
|
||||
if (!empty($param[ 'data' ])) {
|
||||
foreach ($param[ 'data' ] as $key => $value) {
|
||||
//防止参数过长,source_member用m代替
|
||||
if ($key == 'source_member') {
|
||||
$key = 'm';
|
||||
}
|
||||
if ($scene == '') $scene .= $key . '-' . $value;
|
||||
else $scene .= '&' . $key . '-' . $value;
|
||||
}
|
||||
}
|
||||
$response = $this->app->app_code->getUnlimit($scene, [
|
||||
'page' => substr($param[ 'page' ], 1),
|
||||
'width' => $param['width'] ?? 120
|
||||
]);
|
||||
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
|
||||
$filename = $param[ 'qrcode_path' ] . '/';
|
||||
$filename .= $response->saveAs($param[ 'qrcode_path' ], $param[ 'qrcode_name' ] . '_' . $param[ 'app_type' ] . '.png');
|
||||
return $this->success([ 'type' => 'weapp', 'path' => $filename ]);
|
||||
} else {
|
||||
return $this->handleError($response[ 'errcode' ], $response[ 'errmsg' ]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'formattedResponse')) {
|
||||
return $this->handleError($e->formattedResponse[ 'errcode' ], $e->formattedResponse[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验目录是否可写
|
||||
* @param unknown $path
|
||||
* @return multitype:number unknown |multitype:unknown
|
||||
*/
|
||||
private function checkPath($path)
|
||||
{
|
||||
if (is_dir($path) || mkdir($path, intval('0755', 8), true)) {
|
||||
return $this->success();
|
||||
}
|
||||
return $this->error('', "directory {$path} creation failed");
|
||||
}
|
||||
/************************************************************* 数据统计与分析 start **************************************************************/
|
||||
|
||||
/**
|
||||
* 访问日趋势
|
||||
* @param $from 格式 20170313
|
||||
* @param $to 格式 20170313
|
||||
*/
|
||||
public function dailyVisitTrend($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->data_cube->dailyVisitTrend($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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问周趋势
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function weeklyVisitTrend($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->data_cube->weeklyVisitTrend($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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问月趋势
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function monthlyVisitTrend($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->data_cube->monthlyVisitTrend($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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问分布
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function visitDistribution($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->data_cube->visitDistribution($from, $to);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result[ "list" ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问页面
|
||||
* @param $from
|
||||
* @param $to
|
||||
* @return array
|
||||
*/
|
||||
public function visitPage($from, $to)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->data_cube->visitPage($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());
|
||||
}
|
||||
}
|
||||
/************************************************************* 数据统计与分析 end **************************************************************/
|
||||
|
||||
/**
|
||||
* 下载小程序代码包
|
||||
* @param $site_id
|
||||
*/
|
||||
public function download($site_id)
|
||||
{
|
||||
$source_file_path = $this->createTempPackage($site_id, 'public/weapp');
|
||||
$file_arr = getFileMap($source_file_path);
|
||||
|
||||
if (!empty($file_arr)) {
|
||||
$zipname = 'upload/weapp_' . $site_id . '_' . date('Ymd') . '.zip';
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
$res = $zip->open($zipname, \ZipArchive::CREATE);
|
||||
if ($res === TRUE) {
|
||||
foreach ($file_arr as $file_path => $file_name) {
|
||||
if (is_dir($file_path)) {
|
||||
$file_path = str_replace($source_file_path . '/', '', $file_path);
|
||||
$zip->addEmptyDir($file_path);
|
||||
} else {
|
||||
$zip_path = str_replace($source_file_path . '/', '', $file_path);
|
||||
$zip->addFile($file_path, $zip_path);
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Transfer-Encoding: Binary");
|
||||
header("Content-Length: " . filesize($zipname));
|
||||
header("Content-Disposition: attachment; filename=\"" . basename($zipname) . "\"");
|
||||
readfile($zipname);
|
||||
@unlink($zipname);
|
||||
deleteDir($source_file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时包
|
||||
* @param $site_id
|
||||
* @param $package_path
|
||||
* @param string $to_path
|
||||
* @return string
|
||||
*/
|
||||
private function createTempPackage($site_id, $package_path, $to_path = '')
|
||||
{
|
||||
if (is_dir($package_path)) {
|
||||
$package = scandir($package_path);
|
||||
|
||||
if (empty($to_path)) {
|
||||
$to_path = 'upload/temp/' . $site_id . '/';
|
||||
dir_mkdir($to_path);
|
||||
}
|
||||
|
||||
foreach ($package as $path) {
|
||||
$temp_path = $package_path . '/' . $path;
|
||||
if (is_dir($temp_path)) {
|
||||
if ($path == '.' || $path == '..') {//判断是否为系统隐藏的文件.和.. 如果是则跳过否则就继续往下走,防止无限循环再这里。
|
||||
continue;
|
||||
}
|
||||
dir_mkdir($to_path . $path);
|
||||
$this->createTempPackage($site_id, $temp_path, $to_path . $path . '/');
|
||||
} else {
|
||||
if (file_exists($temp_path)) {
|
||||
copy($temp_path, $to_path . $path);
|
||||
if (stristr($temp_path, 'common/vendor.js')) {
|
||||
$content = file_get_contents($to_path . $path);
|
||||
$content = $this->paramReplace($site_id, $content);
|
||||
file_put_contents($to_path . $path, $content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $to_path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数替换
|
||||
* @param $site_id
|
||||
* @param $string
|
||||
* @return null|string|string[]
|
||||
*/
|
||||
private function paramReplace($site_id, $string)
|
||||
{
|
||||
$api_model = new Api();
|
||||
$api_config = $api_model->getApiConfig()[ 'data' ];
|
||||
|
||||
$web_config_model = new WebConfig();
|
||||
$web_config = $web_config_model->getMapConfig()[ 'data' ][ 'value' ];
|
||||
|
||||
$socket_url = ( strstr(ROOT_URL, 'https://') === false ? str_replace('http', 'ws', ROOT_URL) : str_replace('https', 'wss', ROOT_URL) ) . '/wss';
|
||||
|
||||
$patterns = [
|
||||
'/\{\{\$baseUrl\}\}/',
|
||||
'/\{\{\$imgDomain\}\}/',
|
||||
'/\{\{\$h5Domain\}\}/',
|
||||
'/\{\{\$mpKey\}\}/',
|
||||
'/\{\{\$apiSecurity\}\}/',
|
||||
'/\{\{\$publicKey\}\}/',
|
||||
'/\{\{\$webSocket\}\}/'
|
||||
];
|
||||
$replacements = [
|
||||
ROOT_URL,
|
||||
ROOT_URL,
|
||||
ROOT_URL . '/h5',
|
||||
$web_config[ 'tencent_map_key' ] ?? '',
|
||||
$api_config[ 'is_use' ] ?? 0,
|
||||
$api_config[ 'value' ][ 'public_key' ] ?? '',
|
||||
$socket_url
|
||||
];
|
||||
$string = preg_replace($patterns, $replacements, $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息解密
|
||||
* @param array $param
|
||||
*/
|
||||
public function decryptData($param = [])
|
||||
{
|
||||
try {
|
||||
$cache = Cache::get('weapp_' . $param[ 'weapp_openid' ]);
|
||||
$session_key = $cache[ 'session_key' ] ?? '';
|
||||
$result = $this->app->encryptor->decryptData($session_key, $param[ 'iv' ], $param[ 'encryptedData' ]);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->handleError($result[ 'errcode' ], $result[ 'errmsg' ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'formattedResponse')) {
|
||||
return $this->handleError($e->formattedResponse[ 'errcode' ], $e->formattedResponse[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户手机号
|
||||
* @param $code
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function getUserPhoneNumber($code)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->auth->phoneNumber($code);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->handleError($result[ 'errcode' ], $result[ 'errmsg' ]);
|
||||
}
|
||||
return $this->success($result[ 'phone_info' ]);
|
||||
} catch (\Exception $e) {
|
||||
if (property_exists($e, 'formattedResponse')) {
|
||||
return $this->handleError($e->formattedResponse[ 'errcode' ], $e->formattedResponse[ 'errmsg' ]);
|
||||
}
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订阅消息template_id
|
||||
* @param array $param
|
||||
*/
|
||||
public function getTemplateId(array $param)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->subscribe_message->addTemplate($param[ 'tid' ], $param[ 'kidList' ], $param[ 'sceneDesc' ]);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
return [ 'errcode' => -1, 'errmsg' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送订阅消息
|
||||
* @param array $param
|
||||
* @return array
|
||||
*/
|
||||
public function sendTemplateMessage(array $param)
|
||||
{
|
||||
$result = $this->app->subscribe_message->send([
|
||||
'template_id' => $param[ 'template_id' ],// 模板id
|
||||
'touser' => $param[ 'openid' ], // openid
|
||||
'page' => $param[ 'page' ], // 点击模板卡片后的跳转页面 支持带参数
|
||||
'data' => $param[ 'data' ] // 模板变量
|
||||
]);
|
||||
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息推送
|
||||
*/
|
||||
public function relateWeixin()
|
||||
{
|
||||
$server = $this->app->server;
|
||||
$message = $server->getMessage();
|
||||
Log::write('微信小程序消息推送:' . json_encode($message));
|
||||
if (isset($message[ 'MsgType' ])) {
|
||||
switch ( $message[ 'MsgType' ] ) {
|
||||
case 'event':
|
||||
$this->app->server->push(function($res) {
|
||||
// 商品审核结果通知
|
||||
if ($res[ 'Event' ] == 'open_product_spu_audit' && addon_is_exit('shopcomponent', $this->site_id)) {
|
||||
model('shopcompoent_goods')->update([
|
||||
'edit_status' => $res[ 'OpenProductSpuAudit' ][ 'status' ],
|
||||
'reject_reason' => !empty($res[ 'OpenProductSpuAudit' ][ 'reject_reason' ]) ? : '',
|
||||
'audit_time' => time()
|
||||
], [
|
||||
[ 'out_product_id', '=', $res[ 'OpenProductSpuAudit' ][ 'out_product_id' ] ]
|
||||
]);
|
||||
}
|
||||
// 类目审核结果通知
|
||||
if ($res[ 'Event' ] == 'open_product_category_audit' && addon_is_exit('shopcomponent', $this->site_id)) {
|
||||
model('shopcompoent_category_audit')->update([
|
||||
'status' => $res[ 'QualificationAuditResult' ][ 'status' ],
|
||||
'reject_reason' => !empty($res[ 'QualificationAuditResult' ][ 'reject_reason' ]) ? : '',
|
||||
'audit_time' => time()
|
||||
], [
|
||||
[ 'audit_id', '=', $res[ 'QualificationAuditResult' ][ 'audit_id' ] ]
|
||||
]);
|
||||
}
|
||||
|
||||
// 视频号支付订单回调
|
||||
if ($res[ 'Event' ] == 'open_product_order_pay' && addon_is_exit('shopcomponent', $this->site_id)) {
|
||||
event("shopcomponentNotify", $res);
|
||||
}
|
||||
|
||||
// todo trade_manage_remind_access_api 提醒接入发货信息管理服务API
|
||||
if ($res[ 'Event' ] == 'trade_manage_remind_access_api' && addon_is_exit('weapp', $this->site_id)) {
|
||||
Log::write('提醒接入发货信息管理服务API(trade_manage_remind_access_api):' . json_encode($res));
|
||||
}
|
||||
|
||||
// todo trade_manage_remind_shipping 提醒需要上传发货信息
|
||||
if ($res[ 'Event' ] == 'trade_manage_remind_shipping' && addon_is_exit('weapp', $this->site_id)) {
|
||||
Log::write('提醒需要上传发货信息(trade_manage_remind_shipping):' . json_encode($res));
|
||||
}
|
||||
|
||||
// todo trade_manage_order_settlement 订单将要结算或已经结算
|
||||
if ($res[ 'Event' ] == 'trade_manage_order_settlement' && addon_is_exit('weapp', $this->site_id)) {
|
||||
Log::write('订单将要结算或已经结算(trade_manage_order_settlement):' . json_encode($res));
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
$response = $this->app->server->serve();
|
||||
return $response->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查场景值是否在支付校验范围内
|
||||
* @param $scene
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function sceneCheck($scene)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->mini_store->checkScene($scene);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] == 0) {
|
||||
return $this->success($result[ 'is_matched' ]);
|
||||
} else {
|
||||
return $this->error('', $result[ 'errmsg' ]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function createOrder($order_info)
|
||||
{
|
||||
try {
|
||||
$result = $this->app->mini_store->addOrder($order_info);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] == 0) {
|
||||
return $this->success($result[ 'is_matched' ]);
|
||||
} else {
|
||||
return $this->error('', $result[ 'errmsg' ]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理错误信息
|
||||
* @param $errcode
|
||||
* @param string $message
|
||||
* @return array
|
||||
*/
|
||||
public function handleError($errcode, $message = '')
|
||||
{
|
||||
$error = require 'addon/weapp/config/weapp_error.php';
|
||||
return $this->error([], $error[ $errcode ] ?? $message);
|
||||
}
|
||||
|
||||
//物流模式,发货方式枚举值
|
||||
//1、实体物流配送采用快递公司进行实体物流配送形式
|
||||
//2、同城配送
|
||||
//3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式
|
||||
//4、用户自提
|
||||
const LOGISTICS_TYPE_EXPRESS = 1;
|
||||
const LOGISTICS_TYPE_LOCAL = 2;
|
||||
const LOGISTICS_TYPE_VIRTUAL = 3;
|
||||
const LOGISTICS_TYPE_STORE = 4;
|
||||
|
||||
//发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货)
|
||||
const UNIFIED_DELIVERY = 1;
|
||||
const SPLIT_DELIVERY = 2;
|
||||
|
||||
/**
|
||||
* 查询小程序是否已开通发货信息管理服务
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingIsTradeManaged()
|
||||
{
|
||||
try {
|
||||
$result = $this->app->order_shipping->isTradeManaged();
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error(false, $result[ "errmsg" ]);
|
||||
}
|
||||
return $this->success($result[ 'is_trade_managed' ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error(false, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单列表
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingGetOrderList($data = [])
|
||||
{
|
||||
try {
|
||||
$params = [
|
||||
'pay_time_range' => [
|
||||
'begin_time' => $data[ 'begin_time' ] ?? 0, // 起始时间,时间戳形式,不填则视为从0开始。
|
||||
'end_time' => $data[ 'end_time' ] ?? time() // 结束时间(含),时间戳形式,不填则视为32位无符号整型的最大值。
|
||||
],
|
||||
'page_size' => $data[ 'page_size' ] ?? 100 // 翻页时使用,返回列表的长度,默认为100。
|
||||
];
|
||||
|
||||
// 订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款。
|
||||
if (!empty($data[ 'order_state' ])) {
|
||||
$params[ 'order_state' ] = $data[ 'order_state' ];
|
||||
}
|
||||
|
||||
// 翻页时使用,获取第一页时不用传入,如果查询结果中 has_more 字段为 true,则传入该次查询结果中返回的 last_index 字段可获取下一页。
|
||||
if (!empty($data[ 'last_index' ])) {
|
||||
$params[ 'last_index' ] = $data[ 'last_index' ];
|
||||
}
|
||||
|
||||
$result = $this->app->order_shipping->getOrderList($params);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单发货状态
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingGetOrder($data = [])
|
||||
{
|
||||
try {
|
||||
$params = [];
|
||||
|
||||
// 原支付交易对应的微信订单号
|
||||
if (!empty($data[ 'transaction_id' ])) {
|
||||
$params[ 'transaction_id' ] = $data[ 'transaction_id' ];
|
||||
}
|
||||
|
||||
// 支付下单商户的商户号,由微信支付生成并下发
|
||||
if (!empty($data[ 'merchant_id' ])) {
|
||||
$params[ 'merchant_id' ] = $data[ 'merchant_id' ];
|
||||
}
|
||||
|
||||
// 商户系统内部订单号,只能是数字、大小写字母`_-*`且在同一个商户号下唯一
|
||||
if (!empty($data[ 'merchant_trade_no' ])) {
|
||||
$params[ 'merchant_trade_no' ] = $data[ 'merchant_trade_no' ];
|
||||
}
|
||||
|
||||
// 二级商户号
|
||||
if (!empty($data[ 'sub_merchant_id' ])) {
|
||||
$params[ 'sub_merchant_id' ] = $data[ 'sub_merchant_id' ];
|
||||
}
|
||||
|
||||
$result = $this->app->order_shipping->getOrder($params);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
return $this->success($result[ 'order' ]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置消息跳转路径
|
||||
* @return array
|
||||
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function setMsgJumpPath()
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$config_condition = [['site_id','=',0],['app_module','=','shop'],['config_key','=','WEAPP_ORDER_SHIPPINT_CONFIG']];
|
||||
$res = $config->getConfig($config_condition);
|
||||
$config_data = $res['data']['value'];
|
||||
$jump_path = 'pages_tool/weapp/order_shipping';
|
||||
if(empty($config_data['jump_path']) || $config_data['jump_path'] != $jump_path){
|
||||
$result = $this->app->order_shipping->setMsgJumpPath($jump_path);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, 'setMsgJumpPathError:'.$result[ "errmsg" ]);
|
||||
}
|
||||
$config_data['jump_path'] = $jump_path;
|
||||
$config->setConfig($config_data, '小程序发货配置', 1, $config_condition);
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发货信息录入接口,自备数据
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingUploadShippingInfo($data = [])
|
||||
{
|
||||
try {
|
||||
//设置消息跳转路径
|
||||
$result = $this->setMsgJumpPath();
|
||||
if($result['code'] < 0) return $result;
|
||||
|
||||
$pay_config = ( new WechatPayModel() )->getPayConfig($data[ 'site_id' ])[ 'data' ][ 'value' ];
|
||||
$params = [
|
||||
'order_key' => [
|
||||
'order_number_type' => 1, // 订单单号类型,用于确认需要上传详情的订单。枚举值1,使用下单商户号和商户侧单号;枚举值2,使用微信支付单号。
|
||||
'mchid' => $pay_config[ 'mch_id' ], // 支付下单商户的商户号,由微信支付生成并下发。
|
||||
'out_trade_no' => $data[ 'out_trade_no' ] // 商户系统内部订单号,只能是数字、大小写字母`_-*`且在同一个商户号下唯一
|
||||
],
|
||||
'logistics_type' => $data[ 'logistics_type' ], // 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
|
||||
'delivery_mode' => $data[ 'delivery_mode' ], // 发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY
|
||||
// 同城配送没有物流信息,只能传一个订单
|
||||
'shipping_list' => $data[ 'shipping_list' ], // 物流信息列表,发货物流单列表,支持统一发货(单个物流单)和分拆发货(多个物流单)两种模式,多重性: [1, 10]
|
||||
'upload_time' => date("c", time()), // 上传时间,用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
|
||||
'payer' => [
|
||||
'openid' => $data[ 'weapp_openid' ] // 用户标识,用户在小程序appid下的唯一标识。 下单前需获取到用户的Openid 示例值: oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 字符字节限制: [1, 128]
|
||||
],
|
||||
'is_all_delivered' => $data[ 'is_all_delivered' ] // 分拆发货模式时必填,用于标识分拆发货模式下是否已全部发货完成,只有全部发货完成的情况下才会向用户推送发货完成通知。示例值: true/false
|
||||
];
|
||||
|
||||
Log::write('发货信息录入接口,自备数据(参数):' . json_encode($params, JSON_UNESCAPED_UNICODE));
|
||||
$result = $this->app->order_shipping->uploadShippingInfo($params);
|
||||
Log::write('发货信息录入接口,自备数据(结果):' . json_encode($result, JSON_UNESCAPED_UNICODE));
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error($result, 'uploadShippingInfoError:'.$result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage() . ",File:" . $e->getFile() . ",line:" . $e->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* todo【暂时没有用到】发货信息合单录入接口
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingUploadCombinedShippingInfo($data = [])
|
||||
{
|
||||
try {
|
||||
$params = [
|
||||
'order_key' => [
|
||||
'order_number_type' => $data[ 'order_number_type' ] ?? 1, // 订单单号类型,用于确认需要上传详情的订单。枚举值1,使用下单商户号和商户侧单号;枚举值2,使用微信支付单号。
|
||||
],
|
||||
'logistics_type' => $data[ 'logistics_type' ], // 物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
|
||||
'delivery_mode' => $data[ 'delivery_mode' ], // 发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY
|
||||
'sub_orders' => $data[ 'sub_orders' ], // 子单物流详情
|
||||
'upload_time' => $data[ 'upload_time' ], // 上传时间,用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
|
||||
'payer' => [
|
||||
'openid' => $data[ 'openid' ] // 用户标识,用户在小程序appid下的唯一标识。 下单前需获取到用户的Openid 示例值: oUpF8uMuAJO_M2pxb1Q9zNjWeS6o 字符字节限制: [1, 128]
|
||||
]
|
||||
];
|
||||
|
||||
// 原支付交易对应的微信订单号
|
||||
if (!empty($data[ 'transaction_id' ])) {
|
||||
$params[ 'order_key' ][ 'transaction_id' ] = $data[ 'transaction_id' ];
|
||||
}
|
||||
|
||||
// 支付下单商户的商户号,由微信支付生成并下发。
|
||||
if (!empty($data[ 'mchid' ])) {
|
||||
$params[ 'order_key' ][ 'mchid' ] = $data[ 'mchid' ];
|
||||
}
|
||||
|
||||
// 商户系统内部订单号,只能是数字、大小写字母`_-*`且在同一个商户号下唯一
|
||||
if (!empty($data[ 'out_trade_no' ])) {
|
||||
$params[ 'order_key' ][ 'out_trade_no' ] = $data[ 'out_trade_no' ];
|
||||
}
|
||||
|
||||
$result = $this->app->order_shipping->uploadCombinedShippingInfo($params);
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认收货提醒接口
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingNotifyConfirmReceive($data = [])
|
||||
{
|
||||
try {
|
||||
$pay_config = ( new WechatPayModel() )->getPayConfig($data[ 'site_id' ])[ 'data' ][ 'value' ];
|
||||
|
||||
$params = [
|
||||
'merchant_id' => $pay_config[ 'mch_id' ], // 支付下单商户的商户号,由微信支付生成并下发
|
||||
'merchant_trade_no' => $data[ 'out_trade_no' ], // 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
|
||||
'received_time' => time() // 快递签收时间,时间戳形式
|
||||
];
|
||||
|
||||
Log::write('确认收货提醒接口(参数):' . json_encode($params));
|
||||
$result = $this->app->order_shipping->notifyConfirmReceive($params);
|
||||
Log::write('确认收货提醒接口(结果):' . json_encode($result));
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
Log::write('微信小程序确认收货提醒接口报错:' . json_encode($result));
|
||||
return $this->success([], $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
return $this->success($result);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物流公司,运力id列表get_delivery_list
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
public function orderShippingGetDeliveryList()
|
||||
{
|
||||
$cache = Cache::get('orderShippingGetDeliveryList');
|
||||
if ($cache) return $cache;
|
||||
|
||||
try {
|
||||
$result = $this->app->order_shipping->getDeliveryList();
|
||||
if (isset($result[ 'errcode' ]) && $result[ 'errcode' ] != 0) {
|
||||
return $this->error([], $result[ "errmsg" ]);
|
||||
}
|
||||
|
||||
$data = $this->success($result[ 'delivery_list' ]);
|
||||
Cache::set('orderShippingGetDeliveryList', $data);
|
||||
return $data;
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理订单发货物品说明
|
||||
* @param $item_desc
|
||||
* @return string
|
||||
*/
|
||||
public function handleOrderShippingItemDesc($item_desc)
|
||||
{
|
||||
$max_len = 90;
|
||||
$item_desc = join(';',$item_desc);
|
||||
$is_out_len = mb_strlen($item_desc) > $max_len;
|
||||
$item_desc = mb_substr($item_desc, 0, $max_len, 'UTF-8');
|
||||
if($is_out_len){
|
||||
$item_desc .= '...';
|
||||
}
|
||||
return $item_desc;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user