初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

View File

@@ -0,0 +1,368 @@
<?php
/**
* Niushop商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.niushop.com
* =========================================================
*/
namespace addon\store\model\settlement;
use app\model\BaseModel;
use addon\store\model\Config;
use addon\store\model\StoreAccount;
use app\model\store\Store;
use think\facade\Log;
class OrderSettlement extends BaseModel
{
const ACTION_EXECUTE = 1;
const ACTION_RETURN_DATA = 2;
/**
* 门店订单分成计算
* @param $data
* @param $action
*/
public function orderSettlementAccount($data, $action = self::ACTION_EXECUTE)
{
$order_id = $data[ 'order_id' ];
$order_info = model('order')->getInfo([ [ 'order_id', '=', $order_id ] ]);
if(empty($order_info)) return null;
if(empty($order_info['store_id'])) return null;
$store_id = $order_info[ 'store_id' ];
$site_id = $order_info[ 'site_id' ];
$config_model = new Config();
$config = $config_model->getStoreWithdrawConfig($site_id)[ 'data' ][ 'value' ] ?? [];
$is_settlement = $config[ 'is_settlement' ];//结算模式 todo 系统配置的门店计算开关是否会对门店结算开关造成影响
if ($is_settlement > 0) {
$store_model = new Store();
$store_condition = array (
[ 'site_id', '=', $site_id ],
[ 'store_id', '=', $store_id ]
);
$store_info = $store_model->getStoreInfoByAccount($store_condition)[ 'data' ] ?? [];
$is_settlement = $store_info[ 'is_settlement' ];
if ($is_settlement > 0) {
$settlement_pay_type = $config['settlement_pay_type'] ?? [];//参与结算的支付方式
if(!empty($settlement_pay_type)){
if(in_array($order_info['pay_type'], explode(',', $settlement_pay_type))){
$store_settlement_rate = $store_info[ 'settlement_rate' ];
if ($store_settlement_rate > 0) {
$settlement_rate = $store_settlement_rate;
} else {
$settlement_rate = $config[ 'settlement_rate' ];
}
if ($settlement_rate > 0) {
$settlement_rate_calc = $settlement_rate / 100;//计算门店抽成比例
$order_money = $order_info[ 'order_money' ];
//todo 可能还有退款
$settlement_cost = $config[ 'settlement_cost' ];
$settlement_cost_array = explode(',', $settlement_cost);
//总金额
$base_money = $order_money;
$remark = '订单编号:'.$order_info['order_no'].';结算佣金=([订单金额]'.$base_money;
//退款金额
if(!empty($order_info[ 'refund_money' ])){
$base_money -= $order_info[ 'refund_money' ];//todo 这儿涉及到一个问题,退款的金额里面包含一部分余额,可能结算金额不太一致
if($order_info['refund_money'] > 0){
$remark .= '-[退款金额]'.$order_info['refund_money'];
}
}
//余额抵扣
if($order_info['balance_money'] > 0){
$balance_money = $order_info[ 'balance_money' ];
$base_money -= $balance_money;
$remark .= '-[余额抵扣]'.$order_info['balance_money'];
}
//分销佣金
if (in_array('fenxiao_commission', $settlement_cost_array)) {
$commission = $order_info[ 'commission' ];
$base_money -= $commission;
if($order_info['commission'] > 0){
$remark .= '-[分销佣金]'.$order_info['commission'].')';
}
}
//积分抵扣
if (in_array('point', $settlement_cost_array)) {
$point_money = $order_info[ 'point_money' ];
$base_money += $point_money;
if($order_info['point_money'] > 0){
$remark .= '+[积分抵扣]'.$order_info['point_money'];
}
}
//优惠券比较特殊, 不过不扣除要价格优惠券抵扣金额加回去
if (!in_array('coupon', $settlement_cost_array)) {
$coupon_money = $order_info[ 'coupon_money' ];
$base_money += $coupon_money;
if($order_info['coupon_money'] > 0){
$remark .= '+[优惠券券金额]'.$order_info['coupon_money'];
}
}
if ($base_money > 0) {
$store_commission_rate = $settlement_rate;
$store_commission = round($base_money * $settlement_rate_calc, 2);
$remark .= ')*'.$store_commission_rate.'%='.$store_commission;
$order_data = array (
'store_commission_rate' => $store_commission_rate,
'store_commission' => $store_commission
);
$order_condition = array (
[ 'order_id', '=', $order_id ]
);
model('order')->update($order_data, $order_condition);
$store_account_model = new StoreAccount();
//门店账户金额增加
$store_account_data = array (
'account_data' => $store_commission,
'site_id' => $site_id,
'store_id' => $store_id,
'from_type' => 'order',
'remark' => $remark,
'related_id' => $order_id
);
if($action == self::ACTION_EXECUTE){
//防止重复添加
$store_account_info = $store_account_model->getStoreAccountInfo([['from_type', '=', 'order'], ['related_id', '=', $order_id]])['data'];
if(empty($store_account_info)){
$store_account_model->addStoreAccount($store_account_data);
}
}else{
return $store_account_data;
}
}
}
}
}
}
}
}
/**
*
* @param $data
* @param $action
*/
public function orderRefundSettlementAccount($data, $action = self::ACTION_EXECUTE)
{
// $order_goods_id = $data[ 'order_goods_id' ];
$order_goods_info = $data['order_goods_info'];
if (empty($order_goods_info))
return null;
$order_goods_id = $order_goods_info['order_goods_id'];
// $order_id = $order_goods_info[ 'order_id' ];
$order_info = $data['order_info'];
if (empty($order_info))
return null;
$site_id = $order_info[ 'site_id' ];
$store_id = $order_info[ 'store_id' ];
$order_scene = $order_info[ 'order_scene' ];
//只有收银台订单会有这种情况
if ($store_id == 0 || $order_scene != 'cashier')
return null;
$refund_money = sprintf("%.2f", $data['refund_money']);
$order_money = $order_info[ 'order_money' ];
if($order_money <= 0)
return null;
if($refund_money <= 0){
return null;
}
$store_commission = $order_info[ 'store_commission' ];
$refund_store_commission = round($store_commission * ( $refund_money / $order_money ), 2);
$store_account_model = new StoreAccount();
//门店账户金额减少
$store_account_data = array (
'account_data' => -$refund_store_commission,
'site_id' => $site_id,
'store_id' => $store_id,
'from_type' => 'refund',
'remark' => "订单编号:{$order_info['order_no']};退款编号:{$order_goods_info['refund_no']};扣除结算佣金=[结算佣金]{$store_commission}*([退款金额]{$refund_money}/[订单金额]{$order_money})={$refund_store_commission}",
'related_id' => $order_goods_id,
'is_limit' => 0
);
if($action == self::ACTION_EXECUTE){
$store_account_model->addStoreAccount($store_account_data);
}else{
return $store_account_data;
}
}
/**
* 矫正任务
* @param array $param
* @return array
*/
public function correctStoreAccountTask($param = [])
{
$last_order_id = $param['last_order_id'] ?? 0;
$store_id = $param['store_id'] ?? 0;
$start_time = time();
$max_exec_time = 50;
$res_list = [];
$is_end = false;
while (true){
if(time() - $start_time > $max_exec_time){
break;
}
$order_info = model('order')->getFirstData([
['order_id', '>', $last_order_id],
['store_id', '=', $store_id],
]);
if(empty($order_info)){
$is_end = true;
break;
}
$res = $this->correctStoreAccount($order_info);
if(!empty($res)) $res_list[$order_info['order_id']] = $res;
$last_order_id = $order_info['order_id'];
}
$account = model('store_account')->getSum([['store_id', '=', $store_id]], 'account_data');
model('store')->update(['account' => $account], [['store_id', '=', $store_id]]);
return [
'res_list' => $res_list,
'last_order_id' => $last_order_id,
'is_end' => $is_end,
'account' => $account,
];
}
/**
* 矫正方法
* @param $order_info
* @return array
*/
public function correctStoreAccount($order_info)
{
$deal_res = [];
$store_account_model = new StoreAccount();
$from_type_list = $store_account_model->from_type;
//矫正退款总额
$order_goods_list = model('order_goods')->getList([
['order_id', '=', $order_info['order_id']],
]);
$refund_money = 0;
foreach($order_goods_list as $order_goods){
if(in_array($order_goods['refund_status'], [3,-3])){
$refund_money += $order_goods['refund_real_money'] + $order_goods['shop_active_refund_money'];
}
}
if($order_info['refund_money'] != $refund_money){
model('order')->update(['refund_money' => $refund_money], [['order_id', '=', $order_info['order_id']]]);
$deal_res[] = "矫正退款总额,{$order_info['refund_money']}=>$refund_money";
}
//清空数据
model('store_account')->delete([['from_type', '=', 'order'], ['related_id', '=', $order_info['order_id']]]);
if(!empty($order_goods_list)){
model('store_account')->delete([['from_type', '=', 'refund'], ['related_id', 'in', array_column($order_goods_list, 'order_goods_id')]]);
}
//重新计算
if($order_info['order_status'] == 10){
$store_account_data = $this->orderSettlementAccount(['order_id' => $order_info['order_id']], self::ACTION_RETURN_DATA);
if(!empty($store_account_data)){
$store_account_data['from_type_name'] = $from_type_list['order']['type_name'];
$store_account_data['create_time'] = time();
model('store_account')->add($store_account_data);
$deal_res[] = $store_account_data['remark'];
}
}
if(!empty($deal_res)){
Log::write('订单结算数据矫正:order_id=>'.$order_info['order_id']);
Log::write($deal_res);
}
return $deal_res;
}
public function findStoreAccountErrorDataTask($param)
{
$last_order_id = $param['last_order_id'] ?? 0;
$store_id = $param['store_id'] ?? 0;
$start_time = time();
$max_exec_time = 50;
$res_list = [];
$is_end = false;
while (true){
if(time() - $start_time > $max_exec_time){
break;
}
$order_info = model('order')->getFirstData([
['order_id', '>', $last_order_id],
['store_id', '=', $store_id],
]);
if(empty($order_info)){
$is_end = true;
break;
}
$res = $this->findStoreAccountErrorData($order_info);
if(!empty($res)) $res_list[$order_info['order_id']] = $res;
$last_order_id = $order_info['order_id'];
}
return [
'res_list' => $res_list,
'last_order_id' => $last_order_id,
'is_end' => $is_end,
];
}
public function findStoreAccountErrorData($order_info)
{
$deal_res = [];
//矫正退款总额
$order_goods_list = model('order_goods')->getList([
['order_id', '=', $order_info['order_id']],
]);
$refund_money = 0;
foreach($order_goods_list as $order_goods){
if(in_array($order_goods['refund_status'], [3,-3])){
$refund_money += $order_goods['refund_real_money'] + $order_goods['shop_active_refund_money'];
}
}
if($order_info['refund_money'] != $refund_money){
model('order')->update(['refund_money' => $refund_money], [['order_id', '=', $order_info['order_id']]]);
$deal_res[] = "矫正退款总额,{$order_info['refund_money']}=>$refund_money";
}
//比对数据库数据和计算数据
$order_goods_ids = join(',', array_column($order_goods_list, 'order_goods_id'));
if(empty($order_goods_ids)) $order_goods_ids = '0';
$store_account_list = model('store_account')->getList([
['', 'exp', \think\facade\Db::raw("(from_type = 'order' and related_id = {$order_info['order_id']}) or (from_type = 'refund' and related_id in ({$order_goods_ids}))")],
]);
$db_store_account = array_sum(array_column($store_account_list, 'account_data'));
if($order_info['order_status'] == 10){
$store_account_data = $this->orderSettlementAccount(['order_id' => $order_info['order_id']], self::ACTION_RETURN_DATA);
}
$calc_store_account = $store_account_data['account_data'] ?? 0;
if($db_store_account <> $calc_store_account){
$deal_res[] = [
"数据库记录:{$db_store_account},实时计算:{$calc_store_account}",
$store_account_list,
];
}
return $deal_res;
}
}