Browse Source

线上订单支付、回调/线下订单支付、回调

master
weigang 5 years ago
parent
commit
6897b3ce9b
  1. 29
      app/Constants/v3/LogLabel.php
  2. 42
      app/Constants/v3/UserType.php
  3. 150
      app/Controller/TestController.php
  4. 46
      app/Controller/v3/NotifyController.php
  5. 29
      app/Model/v3/CsInfo.php
  6. 2
      app/Model/v3/Goods.php
  7. 2
      app/Model/v3/GoodsActivity.php
  8. 33
      app/Model/v3/OrderSalesStatistic.php
  9. 33
      app/Model/v3/ServiceReward.php
  10. 2
      app/Model/v3/Store.php
  11. 9
      app/Model/v3/StoreAccount.php
  12. 11
      app/Model/v3/SystemConfig.php
  13. 38
      app/Model/v3/UserBalance.php
  14. 40
      app/Model/v3/UserRelationBind.php
  15. 4
      app/Service/v3/Implementations/DeviceService.php
  16. 26
      app/Service/v3/Implementations/FeiePrintService.php
  17. 315
      app/Service/v3/Implementations/FinancialRecordService.php
  18. 36
      app/Service/v3/Implementations/MiniprogramService.php
  19. 13
      app/Service/v3/Implementations/MqttService.php
  20. 35
      app/Service/v3/Implementations/OrderOfflineService.php
  21. 60
      app/Service/v3/Implementations/OrderOnlineService.php
  22. 278
      app/Service/v3/Implementations/SeparateAccountsService.php
  23. 69
      app/Service/v3/Implementations/SmsAliService.php
  24. 4
      app/Service/v3/Implementations/UserService.php
  25. 253
      app/Service/v3/Interfaces/FinancialRecordServiceInterface.php
  26. 1
      app/Service/v3/Interfaces/OrderOfflineServiceInterface.php
  27. 28
      app/Service/v3/Interfaces/SeparateAccountsServiceInterface.php
  28. 9
      app/Service/v3/Interfaces/SmsServiceInterface.php
  29. 10
      config/autoload/dependencies.php

29
app/Constants/v3/LogLabel.php

@ -23,9 +23,29 @@ class LogLabel extends AbstractConstants
const ORDER_ONLINE_LOG = 'order_online_log';
/**
* @Message("线下订单")
* @Message("线上订单支付完成")
*/
const ORDER_OFFLINE_LOG = 'order_onffline_log';
const ORDER_ONLINE_PAID_LOG = 'order_online_paid_log';
/**
* @Message("线上订单支付通知")
*/
const ORDER_ONLINE_PAY_NOTIFY_LOG = 'order_online_pay_notify_log';
/**
* @Message("当面付订单")
*/
const ORDER_OFFLINE_LOG = 'order_offline_log';
/**
* @Message("当面付订单支付完成")
*/
const ORDER_OFFLINE_PAID_LOG = 'order_offline_paid_log';
/**
* @Message("当面付订单支付通知")
*/
const ORDER_OFFLINE_PAY_NOTIFY_LOG = 'order_offline_pay_notify_log';
/**
* @Message("订单支付")
@ -47,4 +67,9 @@ class LogLabel extends AbstractConstants
*/
const COUPON_REBATE_LOG = 'coupon_rebate_log';
/**
* @Message("分账")
*/
const SEPARATE_ACCOUNTS_LOG = 'separate_accounts_log';
}

42
app/Constants/v3/UserType.php

@ -0,0 +1,42 @@
<?php
namespace App\Constants\v3;
use Hyperf\Constants\AbstractConstants;
use Hyperf\Constants\Annotation\Constants;
/**
* @Constants
*/
class UserType extends AbstractConstants
{
/**
* @Message("平台总账")
*/
const LEDGER = -1;
/**
* @Message("用户")
*/
const USER = 1;
/**
* @Message("服务商")
*/
const MP = 2;
/**
* @Message("市场经理")
*/
const MM = 3;
/**
* @Message("代理服务点")
*/
const CS = 4;
/**
* @Message("商户")
*/
const STORE = 5;
}

150
app/Controller/TestController.php

