添加网站文件
This commit is contained in:
81
application/common/logic/AccountLogLogic.php
Normal file
81
application/common/logic/AccountLogLogic.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\common\logic;
|
||||
use app\common\model\User;
|
||||
use app\common\model\AccountLog;
|
||||
|
||||
class AccountLogLogic{
|
||||
/**
|
||||
* Notes:记录会员账户流水,如果变动类型是成长值,且是增加的,则调用更新会员等级方法。该方法应在添加用户账户后调用
|
||||
* @author: cjh 2020/12/15 11:49
|
||||
* @param int $user_id 用户id
|
||||
* @param float $amount 变动数量
|
||||
* @param int $change_type 变动类型:1-增加;2-减少
|
||||
* @param int $source_type 来源类型
|
||||
* @param string $remark 说明
|
||||
* @param string $source_id 来源id
|
||||
* @param string $source_sn 来源单号
|
||||
* @param string $extra 额外字段说明
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function AccountRecord($user_id,$amount,$change_type,$source_type,$remark ='',$source_id ='',$source_sn='',$extra=''){
|
||||
$user = User::get($user_id);
|
||||
if(empty($user)){
|
||||
return false;
|
||||
}
|
||||
$type = AccountLog::getChangeType($source_type);
|
||||
$left_amount = '';
|
||||
switch ($type){
|
||||
case 'money':
|
||||
$left_amount = $user->user_money;
|
||||
break;
|
||||
case 'integral':
|
||||
$left_amount = $user->user_integral;
|
||||
break;
|
||||
case 'growth':
|
||||
$left_amount = $user->user_growth;
|
||||
break;
|
||||
case 'earnings':
|
||||
$left_amount = $user->earnings;
|
||||
}
|
||||
$account_log = new AccountLog();
|
||||
$account_log->log_sn = createSn('account_log','log_sn','',4);
|
||||
$account_log->user_id = $user_id;
|
||||
$account_log->source_type = $source_type;
|
||||
$account_log->source_id = $source_id;
|
||||
$account_log->source_sn = $source_sn;
|
||||
$account_log->change_amount = $amount;
|
||||
$account_log->left_amount = $left_amount;
|
||||
$account_log->remark = AccountLog::getRemarkDesc($source_type,$source_sn,$remark);
|
||||
$account_log->extra = $extra;
|
||||
$account_log->change_type = $change_type;
|
||||
$account_log->create_time = time();
|
||||
$account_log->save();
|
||||
|
||||
//更新会员等级
|
||||
if($type === 'growth' && $change_type == 1){
|
||||
UserLevelLogic::updateUserLevel($user_id);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
51
application/common/logic/AfterSaleLogLogic.php
Normal file
51
application/common/logic/AfterSaleLogLogic.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\model\AfterSaleLog;
|
||||
|
||||
/**
|
||||
* 售后记录日志
|
||||
* Class AfterSaleLogLogic
|
||||
* @package app\common\logic
|
||||
*/
|
||||
class AfterSaleLogLogic
|
||||
{
|
||||
public static function record($type, $channel, $order_id, $after_sale_id, $handle_id, $content, $desc = '')
|
||||
{
|
||||
if (empty($content)) {
|
||||
return true;
|
||||
}
|
||||
$log = new AfterSaleLog();
|
||||
$log->type = $type;
|
||||
$log->channel = $channel;
|
||||
$log->order_id = $order_id;
|
||||
$log->after_sale_id = $after_sale_id;
|
||||
$log->handle_id = $handle_id;
|
||||
$log->content = AfterSaleLog::getLogDesc($content);
|
||||
$log->create_time = time();
|
||||
|
||||
if ($desc != ''){
|
||||
$log->content = AfterSaleLog::getLogDesc($content).'('.$desc.')';
|
||||
}
|
||||
|
||||
$log->save();
|
||||
}
|
||||
}
|
||||
44
application/common/logic/AliPayLogic.php
Normal file
44
application/common/logic/AliPayLogic.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\server\AliPayServer;
|
||||
|
||||
class AliPayLogic
|
||||
{
|
||||
|
||||
//支付宝app支付
|
||||
public static function appPay($order)
|
||||
{
|
||||
$data = [
|
||||
'body'=>'商品简述',
|
||||
'subject'=>'商品名',
|
||||
'out_trade_no'=> $order['sn'],
|
||||
'timeout_express'=>'30m',
|
||||
'total_amount'=> $order['order_amount'],
|
||||
'product_code'=>'FAST_INSTANT_TRADE_PAY'
|
||||
];
|
||||
$notify_url = 'http://tp.test/api/index/notify';
|
||||
|
||||
$alipay = new AliPayServer();
|
||||
return $alipay->appAlipay($data, $notify_url);
|
||||
}
|
||||
}
|
||||
96
application/common/logic/CouponLogic.php
Normal file
96
application/common/logic/CouponLogic.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\common\logic;
|
||||
use think\Db;
|
||||
|
||||
class CouponLogic {
|
||||
public static function couponClose($user_id = ''){
|
||||
$coupon_list = Db::name('coupon')
|
||||
->where(['del'=>0])
|
||||
->column('id,use_time_type,use_time_start,use_time_end,use_time','id');
|
||||
|
||||
$coupon_ids = array_keys($coupon_list);
|
||||
$where[] = ['coupon_id','in',$coupon_ids];
|
||||
$where[] = ['status','in',0];
|
||||
if($user_id){
|
||||
$where[] = ['user_id','=',$user_id];
|
||||
}
|
||||
$user_coupon_list = Db::name('coupon_list')
|
||||
->where(['coupon_id'=>$coupon_ids,'status'=>0])
|
||||
->field('id,coupon_id,create_time')
|
||||
->order('id asc')
|
||||
->select();
|
||||
|
||||
$now = time();
|
||||
$update_data = [];
|
||||
foreach ($user_coupon_list as $coupon_item){
|
||||
$coupon = $coupon_list[$coupon_item['coupon_id']] ?? [];
|
||||
if($coupon){
|
||||
//用券时间类型:1-固定时间;2-领券当天起;3-领券次日起
|
||||
switch ($coupon['use_time_type']){
|
||||
case 1:
|
||||
if($now > $coupon['use_time_end']){
|
||||
$update_data[] = $coupon_item['id'];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$daytime = strtotime(date("Y-m-d",$coupon_item['create_time'])) + 86400 * $coupon['use_time'];
|
||||
if($now > $daytime){
|
||||
$update_data[] = $coupon_item['id'];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
$day = $coupon['use_time'] + 2;
|
||||
$daytime = strtotime(date("Y-m-d",$coupon_item['create_time'])) + 86400 * $day;
|
||||
if($now > $daytime){
|
||||
$update_data[] = $coupon_item['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($update_data){
|
||||
Db::name('coupon_list')->where(['id'=>$update_data])->update(['status'=>2,'update_time'=>$now]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Desc: 使用优惠券
|
||||
* @param $coupon_list_id
|
||||
* @param $order_id
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function handleCouponByOrder($coupon_list_id, $order_id)
|
||||
{
|
||||
$update_coupon = [
|
||||
'status' => 1,
|
||||
'use_time' => time(),
|
||||
'order_id' => $order_id,
|
||||
'update_time' => time(),
|
||||
];
|
||||
|
||||
Db::name('coupon_list')
|
||||
->where('id', $coupon_list_id)
|
||||
->update($update_coupon);
|
||||
}
|
||||
}
|
||||
188
application/common/logic/FileCateLogic.php
Normal file
188
application/common/logic/FileCateLogic.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
|
||||
use think\Db;
|
||||
|
||||
class FileCateLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* Desc: 详情
|
||||
* @param $id
|
||||
* @return array|\PDOStatement|string|\think\Model|null
|
||||
*/
|
||||
public static function info($id)
|
||||
{
|
||||
return Db::name('file_cate')->where(['id' => $id])->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* Desc: 添加分类
|
||||
* @param $post
|
||||
* @return bool
|
||||
*/
|
||||
public static function add($post)
|
||||
{
|
||||
$level = 0;
|
||||
|
||||
if ($post['pid']) {
|
||||
$level = Db::name('file_cate')
|
||||
->where(['id' => $post['pid']])
|
||||
->where(['del' => 0])
|
||||
->value('level');
|
||||
}
|
||||
|
||||
$data = [
|
||||
'name' => $post['name'],
|
||||
'pid' => $post['pid'],
|
||||
'sort' => $post['sort'],
|
||||
'level' => $level + 1,
|
||||
'create_time' => time(),
|
||||
'type' => 1
|
||||
];
|
||||
Db::name('file_cate')->insert($data);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Desc: 编辑分类
|
||||
* @param $post
|
||||
* @return bool
|
||||
*/
|
||||
public static function edit($post)
|
||||
{
|
||||
$level = 0;
|
||||
$data = [
|
||||
'pid' => $post['pid'],
|
||||
'name' => $post['name'],
|
||||
'sort' => $post['sort'],
|
||||
'update_time' => time(),
|
||||
];
|
||||
|
||||
if ($post['pid']) {
|
||||
$level = Db::name('file_cate')
|
||||
->where(['id' => $post['pid']])
|
||||
->where(['del' => 0])
|
||||
->value('level');
|
||||
}
|
||||
|
||||
$data['level'] = $level + 1;
|
||||
|
||||
Db::name('file_cate')->where('id', $post['id'])->update($data);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Desc: 删除
|
||||
* @param $id
|
||||
* @return int|string
|
||||
*/
|
||||
public static function del($id)
|
||||
{
|
||||
$data = [
|
||||
'del' => 1,
|
||||
'update_time' => time(),
|
||||
];
|
||||
return Db::name('file_cate')->where(['del' => 0, 'id' => $id])->update($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Desc: 树形结构
|
||||
* @return array
|
||||
*/
|
||||
public static function cateTree()
|
||||
{
|
||||
$lists = Db::name('file_cate')
|
||||
->where(['del' => 0, 'type'=>1])
|
||||
->order('sort')
|
||||
->select();
|
||||
|
||||
$tree = self::cateListToTree($lists, 0);
|
||||
$all = [
|
||||
'id' => 0,
|
||||
'field' => 'all',
|
||||
'title' => '全部',
|
||||
'children' => [],
|
||||
];
|
||||
array_unshift($tree,$all);
|
||||
return $tree;
|
||||
}
|
||||
|
||||
|
||||
public static function cateListToTree($lists, $pid = 0)
|
||||
{
|
||||
$tree = [];
|
||||
foreach ($lists as $k => $v) {
|
||||
if ($v['pid'] == $pid) {
|
||||
$temp['id'] = $v['id'];
|
||||
$temp['field'] = 'id';
|
||||
$temp['title'] = self::handleFileName($v['name'], 4);
|
||||
$temp['children'] = self::cateListToTree($lists, $v['id']);
|
||||
$temp['spread'] = true;
|
||||
$tree[] = $temp;
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Desc: 下拉框树状结构
|
||||
* @return array
|
||||
*/
|
||||
public static function categoryToSelect()
|
||||
{
|
||||
$lists = Db::name('file_cate')
|
||||
->where(['del' => 0])
|
||||
->order('sort')
|
||||
->select();
|
||||
|
||||
$tree = [];
|
||||
foreach ($lists as $val) {
|
||||
|
||||
if ($val['pid'] != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tree[$val['id']] = "|----" . $val['name'];
|
||||
foreach ($lists as $val2) {
|
||||
if ($val2['pid'] == $val['id']) {
|
||||
$tree[$val2['id']] = "|--------" . $val2['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
//分类名超出隐藏
|
||||
public static function handleFileName($str, $length)
|
||||
{
|
||||
if (mb_strlen($str) > $length) {
|
||||
return mb_substr($str,0, $length) . '..';
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
||||
236
application/common/logic/IntegralLogic.php
Normal file
236
application/common/logic/IntegralLogic.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\api\model\User;
|
||||
use app\common\model\AccountLog;
|
||||
use app\common\model\OrderGoods;
|
||||
use app\common\server\ConfigServer;
|
||||
use think\Db;
|
||||
|
||||
class IntegralLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 订单是否开启积分抵扣
|
||||
* @param $order_goods
|
||||
* @author 段誉(2021/4/1 11:05)
|
||||
* @return bool
|
||||
*/
|
||||
public static function isIntegralInOrder($order_goods)
|
||||
{
|
||||
$integral_switch = ConfigServer::get('marketing', 'integral_deduction_status', 0);
|
||||
|
||||
if ($integral_switch == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($order_goods as $good) {
|
||||
if ($good['is_integral'] != 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Desc: 处理积分
|
||||
* @param $user_id
|
||||
* @param $use_integral
|
||||
* @param $channel
|
||||
* @param $source_id
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function handleIntegral($user_id, $use_integral, $channel, $source_id)
|
||||
{
|
||||
$user = User::get($user_id);
|
||||
switch ($channel) {
|
||||
//下单积分抵扣
|
||||
case AccountLog::order_deduction_integral:
|
||||
$user->user_integral = ['dec', $use_integral];
|
||||
$change_type = 2;
|
||||
break;
|
||||
|
||||
//取消订单退回积分
|
||||
case AccountLog::cancel_order_refund_integral:
|
||||
$user->user_integral = ['inc', $use_integral];
|
||||
$change_type = 1;
|
||||
break;
|
||||
|
||||
//下单奖励积分(每天一单)
|
||||
case AccountLog::order_add_integral:
|
||||
$user->user_integral = ['inc', $use_integral];
|
||||
$change_type = 1;
|
||||
break;
|
||||
|
||||
//扣除首单积分奖励(用户取消订单)
|
||||
case AccountLog::deduct_order_first_integral:
|
||||
$diff = $user->user_integral - $use_integral;
|
||||
if ($diff < 0) {
|
||||
$user->user_integral = 0;
|
||||
} else {
|
||||
$user->user_integral = ['dec', $use_integral];
|
||||
}
|
||||
$change_type = 2;
|
||||
break;
|
||||
|
||||
//购买商品赠送积分
|
||||
case AccountLog::order_goods_give_integral:
|
||||
$user->user_integral = ['inc', $use_integral];
|
||||
$change_type = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
$user->save();
|
||||
//更新积分记录
|
||||
AccountLogLogic::AccountRecord($user_id, $use_integral, $change_type, $channel, '', $source_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Desc: 下单奖励积分(每天第一单)
|
||||
* @param $user_id
|
||||
* @param $order_id
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function rewardIntegral($user_id, $order_id)
|
||||
{
|
||||
//是否为当天第一个订单(是->奖励积分)
|
||||
$check = Db::name('account_log')
|
||||
->where(['user_id' => $user_id, 'source_type' => AccountLog::order_add_integral])
|
||||
->whereTime('create_time', 'today')
|
||||
->find();
|
||||
|
||||
//下单奖励开关;0-关闭;1-开启;
|
||||
$order_award_integral = ConfigServer::get('marketing', 'order_award_integral', 0);
|
||||
if ($order_award_integral == 0 || $check) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::handleIntegral($user_id, $order_award_integral, AccountLog::order_add_integral, $order_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 扣除首单积分
|
||||
* @param $user_id
|
||||
* @param $order_id
|
||||
* @author 段誉(2021/2/25 10:23)
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function backIntegral($user_id, $order_id)
|
||||
{
|
||||
$log = Db::name('account_log')
|
||||
->where([
|
||||
'user_id' => $user_id,
|
||||
'source_type' => AccountLog::order_add_integral,
|
||||
'source_id' => $order_id
|
||||
])
|
||||
->find();
|
||||
|
||||
if (!$log){
|
||||
return false;
|
||||
}
|
||||
|
||||
self::handleIntegral($user_id, $log['change_amount'], AccountLog::deduct_order_first_integral, $order_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 购买商品奖励积分
|
||||
* @param $user_id
|
||||
* @param $order_id
|
||||
* @author 段誉(2021/4/1 11:06)
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function rewardIntegralByGoods($user_id, $order_id)
|
||||
{
|
||||
$goods_model = new OrderGoods();
|
||||
$goods = $goods_model->alias('og')
|
||||
->field('g.*,og.total_pay_price')
|
||||
->join('goods g', 'g.id = og.goods_id')
|
||||
->where(['order_id' => $order_id])
|
||||
->select();
|
||||
|
||||
$get_integral = 0;//可得积分
|
||||
|
||||
foreach ($goods as $good) {
|
||||
//赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分'
|
||||
if ($good['give_integral_type'] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$good['give_integral'] = empty($good['give_integral']) ? 0 : intval($good['give_integral']);
|
||||
|
||||
if ($good['give_integral_type'] == 1) {
|
||||
$get_integral += $good['give_integral'];
|
||||
}
|
||||
|
||||
if ($good['give_integral_type'] == 2) {
|
||||
$get_integral += $good['give_integral'] * $good['total_pay_price'] / 100;
|
||||
}
|
||||
}
|
||||
|
||||
if ($get_integral <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//用户赠送积分
|
||||
self::handleIntegral($user_id, $get_integral, AccountLog::order_goods_give_integral, $order_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 积分抵扣描述
|
||||
* @param $integral_config
|
||||
* @param $integral_limit
|
||||
* @author 段誉(2021/5/19 18:32)
|
||||
* @return string
|
||||
*/
|
||||
public static function getIntegralDesc($integral_config, $integral_limit)
|
||||
{
|
||||
if ($integral_config <= 0) {
|
||||
return '积分不可抵扣';
|
||||
}
|
||||
$integral_desc = $integral_config.'积分可抵扣1元';
|
||||
if ($integral_limit > 0) {
|
||||
$integral_desc .= ',单次抵扣积分不能低于'.$integral_limit;
|
||||
}
|
||||
return $integral_desc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
37
application/common/logic/LogicBase.php
Normal file
37
application/common/logic/LogicBase.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
|
||||
class LogicBase
|
||||
{
|
||||
public static function dataSuccess($msg = '', $data = [], $code = 1, $show = 0)
|
||||
{
|
||||
return data_success($msg, $data, $code, $show);
|
||||
}
|
||||
|
||||
|
||||
public static function dataError($msg = '', $data = [], $code = 0, $show = 1)
|
||||
{
|
||||
return data_error($msg, $data, $code, $show);
|
||||
}
|
||||
|
||||
}
|
||||
203
application/common/logic/NoticeLogic.php
Normal file
203
application/common/logic/NoticeLogic.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
|
||||
use app\common\model\NoticeSetting;
|
||||
use app\common\server\ConfigServer;
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
|
||||
class NoticeLogic
|
||||
{
|
||||
|
||||
//添加通知记录
|
||||
public static function addNoticeLog($params, $scene_info, $send_type, $content, $extra = '')
|
||||
{
|
||||
return Db::name('notice')->insertGetId([
|
||||
'user_id' => $params['user_id'] ?? 0,
|
||||
'title' => self::getTitleByScene($send_type, $scene_info),
|
||||
'content' => $content,
|
||||
'scene' => $params['scene'],
|
||||
'receive_type' => self::getReceiveTypeByScene($params['scene']),
|
||||
'send_type' => $send_type,
|
||||
'extra' => $extra,
|
||||
'create_time' => time()
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
//更新通知记录
|
||||
public static function updateNotice($notice_id, $extra)
|
||||
{
|
||||
return Db::name('notice')
|
||||
->where('id', $notice_id)
|
||||
->update(['extra' => $extra]);
|
||||
}
|
||||
|
||||
|
||||
//格式化消息内容(替换文本)
|
||||
public static function contentFormat($content, $params)
|
||||
{
|
||||
foreach ($params as $k => $v) {
|
||||
$search_replace = '{'.$k.'}';
|
||||
$content = str_replace($search_replace, $v, $content);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
//根据不同发送类型获取标题
|
||||
public static function getTitleByScene($send_type, $scene_info)
|
||||
{
|
||||
$title = '';
|
||||
switch ($send_type) {
|
||||
case NoticeSetting::SYSTEM_NOTICE:
|
||||
$title = $scene_info['system_notice']['title'] ?? '';
|
||||
break;
|
||||
case NoticeSetting::SMS_NOTICE:
|
||||
$title = '';
|
||||
break;
|
||||
case NoticeSetting::OA_NOTICE:
|
||||
$title = $scene_info['oa_notice']['name'] ?? '';
|
||||
break;
|
||||
case NoticeSetting::MNP_NOTICE:
|
||||
$title = $scene_info['mnp_notice']['name'] ?? '';
|
||||
break;
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
|
||||
//根据场景返回当前接收对象
|
||||
public static function getReceiveTypeByScene($scene)
|
||||
{
|
||||
if (in_array($scene, NoticeSetting::NOTICE_PLATFORM_SCENE)) {
|
||||
return NoticeSetting::NOTICE_PLATFORM;
|
||||
}
|
||||
|
||||
if (in_array($scene, NoticeSetting::NOTICE_USER_SCENE)) {
|
||||
return NoticeSetting::NOTICE_USER;
|
||||
}
|
||||
|
||||
if (in_array($scene, NoticeSetting::NOTICE_OTHER_SCENE)) {
|
||||
return NoticeSetting::NOTICE_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//================================================================================================
|
||||
|
||||
|
||||
//消息主页
|
||||
public static function index($user_id)
|
||||
{
|
||||
//最新系统消息
|
||||
$server = Db::name('notice')
|
||||
->where('scene', '<>', NoticeSetting::GET_EARNINGS_NOTICE)
|
||||
->where(['user_id' => $user_id, 'send_type' => NoticeSetting::SYSTEM_NOTICE])
|
||||
->order('id desc')
|
||||
->find();
|
||||
|
||||
//最新收益通知
|
||||
$earning = Db::name('notice')
|
||||
->where('scene', NoticeSetting::GET_EARNINGS_NOTICE)
|
||||
->where(['user_id' => $user_id, 'send_type' => NoticeSetting::SYSTEM_NOTICE])
|
||||
->order('id desc')
|
||||
->find();
|
||||
|
||||
$data['system'] = [
|
||||
'title' => '系统通知',
|
||||
'content' => $server['content'] ?? '暂无系统消息',
|
||||
'img' => UrlServer::getFileUrl(ConfigServer::get('website', 'system_notice')),
|
||||
'type' => 'system',
|
||||
];
|
||||
|
||||
$data['earning'] = [
|
||||
'title' => '收益通知',
|
||||
'content' => $earning['content'] ?? '暂无收益消息',
|
||||
'img' => UrlServer::getFileUrl(ConfigServer::get('website', 'earning_notice')),
|
||||
'type' => 'earning',
|
||||
];
|
||||
$res = array_values($data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
//消息列表
|
||||
public static function lists($user_id, $type, $page, $size)
|
||||
{
|
||||
$where = [];
|
||||
$where[] = ['user_id', '=', $user_id];
|
||||
$where[] = ['send_type', '=', NoticeSetting::SYSTEM_NOTICE];
|
||||
|
||||
if ($type == 'earning') {
|
||||
$where[] = ['scene', '=', NoticeSetting::GET_EARNINGS_NOTICE];
|
||||
}else{
|
||||
$where[] = ['scene', '<>', NoticeSetting::GET_EARNINGS_NOTICE];
|
||||
}
|
||||
|
||||
$count = Db::name('notice')->where($where)->count();
|
||||
|
||||
$lists = Db::name('notice')
|
||||
->where($where)
|
||||
->order('id desc')
|
||||
->page($page, $size)
|
||||
->select();
|
||||
|
||||
foreach ($lists as $k => $item) {
|
||||
$lists[$k]['create_time'] = date('Y-m-d H:i:s', $item['create_time']);
|
||||
$lists[$k]['type'] = NoticeSetting::getSceneDesc(($item['scene']));
|
||||
}
|
||||
|
||||
$data = [
|
||||
'list' => $lists,
|
||||
'page' => $page,
|
||||
'size' => $size,
|
||||
'count' => $count,
|
||||
'more' => is_more($count, $page, $size)
|
||||
];
|
||||
self::setRead($where);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
//更新为已读
|
||||
public static function setRead($where)
|
||||
{
|
||||
//进入列表后全部已读
|
||||
Db::name('notice')
|
||||
->where($where)
|
||||
->where('read','<>', 1)
|
||||
->update(['read' => 1]);
|
||||
}
|
||||
|
||||
//是否有未读的消息
|
||||
public static function unRead($user_id)
|
||||
{
|
||||
$un_read = Db::name('notice')
|
||||
->where(['user_id' => $user_id, 'read' => 0])
|
||||
->where(['send_type' => NoticeSetting::SYSTEM_NOTICE])
|
||||
->find();
|
||||
if ($un_read){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
141
application/common/logic/OrderGoodsLogic.php
Normal file
141
application/common/logic/OrderGoodsLogic.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
|
||||
use app\api\logic\SeckillLogic;
|
||||
use app\common\model\Pay;
|
||||
use app\common\server\ConfigServer;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 订单商品逻辑
|
||||
* Class OrderGoodsLogic
|
||||
* @package app\common\logic
|
||||
*/
|
||||
class OrderGoodsLogic
|
||||
{
|
||||
//返回订单库存,销量
|
||||
public static function backStock($order_goods, $pay_status)
|
||||
{
|
||||
$deduct_type = ConfigServer::get('trading', 'deduct_type', 1);
|
||||
//支付后扣减
|
||||
if ($deduct_type == 0 && $pay_status == Pay::UNPAID) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($order_goods as $good) {
|
||||
//回退库存,回退规格库存,减少商品销量
|
||||
Db::name('goods')
|
||||
->where('id', $good['goods_id'])
|
||||
->update([
|
||||
// 'sales_sum' => Db::raw("sales_sum-" . $good['goods_num']),
|
||||
'stock' => Db::raw('stock+' . $good['goods_num'])
|
||||
]);
|
||||
|
||||
//补充规格表库存
|
||||
Db::name('goods_item')
|
||||
->where('id', $good['item_id'])
|
||||
->setInc('stock', $good['goods_num']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//下单扣除订单库存
|
||||
public static function decStock($goods)
|
||||
{
|
||||
$seckill_data = SeckillLogic::getSeckillGoods();
|
||||
$seckill = $seckill_data['seckill'];
|
||||
$seckill_goods = $seckill_data['seckill_goods'];
|
||||
|
||||
$goods_ids = [];
|
||||
|
||||
foreach ($goods as $k1 => $good) {
|
||||
$item_id = $good['item_id'];
|
||||
//扣除库存,扣除规格库存,增加商品销量
|
||||
Db::name('goods')
|
||||
->where('id', $good['goods_id'])
|
||||
->update([
|
||||
'sales_sum' => Db::raw("sales_sum+" . $good['goods_num']),
|
||||
'stock' => Db::raw('stock-' . $good['goods_num'])
|
||||
]);
|
||||
|
||||
//扣除规格表库存
|
||||
Db::name('goods_item')
|
||||
->where('id', $item_id)
|
||||
->setDec('stock', $good['goods_num']);
|
||||
|
||||
//秒杀商品增加销量
|
||||
if (isset($seckill_goods[$item_id])){
|
||||
$seckill_goods_id = $seckill_goods[$item_id]['seckill_goods_id'];
|
||||
Db::name('seckill_goods')
|
||||
->where('id', $seckill_goods_id)
|
||||
->update([
|
||||
'sales_sum' => Db::raw("sales_sum+" . $good['goods_num']),
|
||||
'update_time' => time()
|
||||
]);
|
||||
}
|
||||
|
||||
$goods_ids[] = $good['goods_id'];
|
||||
}
|
||||
|
||||
//下架商品总库存为0的商品
|
||||
if (!empty($goods_ids)){
|
||||
self::outGoods($goods_ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 下单后下架商品总库存为0的商品
|
||||
* @param $goods_id
|
||||
* @author 段誉(2021/3/19 16:19)
|
||||
* @return bool
|
||||
*/
|
||||
public static function outGoods($goods_ids)
|
||||
{
|
||||
try{
|
||||
$goods = Db::name('goods')
|
||||
->field('id, stock')
|
||||
->where('id', 'in', $goods_ids)
|
||||
->select();
|
||||
|
||||
if (empty($goods)){
|
||||
return true;
|
||||
}
|
||||
|
||||
$need_handle_ids = [];
|
||||
foreach ($goods as $good) {
|
||||
if ($good['stock'] <= 0) {
|
||||
$need_handle_ids[] = $good['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($need_handle_ids)){
|
||||
return true;
|
||||
}
|
||||
//下架订单商品中 商品总库存已为0的商品
|
||||
Db::name('goods')->where('id', 'in', $need_handle_ids)->update(['status' => 0]);
|
||||
|
||||
} catch (\Exception $e) {}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
50
application/common/logic/OrderLogLogic.php
Normal file
50
application/common/logic/OrderLogLogic.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\model\OrderLog;
|
||||
|
||||
/**
|
||||
* 订单记录日志
|
||||
* Class OrderLogLogic
|
||||
* @package app\common\logic
|
||||
*/
|
||||
class OrderLogLogic
|
||||
{
|
||||
public static function record($type, $channel, $order_id, $handle_id, $content, $desc = '')
|
||||
{
|
||||
if (empty($content)) {
|
||||
return true;
|
||||
}
|
||||
$log = new OrderLog();
|
||||
$log->type = $type;
|
||||
$log->order_id = $order_id;
|
||||
$log->channel = $channel;
|
||||
$log->handle_id = $handle_id;
|
||||
$log->content = OrderLog::getLogDesc($content);
|
||||
$log->create_time = time();
|
||||
|
||||
if ($desc != '') {
|
||||
$log->content = OrderLog::getLogDesc($content) . '(' . $desc . ')';
|
||||
}
|
||||
|
||||
$log->save();
|
||||
}
|
||||
}
|
||||
349
application/common/logic/OrderRefundLogic.php
Normal file
349
application/common/logic/OrderRefundLogic.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
|
||||
use app\api\logic\DistributionLogic;
|
||||
use app\api\model\Order;
|
||||
use app\common\model\AccountLog;
|
||||
use app\common\model\Order as CommonOrder;
|
||||
use app\common\model\OrderGoods;
|
||||
use app\common\model\OrderLog;
|
||||
use app\common\model\Pay;
|
||||
use app\common\model\User;
|
||||
use app\common\server\AliPayServer;
|
||||
use app\common\server\WeChatPayServer;
|
||||
use app\common\server\WeChatServer;
|
||||
use think\Db;
|
||||
use think\Exception;
|
||||
use think\facade\Hook;
|
||||
|
||||
/**
|
||||
* 订单退款逻辑
|
||||
* Class OrderRefundLogic
|
||||
* @package app\common\logic
|
||||
*/
|
||||
class OrderRefundLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 取消订单
|
||||
* @param $order_id
|
||||
* @param int $handle_type
|
||||
* @param int $handle_id
|
||||
* @author 段誉(2021/1/28 15:23)
|
||||
* @return Order
|
||||
*/
|
||||
public static function cancelOrder($order_id, $handle_type = OrderLog::TYPE_SYSTEM, $handle_id = 0)
|
||||
{
|
||||
//更新订单状态
|
||||
$order = Order::get($order_id);
|
||||
$order->order_status = CommonOrder::STATUS_CLOSE;
|
||||
$order->update_time = time();
|
||||
$order->cancel_time = time();
|
||||
$order->save();
|
||||
|
||||
//取消订单后操作
|
||||
Hook::listen('cancel_order', ['order_id' => $order_id, 'handle_id' => $handle_id, 'handle_type' => $handle_type]);
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 处理订单退款(事务在取消订单逻辑处)
|
||||
* @param $order
|
||||
* @param $order_amount
|
||||
* @param $refund_amount
|
||||
* @author 段誉(2021/1/28 15:23)
|
||||
* @throws Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function refund($order, $order_amount, $refund_amount)
|
||||
{
|
||||
//退款记录
|
||||
$refund_id = self::addRefundLog($order, $order_amount, $refund_amount);
|
||||
|
||||
switch ($order['pay_way']) {
|
||||
//余额退款
|
||||
case Pay::BALANCE_PAY:
|
||||
self::balancePayRefund($order, $refund_amount);
|
||||
break;
|
||||
//微信退款
|
||||
case Pay::WECHAT_PAY:
|
||||
self::wechatPayRefund($order, $refund_id);
|
||||
break;
|
||||
//支付宝退款
|
||||
case Pay::ALI_PAY:
|
||||
self::aliPayRefund($order, $refund_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 微信支付退款
|
||||
* @param $order (订单信息)
|
||||
* @param $refund_id (退款记录id)
|
||||
* @author 段誉(2021/1/27 16:04)
|
||||
* @throws Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function wechatPayRefund($order, $refund_id)
|
||||
{
|
||||
$config = WeChatServer::getPayConfigBySource($order['order_source'])['config'];
|
||||
|
||||
if (empty($config)) {
|
||||
throw new Exception('请联系管理员设置微信相关配置!');
|
||||
}
|
||||
|
||||
if (!isset($config['cert_path']) || !isset($config['key_path'])) {
|
||||
throw new Exception('请联系管理员设置微信证书!');
|
||||
}
|
||||
|
||||
if (!file_exists($config['cert_path']) || !file_exists($config['key_path'])) {
|
||||
throw new Exception('微信证书不存在,请联系管理员!');
|
||||
}
|
||||
|
||||
$refund_log = Db::name('order_refund')->where(['id' => $refund_id])->find();
|
||||
|
||||
$data = [
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'refund_sn' => $refund_log['refund_sn'],
|
||||
'total_fee' => $refund_log['order_amount'] * 100,//订单金额,单位为分
|
||||
'refund_fee' => intval($refund_log['refund_amount'] * 100),//退款金额
|
||||
];
|
||||
$result = WeChatPayServer::refund($config, $data);
|
||||
|
||||
if (isset($result['return_code']) && $result['return_code'] == 'FAIL') {
|
||||
throw new Exception($result['return_msg']);
|
||||
}
|
||||
|
||||
if (isset($result['err_code_des'])) {
|
||||
throw new Exception($result['err_code_des']);
|
||||
}
|
||||
|
||||
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
|
||||
$update_data = [
|
||||
'wechat_refund_id' => $result['refund_id'] ?? 0,
|
||||
'refund_msg' => json_encode($result, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
//更新退款日志记录
|
||||
Db::name('order_refund')->where(['id' => $refund_id])->update($update_data);
|
||||
|
||||
} else {
|
||||
throw new Exception('微信支付退款失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 支付宝退款
|
||||
* @param $order
|
||||
* @param $refund_id
|
||||
* @author 段誉(2021/3/23 15:48)
|
||||
* @throws Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function aliPayRefund($order, $refund_id)
|
||||
{
|
||||
$result = (new AliPayServer())->refund($order['order_sn'], $order['order_amount']);
|
||||
$result = (array)$result;
|
||||
|
||||
if ($result['code'] == '10000' && $result['msg'] == 'Success' && $result['fundChange'] == 'Y') {
|
||||
//更新退款日志记录
|
||||
$update_data = ['refund_msg' => json_encode($result['httpBody'], JSON_UNESCAPED_UNICODE)];
|
||||
Db::name('order_refund')->where(['id' => $refund_id])->update($update_data);
|
||||
} else {
|
||||
throw new Exception('支付宝退款失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 增加退款记录
|
||||
* @param $order
|
||||
* @param $order_amount
|
||||
* @param $refund_amount
|
||||
* @param string $result_msg
|
||||
* @author 段誉(2021/1/28 15:23)
|
||||
* @return int|string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function addRefundLog($order, $order_amount, $refund_amount, $result_msg = '退款成功')
|
||||
{
|
||||
$data = [
|
||||
'order_id' => $order['id'],
|
||||
'user_id' => $order['user_id'],
|
||||
'refund_sn' => createSn('order_refund', 'refund_sn'),
|
||||
'order_amount' => $order_amount,
|
||||
'refund_amount' => $refund_amount,
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'create_time' => time(),
|
||||
'refund_status' => 1,
|
||||
'refund_at' => time(),
|
||||
'refund_msg' => json_encode($result_msg, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
return Db::name('order_refund')->insertGetId($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 取消订单,退款后更新订单和订单商品信息
|
||||
* @param $order
|
||||
* @author 段誉(2021/1/28 14:21)
|
||||
* @throws Exception
|
||||
* @throws \think\exception\PDOException
|
||||
*/
|
||||
public static function cancelOrderRefundUpdate($order)
|
||||
{
|
||||
//订单商品=>标记退款成功状态
|
||||
Db::name('order_goods')
|
||||
->where(['order_id' => $order['id']])
|
||||
->update(['refund_status' => OrderGoods::REFUND_STATUS_SUCCESS]);
|
||||
|
||||
//更新订单支付状态为已退款
|
||||
Db::name('order')->where(['id' => $order['id']])->update([
|
||||
'pay_status' => Pay::REFUNDED,
|
||||
'refund_status' => 2,//订单退款状态; 0-未退款;1-部分退款;2-全部退款
|
||||
'refund_amount' => $order['order_amount'],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes:售后退款更新订单或订单商品状态
|
||||
* @param $order
|
||||
* @param $order_goods_id
|
||||
* @author 段誉(2021/1/28 15:22)
|
||||
*/
|
||||
public static function afterSaleRefundUpdate($order, $order_goods_id, $admin_id = 0)
|
||||
{
|
||||
$order_goods = OrderGoods::get(['id' => $order_goods_id]);
|
||||
$order_goods->refund_status = OrderGoods::REFUND_STATUS_SUCCESS;//退款成功
|
||||
$order_goods->save();
|
||||
|
||||
//更新订单状态
|
||||
$order = \app\common\model\Order::get(['id' => $order['id']]);
|
||||
$order->pay_status = Pay::REFUNDED;
|
||||
$order->refund_amount += $order_goods['total_pay_price'];//退款金额 + 以前的退款金额
|
||||
$order->refund_status = 1;//退款状态:0-未退款;1-部分退款;2-全部退款
|
||||
|
||||
//如果订单商品已全部退款
|
||||
if (self::checkOrderGoods($order['id'])) {
|
||||
$order->order_status = CommonOrder::STATUS_CLOSE;
|
||||
$order->refund_status = 2;
|
||||
|
||||
OrderLogLogic::record(
|
||||
OrderLog::TYPE_SHOP,
|
||||
OrderLog::SYSTEM_CANCEL_ORDER,
|
||||
$order['id'],
|
||||
$admin_id,
|
||||
OrderLog::SYSTEM_CANCEL_ORDER
|
||||
);
|
||||
}
|
||||
$order->save();
|
||||
|
||||
//更新相关分佣订单为已失效
|
||||
DistributionLogic::setFailByAfterSale($order_goods_id);
|
||||
}
|
||||
|
||||
|
||||
//订单内商品是否已全部
|
||||
public static function checkOrderGoods($order_id)
|
||||
{
|
||||
$order_goods = OrderGoods::where('order_id', $order_id)->select();
|
||||
if (empty($order_goods)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($order_goods as $item) {
|
||||
if ($item['refund_status'] != OrderGoods::REFUND_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 余额退款
|
||||
* @param $order
|
||||
* @param $refund_amount
|
||||
* @author 段誉(2021/1/28 15:24)
|
||||
* @return bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function balancePayRefund($order, $refund_amount)
|
||||
{
|
||||
$user = User::get($order['user_id']);
|
||||
$user->user_money = ['inc', $refund_amount];
|
||||
$user->save();
|
||||
|
||||
AccountLogLogic::AccountRecord(
|
||||
$order['user_id'],
|
||||
$refund_amount,
|
||||
1,
|
||||
AccountLog::cancel_order_refund,
|
||||
'',
|
||||
$order['id'],
|
||||
$order['order_sn']
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 退款失败增加错误记录
|
||||
* @param $order
|
||||
* @param $err_msg
|
||||
* @author 段誉(2021/1/28 15:24)
|
||||
* @return int|string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public static function addErrorRefund($order, $err_msg)
|
||||
{
|
||||
$refund_data = [
|
||||
'order_id' => $order['id'],
|
||||
'user_id' => $order['user_id'],
|
||||
'refund_sn' => createSn('order_refund', 'refund_sn'),
|
||||
'order_amount' => $order['order_amount'],//订单应付金额
|
||||
'refund_amount' => $order['order_amount'],//订单退款金额
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'create_time' => time(),
|
||||
'refund_status' => 2,
|
||||
'refund_msg' => json_encode($err_msg, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
return Db::name('order_refund')->insertGetId($refund_data);
|
||||
}
|
||||
|
||||
}
|
||||
201
application/common/logic/PayNotifyLogic.php
Normal file
201
application/common/logic/PayNotifyLogic.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\api\logic\GoodsLogic;
|
||||
use app\api\logic\OrderLogic;
|
||||
use app\api\logic\TeamLogic;
|
||||
use app\common\model\{AccountLog, Footprint, MessageScene_, NoticeSetting, OrderLog, User, Pay, Order, OrderTrade};
|
||||
use app\common\server\ConfigServer;
|
||||
use app\common\server\DistributionServer;
|
||||
use think\Db;
|
||||
use think\Exception;
|
||||
use think\facade\Hook;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 支付成功后处理订单状态
|
||||
* Class PayNotifyLogic
|
||||
* @package app\api\logic
|
||||
*/
|
||||
class PayNotifyLogic
|
||||
{
|
||||
public static function handle($action, $order_sn, $extra = [])
|
||||
{
|
||||
Db::startTrans();
|
||||
try {
|
||||
self::$action($order_sn, $extra);
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
Db::rollback();
|
||||
$record = [
|
||||
__CLASS__, __FUNCTION__, $e->getFile(), $e->getLine(), $e->getMessage()
|
||||
];
|
||||
Log::record(implode('-', $record));
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//下单回调
|
||||
private static function order($order_sn, $extra = [])
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$order_model = new Order();
|
||||
$order = $order_model
|
||||
->with('order_goods')
|
||||
->where('order_sn',$order_sn)
|
||||
->find();
|
||||
|
||||
//增加会员消费累计额度
|
||||
$user = User::get($order['user_id']);
|
||||
$user->total_order_amount = ['inc', $order['order_amount']];
|
||||
|
||||
//余额支付,扣除余额
|
||||
if ($order['pay_way'] == Pay::BALANCE_PAY) {
|
||||
$user->user_money = ['dec', $order['order_amount']];
|
||||
$user->save();
|
||||
AccountLogLogic::AccountRecord($order['user_id'], $order['order_amount'], 2, AccountLog::balance_pay_order, '', $order['id'], $order_sn);
|
||||
} else {
|
||||
$user->save();
|
||||
}
|
||||
|
||||
$order->pay_status = Pay::ISPAID;
|
||||
$order->pay_time = $time;
|
||||
$order->order_status = Order::STATUS_WAIT_DELIVERY;
|
||||
if (isset($extra['transaction_id'])) {
|
||||
$order->transaction_id = $extra['transaction_id'];
|
||||
}
|
||||
$order->save();
|
||||
|
||||
//扣除库存
|
||||
$deduct_type = ConfigServer::get('trading','deduct_type', 1);
|
||||
if ($deduct_type == 0) {
|
||||
//扣除库存,增加销量
|
||||
OrderGoodsLogic::decStock($order['order_goods']);
|
||||
}
|
||||
|
||||
//订单日志
|
||||
OrderLogLogic::record(
|
||||
OrderLog::TYPE_USER,
|
||||
OrderLog::USER_PAID_ORDER,
|
||||
$order['id'],
|
||||
$user['id'],
|
||||
OrderLog::USER_PAID_ORDER
|
||||
);
|
||||
|
||||
//拼团订单,更新拼团信息
|
||||
if ($order['order_type'] == Order::TEAM_ORDER){
|
||||
TeamLogic::updateTeam($order['id']);
|
||||
}
|
||||
|
||||
//拼购,砍价的订单不参与分销分佣
|
||||
if ($order['order_type'] == Order::NORMAL_ORDER){
|
||||
DistributionServer::commission($order['id']);
|
||||
}
|
||||
|
||||
|
||||
//发送通知
|
||||
Hook::listen('notice', [
|
||||
'user_id' => $user['id'],
|
||||
'order_id' => $order['id'],
|
||||
'scene' => NoticeSetting::ORDER_PAY_NOTICE,
|
||||
]);
|
||||
|
||||
|
||||
//短信通知
|
||||
Hook::listen('sms_send', [
|
||||
'key' => NoticeSetting::ORDER_PAY_NOTICE,
|
||||
'mobile' => $order->mobile,
|
||||
'user_id' => $user->id,
|
||||
'params' => [
|
||||
'nickname' => $user->nickname,
|
||||
'order_sn' => $order->order_sn,
|
||||
'order_amount' => $order->order_amount,
|
||||
'time' => $order->create_time,
|
||||
'total_num' => $order->total_num.'件',
|
||||
'goods_name' => omit_str(($order->order_goods[0]['goods_name'] ?? '商品'), 8)
|
||||
]
|
||||
]);
|
||||
|
||||
$order_contact_mobile = ConfigServer::get('order_message', 'order_contact_mobile');
|
||||
//平台短信通知
|
||||
if($order_contact_mobile) {
|
||||
Hook::listen('sms_send',[
|
||||
'key' => NoticeSetting::USER_PAID_NOTICE_PLATFORM,
|
||||
'mobile' => $order_contact_mobile,
|
||||
'params' => [
|
||||
'order_sn' => $order['order_sn'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
// 赠送成长值和积分
|
||||
Hook::listen('give_reward', [
|
||||
'order_id' => $order['id'],
|
||||
'scene' => 1, //1=下单支付场景
|
||||
]);
|
||||
|
||||
// 钩子-记录足迹(下单结算)
|
||||
Hook::listen('footprint', [
|
||||
'type' => Footprint::place_order,
|
||||
'user_id' => $user['id'],
|
||||
'foreign_id' => $order['id'], //订单ID
|
||||
'total_money' => $order['order_amount'] //订单应付金额
|
||||
]);
|
||||
|
||||
//打印订单
|
||||
Hook::listen('printer', [
|
||||
'order_id' => $order['id'],
|
||||
]);
|
||||
|
||||
}
|
||||
/**
|
||||
* note 充值回调
|
||||
* create_time 2020/10/26 18:53
|
||||
*/
|
||||
private static function recharge($order_sn,$extra = []){
|
||||
$new = time();
|
||||
$order = Db::name('recharge_order')->where(['order_sn'=>$order_sn])->find();
|
||||
$update_data['pay_time'] = $new;
|
||||
$update_data['pay_status'] = Pay::ISPAID;
|
||||
if (isset($extra['transaction_id'])) {
|
||||
$update_data['transaction_id'] = $extra['transaction_id'];
|
||||
}
|
||||
Db::name('recharge_order')->where(['id'=>$order['id']])->update($update_data);
|
||||
$user = User::get($order['user_id']);
|
||||
$total_money = $order['order_amount']+$order['give_money'];
|
||||
$total_integral = $order['give_integral'];
|
||||
$user->user_money = ['inc', $total_money];
|
||||
$user->user_integral = ['inc', $total_integral];
|
||||
$user->user_growth = ['inc', $order['give_growth']];
|
||||
$user->total_recharge_amount = ['inc',$total_money];
|
||||
$user->save();
|
||||
//记录余额
|
||||
$total_money > 0 && AccountLogLogic::AccountRecord($user->id,$total_money,1, AccountLog::recharge_money);
|
||||
//记录积分
|
||||
$total_integral > 0 && AccountLogLogic::AccountRecord($user->id,$total_integral,1, AccountLog::recharge_give_integral);
|
||||
//记录成长值
|
||||
$order['give_growth'] > 0 &&AccountLogLogic::AccountRecord($user->id,$order['give_growth'],1, AccountLog::recharge_give_growth);
|
||||
}
|
||||
|
||||
}
|
||||
419
application/common/logic/PaymentLogic.php
Normal file
419
application/common/logic/PaymentLogic.php
Normal file
@@ -0,0 +1,419 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\server\AliPayServer;
|
||||
use app\common\server\WeChatPayServer;
|
||||
use app\common\model\{Client_, Order, Pay, User};
|
||||
use think\facade\Env;
|
||||
|
||||
class PaymentLogic extends LogicBase
|
||||
{
|
||||
|
||||
protected static $error = '';
|
||||
protected static $return_code = 0;
|
||||
|
||||
/**
|
||||
* Notes: 错误信息
|
||||
* @return string
|
||||
* @author 段誉(2021/2/1 11:19)
|
||||
*/
|
||||
public static function getError()
|
||||
{
|
||||
return self::$error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 返回状态码
|
||||
* @return int
|
||||
* @author 段誉(2021/2/1 11:19)
|
||||
*/
|
||||
public static function getReturnCode()
|
||||
{
|
||||
return self::$return_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 支付
|
||||
* @param $from
|
||||
* @param $order
|
||||
* @param $order_source
|
||||
* @return array|bool|string
|
||||
* @author 段誉(2021/2/1 11:19)
|
||||
*/
|
||||
public static function pay($from, $order, $order_source)
|
||||
{
|
||||
switch ($order['pay_way']) {
|
||||
case Pay::WECHAT_PAY:
|
||||
|
||||
$res = WeChatPayServer::unifiedOrder($from, $order, $order_source);
|
||||
if (false === $res) {
|
||||
self::$error = WeChatPayServer::getError();
|
||||
}
|
||||
break;
|
||||
|
||||
case Pay::ALI_PAY:
|
||||
|
||||
$aliPay = new AliPayServer();
|
||||
$res = $aliPay->pay($from, $order, $order_source);
|
||||
if(false === $res) {
|
||||
self::$error = $aliPay->getError();
|
||||
} else {
|
||||
self::$return_code = 20001;//特殊状态码,用于前端判断
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
$ttPay = new ttPay();
|
||||
$res = $ttPay->run('order',$order);
|
||||
|
||||
// $res = self::ttpay($order);
|
||||
if(!empty($res['data'])) {
|
||||
self::$return_code = 8888;//特殊状态码,用于前端判断
|
||||
$res = $res['data'];
|
||||
}else{
|
||||
self::$error = $res['err_tips'];
|
||||
$res = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
self::$error = '订单异常';
|
||||
$res = false;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
//抖音支付
|
||||
public static function ttpay($data)
|
||||
{
|
||||
$url = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
|
||||
$params['app_id'] = 'tt0523739e9a12236501';
|
||||
$params['out_order_no'] = (string)$data['order_sn'];
|
||||
$params['total_amount'] = (int)$data['order_amount'] * 100;
|
||||
$params['subject'] = 'subject';
|
||||
$params['body'] = 'body';
|
||||
$params['valid_time'] = 3600;
|
||||
|
||||
|
||||
$params['sign'] = self::ttsign($params,'ejAuHvbI472euyhb34aVyLD92ll9tgZCqWnMi0tX');
|
||||
|
||||
|
||||
$http = self::httpPost($url, $params);
|
||||
return json_decode($http,true);
|
||||
}
|
||||
|
||||
//curl
|
||||
public static function httpPost($url, $data = null)
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
if (!$data) return false;
|
||||
if (is_array($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_POST, 1);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($curl, CURLOPT_HEADER, 0);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json; charset=utf-8',
|
||||
'Content-Length:' . strlen($data),
|
||||
'Cache-Control: no-cache',
|
||||
'Pragma: no-cache'
|
||||
));
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
$res = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return $res;
|
||||
}
|
||||
// 签名
|
||||
public static function ttsign($map,$secret)
|
||||
{
|
||||
|
||||
$rList = [];
|
||||
foreach($map as $k =>$v) {
|
||||
if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
|
||||
continue;
|
||||
|
||||
$value = trim(strval($v));
|
||||
|
||||
$len = strlen($value);
|
||||
if ($len > 1 && substr($value, 0,1)=="\"" && substr($value, $len-1)=="\"")
|
||||
$value = substr($value,1, $len-1);
|
||||
$value = trim($value);
|
||||
if ($value == "" || $value == "null")
|
||||
continue;
|
||||
$rList[] = $value;
|
||||
}
|
||||
$rList[] = $secret;
|
||||
sort($rList, SORT_STRING);
|
||||
|
||||
|
||||
return md5(implode('&', $rList));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 是否在白名单内支付
|
||||
* @param $user_id
|
||||
* @author 段誉(2021/2/24 10:01)
|
||||
* @return bool
|
||||
*/
|
||||
public static function isPayWhiteList($user_id)
|
||||
{
|
||||
$white_list = Env::get('wechat.white_list', '');
|
||||
$white_list = explode(',', $white_list);
|
||||
if (in_array($user_id, $white_list)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Class ttPay{
|
||||
|
||||
private $api_url='https://developer.toutiao.com/api/apps/ecpay/v1/';
|
||||
private $app_id;
|
||||
private $token;
|
||||
private $salt;
|
||||
|
||||
public function __construct() {
|
||||
$this->app_id = 'tt0523739e9a12236501';
|
||||
$this->token='123qazqweeesdflomswwe';
|
||||
$this->salt='ejAuHvbI472euyhb34aVyLD92ll9tgZCqWnMi0tX';
|
||||
// $this->salt='58280e4f36d88e93d7a4be9f0e590b2302a462c5';
|
||||
}
|
||||
|
||||
public function run($action,$order){
|
||||
$action=$action?$action:'order';
|
||||
if(!in_array($action,['order','query','refund','settle','notify','set'])){
|
||||
echo '非法请求';die;
|
||||
}
|
||||
return $this->$action($order);
|
||||
}
|
||||
|
||||
//下单
|
||||
private function order($order){
|
||||
$data=[
|
||||
'out_order_no'=>$order['order_sn'],
|
||||
'total_amount'=>(int)$order['order_amount'] * 100,
|
||||
'subject'=>'购买服务',
|
||||
'body'=>'购买商品',
|
||||
'valid_time'=>3600,
|
||||
];
|
||||
return $this->post('create_order',$data);
|
||||
|
||||
}
|
||||
|
||||
//查询订单
|
||||
private function query(){
|
||||
$data=[
|
||||
'out_order_no'=>'2021110117254573565'
|
||||
];
|
||||
$res=$this->post('query_order',$data,false);
|
||||
echo json_encode($res);die;
|
||||
}
|
||||
|
||||
//订单退款
|
||||
private function refund(){
|
||||
$data=[
|
||||
'out_order_no'=>'2021110118351347832',
|
||||
'out_refund_no'=>$this->order_number(),
|
||||
'reason'=>'退款原因',
|
||||
'refund_amount'=>1,
|
||||
];
|
||||
$res=$this->post('create_refund',$data);
|
||||
echo json_encode($res);die;
|
||||
}
|
||||
|
||||
//订单分账
|
||||
private function settle(){
|
||||
$data=[
|
||||
'out_order_no'=>'2021110118301265990',
|
||||
'out_settle_no'=>$this->order_number(),
|
||||
'settle_desc'=>'分账描述',
|
||||
'settle_params'=>json_encode([]),//分润方参数 如[['merchant_uid'=>'商户号','amount'=>'10']] 可以有多个分账商户
|
||||
];
|
||||
$res=$this->post('settle',$data);
|
||||
echo json_encode($res);die;
|
||||
}
|
||||
|
||||
//支付设置回调测试
|
||||
private function set(){
|
||||
$content=file_get_contents('php://input');
|
||||
$this->log('log.txt',$content);
|
||||
}
|
||||
|
||||
//回调
|
||||
private function notify(){
|
||||
$content=file_get_contents('php://input');
|
||||
if(empty($content)) return false;
|
||||
$this->log('notify.txt',$content);
|
||||
$content=json_decode($content,true);
|
||||
$sign=$this->handler($content);
|
||||
if($sign==$content['msg_signature']){
|
||||
$msg=json_decode($content['msg'],true);
|
||||
echo '回调----'.$content['type']."\n";
|
||||
//这里更新应用业务逻辑代码,使用$msg跟应用订单比对更新订单,可以用 $content['type']判断是支付回调还是退款回调,payment支付回调 refund退款回调。
|
||||
$res=['err_no'=>0,'err_tips'=>'success'];
|
||||
echo json_encode($res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试订单号,实际应用根据自己应用实际生成
|
||||
* @return string
|
||||
*/
|
||||
private function order_number(){
|
||||
return date('YmdHis').rand(10000,99999);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求小程序平台服务端
|
||||
* @param string $url 接口地址
|
||||
* @param array $data 参数内容
|
||||
* @param boolean $notify 是否有回调
|
||||
* @return array
|
||||
*/
|
||||
private function post($method,$data,$notify=true){
|
||||
$data['app_id']=$this->app_id;
|
||||
|
||||
$data['sign']=$this->sign($data);
|
||||
$url=$this->api_url.$method;
|
||||
$res=$this->http('POST',$url,json_encode($data),['Content-Type: application/json'],true);
|
||||
return json_decode($res,true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 回调验签
|
||||
* @param array $map 验签参数
|
||||
* @return stirng
|
||||
*/
|
||||
private function handler($map){
|
||||
$rList = array();
|
||||
array_push($rList, $this->token);
|
||||
foreach($map as $k =>$v) {
|
||||
if ( $k == "type" || $k=='msg_signature')
|
||||
continue;
|
||||
$value = trim(strval($v));
|
||||
if ($value == "" || $value == "null")
|
||||
continue;
|
||||
array_push($rList, $value);
|
||||
}
|
||||
sort($rList,2);
|
||||
return sha1(implode($rList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求签名
|
||||
* @param array $map 请求参数
|
||||
* @return stirng
|
||||
*/
|
||||
private function sign($map) {
|
||||
$rList = array();
|
||||
foreach($map as $k =>$v) {
|
||||
if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
|
||||
continue;
|
||||
$value = trim(strval($v));
|
||||
$len = strlen($value);
|
||||
if ($len > 1 && substr($value, 0,1)=="\"" && substr($value,$len, $len-1)=="\"")
|
||||
$value = substr($value,1, $len-1);
|
||||
$value = trim($value);
|
||||
if ($value == "" || $value == "null")
|
||||
continue;
|
||||
array_push($rList, $value);
|
||||
}
|
||||
array_push($rList, $this->salt);
|
||||
sort($rList, 2);
|
||||
return md5(implode('&', $rList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 写日志
|
||||
* @param string $path 日志路径
|
||||
* @param string $content 内容
|
||||
*/
|
||||
private function log($path, $content){
|
||||
$file=fopen($path, "a");
|
||||
fwrite($file, date('Y-m-d H:i:s').'-----'.$content."\n");
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 网络请求
|
||||
* @param stirng $method 请求模式
|
||||
* @param stirng $url请求网关
|
||||
* @param array $params 请求参数
|
||||
* @param stirng $header 自定义头
|
||||
* @param boolean $multi 文件上传
|
||||
* @return array
|
||||
*/
|
||||
private function http( $method = 'GET', $url,$params,$header = array(), $multi = false){
|
||||
|
||||
$opts = array(
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_RETURNTRANSFER => 1,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
CURLOPT_HTTPHEADER => $header
|
||||
);
|
||||
/* 根据请求类型设置特定参数 */
|
||||
switch(strtoupper($method)){
|
||||
case 'GET':
|
||||
$opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
|
||||
break;
|
||||
case 'POST':
|
||||
//判断是否传输文件
|
||||
$params = $multi ? $params : http_build_query($params);
|
||||
$opts[CURLOPT_URL] = $url;
|
||||
$opts[CURLOPT_POST] = 1;
|
||||
$opts[CURLOPT_POSTFIELDS] = $params;
|
||||
break;
|
||||
default:
|
||||
throw new Exception('不支持的请求方式!');
|
||||
}
|
||||
|
||||
/* 初始化并执行curl请求 */
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, $opts);
|
||||
$data = curl_exec($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
if($error) throw new Exception('请求发生错误:' . $error);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
593
application/common/logic/QrCodeLogic.php
Normal file
593
application/common/logic/QrCodeLogic.php
Normal file
@@ -0,0 +1,593 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\common\logic;
|
||||
use app\common\server\ConfigServer;
|
||||
use app\common\server\storage\Driver as StorageDriver;
|
||||
use app\common\server\UrlServer;
|
||||
use app\common\server\WeChatServer;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use think\facade\Cache;
|
||||
use think\Exception;
|
||||
use EasyWeChat\Factory;
|
||||
|
||||
class QrCodeLogic extends LogicBase{
|
||||
//商品图片配置
|
||||
public function goodsShareConfig(){
|
||||
return [
|
||||
//会员头像
|
||||
'head_pic' => [
|
||||
'w' => 64, 'h' => 64, 'x' => 40, 'y' => 20,
|
||||
],
|
||||
//会员昵称
|
||||
'nickname' => [
|
||||
'color' => '#555555', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 19, 'x' => 120, 'y' => 60,
|
||||
],
|
||||
//标题
|
||||
'title' => [
|
||||
'color' => '#333333', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Bold.otf', 'font_size' => 20, 'w' => 360, 'x' => 40, 'y' => 785,
|
||||
],
|
||||
//价格符号
|
||||
'price_symbol' => [
|
||||
'color' => '#FF2C3C', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 22, 'w' => 140, 'x' => 40, 'y' => 722,
|
||||
],
|
||||
//商品价格
|
||||
'price' => [
|
||||
'color' => '#FF2C3C', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Bold.otf', 'font_size' => 32, 'w' => 140, 'x' => 64, 'y' => 722,
|
||||
],
|
||||
//小数
|
||||
'decimal'=> [
|
||||
'color' => '#FF2C3C', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Bold.otf', 'font_size' => 22, 'w' => 140, 'x' => 114, 'y' => 722,
|
||||
],
|
||||
//市场价
|
||||
'market_price_symbol' => [
|
||||
'color' => '#999999', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 22, 'w' => 140, 'x' => 142, 'y' => 722,
|
||||
],
|
||||
//市场价符号
|
||||
'market_price' => [
|
||||
'color' => '#999999', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'w' => 140, 'x' => 168, 'y' => 722,
|
||||
],
|
||||
//推广主图商品主图
|
||||
'main_pic' => [
|
||||
'w' => 560, 'h' => 560, 'x' => 40, 'y' => 100,
|
||||
],
|
||||
//提醒长按扫码
|
||||
'notice' => [
|
||||
'color' => '#888888', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 18, 'x' => 432, 'y' => 895,
|
||||
],
|
||||
//二维码
|
||||
'qr' => [
|
||||
'w' => 165,'h' => 165, 'x' => 436, 'y' => 700,
|
||||
],
|
||||
];
|
||||
}
|
||||
//生成商品分享图
|
||||
public function makeGoodsPoster($user,$goods,$url,$url_type){
|
||||
|
||||
try {
|
||||
$save_dir = ROOT_PATH .'/uploads/qr_code/goods_share/';
|
||||
$background_img = ROOT_PATH .'/images/share/share_goods_bg.png';
|
||||
!file_exists($save_dir) && mkdir($save_dir, 0777, true);
|
||||
|
||||
$cache_key = 'gid' . $goods['id'].'uid'.$user['id'].$url_type;
|
||||
$qr_src = md5($cache_key) . '.png';
|
||||
$poster_url = $save_dir . $qr_src;
|
||||
|
||||
$base64 = Cache::get($cache_key);
|
||||
if (!empty($base64)) {
|
||||
return self::dataSuccess('海报生成成功',$base64);
|
||||
}
|
||||
|
||||
|
||||
$poster_config = self::goodsShareConfig();
|
||||
//生成二维码
|
||||
if($url_type == 'path'){
|
||||
$scene = 'id='.$goods['id'].'&invite_code='.$user['distribution_code'];
|
||||
$result = $this->makeMnpQrcode($scene,$url,$qr_src,$save_dir);
|
||||
if(true !== $result){
|
||||
return self::dataError('微信配置错误:'.$result);
|
||||
}
|
||||
}else{
|
||||
$qrCode = new QrCode();
|
||||
$qrCode->setText($url);
|
||||
$qrCode->setSize(1000);
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->writeFile($poster_url);
|
||||
|
||||
}
|
||||
$user_avatar = UrlServer::getFileUrl($user['avatar'],'share');
|
||||
//判断头像是否存在
|
||||
if(!check_file_exists($user_avatar)){
|
||||
//如果不存在,使用默认头像
|
||||
$user_avatar = ROOT_PATH.ConfigServer::get('website', 'user_image');
|
||||
}
|
||||
|
||||
//默认商品主图
|
||||
$goods_image = UrlServer::getFileUrl($goods['image'],'share');
|
||||
|
||||
//判断是否有自定义分享海报图
|
||||
if($goods['poster']){
|
||||
$goods_image = UrlServer::getFileUrl($goods['poster'],'share');
|
||||
}
|
||||
if(!check_file_exists($goods_image)){
|
||||
//如果不存在,使用默认商品主图
|
||||
$goods_image = ROOT_PATH.ConfigServer::get('website', 'goods_image');
|
||||
}
|
||||
|
||||
$qr_code_logic = new QrCodeLogic();
|
||||
//获取背景图
|
||||
$share_background_img = imagecreatefromstring(file_get_contents($background_img));
|
||||
|
||||
//合成头像
|
||||
$qr_code_logic->writeImg($share_background_img, $user_avatar, $poster_config['head_pic'],true);
|
||||
|
||||
//合并商品主图
|
||||
$qr_code_logic->writeImg($share_background_img, $goods_image, $poster_config['main_pic'],false);
|
||||
|
||||
//合成昵称
|
||||
$nickname = filterEmoji($user['nickname']);
|
||||
$nickname = '来自'.$nickname.'的分享';
|
||||
$qr_code_logic->writeText($share_background_img, $nickname, $poster_config['nickname']);
|
||||
|
||||
//长按识别
|
||||
$notice = '长按识别二维码';
|
||||
$qr_code_logic->writeText($share_background_img, $notice, $poster_config['notice']);
|
||||
|
||||
//合成价格
|
||||
$qr_code_logic->writeText($share_background_img, '¥', $poster_config['price_symbol']);
|
||||
$qr_code_logic->writeText($share_background_img, floatval($goods['min_price']), $poster_config['price']);
|
||||
|
||||
//合成商品标题
|
||||
$goods_name = auto_adapt($poster_config['title']['font_size'], 0, $poster_config['title']['font_face'], $goods['name'], $poster_config['title']['w'],$poster_config['title']['y'],getimagesize($background_img));
|
||||
$qr_code_logic->writeText($share_background_img, $goods_name, $poster_config['title']);
|
||||
|
||||
//合成二维码
|
||||
$qr_code_logic->writeImg($share_background_img, $poster_url, $poster_config['qr'],false);
|
||||
|
||||
imagepng($share_background_img, $poster_url);
|
||||
if ($fp = fopen($poster_url, "rb", 0)) {
|
||||
$gambar = fread($fp, filesize($poster_url));
|
||||
fclose($fp);
|
||||
$base64 = chunk_split(base64_encode($gambar));
|
||||
$base64 = 'data:image/png;base64,' . $base64;
|
||||
}
|
||||
//删除文件
|
||||
if (strstr($poster_url, $save_dir)) {
|
||||
unlink($poster_url);
|
||||
}
|
||||
Cache::set($cache_key, $base64, 3600);
|
||||
|
||||
return self::dataSuccess('海报生成成功',$base64);
|
||||
|
||||
}catch (Exception $e){
|
||||
return self::dataError('海报生成错误:' . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//用户图片配置
|
||||
public function userShareConfig()
|
||||
{
|
||||
return [
|
||||
//会员头像
|
||||
'head_pic' => [
|
||||
'w' => 80, 'h' => 80, 'x' => 30, 'y' => 680,
|
||||
],
|
||||
//会员昵称
|
||||
'nickname' => [
|
||||
'color' => '#333333', 'font_face' => ROOT_PATH.'/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'x' => 120, 'y' => 730,
|
||||
],
|
||||
//标题
|
||||
'title' => [
|
||||
'color' => '#333333', 'font_face' => ROOT_PATH.'/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'w' => 360, 'x' => 30, 'y' => 810,
|
||||
],
|
||||
//提醒长按扫码
|
||||
'notice' => [
|
||||
'color' => '#333333', 'font_face' => ROOT_PATH.'/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'x' => 30, 'y' => 880,
|
||||
],
|
||||
//邀请码文本
|
||||
'code_text' => [
|
||||
'color' => '#FF2C3C', 'font_face' => ROOT_PATH.'/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'x' => 355, 'y' => 930,
|
||||
],
|
||||
//二维码
|
||||
'qr' => [
|
||||
'w' => 170,'h' => 170, 'x' => 370, 'y' => 730,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
//生成用户小程序二维码
|
||||
public function makeUserMnpQrcode($code,$content,$img_src)
|
||||
{
|
||||
try {
|
||||
$config = WeChatServer::getMnpConfig();
|
||||
$app = Factory::miniProgram($config);
|
||||
$response = $app->app_code->get($content.'?invite_code='.$code, [
|
||||
'width' => 170,
|
||||
]);
|
||||
|
||||
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
|
||||
$response->saveAs('uploads/qr_code/user_share/', $img_src);
|
||||
return true;
|
||||
}
|
||||
if(isset($response['errcode']) && 41030 === $response['errcode']){
|
||||
return '商城小程序码,先提交审核并通过';
|
||||
}
|
||||
return $response['errmsg'];
|
||||
|
||||
} catch (\EasyWeChat\Kernel\Exceptions\Exception $e){
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//获取分享海报背景
|
||||
public function getSharePosterBg()
|
||||
{
|
||||
$share_bg = ConfigServer::get('distribution', 'share_poster');
|
||||
// 获取存储引擎
|
||||
$config = [
|
||||
'default' => ConfigServer::get('storage', 'default', 'local'),
|
||||
'engine' => ConfigServer::get('storage_engine')
|
||||
];
|
||||
|
||||
if ($config['default'] == 'local') {
|
||||
return ROOT_PATH .'/'.$share_bg;
|
||||
} else {
|
||||
$share_bg = UrlServer::getFileUrl($share_bg,'share');
|
||||
if (!check_file_exists($share_bg)) {
|
||||
return ROOT_PATH .'/images/share/share_user_bg.png';
|
||||
}
|
||||
return $share_bg;
|
||||
}
|
||||
}
|
||||
|
||||
//删除旧的文件
|
||||
public function delOldPoster($poster_url, $save_dir, $qr_src)
|
||||
{
|
||||
// 获取存储引擎
|
||||
$config = [
|
||||
'default' => ConfigServer::get('storage', 'default', 'local'),
|
||||
'engine' => ConfigServer::get('storage_engine')
|
||||
];
|
||||
|
||||
if ($config['default'] == 'local') {
|
||||
//删除文件
|
||||
if (file_exists($poster_url) && strstr($poster_url, $save_dir)) {
|
||||
unlink($poster_url);
|
||||
}
|
||||
} else {
|
||||
try{
|
||||
$StorageDriver = new StorageDriver($config);
|
||||
$file_name = $save_dir . $qr_src;
|
||||
$StorageDriver->delete($file_name);
|
||||
} catch(Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//生成用户分享图
|
||||
public function makeUserPoster($user, $content, $url_type, $client)
|
||||
{
|
||||
try {
|
||||
$save_dir = 'uploads/qr_code/user_share/';
|
||||
$background_img = $this->getSharePosterBg();
|
||||
!file_exists($save_dir) && mkdir($save_dir, 0777, true);
|
||||
|
||||
$save_key = 'uid'.$user['id'].$url_type.$client;
|
||||
$qr_src = md5($save_key) . '.png';
|
||||
$poster_url = ROOT_PATH.'/'.$save_dir . $qr_src;
|
||||
|
||||
//删除旧的图片
|
||||
$this->delOldPoster($poster_url, $save_dir, $qr_src);
|
||||
|
||||
$poster_config = $this->userShareConfig();
|
||||
//生成二维码
|
||||
if($url_type == 'path'){
|
||||
$result = $this->makeUserMnpQrcode($user['distribution_code'], $content, $qr_src);
|
||||
if(true !== $result){
|
||||
return ['status' => 0, 'msg' => '微信配置错误:'.$result, 'data' => ''];
|
||||
}
|
||||
}else{
|
||||
$qrCode = new QrCode();
|
||||
$qrCode->setText($content);
|
||||
$qrCode->setSize(1000);
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->writeFile($poster_url);
|
||||
}
|
||||
$user_avatar = UrlServer::getFileUrl($user['avatar'],'share');
|
||||
//判断头像是否存在
|
||||
if(!check_file_exists($user_avatar)){
|
||||
//如果不存在,使用默认头像
|
||||
$user_avatar = ROOT_PATH.ConfigServer::get('website', 'user_image');
|
||||
}
|
||||
|
||||
$qr_code_logic = new QrCodeLogic();
|
||||
|
||||
//获取背景图
|
||||
$share_background_img = imagecreatefromstring(file_get_contents($background_img));
|
||||
//合成头像
|
||||
$qr_code_logic->writeImg($share_background_img, $user_avatar, $poster_config['head_pic'],true);
|
||||
|
||||
//合成昵称
|
||||
$nickname = filterEmoji($user['nickname']);
|
||||
$qr_code_logic->writeText($share_background_img, $nickname, $poster_config['nickname']);
|
||||
//长按识别
|
||||
$notice = '长按识别二维码 >>';
|
||||
$qr_code_logic->writeText($share_background_img, $notice, $poster_config['notice']);
|
||||
//合成商品标题
|
||||
$title = auto_adapt($poster_config['title']['font_size'], 0, $poster_config['title']['font_face'], '邀请你一起来赚大钱', $poster_config['title']['w'],$poster_config['title']['y'],getimagesize($background_img));
|
||||
$qr_code_logic->writeText($share_background_img, $title, $poster_config['title']);
|
||||
//邀请码
|
||||
$qr_code_logic->writeText($share_background_img, '邀请码 '.$user['distribution_code'], $poster_config['code_text']);
|
||||
//合成二维码
|
||||
$qr_code_logic->writeImg($share_background_img, $poster_url, $poster_config['qr'],false);
|
||||
|
||||
imagepng($share_background_img, $poster_url);
|
||||
|
||||
$file_name = $save_dir . $qr_src;
|
||||
$local_uir = ROOT_PATH.'/'.$file_name;
|
||||
self::upload($local_uir, $file_name);
|
||||
|
||||
return ['status' => 1, 'msg' => '', 'data' => $file_name.'?v='.time()];
|
||||
}catch (Exception $e){
|
||||
return ['status' => 0, 'msg' => $e->getMessage(), 'data' => ''];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 生成的图片根据不同的存储方式储存
|
||||
* @param $local_uri 本地图片路径
|
||||
* @param $img_uri 图片地址名称
|
||||
* @author 段誉(2021/3/2 18:47)
|
||||
* @throws Exception
|
||||
*/
|
||||
public function upload($local_uri, $file_name)
|
||||
{
|
||||
$config = [
|
||||
'default' => ConfigServer::get('storage', 'default', 'local'),
|
||||
'engine' => ConfigServer::get('storage_engine')
|
||||
];
|
||||
|
||||
if (empty($config['engine']['local'])) {
|
||||
$config['engine']['local'] = [];
|
||||
}
|
||||
|
||||
if ($config['default'] != 'local') {
|
||||
$StorageDriver = new StorageDriver($config);
|
||||
if (!$StorageDriver->fetch($local_uri, $file_name)) {
|
||||
throw new Exception('图片保存出错:' . $StorageDriver->getError());
|
||||
}
|
||||
//删除本地图片
|
||||
@unlink($file_name);
|
||||
}
|
||||
}
|
||||
//砍价图片配置
|
||||
public function bargainShareConfig(){
|
||||
return [
|
||||
//会员头像
|
||||
'head_pic' => [
|
||||
'w' => 64, 'h' => 64, 'x' => 40, 'y' => 20,
|
||||
],
|
||||
//会员昵称
|
||||
'nickname' => [
|
||||
'color' => '#555555', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 19, 'x' => 120, 'y' => 60,
|
||||
],
|
||||
|
||||
'bargain_title' => [
|
||||
'color' => '#FF2C3C', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Bold.otf', 'font_size' => 24, 'w' => 360, 'x' => 40, 'y' => 735,
|
||||
],
|
||||
'brief_title' => [
|
||||
'color' => '#F95F2F', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 16, 'w' => 360, 'x' => 40, 'y' => 765,
|
||||
],
|
||||
//标题
|
||||
'title' => [
|
||||
'color' => '#333333', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'w' => 360, 'x' => 40, 'y' => 795,
|
||||
],
|
||||
//推广主图商品主图
|
||||
'main_pic' => [
|
||||
'w' => 560, 'h' => 560, 'x' => 40, 'y' => 100,
|
||||
],
|
||||
//提醒长按扫码
|
||||
'notice' => [
|
||||
'color' => '#888888', 'font_face' => ROOT_PATH .'/font/SourceHanSansCN-Regular.otf', 'font_size' => 18, 'x' => 432, 'y' => 895,
|
||||
],
|
||||
//二维码
|
||||
'qr' => [
|
||||
'w' => 165,'h' => 165, 'x' => 436, 'y' => 700,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function makeBargainPoster($user,$bargain_launch,$url,$url_type){
|
||||
|
||||
try {
|
||||
$save_dir = ROOT_PATH .'/uploads/qr_code/bargain_share/';
|
||||
$background_img = ROOT_PATH .'/images/share/share_goods_bg.png';
|
||||
!file_exists($save_dir) && mkdir($save_dir,0777,true);
|
||||
|
||||
$cache_key = 'bid' . $bargain_launch['id'].'uid'.$user['id'].$url_type;
|
||||
$qr_src = md5($cache_key) . '.png';
|
||||
$poster_url = $save_dir . $qr_src;
|
||||
|
||||
$base64 = Cache::get($cache_key);
|
||||
if (!empty($base64)) {
|
||||
return self::dataSuccess('海报生成成功',$base64);
|
||||
}
|
||||
|
||||
|
||||
$poster_config = self::bargainShareConfig();
|
||||
//生成二维码
|
||||
if($url_type == 'path'){
|
||||
$scene = 'id='.$bargain_launch['id'];
|
||||
$result = $this->makeMnpQrcode($scene,$url,$qr_src,$save_dir);
|
||||
if(true !== $result){
|
||||
return self::dataError('微信配置错误:'.$result);
|
||||
}
|
||||
}else{
|
||||
$qrCode = new QrCode();
|
||||
$qrCode->setText($url);
|
||||
$qrCode->setSize(1000);
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->writeFile($poster_url);
|
||||
|
||||
}
|
||||
$user_avatar = UrlServer::getFileUrl($user['avatar'],'share');
|
||||
//判断头像是否存在
|
||||
if(!check_file_exists($user_avatar)){
|
||||
//如果不存在,使用默认头像
|
||||
$user_avatar = ROOT_PATH.ConfigServer::get('website', 'user_image');
|
||||
}
|
||||
//判断商品主图是否存在
|
||||
$goods_image = UrlServer::getFileUrl($bargain_launch['goods_snap']['goods_iamge'],'share');
|
||||
if(!check_file_exists($goods_image)){
|
||||
//如果不存在,使用默认商品主图
|
||||
$goods_image = ROOT_PATH.ConfigServer::get('website', 'goods_image');
|
||||
}
|
||||
|
||||
$qr_code_logic = new QrCodeLogic();
|
||||
//获取背景图
|
||||
$share_background_img = imagecreatefromstring(file_get_contents($background_img));
|
||||
|
||||
//合成头像
|
||||
$qr_code_logic->writeImg($share_background_img, $user_avatar, $poster_config['head_pic'],true);
|
||||
|
||||
//合并商品主图
|
||||
$qr_code_logic->writeImg($share_background_img, $goods_image, $poster_config['main_pic'],false);
|
||||
|
||||
//合成昵称
|
||||
$nickname = filterEmoji($user['nickname']);
|
||||
$nickname = '来自'.$nickname.'的分享';
|
||||
$qr_code_logic->writeText($share_background_img, $nickname, $poster_config['nickname']);
|
||||
|
||||
//长按识别
|
||||
$notice = '长按识别二维码';
|
||||
$qr_code_logic->writeText($share_background_img, $notice, $poster_config['notice']);
|
||||
|
||||
//合成砍价标题
|
||||
$bargain_title = '我正在参与砍价 还差一步';
|
||||
$qr_code_logic->writeText($share_background_img, $bargain_title, $poster_config['bargain_title']);
|
||||
|
||||
//合成简介
|
||||
$brief_title = '帮忙砍一刀';
|
||||
$qr_code_logic->writeText($share_background_img, $brief_title, $poster_config['brief_title']);
|
||||
|
||||
//合成商品标题
|
||||
$goods_name = auto_adapt($poster_config['title']['font_size'], 0, $poster_config['title']['font_face'], $bargain_launch['goods_snap']['name'], $poster_config['title']['w'],$poster_config['title']['y'],getimagesize($background_img));
|
||||
$qr_code_logic->writeText($share_background_img, $goods_name, $poster_config['title']);
|
||||
|
||||
//合成二维码
|
||||
$qr_code_logic->writeImg($share_background_img, $poster_url, $poster_config['qr'],false);
|
||||
|
||||
imagepng($share_background_img, $poster_url);
|
||||
if ($fp = fopen($poster_url, "rb", 0)) {
|
||||
$gambar = fread($fp, filesize($poster_url));
|
||||
fclose($fp);
|
||||
$base64 = chunk_split(base64_encode($gambar));
|
||||
$base64 = 'data:image/png;base64,' . $base64;
|
||||
}
|
||||
//删除文件
|
||||
if (strstr($poster_url, $save_dir)) {
|
||||
unlink($poster_url);
|
||||
}
|
||||
|
||||
$expire = $bargain_launch['launch_end_time'] - time();
|
||||
|
||||
Cache::set($cache_key, $base64, $expire);
|
||||
|
||||
return self::dataSuccess('海报生成成功',$base64);
|
||||
|
||||
}catch (Exception $e){
|
||||
return self::dataError('海报生成错误:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//小程序生成二维码(非永久码)
|
||||
public function makeMnpQrcode($scene,$url,$img_src,$save_dir){
|
||||
try {
|
||||
$config = WeChatServer::getMnpConfig();
|
||||
$app = Factory::miniProgram($config);
|
||||
|
||||
$response = $app->app_code->getUnlimit($scene, [
|
||||
'page' => $url,
|
||||
]);
|
||||
|
||||
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
|
||||
$response->saveAs($save_dir, $img_src);
|
||||
return true;
|
||||
}
|
||||
if(isset($response['errcode']) && 41030 === $response['errcode']){
|
||||
return '商城小程序未上线或商城小程序页面发布';
|
||||
}
|
||||
return $response['errmsg'];
|
||||
|
||||
|
||||
} catch (\EasyWeChat\Kernel\Exceptions\Exception $e){
|
||||
|
||||
return $e->getMessage();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//写入图片
|
||||
public function writeImg($poster, $img_uri, $config, $is_rounded = false){
|
||||
$pic_img = imagecreatefromstring(file_get_contents($img_uri));
|
||||
$is_rounded?$pic_img = rounded_corner($pic_img):'';//切成圆角返回头像资源
|
||||
$pic_w = imagesx($pic_img);
|
||||
$pic_h = imagesy($pic_img);
|
||||
|
||||
//圆形头像大图合并到海报
|
||||
imagecopyresampled($poster, $pic_img,
|
||||
$config['x'],
|
||||
$config['y'],
|
||||
0, 0,
|
||||
$config['w'],
|
||||
$config['h'],
|
||||
$pic_w,
|
||||
$pic_h
|
||||
);
|
||||
|
||||
return $poster;
|
||||
}
|
||||
//写入文字
|
||||
public function writeText($poster, $text, $config){
|
||||
|
||||
$font_uri = $config['font_face'];
|
||||
$font_size = $config['font_size'];
|
||||
$color = substr($config['color'],1);
|
||||
//颜色转换
|
||||
$color= str_split($color, 2);
|
||||
$color = array_map('hexdec', $color);
|
||||
if (empty($color[3]) || $color[3] > 127) {
|
||||
$color[3] = 0;
|
||||
}
|
||||
//写入文字
|
||||
$font_col = imagecolorallocatealpha($poster, $color[0], $color[1], $color[2], $color[3]);
|
||||
imagettftext($poster, $font_size,0, $config['x'], $config['y'], $font_col, $font_uri, $text);
|
||||
return $poster;
|
||||
|
||||
}
|
||||
}
|
||||
75
application/common/logic/SmsLogic.php
Normal file
75
application/common/logic/SmsLogic.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\model\NoticeSetting;
|
||||
use app\common\model\SmsLog;
|
||||
|
||||
class SmsLogic
|
||||
{
|
||||
protected $message_key = '';
|
||||
protected $mobile = '';
|
||||
protected $code = '';
|
||||
protected $sms = '';
|
||||
protected $indate = 300;//todo 验证码有效期
|
||||
|
||||
public function __construct($key, $mobile, $code)
|
||||
{
|
||||
$this->message_key = NoticeSetting::SMS_SCENE[$key];
|
||||
$this->mobile = $mobile;
|
||||
$this->code = $code;
|
||||
$sms_Log = new SmsLog();
|
||||
$sms = $sms_Log
|
||||
->where(['message_key' => $this->message_key, 'mobile' => $this->mobile, 'is_verify' => 0])
|
||||
->order('id desc')
|
||||
->field('id,code,send_time')
|
||||
->find();
|
||||
|
||||
$this->sms = $sms;
|
||||
}
|
||||
|
||||
//检查验证码
|
||||
public function checkCode()
|
||||
{
|
||||
if (!isset($this->sms) || $this->sms->code !== $this->code) {
|
||||
return '验证码错误';
|
||||
}
|
||||
$send_time = $this->sms->getData('send_time');
|
||||
|
||||
$now = time();
|
||||
if ($this->sms->code === $this->code && $send_time + $this->indate < $now) {
|
||||
return '验证码已过期';
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//标记已验证
|
||||
public function cancelCode()
|
||||
{
|
||||
if (empty($this->sms)) {
|
||||
return false;
|
||||
}
|
||||
unset($this->sms->send_time);
|
||||
$this->sms->is_verify = 1;
|
||||
$this->sms->update_time = time();
|
||||
return $this->sms->save();
|
||||
}
|
||||
}
|
||||
64
application/common/logic/UserLevelLogic.php
Normal file
64
application/common/logic/UserLevelLogic.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\common\logic;
|
||||
use think\Db;
|
||||
|
||||
class UserLevelLogic{
|
||||
/**
|
||||
* note 更新个人会员等级
|
||||
* create_time 2020/11/26 18:52
|
||||
*/
|
||||
public static function updateUserLevel($id){
|
||||
|
||||
$user = Db::name('user')->where(['id'=>$id])->field('user_growth,level')->find();
|
||||
$level = Db::name('user_level')
|
||||
->where([['growth_value','<=',$user['user_growth']],['del','=',0]])
|
||||
->order('growth_value desc')
|
||||
->find();
|
||||
|
||||
if($level){
|
||||
$growth_value = 0;
|
||||
$user['level'] > 0 && $growth_value = Db::name('user_level')->where(['id'=>$user['level']])->value('growth_value');
|
||||
if($level['growth_value'] > $growth_value){
|
||||
Db::name('user')->where(['id'=>$id])->update(['level'=>$level['id'],'update_time'=>time()]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
/**
|
||||
* note 更新所有用户的等级
|
||||
* create_time 2020/11/26 19:11
|
||||
*/
|
||||
public static function updateAllUserLevel($level_id){
|
||||
$growth_value = Db::name('user_level')->where(['id'=>$level_id])->value('growth_value');
|
||||
$no_update_user_ids = Db::name('user')->alias('U')
|
||||
->join('user_level L','U.level = L.id')
|
||||
->where('L.growth_value','>',$growth_value)
|
||||
->column('U.id');
|
||||
|
||||
return Db::name('user')
|
||||
->where([
|
||||
['id','not in',$no_update_user_ids],
|
||||
['del','=',0],
|
||||
['user_growth','>=',$growth_value],
|
||||
])->update(['level'=>$level_id,'update_time'=>time()]);
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user