初始版本

This commit is contained in:
贾祥聪
2025-08-19 14:16:51 +08:00
commit f937a1f9b9
4373 changed files with 359728 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
<?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\enum\accountLog\AccountLogEnum;
use app\common\model\accountLog\AccountLog;
use app\common\model\user\User;
class AccountLogLogic extends BaseLogic
{
/**
* @notes 添加账户流水记录
* @param $userId //会员ID
* @param $changeObject //变动对象
* @param $changeType //变动类型
* @param $action //变动动作
* @param $changeAmount //变动数量
* @param string $associationSn //关联单号
* @param string $remark //备注
* @param array $feature //预留字段,方便存更多其它信息
* @return bool
* @author ljj
* @date 2022/10/28 5:15 下午
*/
public static function add($userId, $changeObject, $changeType, $action, $changeAmount, $associationSn = '', $remark = '', $feature = [])
{
$user = User::findOrEmpty($userId);
if($user->isEmpty()) {
return false;
}
$left_amount = 0;
switch ($changeObject) {
case AccountLogEnum::MONEY:
$left_amount = $user->user_money;
break;
}
$accountLog = new AccountLog();
$data = [
'sn' => generate_sn($accountLog, 'sn', 20),
'user_id' => $userId,
'change_object' => $changeObject,
'change_type' => $changeType,
'action' => $action,
'left_amount' => $left_amount,
'change_amount' => $changeAmount,
'association_sn' => $associationSn,
'remark' => $remark,
'feature' => $feature ? json_encode($feature, JSON_UNESCAPED_UNICODE) : '',
];
return $accountLog->save($data);
}
}

View File

@@ -0,0 +1,119 @@
<?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 BaseLogic
* @package app\common\logic
*/
class BaseLogic
{
/**
* 错误信息
* @var string
*/
protected static $error;
/**
* 返回状态码
* @var int
*/
protected static $returnCode = 0;
protected static $returnData;
/**
* @notes 获取错误信息
* @return string
* @author 段誉
* @date 2021/7/21 18:23
*/
public static function getError() : string
{
if (false === self::hasError()) {
return '系统错误';
}
return self::$error;
}
/**
* @notes 设置错误信息
* @param $error
* @author 段誉
* @date 2021/7/21 18:20
*/
public static function setError($error) : void
{
!empty($error) && self::$error = $error;
}
/**
* @notes 是否存在错误
* @return bool
* @author 段誉
* @date 2021/7/21 18:32
*/
public static function hasError() : bool
{
return !empty(self::$error);
}
/**
* @notes 设置状态码
* @param $code
* @author 段誉
* @date 2021/7/28 17:05
*/
public static function setReturnCode($code) : void
{
self::$returnCode = $code;
}
/**
* @notes 特殊场景返回指定状态码,默认为0
* @return int
* @author 段誉
* @date 2021/7/28 15:14
*/
public static function getReturnCode() : int
{
return self::$returnCode;
}
/**
* @notes 获取内容
* @return mixed
* @author cjhao
* @date 2021/9/11 17:29
*/
public static function getReturnData()
{
return self::$returnData;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace app\common\logic;
use app\common\model\city\City;
/**
* 城市逻辑类
* Class CityLogic
* @package app\common\logic
*/
class CityLogic extends BaseLogic
{
/**
* @notes 获取经纬度附近的城市
* @param $longitude
* @param $latitude
* @return array
* @author cjhao
* @date 2024/9/3 23:41
*/
public static function getNearbyCity($longitude,$latitude)
{
//用st_distance_sphere函数计算两点记录单位米这里换成千米
$field = 'id,city_id,name,0 as distance,gcj02_lng as longitude,gcj02_lat as latitude';
if($longitude && $latitude){
//用st_distance_sphere函数计算两点记录单位米这里换成千米
$field = 'id,city_id,name,round(st_distance_sphere(point('.$longitude.','.$latitude.'),
point(gcj02_lng, gcj02_lat))/1000,2) as distance,'.$longitude.' as longitude,'.$latitude.' as latitude';
}
$cityLists = City::field($field)
->append(['distance_desc'])
->order('distance asc')
->hidden(['distance'])
->select()
->toArray();
return $cityLists;
}
}

View File

@@ -0,0 +1,77 @@
<?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\enum\accountLog\AccountLogEnum;
use app\common\enum\accountLog\CoachAccountLogEnum;
use app\common\model\accountLog\AccountLog;
use app\common\model\accountLog\CoachAccountLog;
use app\common\model\coach\Coach;
use app\common\model\user\User;
class CoachAccountLogLogic extends BaseLogic
{
/**
* @notes 添加账户流水记录
* @param $userId //会员ID
* @param $changeObject //变动对象
* @param $changeType //变动类型
* @param $action //变动动作
* @param $changeAmount //变动数量
* @param string $associationSn //关联单号
* @param string $remark //备注
* @param array $feature //预留字段,方便存更多其它信息
* @return bool
* @author ljj
* @date 2022/10/28 5:15 下午
*/
public static function add($coachId, $changeObject, $changeType, $action, $changeAmount, $associationSn = '', $adminId = '',$remark = '', $feature = [])
{
// 取用户信息
$coach = (new Coach())->findOrEmpty($coachId);
if ($coach->isEmpty()) {
return false;
}
// 取变动对象
// $changeObject = CoachAccountLogEnum::getChangeTypeDesc($changeType);
// if (!$changeObject) {
// return false;
// }
$leftAmount = $coach->money;
if(in_array($changeType,CoachAccountLogEnum::DEPOSIT_DESC)){
$leftAmount = $coach->deposit;
}
$data = [
'sn' => generate_sn((new CoachAccountLog()), 'sn', 20),
'coach_id' => $coachId,
'change_object' => $changeObject,
'change_type' => $changeType,
'action' => $action,
'left_amount' => $leftAmount,
'change_amount' => $changeAmount,
'association_sn'=> $associationSn,
'remark' => $remark,
'feature' => $feature ? json_encode($feature, JSON_UNESCAPED_UNICODE) : '',
'admin_id' => $adminId
];
CoachAccountLog::create($data);
return true;
}
}

View File