@ -4,7 +4,19 @@ declare(strict_types=1);
namespace App\Controller;
use App\Constants\v3\LogLabel;
use App\Constants\v3\OrderState;
use App\Constants\v3\OrderType;
use App\Libs\FeiePrintClient;
use App\Model\v3\OrderMain;
use App\Service\v3\Interfaces\CouponRebateServiceInterface;
use App\Service\v3\Interfaces\DeviceServiceInterface;
use App\Service\v3\Interfaces\FeiePrintServiceInterface;
use App\Service\v3\Interfaces\MiniprogramServiceInterface;
use App\Service\v3\Interfaces\MqttServiceInterface;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use App\Service\v3\Interfaces\UserServiceInterface;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\Utils\Coroutine;
@ -13,6 +25,7 @@ use Hyperf\Task\TaskExecutor;
use Hyperf\Task\Task;
use App\TaskWorker\SSDBTask;
use App\Commons\Log;
use Hyperf\Di\Annotation\Inject;
/**
* @AutoController()
@ -25,6 +38,54 @@ class TestController extends AbstractController
protected $client = null;
/**
* @Inject
* @var MqttServiceInterface
*/
protected $mqttService;
/**
* @Inject
* @var DeviceServiceInterface
*/
protected $deviceService;
/**
* @Inject
* @var MiniprogramServiceInterface
*/
protected $miniprogramService;
/**
* @Inject
* @var FeiePrintServiceInterface
*/
protected $feiePrintService;
/**
* @Inject
* @var UserServiceInterface
*/
protected $userService;
/**
* @Inject
* @var CouponRebateServiceInterface
*/
protected $couponRebateService;
/**
* @Inject
* @var OrderOnlineServiceInterface
*/
protected $orderOnlineService;
/**
* @Inject
* @var SeparateAccountsServiceInterface
*/
protected $separateAccountsService;
public function index1(RequestInterface $request)
{
// $container = ApplicationContext::getContainer();
@ -48,24 +109,81 @@ class TestController extends AbstractController
// //$this->name = 'index1 action '. $result;
// return $this->name;
$time = time();
$msgInfo = array(
'user' => '13161443713@163.com',
'stime' => $time,
'sig' => sha1('13161443713@163.com' . 'XsaHzgePdyWTfcMX' . $time),
'apiname' => 'Open_printMsg',
'sn' => '920527381',
'content' => '1111',
'times' => 1//打印次数
// $time = time();
// $msgInfo = array(
// 'user' => '13161443713@163.com',
// 'stime' => $time,
// 'sig' => sha1('13161443713@163.com' . 'XsaHzgePdyWTfcMX' . $time),
// 'apiname' => 'Open_printMsg',
// 'sn' => '920527381',
// 'content' => '1111',
// 'times' => 1//打印次数
// );
// $this->client = new FeiePrintClient('api.feieyun.cn', 80);
// if (!$this->client->post('/Api/Open/', $msgInfo)) {
// return '12';
// } else {
// //服务器返回的JSON字符串,建议要当做日志记录起来
// $result = $this->client->getContent();
// return $result;
// }
$orderMainId = $this->request->input('order_main_id');
// 查询订单
$orderMain = OrderMain::query()
->where([
'id' => $orderMainId,
'type' => OrderType::ONLINE,
'state' => OrderState::UNPAID
])
->first();
// 订单不存在
if (empty($orderMain)) {
$this->log->event(
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
['global_order_id_fail' => $orderMainId]
);
$this->client = new FeiePrintClient('api.feieyun.cn', 80);
if (!$this->client->post('/Api/Open/', $msgInfo)) {
return '12';
} else {
//服务器返回的JSON字符串,建议要当做日志记录起来
$result = $this->client->getContent();
return $result;
return true;
}
// $orderPaid = $this->orderOfflineService->doPaid($orderMainId);
// var_dump('orderOfflineService', $orderPaid);
// $separate = $this->separateAccountsService->orderOfflinePaid($orderMainId);
// var_dump('separateAccountsService', $separate);
//
// // 喇叭通知,兼容旧音响,MQTT+IOT
// $res = $this->mqttService->speakToStore($orderMainId);
// var_dump('mqttService', $res);
// $res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMainId);
// var_dump('deviceService', $res);
//
// // 公众号模板消息
// $res = $this->miniprogramService->sendTemMsgForOfflineOrder($orderMainId);
// var_dump('miniprogramService', $res);
$res = $this->orderOnlineService->doByPaid($orderMainId);
var_dump('orderOnlineService', $res);
$res = $this->separateAccountsService->orderOnlinePaid($orderMainId);
var_dump('separateAccountsService', $res);
// 优惠券返券
$res = $this->couponRebateService->couponRebateInTask($orderMainId);
var_dump('couponRebateService', $res);
// 喇叭通知,兼容旧音响,MQTT+IOT
$res = $this->mqttService->speakToStore($orderMainId);
var_dump('mqttService', $res);
$res = $this->deviceService->pubMsgToStoreByOrderMainId($orderMainId);
var_dump('deviceService', $res);
// 公众号模板消息
$res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMainId);
var_dump('miniprogramService', $res);
// 打印订单,自动打印
$res = $this->feiePrintService->feiePrint($orderMainId);
var_dump('feiePrintService', $res);
}
public function index2(RequestInterface $request)

46
app/Controller/v3/NotifyController.php

@ -3,6 +3,7 @@
namespace App\Controller\v3;
use App\Constants\v3\LogLabel;
use App\Constants\v3\OrderState;
use App\Constants\v3\OrderType;
use App\Controller\BaseController;
use App\Model\v3\OrderMain;
@ -11,6 +12,9 @@ use App\Service\v3\Interfaces\DeviceServiceInterface;
use App\Service\v3\Interfaces\FeiePrintServiceInterface;
use App\Service\v3\Interfaces\MiniprogramServiceInterface;
use App\Service\v3\Interfaces\MqttServiceInterface;
use App\Service\v3\Interfaces\OrderOfflineServiceInterface;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use App\Service\v3\Interfaces\UserServiceInterface;
use EasyWeChat\Factory;
use Hyperf\DbConnection\Db;
@ -61,9 +65,15 @@ class NotifyController extends BaseController
/**
* @Inject
* @var OrderServiceInterface
* @var OrderOnlineServiceInterface
*/
protected $orderService;
protected $orderOnlineService;
/**
* @Inject
* @var OrderOfflineServiceInterface
*/
protected $orderOfflineService;
/**
* @Inject
@ -100,7 +110,7 @@ class NotifyController extends BaseController
|| $message['result_code'] != 'SUCCESS'
) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
$message
);
Db::rollBack();
@ -109,24 +119,21 @@ class NotifyController extends BaseController
// 查询订单
$orderMain = OrderMain::query()
->where([
'global_order_id' => $message['out_trade_no'],
'type' => OrderType::ONLINE
])
->where(['global_order_id' => $message['out_trade_no'],'type' => OrderType::ONLINE,'state' => OrderState::UNPAID])
->first();
// 订单不存在
if (empty($orderMain) || $orderMain->state == OrderMain::ORDER_STATE_DELIVERY) {
if (empty($orderMain)) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
['global_order_id_fail' => $message['out_trade_no']]
);
Db::rollBack();
return true;
}
$this->orderService->onlinePaid($message['out_trade_no']);
$this->separateAccountsService->orderOnlinePaid($message['out_trade_no']);
$this->orderOnlineService->doByPaid($orderMain->id);
$this->separateAccountsService->orderOnlinePaid($orderMain->id);
// 优惠券返券
$this->couponRebateService->couponRebateInTask($orderMain->id);
@ -139,7 +146,7 @@ class NotifyController extends BaseController
$res = $this->miniprogramService->sendTemMsgForOnlineOrder($orderMain->id);
// 打印订单,自动打印
$res = $this->feiePrintService->feiePrint($orderMain->global_order_id);
$res = $this->feiePrintService->feiePrint($orderMain->id);
Db::commit();
return true;
@ -147,7 +154,7 @@ class NotifyController extends BaseController
} catch (Exception $e) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
LogLabel::ORDER_ONLINE_PAY_NOTIFY_LOG,
['exception_fail' => $e->getMessage()]
);
Db::rollBack();
@ -192,7 +199,7 @@ class NotifyController extends BaseController
|| $message['result_code'] != 'SUCCESS'
) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
$message
);
Db::rollBack();
@ -203,22 +210,23 @@ class NotifyController extends BaseController
$orderMain = OrderMain::query()
->where([
'global_order_id' => $message['out_trade_no'],
'type' => OrderMain::ORDER_TYPE_OFFLINE
'type' => OrderType::OFFLINE,
'state' => OrderState::UNPAID
])
->first();
// 订单不存在
if (empty($orderMain)) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
['global_order_id_fail' => $message['out_trade_no']]
);
Db::rollBack();
return true;
}
$orderPaid = $this->orderService->offlinePaid($message['out_trade_no']);
$separate = $this->separateAccountsService->orderOfflinePaid($message['out_trade_no']);
$orderPaid = $this->orderOfflineService->doPaid($orderMain->id);
$separate = $this->separateAccountsService->orderOfflinePaid($orderMain->id);
// 喇叭通知,兼容旧音响,MQTT+IOT
$res = $this->mqttService->speakToStore($orderMain->id);
@ -233,7 +241,7 @@ class NotifyController extends BaseController
} catch (Exception $e) {
$this->log->event(
LogLabel::PAY_NOTIFY_WXMINI,
LogLabel::ORDER_OFFLINE_PAY_NOTIFY_LOG,
['exception_fail' => $e->getMessage()]
);
Db::rollBack();

29
app/Model/v3/CsInfo.php

@ -0,0 +1,29 @@
<?php
declare (strict_types=1);
namespace App\Model\v3;
use Hyperf\DbConnection\Model\Model;
/**
*/
class CsInfo extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_cs_info';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
}

2
app/Model/v3/Goods.php

@ -90,7 +90,7 @@ class Goods extends Model
public function getMonthSalesAttribute()
{
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
return (integer)$ssdb->exec('get', SsdbKeys::GOODS_MONTH_SALES.date('YM').'_'.$this->id);
return (integer)$ssdb->exec('get', SsdbKeys::GOODS_MONTH_SALES.date('Ym').'_'.$this->id);
}
public function getCartNumAttribute()

2
app/Model/v3/GoodsActivity.php

