文件还在测试中
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\Order;
|
||||
use App\Models\Payment;
|
||||
use Core\Payment\GatewayFactory;
|
||||
use Core\Payment\OrderService;
|
||||
use Core\Notify;
|
||||
|
||||
/** 前台:下单 → 支付 → 查询 */
|
||||
class OrderController extends Controller
|
||||
{
|
||||
public function checkout($slug)
|
||||
{
|
||||
$product = (new Product())->where('slug', $slug);
|
||||
if (!$product) { \Core\App::notFound(); return ''; }
|
||||
$err = isset($_GET['err']) ? '请填写姓名与手机号' : '';
|
||||
return $this->view('order/checkout', ['p' => $product, 'slug' => $slug, 'err' => $err]);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { $this->redirect('products'); }
|
||||
if (!csrf_check()) { $this->redirect('products'); }
|
||||
$slug = $this->post('slug', '');
|
||||
$product = (new Product())->where('slug', $slug);
|
||||
if (!$product) { $this->redirect('products'); }
|
||||
$name = trim($this->post('name', ''));
|
||||
$phone = trim($this->post('phone', ''));
|
||||
$email = trim($this->post('email', ''));
|
||||
$qty = max(1, (int) $this->post('qty', 1));
|
||||
if ($name === '' || $phone === '') {
|
||||
$this->redirect('order/checkout/' . $slug . '?err=1');
|
||||
}
|
||||
$amount = round((float) $product['price'] * $qty, 2);
|
||||
$orderNo = $this->genNo();
|
||||
$oid = (new Order())->insert([
|
||||
'order_no' => $orderNo,
|
||||
'product_id' => $product['id'],
|
||||
'product_name' => $product['name'],
|
||||
'customer_name' => $name,
|
||||
'phone' => $phone,
|
||||
'email' => $email,
|
||||
'qty' => $qty,
|
||||
'amount' => $amount,
|
||||
'channel' => '',
|
||||
'status' => 'pending',
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
Notify::newCustomerOrder($orderNo, $name, $phone, $oid);
|
||||
$this->redirect('order/pay/' . $orderNo);
|
||||
}
|
||||
|
||||
public function pay($orderNo)
|
||||
{
|
||||
$order = (new Order())->where('order_no', $orderNo);
|
||||
if (!$order) { \Core\App::notFound(); return ''; }
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$channel = $this->post('channel', '');
|
||||
if ($channel === 'alipay' || $channel === 'wechat') {
|
||||
if ($order['channel'] !== $channel) {
|
||||
(new Order())->update($order['id'], ['channel' => $channel]);
|
||||
$order['channel'] = $channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($order['status'] === 'paid') {
|
||||
return $this->view('order/pay', ['order' => $order, 'paid' => true]);
|
||||
}
|
||||
if (empty($order['channel'])) {
|
||||
return $this->view('order/pay', ['order' => $order, 'choose' => true]);
|
||||
}
|
||||
$gw = GatewayFactory::make($order['channel']);
|
||||
$res = $gw->pay($order);
|
||||
return $this->view('order/pay', ['order' => $order, 'gw' => $res]);
|
||||
}
|
||||
|
||||
/** 演示支付:模拟支付成功(默认模式可用,便于走通全流程) */
|
||||
public function demo($orderNo)
|
||||
{
|
||||
$o = (new Order())->where('order_no', $orderNo);
|
||||
$channel = ($o && $o['channel'] === 'wechat') ? 'wechat' : 'alipay';
|
||||
OrderService::markPaid($orderNo, 'DEMO' . time(), $channel);
|
||||
$this->redirect('order/success/' . $orderNo);
|
||||
}
|
||||
|
||||
public function success($orderNo)
|
||||
{
|
||||
$order = (new Order())->where('order_no', $orderNo);
|
||||
if (!$order) { \Core\App::notFound(); return ''; }
|
||||
$payments = (new Payment())->whereAll('order_no', $orderNo);
|
||||
return $this->view('order/result', ['order' => $order, 'payments' => $payments]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户查询订单:客户名 + 手机号 双重校验
|
||||
* - 必填:客户名(下单时填写的姓名/单位)+ 手机号
|
||||
* - 选填:订单号(精确查单笔)
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$orders = []; $no = ''; $name = ''; $phone = ''; $err = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && csrf_check()) {
|
||||
$no = trim($this->post('order_no', ''));
|
||||
$name = trim($this->post('name', ''));
|
||||
$phone = trim($this->post('phone', ''));
|
||||
|
||||
if ($name === '' || $phone === '') {
|
||||
$err = '请输入客户名与手机号以核验身份';
|
||||
} else {
|
||||
$om = new Order();
|
||||
$pm = new Payment();
|
||||
$nameKey = mb_strtolower($name, 'UTF-8');
|
||||
// 客户名 + 手机号 同时匹配
|
||||
$matched = array_filter($om->all(), function ($o) use ($nameKey, $phone) {
|
||||
$oName = mb_strtolower(trim($o['customer_name'] ?? ''), 'UTF-8');
|
||||
$oPhone = trim($o['phone'] ?? '');
|
||||
return $oName === $nameKey && $oPhone === $phone;
|
||||
});
|
||||
|
||||
if ($no !== '') {
|
||||
$matched = array_values(array_filter($matched, fn($o) => ($o['order_no'] ?? '') === $no));
|
||||
}
|
||||
|
||||
if (empty($matched)) {
|
||||
$err = $no !== ''
|
||||
? '未找到该订单号对应的订单,请核对客户名与手机号'
|
||||
: '未找到匹配的客户名与手机号对应的订单';
|
||||
} else {
|
||||
$orders = array_map(function ($o) use ($pm) {
|
||||
return ['order' => $o, 'payments' => $pm->whereAll('order_no', $o['order_no'])];
|
||||
}, $matched);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->view('order/query', [
|
||||
'orders' => $orders,
|
||||
'no' => $no,
|
||||
'name' => $name,
|
||||
'phone' => $phone,
|
||||
'err' => $err,
|
||||
]);
|
||||
}
|
||||
|
||||
private function genNo(): string
|
||||
{
|
||||
return 'SQY' . date('YmdHis') . str_pad((int) ((microtime(true) * 1000) % 1000), 3, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user