@@ -0,0 +1,341 @@
<?php
namespace app\common\logic;
use app\common\enum\coach\CoachEnum;
use app\common\enum\OrderEnum;
use app\common\model\coach\Coach;
use app\common\model\coach\CoachServerTime;
use app\common\model\deposit\DepositPackage;
use app\common\model\goods\Goods;
use app\common\model\goods\GoodsComment;
use app\common\model\order\Order;
use app\common\model\shop\Shop;
use app\common\service\ConfigService;
use DateTime;
use think\Exception;
/**
* 技师逻辑类
* Class CoachLogic
* @package app\common\logic
*/
class CoachLogic
{
/**
* @notes 获取技师订单时间
* @param int $coachId
* @return array
* @throws \Exception
* @author cjhao
* @date 2024/9/8 17:36
*/
public static function getCoachOrderAppoint(int $coachId)
{
$appointOrderList = Order::where(['coach_id'=>$coachId])
->where('order_status','not in',[OrderEnum::ORDER_STATUS_SERVER_FINISH,OrderEnum::ORDER_STATUS_CLOSE])
->column('id,appoint_time,total_duration,server_finish_time');
$appointLists = [];
foreach ($appointOrderList as $appointOrder)
{
$appointTime = $appointOrder['appoint_time'];
$totalDuration = $appointOrder['total_duration'];
$dateTime = new DateTime(date('Y-m-d H:i:s',$appointTime));
if(30 < $dateTime->format('i') && 0 != $dateTime->format('i')){
$dateTime->modify('+30 minutes');
}
if($dateTime->format('i') > 30 ){
$surplusMinute = 60 - $dateTime->format('i');
$dateTime->modify('+'.$surplusMinute.' minutes');
}
$dateHi = $dateTime->format('H:i');
$dateMd = $dateTime->format('m-d');
$appointLists[$dateMd][] = $dateHi;
$nums = intval($totalDuration / 30);
for ($i = 0;$nums > $i;$i++){
$dateHi = $dateTime->format('H:i');
//特殊时段,跨天
if( "23:00" == $dateHi){
$dateTime->modify('+1 day');
}
$dateTime->modify('+30 minutes');
$dateMd = $dateTime->format('m-d');
$dateHi = $dateTime->format('H:i');
$appointLists[$dateMd][] = $dateHi;
}
}
return $appointLists;
}
/**
* @notes 获取技师的服务时间
* @param $coachId
* @param $coachId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author cjhao
* @date 2024/9/9 14:38
*/
public static function getCoachServerTime($coachId,$goodsId = 0)
{
$advanceAppoint = ConfigService::get('server_setting', 'advance_appoint');
$timestampLists[date('m-d',time())] = time()+60*60;
for ($i = 1;$i < $advanceAppoint;$i++){
$timestampLists[date('m-d',strtotime('+ '.$i.' days'))] = strtotime('+ '.$i.' days midnight');
}
$intervalsLists = [];
foreach ($timestampLists as $date => $timestamp){
$intervalsLists[$date] = get_hour_to_midnight($timestamp);
}
//订单预约时间
$orderAppointLists = CoachLogic::getCoachOrderAppoint($coachId);
//师傅空闲时间
$serverTimeLists = [];
//师傅忙碌时间
$serverTimeBusyLists = [];
$coachServerTime = CoachServerTime::where(['coach_id'=>$coachId])
->field('date,time,status')
->select();
foreach ($coachServerTime as $time)
{
if(1 == $time['status']){
$serverTimeLists[$time['date']][] = $time['time'];
}else{
$serverTimeBusyLists[$time['date']][] = $time['time'];
}
}
$nowMd = date('m-d');
//往后一个小时可预约
$nowHi = date('H:i',strtotime('+1 hour'));
$goods = [];
if($goodsId){
$goods = Goods::where(['id'=>$goodsId])->field('appoint_start_time,appoint_end_time')->findOrEmpty()->toArray();
$appointMd = date('m-d',convert_to_time($goods['appoint_end_time']));
$goods['appoint_start_time'] = date('H:i',convert_to_time($goods['appoint_start_time']));
$goods['appoint_end_time'] = date('H:i',convert_to_time($goods['appoint_end_time']));
if( '00:00' == $goods['appoint_end_time'] && $nowMd != $appointMd){
$goods['appoint_end_time'] = "24:00";
}
}
foreach ($intervalsLists as $date => $intervals){
foreach ($intervals as $key => $interval){
$orderAppoint = $orderAppointLists[$date] ?? [];
$serverTime = $serverTimeLists[$date] ?? [];
$serverTimeBusy = $serverTimeBusyLists[$date]?? [];
// $intervalsLists[$date][$key]['status'] = 0;
//(不在服务时间)
//空闲时间
if(in_array($interval['time'],$serverTime) || empty($serverTime)){
$intervals[$key]['status'] = 1;
}
//忙
if(in_array($interval['time'],$serverTimeBusy)){
$intervals[$key]['status'] = 2;
}
//已预约
if(in_array($interval['time'],$orderAppoint)){
$intervals[$key]['status'] = 3;
}
if($goods){
if($goods['appoint_start_time'] > $interval['time'] || $goods['appoint_end_time'] < $interval['time']){
// $intervalsLists[$date][$key]['status'] = 4;
unset($intervals[$key]);
}
}
//不可预约4超过当前时间或者不在服务时间
// if($date == $nowMd){
// if($nowHi > $interval['time']){
// $intervalsLists[$date][$key]['status'] = 4;
// }
// }
}
// if(empty($intervals)){
// unset($intervalsLists[$date]);
// }else{
$intervalsLists[$date] = array_values($intervals);
// }
}
return $intervalsLists;
}
/**
* @notes 获取空闲技师
* @param $coachId :技师
* @param $startTime :空闲开始时间段
* @param $endTime :空闲结束时间段
* @return array
* @author cjhao
* @date 2024/10/9 16:37
*/
public static function getLeisureCoach(int $coachId = 0,int $startTime = 0,int $endTime = 0,$order = [],$keyword = '')
{
$where = [];
$where[] = ['audit_status','=',CoachEnum::AUDIT_STATUS_PASS];
$where[] = ['work_status','=',CoachEnum::WORK_STATUS_ONLINE];
$where[] = ['server_status','=',CoachEnum::WORK_STATUS_NORMAL];
if($coachId){
$where[] = ['id','<>',$coachId];
}
if($keyword){
$where[] = ['name','like','%'.$keyword.'%'];
}
$longitude = $order['address_snap']['longitude'];
$latitude = $order['address_snap']['latitude'];
$coachLists = Coach::where($where)
->field('id,order_num,work_photo,good_comment,location,name,longitude,latitude,longitude_location,latitude_location')
->select()->toArray();
$coachServerScope = ConfigService::get('server_setting', 'coach_server_scope');
$startTimeDay = date('m-d',$startTime);
$endTimeDay = date('m-d',$endTime);
$startTimeHour = date('H:i',$startTime);
$endTimeHour = date('H:i',$endTime);
$leisureLists = [];
foreach ($coachLists as $key => $coach){
$filed = 'round(st_distance_sphere(point('.$longitude.','.$latitude.'),
point(longitude_location, latitude_location))/1000,2) as distance';
if(empty($coach['longitude_location'])){
$filed = 'round(st_distance_sphere(point('.$longitude.','.$latitude.'),
point(longitude, latitude))/1000,2) as distance';
}
$distance = Coach::where(['id'=>$coach['id']])
->value($filed);
if(empty($distance)){
continue;
}
if($distance > $coachServerScope){
continue;
}
$coachServerLists = self::getCoachServerTime($coach['id']);
$startTimeLists = $coachServerLists[$startTimeDay] ?? [];
$endTimeLists = $coachServerLists[$endTimeDay] ?? [];
$startTimeLists = array_column($startTimeLists,null,'time');
$endTimeLists = array_column($endTimeLists,null,'time');
$startTimeData = $startTimeLists[$startTimeHour] ?? [];
$endTimeData = $endTimeLists[$endTimeHour] ?? [];
if(empty($startTimeData)){
continue;
}
if(1 != $startTimeData['status'] && 1 != $endTimeData['status']){
continue;
}
$coach['wait_serve_num'] = Order::where(['coach_id'=>$coach['id']])
->where('order_status','>',OrderEnum::ORDER_STATUS_WAIT_RECEIVING)
->where('order_status','<',OrderEnum::ORDER_STATUS_SERVER_FINISH)
->count();
$leisureLists[] = $coach;
}
return $leisureLists;
}
/**
* @notes
* @param int $coachId
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author cjhao
* @date 2024/11/22 17:43
*/
public static function getLatelyLeisureTime(int $coachId)
{
$serverTime = self::getCoachServerTime($coachId);
$today = date('m-d');
if(isset($serverTime[$today])){
return $serverTime[$today][0]['time'] ?? '';
}
$tomorrow = date('m-d',strtotime("+1 day"));
if(isset($serverTime[$tomorrow])){
return '明天:'.$serverTime[$tomorrow][0]['time'] ?? '';
}
$dayafter = date('m-d',strtotime("+2 day"));
if(isset($serverTime[$dayafter])){
return '后天:'.$serverTime[$dayafter][0]['time'] ?? '';
}
$dayKey = array_key_first($serverTime);
$time = $serverTime[$dayKey][0]['time'];
return $dayKey.' '.$time;
}
/**
* @notes 验证技师的接单数量
* @param $coach
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author cjhao
* @date 2024/11/26 23:44
*/
public static function ckechCoachTakeOrderNum($coach){
$deposit = $coach['deposit'];
$depositPackageLists = [];
$takeOrderNum = ConfigService::get('server_setting', 'shop_order_limit');
if($coach['shop_id']){
$deposit = Shop::where(['id'=>$coach['shop_id']])->value('deposit');
$where[] = ['type','=',2];
$orderNum = Order::where(['shop_id'=>$coach['shop_id'],'coach_id'=>$coach['id']])
->where('order_status','in',[OrderEnum::ORDER_STATUS_WAIT_DEPART,OrderEnum::ORDER_STATUS_DEPART,OrderEnum::ORDER_STATUS_ARRIVE,OrderEnum::ORDER_STATUS_START_SERVER,OrderEnum::ORDER_STATUS_SERVER_FINISH])
->whereDay('create_time')->count();
}else{
$where[] = ['type','=',1];
$orderNum = Order::where(['coach_id'=>$coach['id']])
->where('order_status','in',[OrderEnum::ORDER_STATUS_WAIT_DEPART,OrderEnum::ORDER_STATUS_DEPART,OrderEnum::ORDER_STATUS_ARRIVE,OrderEnum::ORDER_STATUS_START_SERVER,OrderEnum::ORDER_STATUS_SERVER_FINISH])
->whereDay('create_time')->count();
}
$depositPackageLists = DepositPackage::where($where)->order('money desc')->select()->toArray();
//套餐列表
$depositPackageTakeOrderNum = 0;
foreach ($depositPackageLists as $depositPackage){
if($deposit >= $depositPackage['money']){
$depositPackageTakeOrderNum = $depositPackage['order_limit'];
break;
}
}
$takeOrderNum += $depositPackageTakeOrderNum;
if($orderNum >= $takeOrderNum){
throw new Exception('今日接单数量已达上限');
}
}
/**
* @notes 更新技师评论分数
* @param $coachId
* @return true
* @author cjhao
* @date 2024/12/6 12:30
*/
public static function updateCoachComment($coachId)
{
//技师的好评
$allComment = GoodsComment::where(['coach_id'=>$coachId])->count();
$goodsComment = GoodsComment::where(['coach_id'=>$coachId])
->where('service_comment','>=',3)
->count();
$coachGoodsComment = 0;
if($goodsComment){
$coachGoodsComment = round($goodsComment/$allComment,2) * 100;
}
//更新技师的好评率
Coach::update(['good_comment'=>$coachGoodsComment],['id'=>$coachId]);
return true;
}
}