@ -55,7 +55,7 @@ class GoodsActivity extends Model
public function getMonthSalesAttribute()
{
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
return (integer)$ssdb->exec('get', SsdbKeys::GOODS_MONTH_SALES.date('YM').'_'.$this->id);
return (integer)$ssdb->exec('get', SsdbKeys::GOODS_MONTH_SALES.date('Ym').'_'.$this->id);
}
public function getCartNumAttribute()

33
app/Model/v3/OrderSalesStatistic.php

@ -0,0 +1,33 @@
<?php
declare (strict_types=1);
namespace App\Model\v3;
use App\Model\Model;
/**
*/
class OrderSalesStatistic extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_order_sales_statistics';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
public $timestamps = false;
}

33
app/Model/v3/ServiceReward.php

@ -0,0 +1,33 @@
<?php
declare (strict_types=1);
namespace App\Model\v3;
class ServiceReward extends Model
{
/**
* 社区服务点
*/
const TYPE_COMMUNITY = 1;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_service_reward';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'set_reward' => 'array'
];
}

2
app/Model/v3/Store.php

@ -60,7 +60,7 @@ class Store extends Model
public function getMonthSalesAttribute() {
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
return (integer)$ssdb->exec('get', SsdbKeys::STORE_MONTH_SALES.date('YM').'_'.$this->id);
return (integer)$ssdb->exec('get', SsdbKeys::STORE_MONTH_SALES.date('Ym').'_'.$this->id);
}
public function goods()

9
app/Model/v3/StoreAccount.php

@ -0,0 +1,9 @@
<?php
namespace App\Model\v3;
class StoreAccount extends Model
{
protected $table = 'ims_cjdc_store_account';
public $timestamps = false;
}

11
app/Model/v3/SystemConfig.php

@ -0,0 +1,11 @@
<?php
namespace App\Model\v3;
class SystemConfig extends Model
{
protected $table = 'ims_cjdc_system_config';
public $timestamps = false;
}

38
app/Model/v3/UserBalance.php

@ -0,0 +1,38 @@
<?php
declare (strict_types=1);
namespace App\Model\v3;
use App\Model\Model;
/**
*/
class UserBalance extends Model
{
const USER_TYPE_MP = 1;
const USER_TYPE_MM = 2;
const USER_TYPE_CS = 3;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_user_balance';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'source_id',
'user_type',
'balance'
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
}

40
app/Model/v3/UserRelationBind.php

@ -0,0 +1,40 @@
<?php
declare (strict_types=1);
namespace App\Model\v3;
/**
*/
class UserRelationBind extends Model
{
/**
* 社区服务点类型
*/
const BIND_TYPE_COMMUNITY = 1;
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'lanzu_user_relation_bind';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['bind_type', 'source_id', 'user_id', 'json_data'];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
public function setJsonDataAttribute($value)
{
$this->attributes['json_data'] = $value ? json_encode(json_decode($value, true)) : '';
}
}

4
app/Service/v3/Implementations/DeviceService.php

