Merge pull request 'dev' (#441) from dev into main

Reviewed-on: https://gitea.lihaink.cn/mkm/multi-store/pulls/441
This commit is contained in:
mkm 2025-01-07 15:11:44 +08:00
commit b4bc60cf4c
16 changed files with 385 additions and 44 deletions

View File

@ -21,6 +21,7 @@ use app\common\model\store_product_unit\StoreProductUnit;
use app\common\model\system_store\SystemStore;
use app\common\model\warehouse_order\WarehouseOrder;
use app\common\model\warehouse_product\WarehouseProduct;
use app\common\service\RefundOrderService;
use app\common\service\xlsx\Beforehand;
use app\common\service\xlsx\OrderDetail;
use support\exception\BusinessException;
@ -124,17 +125,16 @@ class StoreOrderController extends BaseAdminController
* @return \support\Response
* @throws \Exception
*/
public function refund()
public function refund(RefundOrderService $refundOrderService)
{
$params = $this->request->post();
$detail = StoreOrder::where('order_id', $params['order_id'])->findOrEmpty();
if (empty($detail)) {
return $this->fail('无该订单请检查');
}
$res = StoreOrderLogic::refund($detail, $params);
if ($res == false) {
return $this->fail('退款失败');
}
$params['id'] = $detail['id'];
$params['old_cart_id'] = StoreOrderCartInfo::where('oid', $detail['id'])->column('id');
$refundOrderService->refund($detail['uid'], $params);
return $this->success('退款成功',[],1,1);
}

View File

@ -27,7 +27,7 @@ class ChangeLogLists extends BaseAdminDataLists implements ListsSearchInterface
{
return [
'=' => ['model', 'link_id', 'nums', 'pm'],
'%like%' => ['mark','url'],
'%like%' => ['mark', 'url'],
];
}
@ -45,13 +45,17 @@ class ChangeLogLists extends BaseAdminDataLists implements ListsSearchInterface
public function lists(): array
{
return ChangeLog::where($this->searchWhere)
->field(['id', 'admin_id','model', 'link_id', 'nums', 'pm', 'url', 'mark'])
->field(['id', 'admin_id', 'model', 'link_id', 'nums', 'pm', 'url', 'mark'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()->each(function ($item) {
if($item->admin_id){
$item->admin_name = Admin::where('id', $item->admin_id)->value('name');
}}
->select()->each(
function ($item) {
if ($item->admin_id) {
$item->admin_name = Admin::where('id', $item->admin_id)->value('name');
} else {
$item->admin_name = $item->admin_id;
}
}
)
->toArray();
}
@ -67,5 +71,4 @@ class ChangeLogLists extends BaseAdminDataLists implements ListsSearchInterface
{
return ChangeLog::where($this->searchWhere)->count();
}
}
}

View File

@ -81,10 +81,7 @@ class BeforehandOrderLists extends BaseAdminDataLists implements ListsSearchInte
$oid=WarehouseOrder::where('financial_pm',0)->where('code','like','%'.$order_ck)->column('id');
$this->searchWhere[] = ['outbound_id','in',$oid];
}
$file=['id','uid', 'order_id', 'order_sn','store_id', 'order_type', 'total_num', 'total_price', 'outbound_id', 'admin_id', 'create_time', 'status', 'mark', 'warehousing_id', 'file'];
if($export==2){
$file=['id','uid', 'order_id', 'order_sn','store_id', 'order_type', 'total_num', 'total_price', 'outbound_id', 'admin_id', 'create_time', 'status', 'mark', 'warehousing_id', 'file','other_data'];
}
$file=['id','uid', 'order_id', 'order_sn','store_id', 'order_type', 'total_num', 'total_price', 'outbound_id', 'admin_id', 'create_time', 'status', 'mark', 'warehousing_id', 'file','other_data'];
return BeforehandOrder::where($this->searchWhere)
->field($file)
->limit($this->limitOffset, $this->limitLength)

View File

@ -171,7 +171,7 @@ class PurchaseProductOfferLogic extends BaseLogic
'buyer_nums' => $params['buyer_nums'],
'supplier_id' => $params['supplier_id'],
'price' => $params['purchase'],
'outbound_price' => $params['outbound_price'] ?? 0,
'purchase_price' => $params['purchase_price'] ?? 0,
'total_price' => $params['total_price'],
'pay_type' => $params['pay_type'] ?? 0,
'buyer_confirm' => 1,

View File

@ -18,6 +18,7 @@ use app\common\model\system_store\SystemStoreStaff;
use app\common\model\user\User;
use app\common\model\user\UserAddress;
use app\common\service\Curl;
use app\common\service\RefundOrderService;
use Exception;
use support\Log;
use think\facade\Db;
@ -464,19 +465,11 @@ class OrderController extends BaseApiController
/**
* 订单退款申请
*/
public function apply_refund()
public function apply_refund(RefundOrderService $refundOrderService)
{
$params = (new OrderValidate())->post()->goCheck('add');
$uid = $this->userId;
//拆单逻辑
// $res = OrderLogic::dealRefund($uid, $params);
$detail = StoreOrder::where('id', $params['id'])->where('uid',$uid)->where('status','<>',2)->where('paid',1)->find();
if ($detail) {
$res = StoreOrderLogic::refund($detail, ['order_id' => $detail['order_id']]);
if ($res != false) {
return $this->success($res);
}
}
$refundOrderService->refund($uid, $params);
return $this->success('申请成功');
}

View File

@ -51,7 +51,7 @@ class OrderList extends BaseAdminDataLists implements ListsSearchInterface
->select()
->each(function ($item) {
$item['goods_list'] = StoreOrderCartInfo::where('oid', $item['id'])
->field('product_id,cart_num,verify_code,is_writeoff,writeoff_time,cart_info')->limit(3)->select()
->field('id,product_id,cart_num,verify_code,is_writeoff,writeoff_time,cart_info,status')->select()
->each(function ($v) use ($item) {
$v['store_name'] = '';
$v['image'] = '';

View File

@ -148,24 +148,16 @@ class StoreFinanceFlowLogic extends BaseLogic
{
$store = SystemStore::where('id', $store_id)->find();
$capitalFlowDao = new CapitalFlowLogic($store, 'store');
if ($money > 0) {
//判断是否是押金
if($store['paid_deposit']<$store['security_deposit']){
StoreFinanceFlow::where(['order_id' => $order_id, 'financial_type' => 11])->update(['status' => 1,'number'=>$money]);
StoreFinanceFlow::where(['order_id' => $order_id, 'financial_type' => 2])->update(['status' => 1,'number'=>0]);
$capitalFlowDao->storeIncome('store_paid_deposit_add', 'order', $order_id, $money,'','paid_deposit');
SystemStore::where('id', $store_id)->inc('paid_deposit', $money)->update();
}else{
$capitalFlowDao->storeIncome('store_money_add', 'order', $order_id, $money,'','store_money');
SystemStore::where('id', $store_id)->inc('store_money', $money)->update();
}
}
if ($deposit > 0) {
if ($deposit > 0 && $store['paid_deposit'] < $store['security_deposit']) {
StoreFinanceFlow::where(['order_id' => $order_id, 'financial_type' => 11])->update(['status' => 1]);
$capitalFlowDao->storeIncome('store_paid_deposit_add', 'order', $order_id, $deposit,'','paid_deposit');
SystemStore::where('id', $store_id)->inc('paid_deposit', $deposit)->update();
}
if ($money > 0) {
StoreFinanceFlow::where(['order_id' => $order_id, 'financial_type' => 2])->update(['status' => 1]);
$capitalFlowDao->storeIncome('store_money_add', 'order', $order_id, $money,'','store_money');
SystemStore::where('id', $store_id)->inc('store_money', $money)->update();
}
$find = StoreFinanceFlow::where(['order_id' => $order_id, 'financial_pm' => 1, 'financial_type' => 16, 'status' => 0])->find();
StoreFinanceFlow::where(['order_id' => $order_id, 'financial_type' => 16])->update(['status' => 1]);
if ($find) {

View File

@ -126,4 +126,13 @@ class StoreOrder extends BaseModel
Log::error('store_order:更新后' . $e->getMessage());
}
}
public function allowRefund(): bool
{
if (in_array($this->status, [0, 1, 2])) {
return true;
}
return false;
}
}

View File

@ -20,7 +20,8 @@ class StoreProduct extends BaseModel
use SoftDelete;
protected $name = 'store_product';
protected $deleteTime = 'delete_time';
// 不生成该表的日志
public $doNotRecordLog = true;
public function unitName()
{

View File

@ -0,0 +1,194 @@
<?php
namespace app\common\service;
use app\common\enum\OrderEnum;
use app\common\logic\CapitalFlowLogic;
use app\common\logic\CommissionnLogic;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_finance_flow\StoreFinanceFlow;
use app\common\model\store_finance_flow_product\StoreFinanceFlowProduct;
use app\common\model\store_order\StoreOrder;
use app\common\model\store_order_cart_info\StoreOrderCartInfo;
use app\common\model\system_store\SystemStore;
use app\common\model\user\User;
use app\common\service\pay\PayTool;
use Exception;
use support\exception\BusinessException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
class RefundOrderService
{
public function refund($userId, $params): void
{
Db::startTrans();
try {
$order = StoreOrder::where('id', $params['id'])->where('uid', $userId)->find();
if (empty($order)) {
throw new BusinessException('订单不存在');
}
if (!$order->allowRefund()) {
throw new BusinessException('订单不能退款');
}
$orderCartProducts = StoreOrderCartInfo::where('oid', $order['id'])->whereIn('id', $params['old_cart_id'])->select();
if ($order->status == 2 && $order->is_writeoff == 1) {
$this->refundStoreMoney($order);
$this->refundCommission($order);
}
$refundAmount = $this->calculate($orderCartProducts);
$this->refundMoney($order, $refundAmount);
$this->updateProductStock($orderCartProducts);
$this->updateOrderProductStatus($order, $params['old_cart_id']);
$this->updateOrderStatus($order, $refundAmount, count($params['old_cart_id']));
$this->resetStoreFinanceFlow($order, $orderCartProducts);
Db::commit();
} catch (Exception $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* 计算退款金额
* @param $orderCartProducts
* @return string
*/
public function calculate($orderCartProducts): string
{
$amount = '0.00';
foreach ($orderCartProducts as $orderCartProduct) {
$amount = bcadd($amount, $orderCartProduct['total_price'], 2);
}
return $amount;
}
/**
* 资金原路退回
* @param $order
* @param $refundAmount
* @return void
*/
public function refundMoney($order, $refundAmount): void
{
$payTool = PayTool::getInstance($order['pay_type']);
$payTool->refund($refundAmount, $order);
}
/**
* 更新商品库存
* @param $orderCartProducts
* @throws Exception
*/
public function updateProductStock($orderCartProducts): void
{
$updateData = [];
foreach ($orderCartProducts as $product) {
$storeBranchProductId = StoreBranchProduct::where('store_id', $product['store_id'])
->where('product_id', $product['product_id'])
->withTrashed()->value('id');
if ($storeBranchProductId) {
$updateData[] = [
'id' => $storeBranchProductId,
'stock' => ['inc', $product['cart_num']],
'sales' => ['dec', $product['cart_num']],
];
}
}
(new StoreBranchProduct())->saveAll($updateData);
}
/**
* 更新订单商品状态
* @param $order
* @param $orderCartIds
* @return void
* @throws DbException
*/
public function updateOrderProductStatus($order, $orderCartIds): void
{
StoreOrderCartInfo::whereIn('id', $orderCartIds)->where('oid', $order['id'])->update(['is_pay' => -1, 'status' => OrderEnum::REFUND_STATUS_FINISH]);
}
/**
* 更新订单状态
* @param $order
* @param $refundAmount
* @param $refundNum
* @return void
* @throws DbException
*/
public function updateOrderStatus($order, $refundAmount, $refundNum): void
{
$orderProductCount = StoreOrderCartInfo::where('oid', $order['id'])->count();
if (($order['refund_num'] + $refundNum) == $orderProductCount) {
// 全部退款完成,订单状态改为已退款
$order->refund_status = OrderEnum::REFUND_STATUS_FINISH;
$order->status = OrderEnum::RECEIVED_BACK;
}
$order->refund_price = bcadd($order['refund_price'], $refundAmount, 2);
$order->refund_num += $refundNum;
$order->save();
}
/**
* 退佣金
* @param $order
* @param $storeOrderProducts
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function resetStoreFinanceFlow($order, $storeOrderProducts): void
{
$productIds = array_unique(array_column($storeOrderProducts->toArray(), 'product_id'));
StoreFinanceFlowProduct::where('oid', $order['id'])->whereIn('product_id', $productIds)->update(['number' => 0, 'update_time' => strtotime(time())]);
$village_uid = StoreFinanceFlow::where('order_id', $order['id'])->where('financial_type', 14)->value('other_uid');
$brigade_uid = StoreFinanceFlow::where('order_id', $order['id'])->where('financial_type', 15)->value('other_uid');
$transaction_id = StoreFinanceFlow::where('order_id', $order['id'])->value('transaction_id');
StoreFinanceFlow::where('order_id', $order['id'])->update(['delete_time' => time()]);
CommissionnLogic::setStore($order, $village_uid, $brigade_uid, $transaction_id);
}
/**
* 扣除店铺余额和押金
* @param $order
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function refundStoreMoney($order): void
{
$margin = StoreFinanceFlow::where('order_id', $order['id'])->where('financial_type', OrderEnum::ORDER_MARGIN)->value('number');
$income = StoreFinanceFlow::where('order_id', $order['id'])->where('financial_type', OrderEnum::MERCHANT_ORDER_OBTAINS)->value('number');
if (empty($margin) && empty($income)) {
return;
}
$store = SystemStore::where('id', $order['store_id'])->find();
if ($margin > 0) {
$store->paid_deposit = bcsub($store->paid_deposit, $margin, 2);
}
if ($income > 0) {
$store->store_money = bcsub($store->store_money, $income, 2);
}
$store->save();
}
public function refundCommission($order)
{
$list = StoreFinanceFlow::where(['order_id' => $order['id'], 'financial_pm' => 1, 'status' => 0])->where('other_uid', '>', 0)->select();
foreach ($list as $v) {
$v->save(['status' => 1]);
$find = User::where('id', $v['other_uid'])->find();
$capitalFlowDao = new CapitalFlowLogic($find);
$capitalFlowDao->userExpense('system_balance_sub', 'order', $order['id'], $v['number']);
$find->dec('now_money', $v['number'])->update();
}
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace app\common\service\pay;
use app\common\logic\CapitalFlowLogic;
use app\common\model\user\User;
/**
* 余额支付
* Class BalancePay
* @package app\common\service\pay
*/
class BalancePay extends PayTool
{
public function refund($amount, $order)
{
$user = User::where('id', $order['uid'])->findOrEmpty();
$capitalFlowDao = new CapitalFlowLogic($user);
$capitalFlowDao->userIncome('now_money_refund', 'system_back', $order['id'], $amount);
$user->now_money = bcadd($user['now_money'], $amount, 2);
$user->save();
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace app\common\service\pay;
use app\common\enum\OrderEnum;
use app\common\enum\YesNoEnum;
use app\common\model\store_cash_finance_flow\StoreCashFinanceFlow;
/**
* 现金支付
* Class CashPay
* @package app\common\service\pay
*/
class CashPay extends PayTool
{
public function refund($amount, $order)
{
$model = new StoreCashFinanceFlow();
$model->store_id = $order['store_id'] ?? 0;
$model->cash_price = $order->pay_price;
$model->receivable = $order->pay_price;
$model->remark = '退款';
$model->type = 1;
$model->status = YesNoEnum::YES;
$model->save();
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace app\common\service\pay;
use app\common\enum\PayEnum;
/**
* 支付
* Class PayTool
* @package app\common\service\pay
*/
abstract class PayTool
{
/**
* @param int $type
* @param $params
* @return BalancePay|CashPay|PurchaseFundPay|WeChatPay
*/
public static function getInstance(int $type, $params = [])
{
return match ($type) {
PayEnum::WECHAT_PAY, PayEnum::WECHAT_PAY_BARCODE, PayEnum::WECHAT_PAY_MINI => new WeChatPay($params),
PayEnum::BALANCE_PAY => new BalancePay($params),
PayEnum::PURCHASE_FUNDS => new PurchaseFundPay($params),
default => new CashPay(),
};
}
abstract function refund($amount, $order);
}

View File

@ -0,0 +1,25 @@
<?php
namespace app\common\service\pay;
use app\common\logic\CapitalFlowLogic;
use app\common\model\user\User;
/**
* 采购款支付
* Class PurchaseFundPay
* @package app\common\service\pay
*/
class PurchaseFundPay extends PayTool
{
public function refund($amount, $order)
{
$user = User::where('id', $order['uid'])->findOrEmpty();
$capitalFlowDao = new CapitalFlowLogic($user);
$capitalFlowDao->userIncome('purchase_refund', 'system_back', $order['id'], $amount, '', 1);
$user->purchase_funds = bcadd($user['purchase_funds'], $amount, 2);
$user->save();
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace app\common\service\pay;
use support\exception\BusinessException;
/**
* 微信支付
* Class WeChatPay
* @package app\common\service\pay
*/
class WeChatPay extends PayTool
{
public function refund($amount, $order)
{
$totalFee = (int)bcmul($amount, 100);
try {
$wechat = new PayService(1);
$order = [
'out_trade_no' => $order['order_id'],
'out_refund_no' => 'BO' . time(),
'amount' => [
'refund' => $totalFee,
'total' => $order['pay_price'],
'currency' => 'CNY',
],
];
$res = $wechat->wechat->refund($order);
if ($res['status'] == 'PROCESSING') {
return true;
}
return false;
} catch (\Exception $e) {
\support\Log::info($e->extra['message'] ?? $e->getMessage());
throw new BusinessException($e->extra['message'] ?? $e->getMessage());
}
}
}

View File

@ -77,6 +77,7 @@ class BeforehandOrderController extends BaseAdminController
'transporter' => $params['transporter'] ?? '',
'system_store_name' => $params['system_store_name'] ?? '',
'regional_manager' => $params['regional_manager'] ?? '',
'store_mark' => $params['store_mark'] ?? '',
];
$params['other_data'] = $other_data;
$result = BeforehandOrderLogic::add($params);