添加网站文件

This commit is contained in:
2025-12-22 13:59:40 +08:00
commit 117aaf83d1
19468 changed files with 2111999 additions and 0 deletions

View 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;
}
}

View 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();
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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) {}
}
}

View 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();
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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();
}
}

View 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()]);
}
}