@ -99,7 +99,7 @@ class DeviceService implements DeviceServiceInterface
{
// 获取订单
$orders = Order::query()->select(['id','order_num','money', 'pay_type', 'store_id', 'type']);
$orders = Order::query()->with('orderMain');
if ($is_main) {
$orders = $orders->where(['order_main_id' => $order_id])->get()->toArray();
} else {
@ -116,7 +116,7 @@ class DeviceService implements DeviceServiceInterface
->where(['store_id' => $order['store_id'], 'is_bind' => SpeakerDevic::IS_BIND_YES])
->get()
->toArray();
$msg = $order['type']==1 ? "{\"msg\":\"您有新的懒族外卖订单\"}" : "{\"msg\":\"微信到账".$order['money']."\"}";
$msg = $order['order_main']['type'] == 1 ? "{\"msg\":\"您有新的懒族外卖订单\"}" : "{\"msg\":\"微信到账".$order['money']."\"}";
foreach ($device_names as $key => $dev_name) {
$this->IOTService->pub($dev_name['device_name'], $msg);
}

26
app/Service/v3/Implementations/FeiePrintService.php

@ -38,7 +38,7 @@ class FeiePrintService implements FeiePrintServiceInterface
$this->feieApiPath = config('feie.api_path');
}
public function feiePrint($order_num)
public function feiePrint($orderMainId)
{
// TODO 对象数组=》二维数组
$data = Db::table('lanzu_order_main as m')
@ -46,8 +46,8 @@ class FeiePrintService implements FeiePrintServiceInterface
->join('lanzu_order_goods as g','o.id','=', 'g.order_id','inner')
->join('lanzu_feprint as f','m.market_id','=', 'f.market_id','inner')
->join('lanzu_store as s','s.id','=', 'o.store_id','inner')
->where('m.global_order_id', $order_num)
->selectRaw("o.note as o_note,g.name,g.number,g.money,g.good_unit,m.delivery_time as ps_time,m.address,m.note,m.name as user_name,m.dada_fee,m.money as m_money,m.yhq_money2,m.box_money,f.sn,m.tel,m.order_num,g.id,g.spec,s.name as shopname")
->where('m.id', $orderMainId)
->selectRaw("o.note as o_note,g.name,g.number,g.price,g.goods_unit,m.delivery_time_note as ps_time,m.address,m.note,m.name as user_name,m.delivery_money,m.money as m_money,m.coupon_money,m.services_money,f.sn,m.tel,m.order_num,g.id,g.spec,s.name as shopname")
->orderBy('s.id')
->get()
->toArray();
@ -197,30 +197,30 @@ class FeiePrintService implements FeiePrintServiceInterface
}
// $time = date('Y-m-d H:i:s', time());
$orderInfo .= '--------------------------------<BR>';
if ($arr[0]['box_money'] > 0) {
if ($arr[0]['services_money'] > 0) {
$kw5 = '';
$len = 24 - strlen($arr[0]['box_money']);
$len = 24 - strlen($arr[0]['services_money']);
for ($q = 0; $q < $len; $q++) {
$kw5 .= ' ';
}
$orderInfo .= '包装费:' . $kw5 . $arr[0]['box_money'] . '<BR>';
$orderInfo .= '服务费:' . $kw5 . $arr[0]['services_money'] . '<BR>';
}
if($arr[0]['dada_fee'] > 0){
if($arr[0]['delivery_money'] > 0){
$kw5 = '';
$len = 24 - strlen($arr[0]['dada_fee']);
$len = 24 - strlen($arr[0]['delivery_money']);
for ($q = 0; $q < $len; $q++) {
$kw5 .= ' ';
}
$orderInfo .= '配送费:'.$kw5.$arr[0]['dada_fee'].'<BR>';
$orderInfo .= '配送费:'.$kw5.$arr[0]['delivery_money'].'<BR>';
}
if($arr[0]['yhq_money2'] > 0){
$yhq_money2 = sprintf("%.2f",$arr[0]['yhq_money2']);
if($arr[0]['coupon_money'] > 0){
$coupon_money = sprintf("%.2f",$arr[0]['coupon_money']);
$kw6 = '';
$len = 25 - strlen($yhq_money2);
$len = 25 - strlen($coupon_money);
for ($q = 0; $q < $len; $q++) {
$kw6 .= ' ';
}
$orderInfo .= '红包:'.$kw6.'-'.$yhq_money2.'<BR>';
$orderInfo .= '红包:'.$kw6.'-'.$coupon_money.'<BR>';
}
$total = '合计:'.$arr[0]['m_money'];
$user_name = $arr[0]['user_name'];

315
app/Service/v3/Implementations/FinancialRecordService.php

@ -0,0 +1,315 @@
<?php
namespace App\Service\v3\Implementations;
use App\Constants\v3\UserType;
use App\Model\v3\FinancialRecord;
use App\Model\v3\Store;
use App\Model\v3\UserBalance;
use App\Service\v3\Interfaces\FinancialRecordServiceInterface;
use App\Service\v3\Interfaces\SmsServiceInterface;
use Hyperf\Di\Annotation\Inject;
class FinancialRecordService implements FinancialRecordServiceInterface
{
/**
* @Inject
* @var SmsServiceInterface
*/
protected $smsAliService;
public function ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment='')
{
return $this->record(
-1,
[
'user_id' => -1,
'user_type' => UserType::LEDGER,
'money' => $money,
'money_type' => $money_type,
'source_id' => $source_id,
'source_type' => $source_type,
'desc' => $desc,
'comment' => $comment,
'status' => FinancialRecord::STATUS_NORMAL,
],
true
);
}
public function record($user_id, $record, $isLedger=false)
{
$financialRecord = new FinancialRecord();
if (!$isLedger) {
$mod = bcmod((string)$user_id, '5', 0);
$financialRecord->suffix($mod);
}
return $financialRecord->fill(
[
'user_id' => $user_id,
'user_type' => $record['user_type'],
'money' => $record['money'],
'money_type' => $record['money_type'],
'source_id' => $record['source_id'],
'source_type' => $record['source_type'],
'desc' => $record['desc'],
'comment' => $record['comment'],
'status' => $record['status'],
]
)->save();
}
/**
* @inheritDoc
*/
public function communityAwardByPlatNewUser(
$user_id,
$source_id,
$money,
$user_type=UserType::CS,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_CS_PLAT_NEW_USER,
$desc='新用户奖励',
$comment='社区服务点'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护社区服务点余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::CS,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money, 2);
$balance->save();
// 发送短信
$this->smsAliService->sendForCommunityFinancial($user_id, $money);
}
/**
* @inheritDoc
*/
public function communityAwardByPlatNewUserFirstOLOrder(
$user_id,
$source_id,
$money,
$user_type=UserType::CS,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_CS_FIRST_ORDER,
$desc='新用户首单奖励',
$comment='社区服务点'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护社区服务点余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::CS,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money, 2);
$balance->save();
// 发送短信
$this->smsAliService->sendForCommunityFinancial($user_id, $money);
}
/**
* @inheritDoc
*/
public function communitySeparateAccountsByOrderComp(
$user_id,
$source_id,
$money,
$user_type=UserType::CS,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_CS_OL_ORDER,
$desc='用户订单分成',
$comment='社区服务点'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护社区服务点余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::CS,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money,2);
$balance->save();
// 发送短信
$this->smsAliService->sendForCommunityFinancial($user_id, $money);
}
/**
* @inheritDoc
*/
public function storeAwardByPlatNewUserOFLOrder(
$user_id,
$source_id,
$money,
$user_type=UserType::STORE,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_STORE_PLAT_NEW_USER,
$desc='新用户下单奖励',
$comment='用户当面付商户奖励'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::STORE,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money, 2);
$balance->save();
}
/**
* @inheritDoc
*/
public function storeAwardByTodayFirstOFLOrder(
$user_id,
$source_id,
$money,
$user_type=UserType::STORE,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_STORE_FIRST_ORDER,
$desc='用户店铺首单奖励',
$comment='用户当面付商户奖励'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::STORE,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money, 2);
$balance->save();
}
public function recordAll($user_id, $source_id, $money, $user_type=1, $source_type=0, $money_type=0, $desc='', $comment='') {
$this->record(
$user_id,
[
'user_id' => $user_id,
'user_type' => $user_type,
'money' => $money,
'money_type' => $money_type,
'source_id' => $source_id,
'source_type' => $source_type,
'desc' => $desc,
'comment' => $comment,
'status' => FinancialRecord::STATUS_NORMAL,
]
);
$this->ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment);
}
/**
* @inheritDoc
*/
public function userByOFLOrderPaid(
$user_id,
$source_id,
$money,
$user_type=UserType::USER,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_USER_OFL_ORDER,
$desc='用户下单(线下)',
$comment='用户下单'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
}
/**
* @inheritDoc
*/
public function userByOLOrderPaid(
$user_id,
$source_id,
$money,
$user_type=UserType::USER,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_USER_OL_ORDER,
$desc='用户下单(线上)',
$comment='用户下单'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
}
/**
* @inheritDoc
*/
public function storeByOLOrderComp(
$user_id,
$source_id,
$money,
$user_type = UserType::STORE,
$source_type = FinancialRecord::SOURCE_TYPE_ORDER,
$money_type = FinancialRecord::MONEY_TYPE_STORE_OL_ORDER_COMP,
$desc = '线上外卖订单收入',
$comment = '用户订单完成'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::STORE,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money, 2);
$balance->save();
}
/**
* @inheritDoc
*/
public function storeByOFLOrderComp(
$user_id,
$source_id,
$money,
$user_type = UserType::STORE,
$source_type = FinancialRecord::SOURCE_TYPE_ORDER,
$money_type = FinancialRecord::MONEY_TYPE_STORE_OFL_ORDER_COMP,
$desc = '线下当面付订单收入',
$comment = '用户订单完成'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
// 维护余额
$balance = UserBalance::query()->firstOrNew([
'user_type' => UserType::STORE,
'source_id' => $user_id
]);
$balance->balance = bcadd($balance->balance, $money, 2);
$balance->save();
}
/**
* @inheritDoc
* 订单退款(线上)
*/
public function userByOLOrderRefund(
$user_id,
$source_id,
$money,
$user_type = UserType::USER,
$source_type = FinancialRecord::SOURCE_TYPE_ORDER,
$money_type = FinancialRecord::MONEY_TYPE_USER_OL_ORDER_REFUND,
$desc = '线上订单退款',
$comment = '线上订单退款到微信'
)
{
$this->recordAll($user_id, $source_id, $money, $user_type, $source_type, $money_type, $desc, $comment);
}
}

36
app/Service/v3/Implementations/MiniprogramService.php

