文件还在测试中
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
namespace App\Controllers\PSI;
|
||||
|
||||
use App\Controllers\Controller;
|
||||
use App\Models\PSI\Material;
|
||||
use App\Models\PSI\Product;
|
||||
use App\Models\PSI\Purchase;
|
||||
use App\Models\PSI\Sales;
|
||||
use App\Models\PSI\StockMove;
|
||||
|
||||
/** PSI 进销存入口与子路由。权限:super_admin 或 psi_role ∈ {admin,user} */
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function nav(string $seg): array
|
||||
{
|
||||
return \psi_nav();
|
||||
}
|
||||
|
||||
public function dispatch(array $s)
|
||||
{
|
||||
$res = $s[0] ?? 'dashboard';
|
||||
$action = $s[1] ?? '';
|
||||
$id = $s[2] ?? null;
|
||||
|
||||
// 仪表盘始终可进
|
||||
if ($res === 'dashboard') {
|
||||
return $this->dashboard();
|
||||
}
|
||||
|
||||
// 用户管理(仅该系统管理员):统一管理本系统用户及其页面权限
|
||||
if ($res === 'users') {
|
||||
if (!\subsys_admin('psi')) {
|
||||
\Core\App::forbidden('需要 PSI 管理员权限');
|
||||
return;
|
||||
}
|
||||
$uc = new \App\Controllers\PSI\UsersController();
|
||||
if ($action === '' || $action === 'index') return $uc->index();
|
||||
if ($action === 'create') return $uc->create();
|
||||
if ($action === 'store') return $uc->store();
|
||||
if ($action === 'edit') return $uc->edit($id);
|
||||
if ($action === 'update') return $uc->update($id);
|
||||
if ($action === 'destroy') return $uc->destroy($id);
|
||||
if ($action === 'reset') return $uc->reset($id);
|
||||
\Core\App::notFound('未知操作: ' . $action);
|
||||
return;
|
||||
}
|
||||
|
||||
// 订单管理:合并原「后台订单」到 PSI,方便管理人员在同一系统内快速处理
|
||||
if ($res === 'orders') {
|
||||
if (!\subsys_page_can('psi', 'orders')) {
|
||||
\Core\App::forbidden('您没有访问订单管理的权限');
|
||||
return;
|
||||
}
|
||||
$oc = new \App\Controllers\PSI\OrdersController();
|
||||
if ($action === '' || $action === 'index') return $oc->index();
|
||||
if ($action === 'show') return $oc->show($id);
|
||||
if ($action === 'markPaid') return $oc->markPaid($id);
|
||||
if ($action === 'destroy') return $oc->destroy($id);
|
||||
\Core\App::notFound('未知操作: ' . $action);
|
||||
return;
|
||||
}
|
||||
|
||||
// 销售订单:录入 / 打印 / 关联出库
|
||||
if ($res === 'sales_orders') {
|
||||
if (!\subsys_page_can('psi', 'sales_orders')) { \Core\App::forbidden('您没有访问销售订单的权限'); return; }
|
||||
$c = new \App\Controllers\PSI\SalesOrdersController();
|
||||
if ($action === '' || $action === 'index') return $c->index();
|
||||
if ($action === 'create') return $c->create();
|
||||
if ($action === 'store') return $c->store();
|
||||
if ($action === 'show') return $c->show($id);
|
||||
if ($action === 'edit') return $c->edit($id);
|
||||
if ($action === 'update') return $c->update($id);
|
||||
if ($action === 'destroy') return $c->destroy($id);
|
||||
if ($action === 'print') return $c->printDoc($id);
|
||||
\Core\App::notFound('未知操作: ' . $action); return;
|
||||
}
|
||||
|
||||
// 采购订单:录入 / 打印 / 收货入库
|
||||
if ($res === 'purchase_orders') {
|
||||
if (!\subsys_page_can('psi', 'purchase_orders')) { \Core\App::forbidden('您没有访问采购订单的权限'); return; }
|
||||
$c = new \App\Controllers\PSI\PurchaseOrdersController();
|
||||
if ($action === '' || $action === 'index') return $c->index();
|
||||
if ($action === 'create') return $c->create();
|
||||
if ($action === 'store') return $c->store();
|
||||
if ($action === 'show') return $c->show($id);
|
||||
if ($action === 'edit') return $c->edit($id);
|
||||
if ($action === 'update') return $c->update($id);
|
||||
if ($action === 'destroy') return $c->destroy($id);
|
||||
if ($action === 'receive') return $c->receive($id);
|
||||
if ($action === 'print') return $c->printDoc($id);
|
||||
\Core\App::notFound('未知操作: ' . $action); return;
|
||||
}
|
||||
|
||||
// 出库单:录入 / 打印(关联销售订单、扣减库存)
|
||||
if ($res === 'outbounds') {
|
||||
if (!\subsys_page_can('psi', 'outbounds')) { \Core\App::forbidden('您没有访问出库单的权限'); return; }
|
||||
$c = new \App\Controllers\PSI\OutboundsController();
|
||||
if ($action === '' || $action === 'index') return $c->index();
|
||||
if ($action === 'create') return $c->create();
|
||||
if ($action === 'store') return $c->store();
|
||||
if ($action === 'show') return $c->show($id);
|
||||
if ($action === 'edit') return $c->edit($id);
|
||||
if ($action === 'update') return $c->update($id);
|
||||
if ($action === 'destroy') return $c->destroy($id);
|
||||
if ($action === 'print') return $c->printDoc($id);
|
||||
\Core\App::notFound('未知操作: ' . $action); return;
|
||||
}
|
||||
|
||||
// 报表中心:采购订单明细 / 销售·采购订单明细 / 交付明细
|
||||
if ($res === 'reports') {
|
||||
if (!\subsys_page_can('psi', 'reports')) { \Core\App::forbidden('您没有访问报表中心的权限'); return; }
|
||||
$c = new \App\Controllers\PSI\ReportsController();
|
||||
if ($action === '' || $action === 'index') return $c->index();
|
||||
if ($action === 'poDetail') return $c->poDetail();
|
||||
if ($action === 'soPo') return $c->soPo();
|
||||
if ($action === 'delivery') return $c->delivery();
|
||||
\Core\App::notFound('未知操作: ' . $action); return;
|
||||
}
|
||||
|
||||
// 紧急提醒中心(所有 PSI 用户可见)
|
||||
if ($res === 'reminders') {
|
||||
$c = new \App\Controllers\PSI\RemindersController();
|
||||
return $c->handle(array_slice($s, 1));
|
||||
}
|
||||
|
||||
// 通知设置(仅 PSI 管理员,控制器内二次鉴权)
|
||||
if ($res === 'notifications') {
|
||||
$c = new \App\Controllers\PSI\NotificationsController();
|
||||
return $c->handle(array_slice($s, 1));
|
||||
}
|
||||
|
||||
// 销售出库(支持 show/print 查看与打印预览)
|
||||
if ($res === 'sales') {
|
||||
if (!\subsys_page_can('psi', 'sales')) { \Core\App::forbidden('您没有访问销售出库的权限'); return; }
|
||||
$c = new \App\Controllers\PSI\SalesController();
|
||||
if ($action === '' || $action === 'index') return $c->index();
|
||||
if ($action === 'create') return $c->create();
|
||||
if ($action === 'store') return $c->store();
|
||||
if ($action === 'show') return $c->show($id);
|
||||
if ($action === 'destroy') return $c->destroy($id);
|
||||
if ($action === 'print') return $c->printDoc($id);
|
||||
\Core\App::notFound('未知操作: ' . $action); return;
|
||||
}
|
||||
|
||||
$map = [
|
||||
'materials' => 'MaterialsController',
|
||||
'products' => 'ProductsController',
|
||||
'suppliers' => 'SuppliersController',
|
||||
'purchases' => 'PurchasesController',
|
||||
'stock' => 'StockController',
|
||||
];
|
||||
if (!isset($map[$res])) {
|
||||
\Core\App::notFound('未知页面: ' . $res);
|
||||
return;
|
||||
}
|
||||
// 页面级权限:按分系统「页面可见权限」拦截
|
||||
if (!\subsys_page_can('psi', $res)) {
|
||||
\Core\App::forbidden('您没有访问该页面的权限');
|
||||
return;
|
||||
}
|
||||
// 资源子操作路由:/PSI/{resource}[/{action}[/{id}]]
|
||||
// 支持 index/create/store/edit/update/destroy/adjust
|
||||
$method = $this->resolveSubsysAction($action);
|
||||
if ($method === null) {
|
||||
\Core\App::notFound('未知操作: ' . $action);
|
||||
return;
|
||||
}
|
||||
$class = 'App\\Controllers\\PSI\\' . $map[$res];
|
||||
$instance = new $class();
|
||||
if (!method_exists($instance, $method)) {
|
||||
\Core\App::notFound('操作不存在: ' . $method);
|
||||
return;
|
||||
}
|
||||
return $instance->$method($id);
|
||||
}
|
||||
|
||||
/** 将 URL 动作段解析为控制器方法名;不支持的动作返回 null */
|
||||
private function resolveSubsysAction(string $action): ?string
|
||||
{
|
||||
$verbs = [
|
||||
'' => 'index',
|
||||
'index' => 'index',
|
||||
'create' => 'create',
|
||||
'store' => 'store',
|
||||
'edit' => 'edit',
|
||||
'update' => 'update',
|
||||
'destroy' => 'destroy',
|
||||
'adjust' => 'adjust',
|
||||
];
|
||||
return $verbs[$action] ?? null;
|
||||
}
|
||||
|
||||
public function dashboard()
|
||||
{
|
||||
$materials = (new Material())->all();
|
||||
$products = (new Product())->all();
|
||||
$purchases = (new Purchase())->all();
|
||||
$sales = (new Sales())->all();
|
||||
|
||||
$matStock = array_sum(array_map(fn($m) => (float)($m['stock'] ?? 0), $materials));
|
||||
$prodStock = array_sum(array_map(fn($p) => (float)($p['stock'] ?? 0), $products));
|
||||
$purchaseAmt = array_sum(array_map(fn($p) => (float)($p['amount'] ?? 0), $purchases));
|
||||
$salesAmt = array_sum(array_map(fn($s) => (float)($s['amount'] ?? 0), $sales));
|
||||
$lowStock = [];
|
||||
foreach ($materials as $m) { if ((float)($m['stock'] ?? 0) < 20) $lowStock[] = ['type' => '物料', 'item' => $m]; }
|
||||
foreach ($products as $p) { if ((float)($p['stock'] ?? 0) < 20) $lowStock[] = ['type' => '成品', 'item' => $p]; }
|
||||
|
||||
$recentPurchases = array_slice(array_reverse($purchases), 0, 5);
|
||||
$recentSales = array_slice(array_reverse($sales), 0, 5);
|
||||
|
||||
// 订单/出库业务指标(表未创建时静默降级)
|
||||
$bySalesman = [];
|
||||
$salesAmount = 0; $salesAmountMonth = 0;
|
||||
$undelivered = ['count' => 0, 'amount' => 0];
|
||||
$monthDeliveries = ['count' => 0, 'amount' => 0];
|
||||
try {
|
||||
$bySalesman = \Core\Db::query(
|
||||
"SELECT o.salesman AS salesman, COUNT(DISTINCT o.id) AS orders,
|
||||
COALESCE(SUM(i.amount),0) AS amount
|
||||
FROM psi_sales_orders o
|
||||
LEFT JOIN psi_sales_order_items i ON i.so_id=o.id
|
||||
WHERE o.salesman <> '' AND o.status <> 'closed'
|
||||
GROUP BY o.salesman ORDER BY amount DESC"
|
||||
)->fetchAll();
|
||||
|
||||
$r = \Core\Db::query(
|
||||
"SELECT COALESCE(SUM(i.amount),0) AS amt,
|
||||
COALESCE(SUM(CASE WHEN MONTH(o.created_at)=MONTH(CURDATE()) AND YEAR(o.created_at)=YEAR(CURDATE()) THEN i.amount ELSE 0 END),0) AS amt_m
|
||||
FROM psi_sales_orders o LEFT JOIN psi_sales_order_items i ON i.so_id=o.id
|
||||
WHERE o.status <> 'closed'"
|
||||
)->fetch();
|
||||
$salesAmount = (float)($r['amt'] ?? 0);
|
||||
$salesAmountMonth = (float)($r['amt_m'] ?? 0);
|
||||
|
||||
$u = \Core\Db::query(
|
||||
"SELECT COUNT(*) AS c, COALESCE(SUM(i.amount),0) AS amt
|
||||
FROM psi_sales_orders o LEFT JOIN psi_sales_order_items i ON i.so_id=o.id
|
||||
WHERE o.status IN ('pending','partial')"
|
||||
)->fetch();
|
||||
$undelivered = ['count' => (int)($u['c'] ?? 0), 'amount' => (float)($u['amt'] ?? 0)];
|
||||
|
||||
$d = \Core\Db::query(
|
||||
"SELECT COUNT(*) AS c, COALESCE(SUM(i.amount),0) AS amt
|
||||
FROM psi_outbounds ob LEFT JOIN psi_outbound_items i ON i.ob_id=ob.id
|
||||
WHERE MONTH(ob.created_at)=MONTH(CURDATE()) AND YEAR(ob.created_at)=YEAR(CURDATE())"
|
||||
)->fetch();
|
||||
$monthDeliveries = ['count' => (int)($d['c'] ?? 0), 'amount' => (float)($d['amt'] ?? 0)];
|
||||
} catch (\Throwable $e) { /* 表未创建时不报错 */ }
|
||||
|
||||
return $this->renderSubsys('psi', 'psi/dashboard', [
|
||||
'materialTotal' => count($materials),
|
||||
'productTotal' => count($products),
|
||||
'matStock' => $matStock,
|
||||
'prodStock' => $prodStock,
|
||||
'purchaseAmt' => $purchaseAmt,
|
||||
'salesAmt' => $salesAmt,
|
||||
'lowStock' => $lowStock,
|
||||
'recentPurchases' => $recentPurchases,
|
||||
'recentSales' => $recentSales,
|
||||
'bySalesman' => $bySalesman,
|
||||
'salesAmount' => $salesAmount,
|
||||
'salesAmountMonth' => $salesAmountMonth,
|
||||
'undelivered' => $undelivered,
|
||||
'monthDeliveries' => $monthDeliveries,
|
||||
], $this->nav('dashboard'), 'dashboard');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user