feat: C2C商家交易系统后端 — API+后台管理

This commit is contained in:
testadmin
2026-04-28 14:35:00 +08:00
commit db5ed78ea9
5 changed files with 312 additions and 0 deletions
+13
View File
@@ -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'
];
}
+16
View File
@@ -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);
}
}