@ -21,36 +21,36 @@ class MiniprogramService implements MiniprogramServiceInterface
{
// 查询订单信息
$order = OrderMain::find($order_main_id);
$order = OrderMain::query()->find($order_main_id)->toArray();
$payTypes = ['1' => '微信支付', '2' => '余额支付', '3' => '积分支付', '4' => '货到付款'];
$address_store = $order['address'] . ';' .$order['name']. ';'. substr_replace($order['tel'],'****',3,4);
$address = $order['address'] . ';' .$order['name']. ';'. $order['tel'];
// 查询子订单,用于发消息给商户
$order_children = Order::query()->select(['id', 'order_num', 'store_id', 'money', 'time'])
$order_children = Order::query()
->with('orderMain')
->where(['order_main_id' => $order_main_id])
->get()
->toArray();
->get();
$goods_temp_all = [];
foreach ($order_children as $key => &$item) {
// 订单商品
$order_goods = OrderGoods::query()->select(['name', 'number', 'spec', 'good_unit'])
->where(['order_id' => $item['id']])
$order_goods = OrderGoods::query()
->where(['order_id' => $item->id])
->get()
->toArray();
$goods_temp = [];
foreach ($order_goods as $k => &$goods) {
array_push($goods_temp, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['good_unit']));
array_push($goods_temp_all, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['good_unit']));
array_push($goods_temp, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['goods_unit']));
array_push($goods_temp_all, $goods['name']."*".$goods['number']."/".($goods['spec']?:$goods['goods_unit']));
}
// 商户/门店的openid
$store = Store::query()->select(['id', 'name', 'user_id'])
->where(['id' => $item['store_id']])
->where(['id' => $item->store_id])
->first()->toArray();
$store['openid'] = User::query()
->where(['id' => $store['user_id']])
@ -58,15 +58,15 @@ class MiniprogramService implements MiniprogramServiceInterface
// 模板数据
$data_store = [
'first' => ['您有新的外卖订单!订单编号:'.$item['order_num'], '#ff0000'],
'first' => ['您有新的外卖订单!订单编号:'.$item->order_num, '#ff0000'],
'keyword' => [
["您的外卖订单详情:\r\n".implode(";\r\n",$goods_temp), '#ff0000'],
$item['money'],
$item->money,
$payTypes[$order['pay_type']],
$item['time']?:'',
$item->created_at_text??'',
$address_store,
],
'remark' => [$order['note'], '#4e6ef2']
'remark' => [$item->note, '#4e6ef2']
];
$ret_store = $this->sendTempMsg($store['openid'], '-M7DG_ACwJxqdAvyvJuAnPpx4xaLf3VkkN0fckno71c',$data_store);
@ -74,12 +74,12 @@ class MiniprogramService implements MiniprogramServiceInterface
// 模板数据发送消息给用户
$data_user = [
'first' => '您好,下单成功!订单编号:'.$order['order_num'],
'first' => '您好,下单成功!订单编号:'.$order['global_order_id'],
'keyword' => [
implode(";\r\n", $goods_temp_all),
$order['money'],
$payTypes[$order['pay_type']],
date('Y-m-d H:i:s', $order['time_add']),
$order['created_at_text'],
$address,
],
'remark' => '感谢您的光临,欢迎下次再来!'
@ -98,14 +98,14 @@ class MiniprogramService implements MiniprogramServiceInterface
{
// 查询子订单,用于发消息给商户
$order_children = Order::query()->select(['id', 'order_num', 'store_id', 'money', 'time'])
$order_children = Order::query()
->where(['order_main_id' => $order_main_id])
->get()
->toArray();
foreach ($order_children as $key => &$item) {
// 商户/门店的openid
$store = Store::query()->select(['id', 'name', 'user_id'])
$store = Store::query()
->where(['id' => $item['store_id']])
->first()->toArray();
$store['openid'] = User::query()
@ -117,7 +117,7 @@ class MiniprogramService implements MiniprogramServiceInterface
'first' => '您有新订单收入!订单编号:'.$item['order_num'],
'keyword' => [
$store['name']?:'',
$item['time']?:'',
$item['created_at_text']??'',
'暂无',
$item['money']
],

13
app/Service/v3/Implementations/MqttService.php

@ -19,22 +19,23 @@ class MqttService implements MqttServiceInterface
{
// 获取订单
$orders = Order::query()->select(['id','order_num','money', 'pay_type', 'store_id', 'type']);
$orders = Order::query()
->with('orderMain');
if ($isMain) {
$orders = $orders->where(['order_main_id' => $orderId])->get()->toArray();
$orders = $orders->where(['order_main_id' => $orderId])->get();
} else {
$orders = $orders->where(['id' => $orderId])->get()->toArray();
$orders = $orders->where(['id' => $orderId])->get();
}
if(empty($orders)) return;
// 循环发送
foreach ($orders as $k => &$order) {
$order['template'] = $order['type']==OrderType::ONLINE ? "您有新的懒族外卖订单" : "微信到账".floatval($order['money'])."";
$template = $order->orderMain->type == OrderType::ONLINE ? "您有新的懒族外卖订单" : "微信到账".floatval($order->money)."";
// 获取终端ID
$order['to_client_id'] = Store::query()->where(['id' => $order['store_id']])->value('loudspeaker_imei');
$to_client_id = Store::query()->where(['id' => $order->store_id])->value('loudspeaker_imei');
// 发布订阅消息
$res = $this->publish($order['template'], config('mqtt.topic'), $order['to_client_id']);
$this->publish($template, config('mqtt.topic'), $to_client_id);
}
}

35
app/Service/v3/Implementations/OrderOfflineService.php

@ -92,4 +92,39 @@ class OrderOfflineService implements OrderOfflineServiceInterface
{
// TODO: Implement undo() method.
}
public function doPaid($orderMainId)
{
Db::beginTransaction();
try {
// 主订单状态更新
$orderMain = OrderMain::query()
->where(['id' => $orderMainId, 'type' => OrderType::OFFLINE])
->first();
if (empty($orderMain)) {
$this->log->event(
LogLabel::ORDER_OFFLINE_PAID_LOG,
['order_not_found' => $orderMain->global_order_id]
);
Db::rollBack();
return false;
}
$currentTime = time();
$orderMain->state = OrderState::COMPLETED;
$orderMain->pay_time = $currentTime;
$orderMain->save();
Db::commit();
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::ORDER_OFFLINE_PAID_LOG, ['exception' => $e->getMessage()]);
Db::rollBack();
return false;
}
}
}

60
app/Service/v3/Implementations/OrderOnlineService.php

@ -3,10 +3,12 @@
namespace App\Service\v3\Implementations;
use App\Commons\Log;
use App\Constants\v3\ActivityType;
use App\Constants\v3\ErrorCode;
use App\Constants\v3\LogLabel;
use App\Constants\v3\OrderState;
use App\Constants\v3\OrderType;
use App\Constants\v3\SsdbKeys;
use App\Exception\ErrorCodeException;
use App\Model\v3\Coupon;
use App\Model\v3\CouponRec;
@ -16,6 +18,7 @@ use App\Model\v3\GoodsActivity;
use App\Model\v3\Order;
use App\Model\v3\OrderGoods;
use App\Model\v3\OrderMain;
use App\Model\v3\OrderSalesStatistic;
use App\Model\v3\ShoppingCart;
use App\Model\v3\Store;
use App\Model\v3\UserAddress;
@ -25,6 +28,7 @@ use App\Service\v3\Interfaces\DeliveryMoneyServiceInterface;
use App\Service\v3\Interfaces\GoodsActivityServiceInterface;
use App\Service\v3\Interfaces\GoodsServiceInterface;
use App\Service\v3\Interfaces\PaymentServiceInterface;
use App\TaskWorker\SSDBTask;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use App\Service\v3\Interfaces\OrderOnlineServiceInterface;
@ -399,6 +403,9 @@ class OrderOnlineService implements OrderOnlineServiceInterface
{
Db::beginTransaction();
try {
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class);
// 查询订单
$orderMain = OrderMain::query()
->where(['id' => $orderMainId,'type' => OrderType::ONLINE])
@ -407,40 +414,40 @@ class OrderOnlineService implements OrderOnlineServiceInterface
// 修改订单、子订单状态
$currentTime = time();
$orderMain->state = OrderState::PAID;
$orderMain->time_pay = $currentTime;
$orderMain->pay_time = date('Y-m-d H:i:s', $currentTime);
$orderMain->pay_time = $currentTime;
$orderMain->save();;
// 更新商户销量
$upStoreScore = Store::query()
->whereIn('id', explode(',', $orderMain->store_ids))
->update(['score' => Db::raw('score+1')]);
// 更新商品库存和销量
$orders = Order::query()->select(['id', 'money', 'user_id', 'store_id'])
$orders = Order::query()
->where(['order_main_id' => $orderMain->id])
->get()
->toArray();
$orderGoods = OrderGoods::query()->select(['good_id AS id', 'number', 'combination_id'])
// 更新商户销量
$upStoreScore = Store::query()
->whereIn('id', array_values(array_column($orders, 'store_id')))
->update(['sales' => Db::raw('sales+1')]);
$orderGoods = OrderGoods::query()
->whereIn('order_id', array_values(array_column($orders, 'id')))
->get()
->toArray();
foreach ($orderGoods as $key => &$goodsItem) {
$goods = Goods::find($goodsItem['id']);
// 库存处理,有规格
if ($goodsItem['combination_id']) {
$combination = SpecCombination::find($goodsItem['combination_id']);
$combination->number = $combination->number - $goodsItem['number'];
$combination->save();
if ($goodsItem['activity_type'] == 2) { # 活动商品
$goods = GoodsActivity::find($goodsItem['goods_id']);
} else {
$goods->inventory = $goods->inventory - $goodsItem['number'];
$goods = Goods::find($goodsItem['goods_id']);
}
$goods->sales = $goods->sales - $goodsItem['number'];
$goods->inventory = $goods->inventory - $goodsItem['number'];
$goods->sales = $goods->sales + $goodsItem['number'];
$goods->save();
// 商品月销
if (!$ssdb->exec('exists', SsdbKeys::GOODS_MONTH_SALES . date('Ym') . '_' . $goodsItem['activity_type'] . '_'.$goods->id)) {
$ssdb->exec('set', SsdbKeys::GOODS_MONTH_SALES . date('Ym') . '_' . $goodsItem['activity_type'] . '_' . $goods->id, $goodsItem['number']);
} else {
$ssdb->exec('incr', SsdbKeys::GOODS_MONTH_SALES . date('Ym') . '_' . $goodsItem['activity_type'] . '_' . $goods->id, $goodsItem['number']);
}
}
// 月销流水
@ -452,8 +459,15 @@ class OrderOnlineService implements OrderOnlineServiceInterface
'store_id' => $order['store_id'],
'market_id' => $orderMain->market_id,
'order_id' => $order['id'],
'createtime' => strtotime($order['pay_time']),
'createtime' => $orderMain->pay_time,
];
// 商户月销
if (!$ssdb->exec('exists', SsdbKeys::STORE_MONTH_SALES . date('Ym').'_' . $order['store_id'])) {
$ssdb->exec('set', SsdbKeys::STORE_MONTH_SALES . date('Ym') . '_' . $order['store_id'], 1);
} else {
$ssdb->exec('incr', SsdbKeys::STORE_MONTH_SALES . date('Ym') . '_' . $order['store_id'], 1);
}
}
if (is_array($statistics) && !empty($statistics)) {
@ -462,9 +476,9 @@ class OrderOnlineService implements OrderOnlineServiceInterface
Db::commit();
return true;
} catch (Exception $e) {
} catch (\Exception $e) {
$this->log->event(LogLabel::ONLINE_PAID_LOG, ['exception' => $e->getMessage()]);
$this->log->event(LogLabel::ORDER_ONLINE_PAID_LOG, ['exception' => $e->getMessage()]);
Db::rollBack();
return false;
}

278
app/Service/v3/Implementations/SeparateAccountsService.php

@ -0,0 +1,278 @@
<?php
namespace App\Service\v3\Implementations;
use App\Commons\Log;
use App\Constants\v3\LogLabel;
use App\Model\v3\FinancialRecord;
use App\Model\v3\Order;
use App\Model\v3\OrderMain;
use App\Model\v3\ServiceReward;
use App\Model\v3\Store;
use App\Model\v3\StoreAccount;
use App\Model\v3\SystemConfig;
use App\Model\v3\UserBalance;
use App\Model\v3\UserRelationBind;
use App\Model\v3\User;
use App\Service\v3\Interfaces\FinancialRecordServiceInterface;
use App\Service\v3\Interfaces\MiniprogramServiceInterface;
use App\Service\v3\Interfaces\SeparateAccountsServiceInterface;
use App\Service\v3\Interfaces\UserServiceInterface;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
class SeparateAccountsService implements SeparateAccountsServiceInterface
{
/**
* @Inject
* @var Log
*/
protected $log;
/**
* @Inject
* @var UserServiceInterface
*/
protected $userService;
/**
* @Inject
* @var FinancialRecordServiceInterface
*/
protected $financialRecordService;
/**
* @Inject
* @var MiniprogramServiceInterface
*/
protected $miniprogramService;
/**
* @inheritDoc
*/
public function orderOnlinePaid($orderMainId)
{
try {
// 线上订单支付完成
// 订单
$orderMain = OrderMain::query()->find($orderMainId);
if (empty($orderMain)) {
return false;
}
// =======用户支付流水 / Start=======
$this->financialRecordService->userByOLOrderPaid($orderMain->user_id, $orderMain->global_order_id, $orderMain->money);
// =======用户支付流水 / End=======
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage()]);
return false;
}
}
/**
* @inheritDoc
*/
public function orderOnlineCompleted($global_order_id)
{
// 线上订单完成(用户点击确认收货完成/管理后台点击完成/配送员点击完成/自动收货等),进行相关分账
// 订单
$orderMain = OrderMain::query()
->where(['global_order_id' => $global_order_id])
->whereIn('state', [OrderMain::ORDER_STATE_COMPLETE,OrderMain::ORDER_STATE_EVALUATED,OrderMain::ORDER_STATE_UNREFUND])
->first();
if (empty($orderMain)) {
return false;
}
$currentTime = time();
Db::beginTransaction();
try {
// =======商户订单收入流水 / Start=======
// 查询子订单
$orders = Order::query()->select(['id', 'money', 'user_id', 'store_id', 'pay_time'])
->where(['order_main_id' => $orderMain->id])
->get()->toArray();
foreach ($orders as $key => &$order) {
// 商户
$store = Store::find($order['store_id']);
// 旧商户流水基础数据 TODO 直接移除或后续考虑移除
$storeAccountBase = [
'user_id' => $order['user_id'],
'order_id' => $order['id'],
'store_id' => $order['store_id'],
'type' => 1,
'time' => date('Y-m-d H:i:s', $currentTime),
'add_time' => $currentTime,
];
// 旧商户流水 TODO 直接移除或后续考虑移除
$storeAccount = [
'money' => $order['money'],
'note' => '线上订单',
'category' => 1,
];
StoreAccount::query()->insert(array_merge($storeAccountBase, $storeAccount));
// 新商户流水
$this->financialRecordService->storeByOLOrderComp($store->user_id, $global_order_id ,$order['money']);
}
// =======商户订单收入流水 / End=======
// =======社区服务点分账 / Start=======
// 前提:用户线上下单并且订单完成
// 奖励规则A:用户是平台新用户,奖励社区服务点平台新用户奖励x元+平台新用户首单奖励y元+订单商品金额z%的分成
// 奖励规则B:用户是非新用户,奖励社区服务点订单实际支付金额z%的分成
// =======社区服务点分账 / Start=======
// 当前用户的社区服务点绑定关系
$communityBind = UserRelationBind::query()
->where(['bind_type' => UserRelationBind::BIND_TYPE_COMMUNITY, 'user_id' => $orderMain->user_id])
->first();
if ($communityBind) {
// 奖励/分账金额
$award = ServiceReward::query()->where(['type' => ServiceReward::TYPE_COMMUNITY])->first();
if (empty($award)) {
Db::rollBack();
return false;
}
$award = $award->set_reward;
// 平台新用户
if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
$this->financialRecordService->communityAwardByPlatNewUser($communityBind->source_id, $global_order_id, $award['new_user_reward']);
$this->financialRecordService->communityAwardByPlatNewUserFirstOLOrder($communityBind->source_id, $global_order_id, $award['first_reward']);
}
// 账单分成
$money = bcmul($orderMain->money, bcdiv($award['flow_reward'], 100, 6), 2);
$this->financialRecordService->communitySeparateAccountsByOrderComp($communityBind->source_id, $global_order_id, $money);
}
// =======社区服务点分账 / End=======
Db::commit();
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
Db::rollBack();
return false;
}
}
/**
* @inheritDoc
*/
public function orderOfflinePaid($orderMainId)
{
// 线下订单支付完成
// 订单
$orderMain = OrderMain::query()->find($orderMainId);
$global_order_id = $orderMain->global_order_id;
if (empty($orderMain)) {
return false;
}
// 查询子订单,当面付目前实际上只有一个子订单
$order = Order::query()
->where(['order_main_id' => $orderMain->id])
->first();
if (empty($order)) {
return false;
}
$currentTime = time();
Db::beginTransaction();
try {
// =======用户支付流水 / Start=======
$this->financialRecordService->userByOFLOrderPaid($orderMain->user_id, $global_order_id, $orderMain->money);
// =======用户支付流水 / End=======
// =======线下订单支付完成商户分账 / Start=======
// 前提:用户线上下单并且支付完成
// 奖励规则A:用户是平台新用户,奖励商户2元
// 奖励规则B:用户是非新用户,但是是商户当日首单,奖励商户0.05元
// =======线下订单支付完成商户分账 / Start=======
$message = [];
// 商户
$store = Store::find($order->store_id);
// 新商户订单流水
$this->financialRecordService->storeByOFLOrderComp($store->user_id, $global_order_id, $order->money);
$needAward = false;
$awardAmount = 0;
// 新用户商户奖励
if ($this->userService->isPlatformNewUser($orderMain->user_id, $orderMain->id)) {
$awardAmount = 2;
// 旧商户流水 TODO 直接移除或后续考虑移除
$message = [
'money' => $awardAmount,
'note' => '新用户下单成功,平台奖励',
];
// 新商户流水
$this->financialRecordService->storeAwardByPlatNewUserOFLOrder($store->user_id, $global_order_id, $awardAmount);
$needAward = true;
} else {
// 商户当日首单奖励
if (
$this->userService->isStoreFirstOrderToday(
$order->user_id,
$order->store_id,
$order->id,
FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
)
&& $order->money >= FinancialRecord::OFL_FIRST_AWARD_LIMIT_AMOUNT
) {
$awardAmount = 0.05;
// 旧商户流水 TODO 直接移除或后续考虑移除
$message = [
'money' => $awardAmount,
'note' => '用户下单成功,平台奖励',
];
// 新商户流水
$this->financialRecordService->storeAwardByTodayFirstOFLOrder($store->user_id, $global_order_id, $awardAmount);
$needAward = true;
}
}
if ($needAward && $awardAmount) {
// 发模板消息
$openid = User::query()->where(['id' => $store['user_id']])->value('openid');
$res = $this->miniprogramService->sendTemMsgForAward($message['money'], $message['note'], $openid, date('Y-m-d H:i:s', $currentTime));
}
// =======线下订单支付完成商户分账 / End=======
Db::commit();
return true;
} catch (\Exception $e) {
$this->log->event(LogLabel::SEPARATE_ACCOUNTS_LOG, ['exception' => $e->getMessage(), 'order_main' => json_encode($orderMain)]);
Db::rollBack();
return false;
}
}
}