View File

@@ -0,0 +1,77 @@
<?php
// +----------------------------------------------------------------------
// | LikeShop100%开源免费商用电商系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | 商业版本务必购买商业授权,以免引起法律纠纷
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | Gitee下载https://gitee.com/likeshop_gitee/likeshop
// | 访问官网https://www.likemarket.net
// | 访问社区https://home.likemarket.net
// | 访问手册http://doc.likemarket.net
// | 微信公众号:好象科技
// | 好象科技开发团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\accountLog\CoachAccountLogEnum;
use app\common\enum\PayEnum;
use app\common\model\coach\Coach;
use app\common\model\deposit\DepositOrder;
use app\common\model\shop\Shop;
use think\facade\Db;
use think\facade\Log;
/**
* 支付成功后处理订单状态
* Class PayNotifyLogic
* @package app\api\logic
*/
class CoachPayNotifyLogic extends BaseLogic
{
public static function handle($action, $orderSn, $extra = [])
{
Db::startTrans();
try {
self::$action($orderSn, $extra);
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
Log::write(implode('-', [
__CLASS__,
__FUNCTION__,
$e->getFile(),
$e->getLine(),
$e->getMessage()
]));
self::setError($e->getMessage());
return $e->getMessage();
}
}
private static function deposit($orderSn, $extra = []){
$order = DepositOrder::where('sn', $orderSn)->findOrEmpty()->toArray();
// 增加用户累计充值金额及用户余额
Coach::update([
'deposit' => ['inc',$order['order_amount']],
],['id'=>$order['relation_id']]);
// 记录账户流水
CoachAccountLogLogic::add($order['relation_id'], CoachAccountLogEnum::DEPOSIT,CoachAccountLogEnum::RECHARGE_INC_DEPOSIT,CoachAccountLogEnum::INC, $order['order_amount'], $order['sn']);
// 更新充值订单状态
DepositOrder::update([
'transaction_id' => $extra['transaction_id'] ?? '',
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
],['id'=>$order['id']]);
}
}

