feat: C2C商家交易系统后端 — API+后台管理
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class C2cMerchant extends Model
|
||||
{
|
||||
protected $table = 'c2c_merchant';
|
||||
protected $fillable = [
|
||||
'name','logo','available_qty','min_amount','max_amount','unit_price',
|
||||
'crypto_currency','fiat_currency','payment_methods','rating',
|
||||
'contact_type','contact_link','status','sort'
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class C2cMerchantOrder extends Model
|
||||
{
|
||||
protected $table = 'c2c_merchant_order';
|
||||
protected $fillable = [
|
||||
'order_no','user_id','merchant_id','direction','crypto_currency','fiat_currency',
|
||||
'amount','unit_price','total_price','fee','fee_rate','status',
|
||||
'contact_type','contact_link','expire_time'
|
||||
];
|
||||
|
||||
public function merchant() { return $this->belongsTo(C2cMerchant::class, 'merchant_id'); }
|
||||
public function user() { return $this->belongsTo(Users::class, 'user_id'); }
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Api\Controller;
|
||||
use App\C2cMerchant;
|
||||
use App\C2cMerchantOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Token;
|
||||
use App\Users;
|
||||
|
||||
class C2cMerchantController extends Controller
|
||||
{
|
||||
public function list(Request $request)
|
||||
{
|
||||
$query = C2cMerchant::where('status', 1);
|
||||
|
||||
$crypto = $request->input('crypto_currency');
|
||||
if ($crypto) $query->where('crypto_currency', $crypto);
|
||||
|
||||
$fiat = $request->input('fiat_currency');
|
||||
if ($fiat) $query->where('fiat_currency', $fiat);
|
||||
|
||||
$list = $query->orderBy('sort', 'desc')->orderBy('id', 'desc')->get();
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
public function createOrder(Request $request)
|
||||
{
|
||||
$user_id = Token::getUserIdByToken(Token::getToken());
|
||||
$user = \App\Users::find($user_id);
|
||||
if (!$user) return $this->error('Please login');
|
||||
|
||||
$merchant_id = intval($request->input('merchant_id'));
|
||||
$direction = $request->input('direction'); // buy / sell
|
||||
$amount = floatval($request->input('amount'));
|
||||
|
||||
if (!in_array($direction, ['buy', 'sell'])) return $this->error('Invalid direction');
|
||||
if ($amount <= 0) return $this->error('Invalid amount');
|
||||
|
||||
$merchant = C2cMerchant::find($merchant_id);
|
||||
if (!$merchant || $merchant->status != 1) return $this->error('Merchant not available');
|
||||
|
||||
if ($amount < $merchant->min_amount) return $this->error('Min: ' . $merchant->min_amount);
|
||||
if ($merchant->max_amount > 0 && $amount > $merchant->max_amount) return $this->error('Max: ' . $merchant->max_amount);
|
||||
if ($merchant->available_qty > 0 && $amount > $merchant->available_qty) return $this->error('Insufficient merchant stock');
|
||||
|
||||
$unit_price = floatval($merchant->unit_price);
|
||||
$total_price = round($amount * $unit_price, 6);
|
||||
$fee_rate = 0.002; // 0.2%
|
||||
$fee = round($total_price * $fee_rate, 6);
|
||||
|
||||
$order_no = date('YmdHis') . rand(1000, 9999);
|
||||
$expire_time = date('Y-m-d H:i:s', time() + 1800);
|
||||
|
||||
$order = C2cMerchantOrder::create([
|
||||
'order_no' => $order_no,
|
||||
'user_id' => $user->id,
|
||||
'merchant_id' => $merchant_id,
|
||||
'direction' => $direction,
|
||||
'crypto_currency' => $merchant->crypto_currency,
|
||||
'fiat_currency' => $merchant->fiat_currency,
|
||||
'amount' => $amount,
|
||||
'unit_price' => $unit_price,
|
||||
'total_price' => $total_price,
|
||||
'fee' => $fee,
|
||||
'fee_rate' => $fee_rate,
|
||||
'status' => 0,
|
||||
'contact_type' => $merchant->contact_type,
|
||||
'contact_link' => $merchant->contact_link,
|
||||
'expire_time' => $expire_time,
|
||||
]);
|
||||
|
||||
$order->merchant_name = $merchant->name;
|
||||
return $this->success($order);
|
||||
}
|
||||
|
||||
public function myOrders(Request $request)
|
||||
{
|
||||
$user_id = Token::getUserIdByToken(Token::getToken());
|
||||
$user = \App\Users::find($user_id);
|
||||
if (!$user) return $this->error('Please login');
|
||||
|
||||
$query = C2cMerchantOrder::where('user_id', $user->id)
|
||||
->with('merchant:id,name,logo');
|
||||
|
||||
$status = $request->input('status');
|
||||
if ($status !== null && $status !== '' && $status !== 'all') {
|
||||
$query->where('status', intval($status));
|
||||
}
|
||||
|
||||
$data = $query->orderBy('id', 'desc')->paginate(intval($request->input('limit', 20)));
|
||||
|
||||
$statusMap = [0 => 'Pending', 1 => 'Completed', 2 => 'Cancelled', 3 => 'Expired'];
|
||||
foreach ($data as $item) {
|
||||
$item->status_text = $statusMap[$item->status] ?? '';
|
||||
}
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
public function orderDetail(Request $request)
|
||||
{
|
||||
$user_id = Token::getUserIdByToken(Token::getToken());
|
||||
$user = \App\Users::find($user_id);
|
||||
if (!$user) return $this->error('Please login');
|
||||
|
||||
$id = intval($request->input('id'));
|
||||
$order = C2cMerchantOrder::with('merchant:id,name,logo,contact_type,contact_link')
|
||||
->where('id', $id)->where('user_id', $user->id)->first();
|
||||
if (!$order) return $this->error('Order not found');
|
||||
|
||||
$statusMap = [0 => 'Pending', 1 => 'Completed', 2 => 'Cancelled', 3 => 'Expired'];
|
||||
$order->status_text = $statusMap[$order->status] ?? '';
|
||||
return $this->success($order);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user