69
app/Service/v3/Implementations/SmsAliService.php

@ -0,0 +1,69 @@
<?php
namespace App\Service\v3\Implementations;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use App\Commons\Log;
use App\Model\v3\CsInfo;
use App\Model\v3\Market;
use App\Service\v3\Interfaces\SmsServiceInterface;
use Hyperf\Di\Annotation\Inject;
class SmsAliService implements SmsServiceInterface
{
const TEMPLATE_COMMUNITY_FINANCIAL = 'SMS_200690862';
/**
* @Inject
* @var Log
*/
protected $log;
public function send($phone, $template, $templateParams, $signName='懒族生活')
{
$alisms = config('alisms');
AlibabaCloud::accessKeyClient($alisms['app_key'], $alisms['app_secret'])
->regionId($alisms['regionid'])
->asDefaultClient();
try {
$result = AlibabaCloud::rpc()
->product($alisms['product'])
// ->scheme('https') // https | http
->version('2017-05-25')
->action('SendSms')
->method('POST')
->host($alisms['host'])
->options([
'query' => [
'RegionId' => $alisms['regionid'],
'PhoneNumbers' => $phone,
'SignName' => $signName,
'TemplateCode' => $template,
'TemplateParam' => $templateParams,
],
])
->request();
return $result->toArray();
} catch (ClientException $e) {
$this->log->event('alisms', ['alisms_error_ClientException' => $e->getErrorMessage()]);
return false;
} catch (ServerException $e) {
$this->log->event('alisms', ['alisms_error_ServerException' => $e->getErrorMessage()]);
return false;
}
}
public function sendForCommunityFinancial($userId, $money)
{
$csInfo = CsInfo::query()->where(['admin_user_id' => $userId])->first();
$market = Market::query()->where(['id' => $csInfo->market_id])->first();
$params = ['user_name' => $csInfo->name, 'market_name' => $market->name, 'money' => $money];
return $this->send($csInfo->phone, self::TEMPLATE_COMMUNITY_FINANCIAL, json_encode($params));
}
}