View File

@@ -0,0 +1,215 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\notice\NoticeEnum;
use app\common\enum\YesNoEnum;
use app\common\model\coach\Coach;
use app\common\model\notice\NoticeRecord;
use app\common\model\notice\NoticeSetting;
use app\common\model\order\Order;
use app\common\model\user\User;
use app\common\service\sms\SmsMessageService;
use app\common\service\WechatMessageService;
/**
* 通知逻辑层
* Class NoticeLogic
* @package app\common\logic
*/
class NoticeLogic extends BaseLogic
{
/**
* @notes 根据场景发送短信
* @param $params
* @return bool
* @author 段誉
* @date 2022/9/15 15:28
*/
public static function noticeByScene($params)
{
try {
$noticeSetting = NoticeSetting::where('scene_id', $params['scene_id'])->findOrEmpty()->toArray();
if (empty($noticeSetting)) {
throw new \Exception('找不到对应场景的配置');
}
// 合并额外参数
$params = self::mergeParams($params);
$res = false;
self::setError('发送通知失败');
// 短信通知
if (isset($noticeSetting['sms_notice']['status']) && $noticeSetting['sms_notice']['status'] == YesNoEnum::YES) {
$res = (new SmsMessageService())->send($params);
}
// 公众号消息
if (isset($noticeSetting['oa_notice']['status']) && $noticeSetting['oa_notice']['status'] == YesNoEnum::YES) {
$res = (new WechatMessageService($params['params']['user_id'], NoticeEnum::OA))->send($params);
}
// 微信小程序
if (isset($noticeSetting['mnp_notice']['status']) && $noticeSetting['mnp_notice']['status'] == YesNoEnum::YES) {
$res = (new WechatMessageService($params['params']['user_id'], NoticeEnum::MNP))->send($params);
}
return $res;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 整理参数
* @param $params
* @return array
* @author 段誉
* @date 2022/9/15 15:28
*/
public static function mergeParams($params)
{
// 订单相关
if(!empty($params['params']['order_id'])) {
$order = Order::where(['id'=>$params['params']['order_id']])->append(['appoint_time','appoint_date'])->findOrEmpty()->toArray();
$params['params']['order_sn'] = $order['sn'];
$params['params']['create_time'] = $order['create_time'];
$params['params']['pay_time'] = $order['pay_time'];
$params['params']['order_amount'] = $order['order_amount'];
$params['params']['mobile'] = $params['params']['mobile'] ?? $order['address_snap']['mobile'];
$params['params']['appoint_time'] = $order['appoint_date'].' '.$order['appoint_time'];
}
// 用户相关
if (!empty($params['params']['user_id'])) {
$user = User::findOrEmpty($params['params']['user_id'])->toArray();
$params['params']['nickname'] = $user['nickname'];
$params['params']['user_name'] = $user['nickname'];
$params['params']['user_sn'] = $user['sn'];
$params['params']['mobile'] = $params['params']['mobile'] ?? $user['mobile'];
}
// 师傅相关
if (!empty($params['params']['coach_id'])) {
$coach = Coach::findOrEmpty($params['params']['coach_id'])->toArray();
$params['params']['staff_name'] = $coach['name'];
// 入驻申请通知平台
if ($params['scene_id'] != NoticeEnum::STAFF_APPLY_NOTICE_PLATFORM) {
$params['params']['mobile'] = $coach['mobile'];
}
}
// 跳转路径
$jumpPath = self::getPathByScene($params['scene_id'], $params['params']['order_id'] ?? 0);
$params['url'] = $jumpPath['url'];
$params['page'] = $jumpPath['page'];
return $params;
}
/**
* @notes 根据场景获取跳转链接
* @param $sceneId
* @param $extraId
* @return string[]
* @author 段誉
* @date 2022/9/15 15:29
*/
public static function getPathByScene($sceneId, $extraId)
{
// 小程序主页路径
$page = '/pages/index/index';
// 公众号主页路径
$url = '/mobile/pages/index/index';
return [
'url' => $url,
'page' => $page,
];
}
/**
* @notes 替换消息内容中的变量占位符
* @param $content
* @param $params
* @return array|mixed|string|string[]
* @author 段誉
* @date 2022/9/15 15:29
*/
public static function contentFormat($content, $params)
{
foreach ($params['params'] as $k => $v) {
$search = '{' . $k . '}';
$content = str_replace($search, $v, $content);
}
return $content;
}
/**
* @notes 添加通知记录
* @param $params
* @param $noticeSetting
* @param $sendType
* @param $content
* @param string $extra
* @return NoticeRecord|\think\Model
* @author 段誉
* @date 2022/9/15 15:29
*/
public static function addNotice($params, $noticeSetting, $sendType, $content, $extra = '')
{
return NoticeRecord::create([
'user_id' => $params['params']['user_id'] ?? 0,
'title' => self::getTitleByScene($sendType, $noticeSetting),
'content' => $content,
'scene_id' => $noticeSetting['scene_id'],
'read' => YesNoEnum::NO,
'recipient' => $noticeSetting['recipient'],
'send_type' => $sendType,
'notice_type' => $noticeSetting['type'],
'extra' => $extra,
]);
}
/**
* @notes 通知记录标题
* @param $sendType
* @param $noticeSetting
* @return string
* @author 段誉
* @date 2022/9/15 15:30
*/
public static function getTitleByScene($sendType, $noticeSetting)
{
switch ($sendType) {
case NoticeEnum::SMS:
$title = '';
break;
case NoticeEnum::OA:
$title = $noticeSetting['oa_notice']['name'] ?? '';
break;
case NoticeEnum::MNP:
$title = $noticeSetting['mnp_notice']['name'] ?? '';
break;
default:
$title = '';
}
return $title;
}
}

View File

@@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 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系列产品在gitee、github等公开渠道开源版本可免费商用未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权购买去版权授权后方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\OrderLogEnum;
use app\common\model\order\OrderLog;
class OrderLogLogic extends BaseLogic
{
/**
* @notes 订单日志
* @param int $type 类型:1-系统;2-后台;3-用户;
* @param int $channel 渠道编号。变动方式
* @param int $order_id 订单id
* @param int $operator_id 操作人id
* @param string $content 日志内容
* @author ljj
* @date 2022/2/11 3:37 下午
*/
public function record(int $type,int $channel,int $order_id,int $operator_id = 0,string $content = '',$location = [],$extra = [])
{
OrderLog::create([
'type' => $type,
'channel' => $channel,
'order_id' => $order_id,
'operator_id' => $operator_id,
'content' => $content ?: OrderLogEnum::getRecordDesc($channel),
'longitude' => $location['longitude'] ?? '',
'latitude' => $location['latitude'] ?? '',
'location' => $location,
'extra' => $extra,
'create_time' => time(),
'update_time' => time(),
]);
}
}

View File

@@ -0,0 +1,255 @@
<?php
// +----------------------------------------------------------------------
// | LikeShop100%开源免费商用电商系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | 商业版本务必购买商业授权,以免引起法律纠纷
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | Gitee下载https://gitee.com/likeshop_gitee/likeshop
// | 访问官网https://www.likemarket.net
// | 访问社区https://home.likemarket.net
// | 访问手册http://doc.likemarket.net
// | 微信公众号:好象科技
// | 好象科技开发团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\accountLog\AccountLogEnum;
use app\common\enum\accountLog\CoachAccountLogEnum;
use app\common\enum\accountLog\ShopAccountLogEnum;
use app\common\enum\notice\NoticeEnum;
use app\common\enum\OrderEnum;
use app\common\enum\OrderLogEnum;
use app\common\enum\PayEnum;
use app\common\model\accountLog\CoachAccountLog;
use app\common\model\accountLog\ShopAccountLog;
use app\common\model\coach\Coach;
use app\common\model\deposit\DepositOrder;
use app\common\model\goods\Goods;
use app\common\model\order\Order;
use app\common\model\order\OrderAppend;
use app\common\model\order\OrderGap;
use app\common\model\RechargeOrder;
use app\common\model\shop\Shop;
use app\common\model\user\User;
use app\common\service\ConfigService;
use think\facade\Db;
use think\facade\Log;
/**
* 支付成功后处理订单状态
* Class PayNotifyLogic
* @package app\api\logic
*/
class PayNotifyLogic extends BaseLogic
{
public static function handle($action, $orderSn, $extra = [])
{
Db::startTrans();
try {
self::$action($orderSn, $extra);
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
Log::write(implode('-', [
__CLASS__,
__FUNCTION__,
$e->getFile(),
$e->getLine(),
$e->getMessage()
]));
self::setError($e->getMessage());
return $e->getMessage();
}
}
/**
* @notes 调用回调方法统一处理 更新订单支付状态
* @param $orderSn
* @param array $extra
* @author ljj
* @date 2022/3/1 11:35 上午
*/
public static function order($orderSn, $extra = [])
{
$order = Order::with(['order_goods'])->where(['sn' => $orderSn])->findOrEmpty();
//更新订单状态
Order::update([
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
'order_status' => OrderEnum::ORDER_STATUS_WAIT_RECEIVING,
'transaction_id' => $extra['transaction_id'] ?? ''
], ['id' => $order['id']]);
//添加订单日志
(new OrderLogLogic())->record(OrderLogEnum::TYPE_USER,OrderLogEnum::USER_PAY_ORDER,$order['id'],$order['user_id']);
//通知师傅接单
event('Notice', [
'scene_id' => NoticeEnum::ACCEPT_ORDER_NOTICE_STAFF,
'params' => [
'coach_id' => $order['coach_id'],
'order_id' => $order['id']
]
]);
// 订单付款通知 - 通知买家
event('Notice', [
'scene_id' => NoticeEnum::ORDER_PAY_NOTICE,
'params' => [
'user_id' => $order['user_id'],
'order_id' => $order['id']
]
]);
//通知平台
$mobile = ConfigService::get('platform', 'mobile','');
if($mobile){
event('Notice', [
'scene_id' => NoticeEnum::ORDER_PAY_NOTICE_PLATFORM,
'params' => [
'mobile' => $mobile,
'order_id' => $order['id']
]
]);
}
foreach ($order['order_goods'] as $order_goods){
Goods::update(['order_num'=>['inc',$order_goods['goods_num']]],['id'=>$order_goods['goods_id']]);
}
// 订单付款通知 - 通知卖家
// $mobile = ConfigService::get('website', 'mobile');
// if (!empty($mobile)) {
// event('Notice', [
// 'scene_id' => NoticeEnum::ORDER_PAY_NOTICE_PLATFORM,
// 'params' => [
// 'mobile' => $mobile,
// 'order_id' => $order['id']
// ]
// ]);
// }
}
/**
* @notes 订单差价
* @param $orderSn
* @param $extra
* @return void
* @author cjhao
* @date 2024/9/19 01:54
*/
private static function orderGap($orderSn, $extra = []){
$orderGap = OrderGap::where(['sn' => $orderSn])->findOrEmpty();
//更新订单状态
OrderGap::update([
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
'transaction_id' => $extra['transaction_id'] ?? ''
], ['id' => $orderGap['id']]);
Order::where(['id'=>$orderGap['order_id']])->update([
// 'total_amount' => Db::raw('total_amount+'.$orderGap['order_amount']),
'total_order_amount' => Db::raw('total_order_amount+'.$orderGap['order_amount']),
'total_gap_amount' => Db::raw('total_gap_amount+'.$orderGap['order_amount'])
]);
//添加订单日志
(new OrderLogLogic())->record(OrderLogEnum::TYPE_USER,OrderLogEnum::USER_PAY_ORDER_GAP,$orderGap['order_id'],$orderGap['user_id']);
}
/**
* @notes 订单差价
* @param $orderSn
* @param $extra
* @return void
* @author cjhao
* @date 2024/9/19 01:54
*/
private static function orderAppend($orderSn, $extra = []){
$orderAppend = OrderAppend::where(['sn' => $orderSn])->findOrEmpty();
//更新订单状态
OrderAppend::update([
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
'transaction_id' => $extra['transaction_id'] ?? ''
], ['id' => $orderAppend['id']]);
Order::where(['id'=>$orderAppend['order_id']])->update([
// 'total_amount' => Db::raw('total_amount+'.$orderAppend['order_amount']),
'total_order_amount' => Db::raw('total_order_amount+'.$orderAppend['order_amount']),
'total_append_amount' => Db::raw('total_append_amount+'.$orderAppend['order_amount'])
]);
//添加订单日志
(new OrderLogLogic())->record(OrderLogEnum::TYPE_USER,OrderLogEnum::USER_PAY_ORDER_APPEND,$orderAppend['order_id'],$orderAppend['user_id']);
}
/**
* @notes 充值回调
* @param $orderSn
* @param array $extra
* @author ljj
* @date 2022/12/26 5:00 下午
*/
public static function recharge($orderSn, $extra = [])
{
$order = RechargeOrder::where('sn', $orderSn)->findOrEmpty()->toArray();
// 增加用户累计充值金额及用户余额
User::update([
'user_money' => ['inc',$order['order_amount']],
'total_recharge_amount' => ['inc',$order['order_amount']],
],['id'=>$order['user_id']]);
// 记录账户流水
AccountLogLogic::add($order['user_id'], AccountLogEnum::MONEY,AccountLogEnum::USER_RECHARGE_ADD_MONEY,AccountLogEnum::INC, $order['order_amount'], $order['sn']);
// 更新充值订单状态
RechargeOrder::update([
'transaction_id' => $extra['transaction_id'],
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
],['id'=>$order['id']]);
}
/**
* @notes
* @param $orderSn
* @param $extra
* @return void
* @author cjhao
* @date 2024/11/29 00:27
*/
private static function deposit($orderSn, $extra = []){
$order = DepositOrder::where('sn', $orderSn)->findOrEmpty()->toArray();
if(1 == $order['type']){
Coach::update([
'deposit' => ['inc',$order['order_amount']],
],['id'=>$order['relation_id']]);
// 记录账户流水
CoachAccountLog::add($order['relation_id'], CoachAccountLogEnum::DEPOSIT,CoachAccountLogEnum::RECHARGE_INC_DEPOSIT,CoachAccountLogEnum::INC, $order['order_amount'], $order['sn']);
}else{
Shop::update([
'deposit' => ['inc',$order['order_amount']],
],['id'=>$order['relation_id']]);
// 记录账户流水
ShopAccountLog::add($order['relation_id'], ShopAccountLogEnum::DEPOSIT,ShopAccountLogEnum::RECHARGE_INC_DEPOSIT,ShopAccountLogEnum::INC, $order['order_amount'], $order['sn']);
}
// 增加用户累计充值金额及用户余额
// 更新充值订单状态
DepositOrder::update([
'transaction_id' => $extra['transaction_id'] ?? '',
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
],['id'=>$order['id']]);
}
}

View File

@@ -0,0 +1,235 @@
<?php
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 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系列产品在gitee、github等公开渠道开源版本可免费商用未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权购买去版权授权后方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\accountLog\AccountLogEnum;
use app\common\enum\OrderEnum;
use app\common\enum\OrderRefundEnum;
use app\common\enum\PayEnum;
use app\common\model\accountLog\AccountLog;
use app\common\model\order\Order;
use app\common\model\order\OrderRefund;
use app\common\model\order\OrderRefundLog;
use app\common\model\user\User;
use app\common\service\AliPayService;
use app\common\service\WeChatConfigService;
use app\common\service\WeChatPayService;
class RefundLogic extends BaseLogic
{
protected $refund;
protected $refund_log;
/**
* @notes 退款
* @param $order
* @param $refund_amount
* @param $type
* @param $operator_id
* @return bool
* @throws \Exception
* @author ljj
* @date 2022/2/15 5:05 下午
*/
public function refund($order, $refund_amount,$refund_car,$type,$orderType,$operator_id)
{
if ($refund_amount+$refund_car <= 0) {
return false;
}
//生成退款记录
$this->log($order,$refund_amount,$refund_car,$type,$orderType,$operator_id);
$totalRefundAmount = round($refund_amount + $refund_car,2);
//原路退款
switch ($order['pay_way']) {
//微信退款
case PayEnum::WECHAT_PAY:
$this->wechatRefund($order,$totalRefundAmount);
break;
//支付宝退款
case PayEnum::ALI_PAY:
$this->alipayRefund($order,$totalRefundAmount);
break;
case PayEnum::BALANCE_PAY:
$this->balanceRefund($order,$totalRefundAmount,$orderType);
break;
}
return true;
}
/**
* @notes 退款记录
* @param $order
* @param $refund_amount
* @param $type
* @param $operator_id
* @author ljj
* @date 2022/2/15 3:49 下午
*/
public function log($order,$refund_amount,$refund_car,$type,$orderType,$operator_id)
{
if(1 == $orderType){
$orderId = $order['id'];
$subOrderId = 0;
}else{
$orderId = $order['order_id'];
$subOrderId = $order['id'] ;
}
$refund = OrderRefund::create([
'sn' => generate_sn(new OrderRefund(), 'sn'),
'order_id' => $orderId,
'sub_order_id' => $subOrderId,
'user_id' => $order['user_id'],
'order_amount' => $order['order_amount'],
'refund_amount' => $refund_amount,
'refund_car_amount' => $refund_car,
'order_terminal' => $order['order_terminal'],
'transaction_id' => $order['transaction_id'],
'type' => $type,
'order_type'=> $orderType
]);
//退款日志
$refund_log = OrderRefundLog::create([
'sn' => generate_sn(new OrderRefundLog(), 'sn'),
'refund_id' => $refund->id,
'type' => $type,
'operator_id' => $operator_id,
]);
$this->refund = $refund;
$this->refund_log = $refund_log;
}
/**
* @notes 微信退款
* @param $order
* @param $refund_amount
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @author ljj
* @date 2022/2/15 5:06 下午
*/
public function wechatRefund($order,$refund_amount)
{
//微信配置信息
$wechatConfig = WeChatConfigService::getWechatConfigByTerminal($order['order_terminal']);
if (!file_exists($wechatConfig['cert_path']) || !file_exists($wechatConfig['key_path'])) {
throw new \Exception('微信证书不存在,请联系管理员!');
}
//发起退款
$result = (new WeChatPayService($order['order_terminal']))->refund([
'transaction_id' => $order['transaction_id'],
'refund_sn' => $this->refund_log->sn,
'total_fee' => $order['order_amount'] * 100,//订单金额,单位为分
'refund_fee' => intval($refund_amount * 100),//退款金额
]);
if ($result['return_code'] == 'FAIL' || $result['result_code'] == 'FAIL') {
if ($result['err_code'] == 'SYSTEMERROR' || $result['err_code'] == 'BIZERR_NEED_RETRY') {
return true;
}
//更新退款日志记录
OrderRefundLog::update([
'wechat_refund_id' => $result['refund_id'] ?? 0,
'refund_status' => OrderRefundEnum::STATUS_FAIL,
'refund_msg' => json_encode($result, JSON_UNESCAPED_UNICODE),
], ['id'=>$this->refund_log->id]);
//更新订单退款状态
OrderRefund::update([
'refund_status' => OrderRefundEnum::STATUS_FAIL,
], ['id'=>$this->refund->id]);
}
return true;
}
/**
* @notes 支付宝退款
* @param $order
* @param $refund_amount
* @return bool
* @throws \Exception
* @author ljj
* @date 2024/3/21 4:55 下午
*/
public function alipayRefund($order,$refund_amount)
{
//原路退回到支付宝的情况
$result = (new AliPayService())->refund($order['sn'], $refund_amount, $this->refund_log->sn);
$result = (array)$result;
//更新退款日志记录
OrderRefundLog::update([
'refund_status' => ($result['code'] == '10000' && $result['msg'] == 'Success' && $result['fundChange'] == 'Y') ? 1 : 2,
'refund_msg' => json_encode($result, JSON_UNESCAPED_UNICODE),
], ['id'=>$this->refund_log->id]);
//更新订单退款状态
OrderRefund::update([
'refund_status' => ($result['code'] == '10000' && $result['msg'] == 'Success' && $result['fundChange'] == 'Y') ? 1 : 2,
], ['id'=>$this->refund->id]);
return true;
}
public function balanceRefund($order,$refund_amount,$orderType)
{
$user = User::where(['id'=>$order['user_id']])->findOrEmpty();
$user->user_money = round($user->user_money + $refund_amount,2);
$user->save();
$mainOrder = $order;
if(1 != $orderType){
$mainOrder = Order::where(['id'=>$order['order_id']])->findOrEmpty();
}
$changeType = AccountLogEnum::CANCEL_ORDER_ADD_MONEY;
if(OrderEnum::ORDER_STATUS_SERVER_FINISH == $mainOrder['order_status'] && OrderEnum::ORDER_STATUS_SERVER_FINISH == $mainOrder['order_status']){
$changeType = AccountLogEnum::REFUND_ORDER_ADD_MONEY;
}
//
AccountLogLogic::add(
$user->id,
AccountLogEnum::MONEY,
$changeType,
AccountLogEnum::INC,
$refund_amount,
$order['sn']);
//更新退款日志记录
OrderRefundLog::update([
'refund_status' => 1 ,
'refund_msg' => '',
], ['id'=>$this->refund_log->id]);
//更新订单退款状态
OrderRefund::update([
'refund_status' => 1,
], ['id'=>$this->refund->id]);
return true;
}
}

View File

@@ -0,0 +1,197 @@
<?php
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 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系列产品在gitee、github等公开渠道开源版本可免费商用未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权购买去版权授权后方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\model\city\City;
use app\common\model\Region;
class RegionLogic extends BaseLogic
{
/**
* @notes 地区
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author ljj
* @date 2022/4/6 10:51 上午
*/
public function region($params)
{
$where = [];
if(isset($params['keyword']) && $params['keyword']){
$where[] = ['name','like','%'.$params['keyword'].'%'];
}
$lists = Region::where($where)->field('id,parent_id,level,name,short,city_code,zip_code,gcj02_lng,gcj02_lat,db09_lng,db09_lat,remark1,remark2')->select()->toArray();
$lists = linear_to_tree($lists,'sub','id','parent_id');
return $lists;
}
/**
* @notes 地级市列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author ljj
* @date 2022/4/6 2:41 下午
*/
public function city($params)
{
$where = [];
$where[] = ['level','=',2];
if(isset($params['keyword']) && $params['keyword']){
$where[] = ['name','like','%'.$params['keyword'].'%'];
}
$lists = City::where($where)
->field('id,parent_id,level,name,gcj02_lng,gcj02_lat,db09_lng,db09_lat,city_id')
->select()
->toArray();
$lists = self::groupByInitials($lists);
unset($lists[null]);
return $lists;
}
/**
* 二维数组根据首字母分组排序
* @param array $data 二维数组
* @param string $targetKey 首字母的键名
* @return array 根据首字母关联的二维数组
*/
public function groupByInitials(array $data, $targetKey = 'name')
{
$data = array_map(function ($item) use ($targetKey) {
return array_merge($item, [
'initials' => $this->getInitials($item[$targetKey]),
]);
}, $data);
$data = $this->sortInitials($data);
return $data;
}
/**
* 按字母排序
* @param array $data
* @return array
*/
public function sortInitials(array $data)
{
$sortData = [];
foreach ($data as $key => $value) {
$sortData[$value['initials']][] = $value;
}
ksort($sortData);
return $sortData;
}
/**
* 获取首字母
* @param string $str 汉字字符串
* @return string 首字母
*/
public function getInitials($str)
{
if (empty($str)) {return '';}
$fchar = ord($str[0]);
if ($fchar >= ord('A') && $fchar <= ord('z')) {
return strtoupper($str[0]);
}
$s1 = iconv('UTF-8', 'GBK', $str);
$s2 = iconv('GBK', 'UTF-8', $s1);
$s = $s2 == $str ? $s1 : $str;
$asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
if ($asc >= -20319 && $asc <= -20284) {
return 'A';
}
if ($asc >= -20283 && $asc <= -19776) {
return 'B';
}
if ($asc >= -19775 && $asc <= -19219) {
return 'C';
}
if ($asc >= -19218 && $asc <= -18711) {
return 'D';
}
if ($asc >= -18710 && $asc <= -18527) {
return 'E';
}
if ($asc >= -18526 && $asc <= -18240) {
return 'F';
}
if ($asc >= -18239 && $asc <= -17923) {
return 'G';
}
if ($asc >= -17922 && $asc <= -17418) {
return 'H';
}
if ($asc >= -17417 && $asc <= -16475) {
return 'J';
}
if ($asc >= -16474 && $asc <= -16213) {
return 'K';
}
if ($asc >= -16212 && $asc <= -15641) {
return 'L';
}
if ($asc >= -15640 && $asc <= -15166) {
return 'M';
}
if ($asc >= -15165 && $asc <= -14923) {
return 'N';
}
if ($asc >= -14922 && $asc <= -14915) {
return 'O';
}
if ($asc >= -14914 && $asc <= -14631) {
return 'P';
}
if ($asc >= -14630 && $asc <= -14150) {
return 'Q';
}
if ($asc >= -14149 && $asc <= -14091) {
return 'R';
}
if ($asc >= -14090 && $asc <= -13319) {
return 'S';
}
if ($asc >= -13318 && $asc <= -12839) {
return 'T';
}
if ($asc >= -12838 && $asc <= -12557) {
return 'W';
}
if ($asc >= -12556 && $asc <= -11848) {
return 'X';
}
if ($asc >= -11847 && $asc <= -11056) {
return 'Y';
}
if ($asc >= -11055 && $asc <= -10247) {
return 'Z';
}
return null;
}
}

View File

@@ -0,0 +1,69 @@
<?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\enum\accountLog\ShopAccountLogEnum;
use app\common\model\accountLog\CoachAccountLog;
use app\common\model\accountLog\ShopAccountLog;
use app\common\model\shop\Shop;
class ShopAccountLogLogic extends BaseLogic
{
/**
* @param $shopId (店铺ID
* @param $changeType (变动类型
* @param $action (操作动作: [1=新增, 2=扣减])
* @param $changeAmount (变动的值
* @param string $sourceSn (来源编号)
* @param string $remark (备注信息)
* @param array $extra (扩展信息)
* @param int $adminId (管理员ID)
* @param array $flowUsage (token信息组)
* @return CoachAccountLog|false|Model
*/
public static function add($shopId, $changeObject,$changeType, $action, $changeAmount, string $sourceSn = '', int $adminId = 0, string $remark = '', array $extra = []): bool|Model|ShopAccountLog
{
// 取用户信息
$shop = (new Shop())->findOrEmpty($shopId);
if ($shop->isEmpty()) {
return false;
}
$leftAmount = $shop->money;
if(ShopAccountLogEnum::DEPOSIT == $changeObject){
$leftAmount = $shop->deposit;
}
$data = [
'sn' => generate_sn((new ShopAccountLog()), 'sn', 20),
'shop_id' => $shopId,
'change_object' => $changeObject,
'change_type' => $changeType,
'action' => $action,
'left_amount' => $leftAmount,
'change_amount' => $changeAmount,
'association_sn'=> $sourceSn,
'remark' => $remark,
'extra' => $extra ? json_encode($extra, JSON_UNESCAPED_UNICODE) : '',
'admin_id' => $adminId
];
return ShopAccountLog::create($data);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace app\common\logic;
use app\common\model\goods\GoodsComment;
use app\common\model\shop\Shop;
class ShopLogic extends BaseLogic
{
/**
* @notes 更新商家评分
* @param int $shopId
* @return true
* @author cjhao
* @date 2024/12/6 12:32
*/
public static function updateShopComment(int $shopId)
{
$shopAllComment = GoodsComment::where(['shop_id'=>$shopId])->sum('service_comment');
$commentCount = GoodsComment::where(['shop_id'=>$shopId])->count();
$shopGoodsComment = 0;
if($commentCount){
$shopGoodsComment = round($shopAllComment/$commentCount,2);
}
Shop::update(['good_comment'=>$shopGoodsComment],['id'=>$shopId]);
return true;
}
}

View File

@@ -0,0 +1,75 @@
<?php
// +----------------------------------------------------------------------
// | LikeShop100%开源免费商用电商系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | 商业版本务必购买商业授权,以免引起法律纠纷
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | Gitee下载https://gitee.com/likeshop_gitee/likeshop
// | 访问官网https://www.likemarket.net
// | 访问社区https://home.likemarket.net
// | 访问手册http://doc.likemarket.net
// | 微信公众号:好象科技
// | 好象科技开发团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\accountLog\ShopAccountLogEnum;
use app\common\enum\PayEnum;
use app\common\model\accountLog\ShopAccountLog;
use app\common\model\deposit\DepositOrder;
use app\common\model\shop\Shop;
use think\facade\Db;
use think\facade\Log;
/**
* 支付成功后处理订单状态
* Class PayNotifyLogic
* @package app\api\logic
*/
class ShopPayNotifyLogic extends BaseLogic
{
public static function handle($action, $orderSn, $extra = [])
{
Db::startTrans();
try {
self::$action($orderSn, $extra);
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
Log::write(implode('-', [
__CLASS__,
__FUNCTION__,
$e->getFile(),
$e->getLine(),
$e->getMessage()
]));
self::setError($e->getMessage());
return $e->getMessage();
}
}
private static function deposit($orderSn, $extra = []){
$order = DepositOrder::where('sn', $orderSn)->findOrEmpty()->toArray();
// 增加用户累计充值金额及用户余额
Shop::update([
'deposit' => ['inc',$order['order_amount']],
],['id'=>$order['relation_id']]);
// 记录账户流水
ShopAccountLogLogic::add($order['relation_id'], ShopAccountLogEnum::DEPOSIT,ShopAccountLogEnum::RECHARGE_INC_DEPOSIT,ShopAccountLogEnum::INC, $order['order_amount'], $order['sn']);
// 更新充值订单状态
DepositOrder::update([
'transaction_id' => $extra['transaction_id'] ?? '',
'pay_status' => PayEnum::ISPAID,
'pay_time' => time(),
],['id'=>$order['id']]);
}
}

View File

@@ -0,0 +1,59 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台PHP版
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用可去除界面版权logo
// | gitee下载https://gitee.com/likeshop_gitee/likeadmin
// | github下载https://github.com/likeshop-github/likeadmin
// | 访问官网https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\notice\NoticeEnum;
/**
* 短信逻辑
* Class SmsLogic
* @package app\api\logic
*/
class SmsLogic extends BaseLogic
{
/**
* @notes 发送验证码
* @param $params
* @return false|mixed
* @author 段誉
* @date 2022/9/15 16:17
*/
public static function sendCode($params)
{
try {
$scene = NoticeEnum::getSceneByTag($params['scene']);
if (empty($scene)) {
throw new \Exception('场景值异常');
}
$result = event('Notice', [
'scene_id' => $scene,
'params' => [
'mobile' => $params['mobile'],
'code' => mt_rand(1000, 9999),
]
]);
return $result[0];
} catch (\Exception $e) {
self::$error = $e->getMessage();
return false;
}
}
}