4
app/Service/v3/Implementations/UserService.php

@ -25,9 +25,7 @@ class UserService implements UserServiceInterface
return !OrderMain::query()
->where(['user_id' => $user_id])
->where('id', '!=', $order_main_id)
->where(function ($query){
$query->whereIn('state', OrderState::FINISH);
})
->whereIn('state', OrderState::FINISH)
->exists();
}

253
app/Service/v3/Interfaces/FinancialRecordServiceInterface.php

@ -0,0 +1,253 @@
<?php
namespace App\Service\v3\Interfaces;
use App\Constants\v3\UserType;
use App\Model\FinancialRecord;
interface FinancialRecordServiceInterface
{
/**
* 社区服务点新用户奖励
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $comment
* @param string $desc
* @return mixed
*/
public function communityAwardByPlatNewUser(
$user_id,
$source_id,
$money,
$user_type=UserType::CS,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_CS_PLAT_NEW_USER,
$desc='新用户奖励',
$comment=''
);
/**
* 社区服务点新用户线上首单奖励
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $comment
* @param string $desc
* @return mixed
*/
public function communityAwardByPlatNewUserFirstOLOrder(
$user_id,
$source_id,
$money,
$user_type=UserType::CS,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_CS_FIRST_ORDER,
$desc='新用户首单奖励',
$comment=''
);
/**
* 社区服务点用户订单完成分账
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $comment
* @param string $desc
* @return mixed
*/
public function communitySeparateAccountsByOrderComp(
$user_id,
$source_id,
$money,
$user_type=UserType::CS,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_CS_OL_ORDER,
$desc='用户订单分成',
$comment=''
);
/**
* 收支总账
* @param $source_id
* @param $money
* @param $source_type
* @param $money_type
* @param $desc
* @param string $comment
* @return mixed
*/
public function ledgerAccounts($source_id, $money, $source_type, $money_type, $desc, $comment='');
/**
* 商户线下用户支付新用户奖励
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function storeAwardByPlatNewUserOFLOrder(
$user_id,
$source_id,
$money,
$user_type=UserType::STORE,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_STORE_PLAT_NEW_USER,
$desc='新用户下单奖励',
$comment=''
);
/**
* 商户线下用户支付用户当日首单奖励
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function storeAwardByTodayFirstOFLOrder(
$user_id,
$source_id,
$money,
$user_type=UserType::STORE,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_STORE_FIRST_ORDER,
$desc='用户店铺首单奖励',
$comment=''
);
/**
* 用户线下订单支付流水
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function userByOFLOrderPaid(
$user_id,
$source_id,
$money,
$user_type=UserType::USER,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_USER_OFL_ORDER,
$desc='用户下单(线下)',
$comment=''
);
/**
* 用户线上订单支付流水
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function userByOLOrderPaid(
$user_id,
$source_id,
$money,
$user_type=UserType::USER,
$source_type=FinancialRecord::SOURCE_TYPE_ORDER,
$money_type=FinancialRecord::MONEY_TYPE_USER_OL_ORDER,
$desc='用户下单(线上)',
$comment=''
);
/**
* 商户线上订单完成收入流水
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function storeByOLOrderComp(
$user_id,
$source_id,
$money,
$user_type = UserType::STORE,
$source_type = FinancialRecord::SOURCE_TYPE_ORDER,
$money_type = FinancialRecord::MONEY_TYPE_STORE_OL_ORDER_COMP,
$desc='线上外卖订单收入',
$comment=''
);
/**
* 商户线下订单完成收入流水
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function storeByOFLOrderComp(
$user_id,
$source_id,
$money,
$user_type = UserType::STORE,
$source_type = FinancialRecord::SOURCE_TYPE_ORDER,
$money_type = FinancialRecord::MONEY_TYPE_STORE_OFL_ORDER_COMP,
$desc='线下当面付订单收入',
$comment=''
);
/**
* 线上订单退款流水
* @param $user_id
* @param $source_id
* @param $money
* @param int $user_type
* @param int $source_type
* @param int $money_type
* @param string $desc
* @param string $comment
* @return mixed
*/
public function userByOLOrderRefund(
$user_id,
$source_id,
$money,
$user_type = UserType::STORE,
$source_type = FinancialRecord::SOURCE_TYPE_ORDER,
$money_type = FinancialRecord::MONEY_TYPE_STORE_OFL_ORDER_COMP,
$desc='线上订单退款',
$comment=''
);
}

1
app/Service/v3/Interfaces/OrderOfflineServiceInterface.php

@ -7,4 +7,5 @@ interface OrderOfflineServiceInterface
public function do($storeId, $userId, $money, $plat='');
public function check();
public function undo();
public function doPaid($orderMainId);
}

28
app/Service/v3/Interfaces/SeparateAccountsServiceInterface.php

@ -0,0 +1,28 @@
<?php
namespace App\Service\v3\Interfaces;
interface SeparateAccountsServiceInterface
{
/**
* (线上)订单支付完成分账
* @param $orderMainId
* @return mixed
*/
public function orderOnlinePaid($orderMainId);
/**
* (线上)订单确认完成分账
* 用户确认或服务商(服务站确认)
* @param $global_order_id
* @return mixed
*/
public function orderOnlineCompleted($global_order_id);
/**
* (线下)订单支付完成分账
* @param $orderMainId
* @return mixed
*/
public function orderOfflinePaid($orderMainId);
}

9
app/Service/v3/Interfaces/SmsServiceInterface.php

@ -0,0 +1,9 @@
<?php
namespace App\Service\v3\Interfaces;
interface SmsServiceInterface
{
public function send($phone, $template, $templateParams);
public function sendForCommunityFinancial($userId, $money);
}

10
config/autoload/dependencies.php

@ -55,7 +55,6 @@ return [
\App\Service\v3\Interfaces\OrderListServiceInterface::class => \App\Service\v3\Implementations\OrderListService::class,
\App\Service\v3\Interfaces\UserCenterBlockServiceInterface::class => \App\Service\v3\Implementations\UserCenterBlockService::class,
\App\Service\v3\Interfaces\StoreLoginServiceInterface::class => \App\Service\v3\Implementations\StoreLoginService::class,
\App\Service\v3\Interfaces\StoreInfoServiceInterface::class => \App\Service\v3\Implementations\StoreInfoService::class,
\App\Service\v3\Interfaces\BannerServiceInterface::class => \App\Service\v3\Implementations\BannerService::class,
\App\Service\v3\Interfaces\ActivityServiceInterface::class => \App\Service\v3\Implementations\ActivityService::class,
\App\Service\v3\Interfaces\TabsServiceInterface::class => \App\Service\v3\Implementations\TabsService::class,
@ -70,4 +69,13 @@ return [
\App\Service\v3\Interfaces\BusinessHoursServiceInterface::class => \App\Service\v3\Implementations\BusinessHoursService::class,
\App\Service\v3\Interfaces\UserAddressServiceInterface::class => \App\Service\v3\Implementations\UserAddressService::class,
\App\Service\v3\Interfaces\MqttServiceInterface::class => \App\Service\v3\Implementations\MqttService::class,
\App\Service\v3\Interfaces\DeviceServiceInterface::class =>\App\Service\v3\Implementations\DeviceService::class,
\App\Service\v3\Interfaces\IOTServiceInterface::class => \App\Service\v3\Implementations\IOTAliService::class,
\App\Service\v3\Interfaces\FeiePrintServiceInterface::class => \App\Service\v3\Implementations\FeiePrintService::class,
\App\Service\v3\Interfaces\MiniprogramServiceInterface::class => \App\Service\v3\Implementations\MiniprogramService::class,
\App\Service\v3\Interfaces\FinancialRecordServiceInterface::class => \App\Service\v3\Implementations\FinancialRecordService::class,
\App\Service\v3\Interfaces\SeparateAccountsServiceInterface::class => \App\Service\v3\Implementations\SeparateAccountsService::class,
\App\Service\v3\Interfaces\UserServiceInterface::class => \App\Service\v3\Implementations\UserService::class,
\App\Service\v3\Interfaces\CouponRebateServiceInterface::class => \App\Service\v3\Implementations\CouponRebateService::class,
\App\Service\v3\Interfaces\SmsServiceInterface::class => \App\Service\v3\Implementations\SmsAliService::class,
];
Loading…
Cancel
Save