初始化
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* 批量删除测试数据
|
||||
*/
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo htmlspecialchars($title); ?> - MES系统</title>
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/admin.css">
|
||||
</head>
|
||||
<body>
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_header.php'; ?>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1><i class="fa fa-trash"></i> <?php echo htmlspecialchars($title); ?></h1>
|
||||
</section>
|
||||
|
||||
<section class="content">
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success"><?php echo htmlspecialchars($success); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 按设备删除 -->
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><i class="fa fa-laptop"></i> 按设备编码删除</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<form method="post" action="" class="confirm-form" data-confirm="确定删除该设备的所有测试数据?此操作不可恢复!">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="by_device">
|
||||
<div class="form-group">
|
||||
<label>设备编码</label>
|
||||
<select name="device_code" class="form-control">
|
||||
<option value="">请选择设备</option>
|
||||
<?php foreach ($devices as $dev): ?>
|
||||
<option value="<?php echo htmlspecialchars($dev['device_code']); ?>">
|
||||
<?php echo htmlspecialchars($dev['device_code'] . ' - ' . ($dev['device_name'] ?? '')); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fa fa-trash"></i> 按设备删除
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 按ID批量删除 -->
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><i class="fa fa-list-ol"></i> 按记录ID批量删除</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<form method="post" action="" class="confirm-form" data-confirm="确定删除这些记录?此操作不可恢复!">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="by_ids">
|
||||
<div class="form-group">
|
||||
<label>记录ID列表(多个ID用逗号分隔,如:1,2,3)</label>
|
||||
<input type="text" name="ids" class="form-control" placeholder="例如:1,2,3">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fa fa-trash"></i> 按ID删除
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 清空全部 -->
|
||||
<div class="box box-danger">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><i class="fa fa-exclamation-triangle"></i> 危险操作</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<form method="post" action="" class="confirm-form" data-confirm="确定清空全部测试数据?此操作不可恢复!请确认您已备份数据。">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="clear_all">
|
||||
<button type="submit" class="btn btn-danger btn-lg">
|
||||
<i class="fa fa-bomb"></i> 清空全部测试数据
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdTestData" class="btn btn-default">
|
||||
<i class="fa fa-arrow-left"></i> 返回测试数据列表
|
||||
</a>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
$activeMenu = 'asdDeviceDebug';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plug"></i> 昂盛达设备调试</h3>
|
||||
<div class="box-tools">
|
||||
<span class="badge bg-blue">共 <?php echo count($devices ?? []); ?> 台设备</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/asdDeviceDebug" class="form-inline">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="form-group" style="margin-right:8px;">
|
||||
<label class="sr-only">查找设备</label>
|
||||
<input type="text" name="keyword" class="form-control" style="width:260px;"
|
||||
placeholder="按名称 / IP / 编号查找" value="<?php echo htmlspecialchars($keyword ?? ''); ?>">
|
||||
</div>
|
||||
<button type="submit" name="action" value="search" class="btn btn-default">
|
||||
<i class="fa fa-search"></i> 查找设备
|
||||
</button>
|
||||
<span class="text-muted" style="margin-left:10px;">共 <?php echo count($devices ?? []); ?> 台</span>
|
||||
</form>
|
||||
<hr>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/asdDeviceDebug">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="form-group">
|
||||
<label>选择设备</label>
|
||||
<select name="device_id" class="form-control" style="max-width:480px;">
|
||||
<option value="0">— 请选择设备 —</option>
|
||||
<?php foreach ($devices ?? [] as $dev): ?>
|
||||
<option value="<?php echo intval($dev['id']); ?>" <?php echo (isset($selDeviceId) && $selDeviceId == $dev['id']) ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($dev['device_name'] ?? '设备' . $dev['id']); ?>
|
||||
(<?php echo htmlspecialchars($dev['device_ip'] ?? '无IP'); ?>:<?php echo intval($dev['device_port'] ?? 502); ?>)
|
||||
- <?php echo ($dev['status'] == 1) ? '启用' : '禁用'; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="btn-group" style="margin-left:8px;">
|
||||
<button type="submit" name="action" value="testLink" class="btn btn-info">
|
||||
<i class="fa fa-wifi"></i> 测试链接状态
|
||||
</button>
|
||||
<button type="submit" name="action" value="readData" class="btn btn-success">
|
||||
<i class="fa fa-download"></i> 数据读取
|
||||
</button>
|
||||
<button type="submit" name="action" value="writeData" class="btn btn-warning">
|
||||
<i class="fa fa-upload"></i> 数据写入(探针)
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="well" style="margin-bottom:0;">
|
||||
<h4><i class="fa fa-plug"></i> 手动连接(IP:端口)</h4>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/asdDeviceDebug" class="form-inline">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="form-group" style="margin-right:6px;">
|
||||
<input type="text" name="manual_ip" class="form-control" style="width:160px;"
|
||||
placeholder="设备 IP,如 192.168.1.10" value="<?php echo htmlspecialchars($_POST['manual_ip'] ?? ''); ?>">
|
||||
</div>
|
||||
<div class="form-group" style="margin-right:6px;">
|
||||
<input type="number" name="manual_port" class="form-control" style="width:90px;"
|
||||
placeholder="端口" value="<?php echo htmlspecialchars($_POST['manual_port'] ?? '502'); ?>">
|
||||
</div>
|
||||
<button type="submit" name="action" value="manualConnect" class="btn btn-primary">
|
||||
<i class="fa fa-wifi"></i> 测试连接
|
||||
</button>
|
||||
</form>
|
||||
<p class="text-muted" style="margin-top:8px;margin-bottom:0;">不依赖数据库记录,直接对任意 IP:端口做 TCP 连通测试。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($result)): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-terminal"></i>
|
||||
<?php
|
||||
$titles = [
|
||||
'testLink' => '链接状态测试结果',
|
||||
'readData' => '数据读取结果',
|
||||
'writeData' => '数据写入(探针)结果',
|
||||
'manualConnect' => '手动连接测试结果',
|
||||
];
|
||||
echo htmlspecialchars($titles[$result['action']] ?? '测试结果');
|
||||
?>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
|
||||
<?php if (!empty($result['error'])): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fa fa-times-circle"></i> <?php echo htmlspecialchars($result['error']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($result['action'] === 'testLink'): ?>
|
||||
<table class="table table-bordered" style="max-width:600px;">
|
||||
<tr><th style="width:160px;">设备</th><td><?php echo htmlspecialchars(($result['device']['device_code'] ?? '') . ' / ' . ($result['device']['device_name'] ?? '')); ?></td></tr>
|
||||
<tr><th>目标地址</th><td><?php echo htmlspecialchars($result['ip']); ?> : <?php echo intval($result['port']); ?></td></tr>
|
||||
<tr><th>连接结果</th>
|
||||
<td>
|
||||
<?php if ($result['reachable']): ?>
|
||||
<span class="label label-success"><i class="fa fa-check"></i> 可达</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger"><i class="fa fa-times"></i> 不可达</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>延迟</th><td><?php echo $result['latency']; ?> ms</td></tr>
|
||||
<?php if ($result['error']): ?>
|
||||
<tr><th>错误信息</th><td class="text-danger"><?php echo htmlspecialchars($result['error']); ?></td></tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($result['action'] === 'readData'): ?>
|
||||
<p>
|
||||
设备编号:<code><?php echo htmlspecialchars($result['device_code']); ?></code>
|
||||
| 测试记录总数:<b><?php echo intval($result['counts']['rec_cnt'] ?? 0); ?></b>
|
||||
| 测试数据总数:<b><?php echo intval($result['counts']['data_cnt'] ?? 0); ?></b>
|
||||
| 设备总数:<b><?php echo intval($result['counts']['dev_cnt'] ?? 0); ?></b>
|
||||
</p>
|
||||
<p class="text-muted">最近 10 条该设备的测试记录(device_code 匹配):</p>
|
||||
<?php if (empty($result['rows'])): ?>
|
||||
<div class="alert alert-info">该设备暂无测试记录。</div>
|
||||
<?php else: ?>
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr><th>ID</th><th>二维码/条码</th><th>产品型号</th><th>测试结果</th><th>测试时间</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($result['rows'] as $r): ?>
|
||||
<tr>
|
||||
<td><?php echo intval($r['id']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['qr_code'] ?? ''); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['product_model'] ?? ''); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['test_result'] ?? ''); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['test_date'] ?? ''); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($result['action'] === 'manualConnect'): ?>
|
||||
<table class="table table-bordered" style="max-width:600px;">
|
||||
<tr><th style="width:160px;">目标</th><td><?php echo htmlspecialchars($result['device']['device_name'] ?? ''); ?></td></tr>
|
||||
<tr><th>地址</th><td><?php echo htmlspecialchars($result['ip']); ?> : <?php echo intval($result['port']); ?></td></tr>
|
||||
<tr><th>连接结果</th>
|
||||
<td>
|
||||
<?php if ($result['reachable']): ?>
|
||||
<span class="label label-success"><i class="fa fa-check"></i> 可达</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger"><i class="fa fa-times"></i> 不可达</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>延迟</th><td><?php echo $result['latency']; ?> ms</td></tr>
|
||||
<?php if ($result['error']): ?>
|
||||
<tr><th>错误信息</th><td class="text-danger"><?php echo htmlspecialchars($result['error']); ?></td></tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($result['action'] === 'writeData'): ?>
|
||||
<?php if (empty($result['error'])): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fa fa-check-circle"></i> 数据读写链路正常(探针已写入并回读、清理)
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<table class="table table-bordered" style="max-width:700px;">
|
||||
<tr><th style="width:180px;">设备编号</th><td><?php echo htmlspecialchars($result['device_code']); ?></td></tr>
|
||||
<tr><th>探针二维码</th><td><code><?php echo htmlspecialchars($result['probe_code']); ?></code></td></tr>
|
||||
<tr><th>写入 ID</th><td><?php echo intval($result['written_id']); ?></td></tr>
|
||||
<tr><th>回读一致</th>
|
||||
<td>
|
||||
<?php if ($result['read_back_match']): ?>
|
||||
<span class="label label-success">一致</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger">不一致</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th>探针记录已清理</th>
|
||||
<td>
|
||||
<?php if ($result['deleted']): ?>
|
||||
<span class="label label-success">已删除</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-warning">未删除(请检查)</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ($result['error']): ?>
|
||||
<tr><th>错误信息</th><td class="text-danger"><?php echo htmlspecialchars($result['error']); ?></td></tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
$activeMenu = 'asdTestData';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-flask"></i> 测试数据管理</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdTestDataImport" class="btn btn-success btn-sm">
|
||||
<i class="fa fa-plus"></i> 导入测试数据
|
||||
</a>
|
||||
<span class="badge bg-blue" style="margin-left:10px;">共 <?php echo $totalCount; ?> 条记录</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-header">
|
||||
<form method="get" action="<?php echo BASE_URL; ?>/Admin/asdTestData" class="form-inline">
|
||||
<div class="input-group input-group-sm" style="width:300px;">
|
||||
<input type="text" name="keyword" class="form-control" placeholder="输入条码搜索..." value="<?php echo htmlspecialchars($keyword ?? ''); ?>">
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i> 搜索</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>条码</th>
|
||||
<th>项目名称</th>
|
||||
<th>测试员</th>
|
||||
<th>工位</th>
|
||||
<th>设备</th>
|
||||
<th>状态</th>
|
||||
<th>工步数</th>
|
||||
<th>失败数</th>
|
||||
<th>测试时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($records)): ?>
|
||||
<tr><td colspan="11" class="text-center text-muted">暂无测试数据</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($records as $r): ?>
|
||||
<tr>
|
||||
<td><?php echo $r['id']; ?></td>
|
||||
<td><code><?php echo htmlspecialchars($r['qr_code']); ?></code></td>
|
||||
<td><?php echo htmlspecialchars($r['project_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['tester']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['site']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['device']); ?></td>
|
||||
<td>
|
||||
<?php if ($r['status'] === 'PASS'): ?>
|
||||
<span class="label label-success">PASS</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger"><?php echo htmlspecialchars($r['status']); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><span class="badge bg-light-blue"><?php echo $r['step_count']; ?></span></td>
|
||||
<td>
|
||||
<?php if ($r['fail_count'] > 0): ?>
|
||||
<span class="badge bg-red"><?php echo $r['fail_count']; ?></span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">0</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo $r['test_time'] ?? '-'; ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdTestDataView/<?php echo $r['id']; ?>" class="btn btn-xs btn-info" title="查看详情">
|
||||
<i class="fa fa-eye"></i>
|
||||
</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/asdTestDataDelete/<?php echo $r['id']; ?>" style="display:inline;" onsubmit="return confirm('确定删除该测试记录及所有工步数据吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger" title="删除"><i class="fa fa-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,805 @@
|
||||
<?php
|
||||
$activeMenu = 'asdTestData';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<style>
|
||||
/* 设备连接操作区样式 */
|
||||
.device-card { border: 1px solid #d2d6de; border-radius: 4px; padding: 15px; margin-bottom: 15px; background: #f9f9f9; }
|
||||
.device-card .device-info { margin-bottom: 10px; }
|
||||
.device-card .device-info .info-row { display: flex; flex-wrap: wrap; gap: 15px; align-items: center; margin-bottom: 8px; }
|
||||
.device-card .device-info .info-label { font-weight: 600; color: #555; min-width: 70px; }
|
||||
.device-card .device-info .info-value { color: #333; }
|
||||
.status-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 4px; }
|
||||
.status-dot.online { background: #00a65a; }
|
||||
.status-dot.offline { background: #dd4b39; }
|
||||
.status-dot.unknown { background: #999; }
|
||||
.device-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
|
||||
#scanInput { font-size: 16px; letter-spacing: 1px; }
|
||||
.btn-connect { min-width: 100px; }
|
||||
.console-log { background: #1e1e1e; color: #d4d4d4; font-family: Consolas, monospace; font-size: 13px; padding: 12px; border-radius: 4px; max-height: 350px; overflow-y: auto; line-height: 1.6; }
|
||||
.console-log .log-line { margin: 2px 0; }
|
||||
.console-log .log-success { color: #4ec9b0; }
|
||||
.console-log .log-error { color: #f44747; }
|
||||
.console-log .log-warn { color: #e6a23c; }
|
||||
.console-log .log-info { color: #9cdcfe; }
|
||||
.console-log .log-time { color: #808080; }
|
||||
.batch-result-table { max-height: 400px; overflow-y: auto; margin-top: 10px; }
|
||||
.batch-result-table table { font-size: 12px; }
|
||||
.device-batch-item { border: 1px solid #e0e0e0; border-radius: 4px; margin-bottom: 10px; }
|
||||
.device-batch-item .panel-heading { background: #f5f5f5; padding: 8px 12px; cursor: pointer; }
|
||||
.device-batch-item .panel-body { display: none; padding: 10px; }
|
||||
.device-batch-item .panel-body.open { display: block; }
|
||||
</style>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-upload"></i> 导入测试数据</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdTestData" class="btn btn-default btn-sm">
|
||||
<i class="fa fa-arrow-left"></i> 返回列表
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (isset($success)): ?>
|
||||
<div class="alert alert-success alert-dismissible" style="margin:10px;">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<i class="fa fa-check-circle"></i> <?php echo h($success); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible" style="margin:10px;">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<i class="fa fa-exclamation-circle"></i> <?php echo h($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Tab 切换 -->
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="<?php echo (empty($activeTab) || $activeTab === 'form') ? 'active' : ''; ?>"><a href="#tab-form" data-toggle="tab"><i class="fa fa-edit"></i> 表单导入</a></li>
|
||||
<li class="<?php echo (isset($activeTab) && $activeTab === 'json') ? 'active' : ''; ?>"><a href="#tab-json" data-toggle="tab"><i class="fa fa-code"></i> JSON 导入</a></li>
|
||||
<li class="<?php echo (isset($activeTab) && $activeTab === 'device') ? 'active' : ''; ?>"><a href="#tab-device" data-toggle="tab"><i class="fa fa-plug"></i> 设备连接与批量操作</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
|
||||
<!-- ==================== 表单导入 ==================== -->
|
||||
<div class="tab-pane <?php echo (empty($activeTab) || $activeTab === 'form') ? 'active' : ''; ?>" id="tab-form" style="display:<?php echo (empty($activeTab) || $activeTab === 'form') ? 'block' : 'none'; ?>;">
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/asdTestDataImport">
|
||||
<div class="box-body">
|
||||
<legend>基本信息</legend>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>条码/二维码 <span class="text-red">*</span></label>
|
||||
<input type="text" name="qr_code" class="form-control" placeholder="SN6977187913642" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>项目名称</label>
|
||||
<input type="text" name="project_name" class="form-control" placeholder="充电器测试">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>工位</label>
|
||||
<select name="site" class="form-control">
|
||||
<option value="">-- 选择工位 --</option>
|
||||
<?php foreach ($stations as $st): ?>
|
||||
<option value="<?php echo htmlspecialchars($st['station_name']); ?>"><?php echo htmlspecialchars($st['station_name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>站点</label>
|
||||
<input type="text" name="station" class="form-control" placeholder="A区-1线">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>单号</label>
|
||||
<input type="text" name="mo" class="form-control" placeholder="MO20240525001">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>工单</label>
|
||||
<input type="text" name="work_order" class="form-control" placeholder="WO-20240525-01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>组别</label>
|
||||
<input type="text" name="group_name" class="form-control" placeholder="A组">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>设备号</label>
|
||||
<input type="text" name="device" class="form-control" placeholder="ASD-989A-001">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>运行时间</label>
|
||||
<input type="text" name="running_time" class="form-control" placeholder="28S">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<legend>测试工步数据</legend>
|
||||
<div id="stepContainer">
|
||||
<?php
|
||||
$defaultSteps = [
|
||||
['name' => '输出测试', 'item' => '电压', 'units' => 'V', 'value' => '5.12', 'lower' => '4.75', 'upper' => '5.25'],
|
||||
['name' => '输出测试', 'item' => '电流', 'units' => 'A', 'value' => '2.10', 'lower' => '1.90', 'upper' => '2.20'],
|
||||
['name' => '空载功耗', 'item' => '功率', 'units' => 'W', 'value' => '0.08', 'lower' => '0', 'upper' => '0.3'],
|
||||
['name' => '效率测试', 'item' => '效率', 'units' => '%', 'value' => '88.5', 'lower' => '85', 'upper' => '95'],
|
||||
];
|
||||
foreach ($defaultSteps as $idx => $ds):
|
||||
?>
|
||||
<div class="row step-row" style="margin-bottom:8px;">
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="step_name[]" class="form-control input-sm" placeholder="工步名称" value="<?php echo $ds['name']; ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="step_item[]" class="form-control input-sm" placeholder="测试项目" value="<?php echo $ds['item']; ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="step_value[]" class="form-control input-sm" placeholder="测试值" value="<?php echo $ds['value']; ?>">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="step_units[]" class="form-control input-sm" placeholder="单位" value="<?php echo $ds['units']; ?>">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="step_lower[]" class="form-control input-sm" placeholder="下限" value="<?php echo $ds['lower']; ?>">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="step_upper[]" class="form-control input-sm" placeholder="上限" value="<?php echo $ds['upper']; ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select name="step_result[]" class="form-control input-sm">
|
||||
<option value="PASS" selected>PASS</option>
|
||||
<option value="FAIL">FAIL</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-xs btn-danger remove-step" title="删除此行">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<button type="button" id="addStep" class="btn btn-sm btn-info" style="margin-top:5px;">
|
||||
<i class="fa fa-plus"></i> 添加工步
|
||||
</button>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fa fa-check"></i> 提交导入
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- ==================== JSON 导入 ==================== -->
|
||||
<div class="tab-pane <?php echo (isset($activeTab) && $activeTab === 'json') ? 'active' : ''; ?>" id="tab-json" style="display:<?php echo (isset($activeTab) && $activeTab === 'json') ? 'block' : 'none'; ?>;">
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/asdTestDataImport">
|
||||
<input type="hidden" name="action" value="import_json">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>粘贴昂盛达设备上报的 JSON 数据:</label>
|
||||
<textarea name="json_data" class="form-control" rows="18"
|
||||
placeholder='{"Tester":"张三","QrCode":"SN6977187913642","Mo":"MO20240525","Site":"成品测试","Status":"PASS","DataList":[{"Seq":1,"TestName":"输出测试","TestItem":"电压","TestUnits":"V","DataValue":5.12,"LowerLimit":4.75,"UpperLimit":5.25,"TestResult":"PASS"}]}'><?php echo isset($_POST['json_data']) ? htmlspecialchars($_POST['json_data']) : ''; ?></textarea>
|
||||
</div>
|
||||
<p class="text-muted">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
JSON 格式请参考接口文档。必填字段:<code>QrCode</code>、<code>Status</code>、<code>DataList</code>
|
||||
</p>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fa fa-upload"></i> 导入 JSON
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 设备连接与批量操作 ==================== -->
|
||||
<div class="tab-pane <?php echo (isset($activeTab) && $activeTab === 'device') ? 'active' : ''; ?>" id="tab-device" style="display:<?php echo (isset($activeTab) && $activeTab === 'device') ? 'block' : 'none'; ?>;">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<!-- 左侧:设备选择与连接 -->
|
||||
<div class="col-md-6">
|
||||
<div class="device-card">
|
||||
<h4 style="margin-top:0;"><i class="fa fa-plug"></i> 设备连接</h4>
|
||||
|
||||
<!-- 扫码 / 手动输入设备编码 -->
|
||||
<div class="form-group">
|
||||
<label>设备编码(扫码枪 / 手动输入) <span class="text-red">*</span></label>
|
||||
<div class="input-group">
|
||||
<input type="text" id="scanInput" class="form-control" placeholder="扫描设备二维码 或 输入设备编码...">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" id="btnScanLookup" class="btn btn-info btn-connect">
|
||||
<i class="fa fa-search"></i> 查找
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 设备选择下拉框 -->
|
||||
<div class="form-group">
|
||||
<label>或从列表选择已注册设备:</label>
|
||||
<select id="deviceSelect" class="form-control">
|
||||
<option value="">-- 选择设备 --</option>
|
||||
<?php foreach ($devices as $dv): ?>
|
||||
<option value="<?php echo htmlspecialchars($dv['device_code']); ?>"
|
||||
data-ip="<?php echo htmlspecialchars($dv['device_ip'] ?? ''); ?>"
|
||||
data-name="<?php echo htmlspecialchars($dv['device_name'] ?? ''); ?>"
|
||||
data-group="<?php echo htmlspecialchars($dv['group_name'] ?? ''); ?>"
|
||||
data-status="<?php echo $dv['status']; ?>">
|
||||
<?php echo htmlspecialchars($dv['device_code']); ?>
|
||||
[<?php echo htmlspecialchars($dv['device_name'] ?? $dv['group_name'] ?? '-'); ?>]
|
||||
<?php echo !empty($dv['device_ip']) ? ' - IP:' . htmlspecialchars($dv['device_ip']) : ''; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- 设备信息展示区 -->
|
||||
<div id="deviceDetail" class="device-info" style="display:none;">
|
||||
<div class="info-row">
|
||||
<span class="info-label">设备编码:</span>
|
||||
<span class="info-value" id="dispDeviceCode">-</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">设备名称:</span>
|
||||
<span class="info-value" id="dispDeviceName">-</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">所属组别:</span>
|
||||
<span class="info-value" id="dispDeviceGroup">-</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">设备IP:</span>
|
||||
<span class="info-value">
|
||||
<input type="text" id="deviceIpInput" class="form-control input-sm" style="width:160px; display:inline-block;" placeholder="192.168.1.101">
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">连接状态:</span>
|
||||
<span class="info-value" id="dispConnStatus">
|
||||
<span class="status-dot unknown"></span> 未连接
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="device-actions">
|
||||
<button type="button" id="btnConnect" class="btn btn-success btn-connect" disabled>
|
||||
<i class="fa fa-link"></i> 连接设备
|
||||
</button>
|
||||
<button type="button" id="btnDisconnect" class="btn btn-default btn-connect" disabled>
|
||||
<i class="fa fa-unlink"></i> 断开
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="device-actions">
|
||||
<button type="button" id="btnBatchRead" class="btn btn-primary" disabled>
|
||||
<i class="fa fa-download"></i> 读取设备数据
|
||||
</button>
|
||||
<button type="button" id="btnBatchImport" class="btn btn-warning">
|
||||
<i class="fa fa-cloud-upload"></i> 批量导入选中设备数据
|
||||
</button>
|
||||
<button type="button" id="btnDeleteDeviceData" class="btn btn-danger" disabled>
|
||||
<i class="fa fa-trash"></i> 删除该设备数据
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已连接设备列表 -->
|
||||
<div class="box box-solid box-default collapsed-box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 已选中设备列表(用于批量读取)</h3>
|
||||
<div class="box-tools">
|
||||
<span class="badge bg-light-blue" id="selectedCount">0</span>
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div id="selectedDevicesList" class="text-muted" style="padding:5px;">
|
||||
尚未选择设备,请先扫码或从列表选择并连接设备
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:操作日志和结果 -->
|
||||
<div class="col-md-6">
|
||||
<div class="box box-solid box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-terminal"></i> 操作日志</h3>
|
||||
<div class="box-tools">
|
||||
<button type="button" id="btnClearLog" class="btn btn-box-tool btn-xs"><i class="fa fa-trash-o"></i> 清空</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body" style="padding:0;">
|
||||
<div id="consoleLog" class="console-log">
|
||||
<div class="log-line log-info">系统就绪,请选择设备进行操作...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 批量读取结果区 -->
|
||||
<div id="batchResultArea" style="display:none;">
|
||||
<div class="box box-solid box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-table"></i> 批量读取结果</h3>
|
||||
<span class="pull-right" id="batchResultSummary"></span>
|
||||
</div>
|
||||
<div class="box-body" style="padding:10px;">
|
||||
<div id="batchResultContent" class="batch-result-table"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.tab-content -->
|
||||
</div><!-- /.nav-tabs-custom -->
|
||||
</div><!-- /.box -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 删除确认弹窗 -->
|
||||
<div class="modal fade" id="deleteConfirmModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title"><i class="fa fa-exclamation-triangle text-red"></i> 确认删除</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="deleteConfirmMsg">确定要删除该设备的所有测试数据吗?此操作不可撤销!</p>
|
||||
<div class="form-group">
|
||||
<label>请输入 <strong>DELETE</strong> 确认:</label>
|
||||
<input type="text" id="deleteConfirmInput" class="form-control" placeholder="输入 DELETE">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button type="button" class="btn btn-danger" id="btnConfirmDelete" disabled>
|
||||
<i class="fa fa-trash"></i> 确认删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
// ==================== 全局状态 ====================
|
||||
var connectedDevices = {}; // { deviceCode: { device info, connected: bool } }
|
||||
var currentDevice = null; // 当前选中的设备编码
|
||||
|
||||
var BASE_URL = '<?php echo BASE_URL; ?>';
|
||||
|
||||
// CSP:设备批次面板标题点击展开(替代动态生成 HTML 的内联 onclick)
|
||||
$(document).on('click', '.device-batch-header', function () {
|
||||
$(this).next().toggleClass('open');
|
||||
});
|
||||
|
||||
// ==================== 控制台日志 ====================
|
||||
function log(msg, type) {
|
||||
type = type || 'info';
|
||||
var now = new Date();
|
||||
var time = now.toTimeString().substring(0, 8);
|
||||
var $log = $('#consoleLog');
|
||||
var cls = 'log-' + type;
|
||||
$log.append('<div class="log-line ' + cls + '"><span class="log-time">[' + time + ']</span> ' + msg + '</div>');
|
||||
$log.scrollTop($log[0].scrollHeight);
|
||||
}
|
||||
|
||||
// ==================== 设备选择处理 ====================
|
||||
$('#deviceSelect').on('change', function() {
|
||||
var code = $(this).val();
|
||||
if (!code) {
|
||||
$('#deviceDetail').hide();
|
||||
$('#btnConnect').prop('disabled', true);
|
||||
currentDevice = null;
|
||||
return;
|
||||
}
|
||||
currentDevice = code;
|
||||
$('#scanInput').val(code);
|
||||
|
||||
var opt = $(this).find('option:selected');
|
||||
$('#dispDeviceCode').text(code);
|
||||
$('#dispDeviceName').text(opt.data('name') || '-');
|
||||
$('#dispDeviceGroup').text(opt.data('group') || '-');
|
||||
$('#deviceIpInput').val(opt.data('ip') || '');
|
||||
$('#deviceDetail').show();
|
||||
$('#btnConnect').prop('disabled', false);
|
||||
updateConnectStatus(code);
|
||||
});
|
||||
|
||||
// 扫码查找
|
||||
$('#btnScanLookup').on('click', function() {
|
||||
var code = $('#scanInput').val().trim();
|
||||
if (!code) { alert('请输入设备编码'); return; }
|
||||
// 尝试从下拉框匹配
|
||||
var found = false;
|
||||
$('#deviceSelect option').each(function() {
|
||||
if ($(this).val().toUpperCase() === code.toUpperCase()) {
|
||||
$('#deviceSelect').val($(this).val()).trigger('change');
|
||||
found = true;
|
||||
log('扫码识别成功: ' + code, 'success');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (!found) {
|
||||
log('设备编码 ' + code + ' 未在系统中注册,请先录入设备信息', 'warn');
|
||||
// 仍允许手动连接
|
||||
currentDevice = code;
|
||||
$('#dispDeviceCode').text(code);
|
||||
$('#dispDeviceName').text('(未注册)');
|
||||
$('#dispDeviceGroup').text('-');
|
||||
$('#deviceIpInput').val('');
|
||||
$('#deviceDetail').show();
|
||||
$('#btnConnect').prop('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
// 更新连接状态显示
|
||||
function updateConnectStatus(code) {
|
||||
if (connectedDevices[code] && connectedDevices[code].connected) {
|
||||
$('#dispConnStatus').html('<span class="status-dot online"></span> 已连接');
|
||||
} else {
|
||||
$('#dispConnStatus').html('<span class="status-dot unknown"></span> 未连接');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 连接设备 ====================
|
||||
$('#btnConnect').on('click', function() {
|
||||
if (!currentDevice) { alert('请先选择设备'); return; }
|
||||
|
||||
var ip = $('#deviceIpInput').val().trim();
|
||||
if (!ip) { alert('请输入设备 IP 地址'); return; }
|
||||
|
||||
var $btn = $(this);
|
||||
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 连接中...');
|
||||
log('正在连接设备 ' + currentDevice + ' (' + ip + ')...', 'info');
|
||||
|
||||
$.ajax({
|
||||
url: BASE_URL + '/Api/asdDeviceConnect',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ DeviceCode: currentDevice, DeviceIp: ip }),
|
||||
success: function(resp) {
|
||||
if (resp.Result == 1) {
|
||||
log('连接成功! 设备: ' + currentDevice + ', IP: ' + ip
|
||||
+ (resp.ConnectionInfo.reachable ? ', 延迟: ' + resp.ConnectionInfo.latency_ms + 'ms' : ', 网络不可达(数据库校验通过)'), 'success');
|
||||
connectedDevices[currentDevice] = {
|
||||
info: resp.Device,
|
||||
connected: true
|
||||
};
|
||||
$('#dispConnStatus').html('<span class="status-dot online"></span> 已连接');
|
||||
$('#btnDisconnect').prop('disabled', false);
|
||||
$('#btnBatchRead').prop('disabled', false);
|
||||
$('#btnDeleteDeviceData').prop('disabled', false);
|
||||
updateSelectedList();
|
||||
} else {
|
||||
log('连接失败: ' + resp.Message, 'error');
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, err) {
|
||||
log('连接异常: ' + err, 'error');
|
||||
},
|
||||
complete: function() {
|
||||
$btn.prop('disabled', false).html('<i class="fa fa-link"></i> 连接设备');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 断开连接
|
||||
$('#btnDisconnect').on('click', function() {
|
||||
if (!currentDevice) return;
|
||||
if (connectedDevices[currentDevice]) {
|
||||
connectedDevices[currentDevice].connected = false;
|
||||
}
|
||||
$('#dispConnStatus').html('<span class="status-dot online" style="background:#999;"></span> 已断开');
|
||||
log('已断开设备: ' + currentDevice, 'warn');
|
||||
updateConnectStatus(currentDevice);
|
||||
updateSelectedList();
|
||||
});
|
||||
|
||||
// ==================== 更新已选设备列表 ====================
|
||||
function updateSelectedList() {
|
||||
var $list = $('#selectedDevicesList');
|
||||
var count = 0;
|
||||
var html = '';
|
||||
for (var code in connectedDevices) {
|
||||
if (connectedDevices[code].connected) {
|
||||
count++;
|
||||
var info = connectedDevices[code].info;
|
||||
html += '<span class="label label-success" style="margin:2px;" title="' + (info.device_ip || '') + '">'
|
||||
+ '<span class="status-dot online"></span> ' + code + '</span> ';
|
||||
}
|
||||
}
|
||||
if (count === 0) {
|
||||
$list.html('尚未选择设备,请先扫码或从列表选择并连接设备');
|
||||
} else {
|
||||
$list.html(html);
|
||||
}
|
||||
$('#selectedCount').text(count);
|
||||
}
|
||||
|
||||
// ==================== 批量读取设备数据 ====================
|
||||
$('#btnBatchRead').on('click', function() {
|
||||
if (!currentDevice) { alert('请先选择设备'); return; }
|
||||
|
||||
var $btn = $(this);
|
||||
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 读取中...');
|
||||
log('正在读取设备 ' + currentDevice + ' 的测试数据...', 'info');
|
||||
|
||||
$.ajax({
|
||||
url: BASE_URL + '/Api/asdBatchRead',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ DeviceCodes: [currentDevice], Limit: 20 }),
|
||||
success: function(resp) {
|
||||
if (resp.Result == 1) {
|
||||
var deviceData = resp.DevicesData[currentDevice];
|
||||
if (!deviceData) {
|
||||
log('设备 ' + currentDevice + ' 无数据', 'warn');
|
||||
return;
|
||||
}
|
||||
log('读取成功! 设备 ' + currentDevice + ' 共 ' + deviceData.total + ' 条记录,本次返回 ' + deviceData.records.length + ' 条', 'success');
|
||||
renderBatchResult(deviceData, currentDevice);
|
||||
} else {
|
||||
log('读取失败: ' + resp.Message, 'error');
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, err) {
|
||||
log('读取异常: ' + err, 'error');
|
||||
},
|
||||
complete: function() {
|
||||
$btn.prop('disabled', false).html('<i class="fa fa-download"></i> 读取设备数据');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 渲染批量读取结果
|
||||
function renderBatchResult(deviceData, deviceCode) {
|
||||
var $area = $('#batchResultArea');
|
||||
var $content = $('#batchResultContent');
|
||||
var records = deviceData.records;
|
||||
|
||||
var html = '<table class="table table-bordered table-condensed table-striped">';
|
||||
html += '<thead><tr><th>ID</th><th>条码</th><th>项目名称</th><th>测试员</th><th>状态</th><th>工步数</th><th>失败</th><th>测试时间</th><th>操作</th></tr></thead>';
|
||||
html += '<tbody>';
|
||||
|
||||
if (records.length === 0) {
|
||||
html += '<tr><td colspan="9" class="text-center text-muted">该设备暂无测试数据</td></tr>';
|
||||
} else {
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
var r = records[i];
|
||||
var statusLabel = r.status === 'PASS' ? 'label-success' : 'label-danger';
|
||||
var failBadge = r.fail_count > 0 ? '<span class="badge bg-red">' + r.fail_count + '</span>' : '<span class="text-muted">0</span>';
|
||||
html += '<tr>';
|
||||
html += '<td>' + r.id + '</td>';
|
||||
html += '<td><code>' + escapeHtml(r.qr_code) + '</code></td>';
|
||||
html += '<td>' + escapeHtml(r.project_name) + '</td>';
|
||||
html += '<td>' + escapeHtml(r.tester) + '</td>';
|
||||
html += '<td><span class="label ' + statusLabel + '">' + r.status + '</span></td>';
|
||||
html += '<td><span class="badge bg-light-blue">' + r.step_count + '</span></td>';
|
||||
html += '<td>' + failBadge + '</td>';
|
||||
html += '<td>' + (r.test_time || '-') + '</td>';
|
||||
html += '<td><a href="' + BASE_URL + '/Admin/asdTestDataView/' + r.id + '" class="btn btn-xs btn-info" target="_blank"><i class="fa fa-eye"></i></a></td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
}
|
||||
html += '</tbody></table>';
|
||||
|
||||
$('#batchResultSummary').html('设备: <strong>' + deviceCode + '</strong> | 总数: ' + deviceData.total + ' | 显示: ' + records.length + ' 条');
|
||||
$content.html(html);
|
||||
$area.show();
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
if (!str) return '';
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
// ==================== 删除设备数据 ====================
|
||||
$('#btnDeleteDeviceData').on('click', function() {
|
||||
if (!currentDevice) { alert('请先选择设备'); return; }
|
||||
$('#deleteConfirmMsg').text('确定要删除设备 [' + currentDevice + '] 的所有测试数据吗?此操作不可撤销!');
|
||||
$('#deleteConfirmInput').val('');
|
||||
$('#btnConfirmDelete').prop('disabled', true);
|
||||
$('#deleteConfirmModal').modal('show');
|
||||
});
|
||||
|
||||
$('#deleteConfirmInput').on('input', function() {
|
||||
$('#btnConfirmDelete').prop('disabled', $(this).val() !== 'DELETE');
|
||||
});
|
||||
|
||||
$('#btnConfirmDelete').on('click', function() {
|
||||
var $btn = $(this);
|
||||
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 删除中...');
|
||||
log('正在删除设备 ' + currentDevice + ' 的所有测试数据...', 'warn');
|
||||
|
||||
$.ajax({
|
||||
url: BASE_URL + '/Api/asdDeviceDataDelete',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ DeviceCode: currentDevice, Confirm: 'YES' }),
|
||||
success: function(resp) {
|
||||
if (resp.Result == 1) {
|
||||
log('删除成功! 共删除 ' + resp.DeletedCount + ' 条记录', 'success');
|
||||
$('#batchResultArea').hide();
|
||||
} else {
|
||||
log('删除失败: ' + resp.Message, 'error');
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, err) {
|
||||
log('删除异常: ' + err, 'error');
|
||||
},
|
||||
complete: function() {
|
||||
$btn.prop('disabled', false).html('<i class="fa fa-trash"></i> 确认删除');
|
||||
$('#deleteConfirmModal').modal('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ==================== 批量导入选中设备数据 ====================
|
||||
$('#btnBatchImport').on('click', function() {
|
||||
var codes = [];
|
||||
for (var code in connectedDevices) {
|
||||
if (connectedDevices[code].connected) {
|
||||
codes.push(code);
|
||||
}
|
||||
}
|
||||
if (codes.length === 0) {
|
||||
alert('请先连接至少一台设备');
|
||||
return;
|
||||
}
|
||||
|
||||
var $btn = $(this);
|
||||
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 读取中...');
|
||||
log('批量读取 ' + codes.length + ' 台设备数据...', 'info');
|
||||
|
||||
$.ajax({
|
||||
url: BASE_URL + '/Api/asdBatchRead',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ DeviceCodes: codes, Limit: 50 }),
|
||||
success: function(resp) {
|
||||
if (resp.Result == 1) {
|
||||
var totalRecords = 0;
|
||||
var html = '';
|
||||
for (var code in resp.DevicesData) {
|
||||
var dd = resp.DevicesData[code];
|
||||
totalRecords += dd.total;
|
||||
html += '<div class="device-batch-item">';
|
||||
html += '<div class="panel-heading device-batch-header">';
|
||||
html += '<strong>' + code + '</strong> ';
|
||||
html += '<span class="badge bg-light-blue pull-right">' + dd.records.length + ' / ' + dd.total + ' 条</span>';
|
||||
html += '<small class="text-muted">' + (dd.device_info ? dd.device_info.device_name + ' | IP:' + dd.device_info.device_ip : '') + '</small>';
|
||||
html += '</div>';
|
||||
html += '<div class="panel-body">';
|
||||
html += '<table class="table table-condensed table-bordered"><thead><tr><th>ID</th><th>条码</th><th>状态</th><th>工步</th><th>时间</th></tr></thead><tbody>';
|
||||
for (var i = 0; i < dd.records.length; i++) {
|
||||
var r = dd.records[i];
|
||||
html += '<tr><td>' + r.id + '</td><td><code>' + escapeHtml(r.qr_code) + '</code></td>';
|
||||
html += '<td><span class="label ' + (r.status === 'PASS' ? 'label-success' : 'label-danger') + '">' + r.status + '</span></td>';
|
||||
html += '<td>' + r.step_count + '</td><td>' + (r.test_time || '-') + '</td></tr>';
|
||||
}
|
||||
html += '</tbody></table></div></div>';
|
||||
}
|
||||
$('#batchResultContent').html(html);
|
||||
$('#batchResultSummary').html('设备数: <strong>' + codes.length + '</strong> | 总记录: ' + totalRecords + ' 条');
|
||||
$('#batchResultArea').show();
|
||||
log('批量读取完成! ' + codes.length + ' 台设备, 共 ' + totalRecords + ' 条记录', 'success');
|
||||
} else {
|
||||
log('批量读取失败: ' + resp.Message, 'error');
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, err) {
|
||||
log('批量读取异常: ' + err, 'error');
|
||||
},
|
||||
complete: function() {
|
||||
$btn.prop('disabled', false).html('<i class="fa fa-cloud-upload"></i> 批量导入选中设备数据');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ==================== 清空日志 ====================
|
||||
$('#btnClearLog').on('click', function() {
|
||||
$('#consoleLog').html('<div class="log-line log-info">日志已清空</div>');
|
||||
});
|
||||
|
||||
// ==================== 表单工步操作 ====================
|
||||
document.getElementById('addStep').addEventListener('click', function() {
|
||||
var container = document.getElementById('stepContainer');
|
||||
var row = document.createElement('div');
|
||||
row.className = 'row step-row';
|
||||
row.style.marginBottom = '8px';
|
||||
row.innerHTML =
|
||||
'<div class="col-md-2"><input type="text" name="step_name[]" class="form-control input-sm" placeholder="工步名称"></div>' +
|
||||
'<div class="col-md-2"><input type="text" name="step_item[]" class="form-control input-sm" placeholder="测试项目"></div>' +
|
||||
'<div class="col-md-2"><input type="text" name="step_value[]" class="form-control input-sm" placeholder="测试值"></div>' +
|
||||
'<div class="col-md-1"><input type="text" name="step_units[]" class="form-control input-sm" placeholder="单位"></div>' +
|
||||
'<div class="col-md-1"><input type="text" name="step_lower[]" class="form-control input-sm" placeholder="下限"></div>' +
|
||||
'<div class="col-md-1"><input type="text" name="step_upper[]" class="form-control input-sm" placeholder="上限"></div>' +
|
||||
'<div class="col-md-2"><select name="step_result[]" class="form-control input-sm"><option value="PASS" selected>PASS</option><option value="FAIL">FAIL</option></select></div>' +
|
||||
'<div class="col-md-1"><button type="button" class="btn btn-xs btn-danger remove-step"><i class="fa fa-times"></i></button></div>';
|
||||
container.appendChild(row);
|
||||
row.querySelector('.remove-step').addEventListener('click', function() {
|
||||
container.removeChild(row);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.remove-step').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var rows = document.querySelectorAll('.step-row');
|
||||
if (rows.length > 1) {
|
||||
this.closest('.step-row').remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 扫码输入框回车自动查找
|
||||
$('#scanInput').on('keypress', function(e) {
|
||||
if (e.which === 13) {
|
||||
e.preventDefault();
|
||||
$('#btnScanLookup').trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
// ==================== Tab 切换(直接操作 display,不依赖 Bootstrap JS) ====================
|
||||
$(function() {
|
||||
// 切换 tab:显示目标,隐藏其余
|
||||
function switchTab(hash) {
|
||||
if (!hash) return;
|
||||
// 隐藏所有 pane,显示目标
|
||||
$('.tab-content > .tab-pane').hide();
|
||||
$(hash).show();
|
||||
// 切换 nav 高亮
|
||||
$('.nav-tabs li').removeClass('active');
|
||||
$('.nav-tabs a[href="' + hash + '"]').parent('li').addClass('active');
|
||||
}
|
||||
|
||||
// 点击 nav tab
|
||||
$('.nav-tabs a').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var hash = $(this).attr('href');
|
||||
switchTab(hash);
|
||||
// 更新 URL hash
|
||||
if (history.replaceState) {
|
||||
history.replaceState(null, null, hash);
|
||||
}
|
||||
});
|
||||
|
||||
// 页面加载时根据 URL hash 切换
|
||||
var hash = window.location.hash;
|
||||
if (hash && '#tab-form,#tab-json,#tab-device'.indexOf(hash) !== -1) {
|
||||
switchTab(hash);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
$activeMenu = 'asdTestData';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-info-circle"></i> 测试数据详情</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdTestData" class="btn btn-default btn-sm">
|
||||
<i class="fa fa-arrow-left"></i> 返回列表
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<table class="table table-bordered table-striped" style="width:auto;">
|
||||
<tr>
|
||||
<th style="width:120px;">记录ID</th>
|
||||
<td><?php echo $record['id']; ?></td>
|
||||
<th style="width:120px;">条码</th>
|
||||
<td><code><?php echo htmlspecialchars($record['qr_code']); ?></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>测试员</th>
|
||||
<td><?php echo htmlspecialchars($record['tester']); ?></td>
|
||||
<th>项目名称</th>
|
||||
<td><?php echo htmlspecialchars($record['project_name']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>工位</th>
|
||||
<td><?php echo htmlspecialchars($record['site']); ?></td>
|
||||
<th>站点</th>
|
||||
<td><?php echo htmlspecialchars($record['station']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>单号</th>
|
||||
<td><?php echo htmlspecialchars($record['mo']); ?></td>
|
||||
<th>工单</th>
|
||||
<td><?php echo htmlspecialchars($record['work_order']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>组别</th>
|
||||
<td><?php echo htmlspecialchars($record['group_name']); ?></td>
|
||||
<th>设备</th>
|
||||
<td><?php echo htmlspecialchars($record['device']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>运行时间</th>
|
||||
<td><?php echo htmlspecialchars($record['running_time']); ?></td>
|
||||
<th>测试时间</th>
|
||||
<td><?php echo $record['test_time']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>整体状态</th>
|
||||
<td colspan="3">
|
||||
<?php if ($record['status'] === 'PASS'): ?>
|
||||
<span class="label label-success">PASS</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger"><?php echo htmlspecialchars($record['status']); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工步详情 -->
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list-ol"></i> 测试工步详情(共 <?php echo count($details); ?> 步)</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:50px;">序号</th>
|
||||
<th>工步名称</th>
|
||||
<th>测试项目</th>
|
||||
<th>测试值</th>
|
||||
<th>单位</th>
|
||||
<th>下限</th>
|
||||
<th>上限</th>
|
||||
<th>字符串值</th>
|
||||
<th>结果</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($details)): ?>
|
||||
<tr><td colspan="9" class="text-center text-muted">无工步数据</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($details as $d): ?>
|
||||
<tr>
|
||||
<td><?php echo $d['seq']; ?></td>
|
||||
<td><?php echo htmlspecialchars($d['test_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($d['test_item']); ?></td>
|
||||
<td>
|
||||
<?php if ($d['data_value'] !== null): ?>
|
||||
<strong><?php echo rtrim(rtrim($d['data_value'], '0'), '.'); ?></strong>
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($d['test_units']); ?></td>
|
||||
<td><?php echo $d['lower_limit'] !== null ? htmlspecialchars($d['lower_limit']) : '-'; ?></td>
|
||||
<td><?php echo $d['upper_limit'] !== null ? htmlspecialchars($d['upper_limit']) : '-'; ?></td>
|
||||
<td><code><?php echo htmlspecialchars($d['test_value']); ?></code></td>
|
||||
<td>
|
||||
<?php if ($d['test_result'] === 'PASS'): ?>
|
||||
<span class="label label-success">PASS</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger"><?php echo htmlspecialchars($d['test_result']); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
$activeMenu = 'config';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<?php if (!empty($msg)): ?>
|
||||
<div class="alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<i class="fa fa-check-circle"></i> <?php echo htmlspecialchars($msg); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<i class="fa fa-exclamation-circle"></i> <?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-cog"></i> 系统配置</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>公司名称</label>
|
||||
<input type="text" name="company_name" class="form-control" value="<?php echo htmlspecialchars($sysConfig['company_name'] ?? ''); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>MES 展示名称</label>
|
||||
<input type="text" name="mes_name" class="form-control" value="<?php echo htmlspecialchars($sysConfig['mes_name'] ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存配置</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 代码前缀规则配置 -->
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-barcode"></i> 序列号前缀规则</h3>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p class="text-muted" style="margin-bottom:12px;">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
设置各产品类型的序列号前缀。工位录入时,序列号必须匹配对应前缀,否则将报错。
|
||||
留空表示不检查前缀。
|
||||
</p>
|
||||
<div id="prefixRulesContainer">
|
||||
<?php
|
||||
$ruleIndex = 0;
|
||||
if (!empty($codePrefixRules)):
|
||||
foreach ($codePrefixRules as $typeName => $prefixVal):
|
||||
?>
|
||||
<div class="prefix-rule-row" style="display:flex; gap:10px; margin-bottom:8px; align-items:center;">
|
||||
<input type="text" name="prefix_types[]" class="form-control" style="flex:1;"
|
||||
placeholder="产品类型(如:成品、电芯、PCBA)"
|
||||
value="<?php echo htmlspecialchars($typeName); ?>">
|
||||
<input type="text" name="prefix_values[]" class="form-control" style="width:120px;"
|
||||
placeholder="前缀(如:CP)"
|
||||
value="<?php echo htmlspecialchars($prefixVal); ?>">
|
||||
<button type="button" class="btn btn-danger btn-sm remove-prefix-row" title="删除">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php
|
||||
$ruleIndex++;
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success btn-sm" id="addPrefixRow" style="margin-top:8px;">
|
||||
<i class="fa fa-plus"></i> 添加规则
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-info-circle"></i> 当前信息</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>公司名称</dt>
|
||||
<dd><?php echo htmlspecialchars($sysConfig['company_name'] ?? ''); ?></dd>
|
||||
<dt>系统名称</dt>
|
||||
<dd><?php echo htmlspecialchars($sysConfig['mes_name'] ?? ''); ?></dd>
|
||||
<dt>前缀规则</dt>
|
||||
<dd>
|
||||
<?php if (!empty($codePrefixRules)): ?>
|
||||
<table class="table table-condensed table-bordered" style="margin-bottom:0;">
|
||||
<thead><tr><th>产品类型</th><th>前缀</th></tr></thead>
|
||||
<tbody>
|
||||
<?php foreach ($codePrefixRules as $typeName => $prefixVal): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($typeName); ?></td>
|
||||
<td>
|
||||
<?php if ($prefixVal !== ''): ?>
|
||||
<code><?php echo htmlspecialchars($prefixVal); ?></code>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">无限制</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">未配置</span>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt>PHP 版本</dt>
|
||||
<dd><?php echo phpversion(); ?></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php // v3-P2:原内联 <script> 已抽离为 external JS,并以 nonce 加载,配合 CSP script-src 'nonce-***' ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/admin_config.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
$activeMenu = 'customer';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 客户列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/customerAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加客户</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:60px">序号</th>
|
||||
<th>公司名称</th>
|
||||
<th>联系人1</th>
|
||||
<th>联系方式1</th>
|
||||
<th>联系人2</th>
|
||||
<th>联系方式2</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($customers)): ?>
|
||||
<?php foreach ($customers as $cust): ?>
|
||||
<tr>
|
||||
<td><?php echo $cust['id']; ?></td>
|
||||
<td><strong><?php echo htmlspecialchars($cust['company_name']); ?></strong></td>
|
||||
<td><?php echo htmlspecialchars($cust['contact1'] ?? '-'); ?></td>
|
||||
<td><?php echo htmlspecialchars($cust['phone1'] ?? '-'); ?></td>
|
||||
<td><?php echo htmlspecialchars($cust['contact2'] ?? '-'); ?></td>
|
||||
<td><?php echo htmlspecialchars($cust['phone2'] ?? '-'); ?></td>
|
||||
<td><?php echo htmlspecialchars($cust['created_by'] ?? '-'); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/customerEdit/<?php echo $cust['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/customerDelete/<?php echo $cust['id']; ?>" style="display:inline;" onsubmit="return confirm('确定删除该客户?')">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="8" class="text-center text-muted">暂无客户数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
$activeMenu = 'customer';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加客户</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>公司名称 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="company_name" class="form-control" placeholder="公司全称" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系人1</label>
|
||||
<input type="text" name="contact1" class="form-control" placeholder="主要联系人">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系方式1</label>
|
||||
<input type="text" name="phone1" class="form-control" placeholder="电话/邮箱">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系人2</label>
|
||||
<input type="text" name="contact2" class="form-control" placeholder="备用联系人">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系方式2</label>
|
||||
<input type="text" name="phone2" class="form-control" placeholder="电话/邮箱">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/customer" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
$activeMenu = 'customer';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑客户</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>公司名称 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="company_name" class="form-control" value="<?php echo htmlspecialchars($cust['company_name']); ?>" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系人1</label>
|
||||
<input type="text" name="contact1" class="form-control" value="<?php echo htmlspecialchars($cust['contact1'] ?? ''); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系方式1</label>
|
||||
<input type="text" name="phone1" class="form-control" value="<?php echo htmlspecialchars($cust['phone1'] ?? ''); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系人2</label>
|
||||
<input type="text" name="contact2" class="form-control" value="<?php echo htmlspecialchars($cust['contact2'] ?? ''); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系方式2</label>
|
||||
<input type="text" name="phone2" class="form-control" value="<?php echo htmlspecialchars($cust['phone2'] ?? ''); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-warning"><i class="fa fa-save"></i> 更新</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/customer" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
$activeMenu = 'database';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-database"></i> 数据库表管理</h3>
|
||||
<div class="box-tools">
|
||||
<span class="badge bg-blue">共 <?php echo count($tables); ?> 张表</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>表名</th>
|
||||
<th>记录数</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($tables as $idx => $tbl): ?>
|
||||
<tr>
|
||||
<td><?php echo $idx + 1; ?></td>
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars($tbl['business_name']); ?></strong>
|
||||
<br><code style="color:#999;"><?php echo htmlspecialchars($tbl['name']); ?></code>
|
||||
</td>
|
||||
<td><span class="badge bg-light-blue"><?php echo $tbl['count']; ?></span></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseView/<?php echo $idx; ?>" class="btn btn-sm btn-primary">
|
||||
<i class="fa fa-eye"></i> 查看/编辑
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
$activeMenu = 'databaseBackup';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<?php if (!empty($message)): ?>
|
||||
<div class="alert alert-<?php echo $messageType; ?> alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa <?php echo $messageType === 'success' ? 'fa-check' : ($messageType === 'danger' ? 'fa-ban' : 'fa-warning'); ?>"></i> 操作结果</h4>
|
||||
<?php echo nl2br(htmlspecialchars($message)); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<!-- 备份操作区 -->
|
||||
<div class="col-md-5">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-cloud-download"></i> 创建备份</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p class="text-muted">将当前数据库导出为 SQL 文件,保存到服务器 <code>backups/</code> 目录。</p>
|
||||
<p>数据库:<strong><?php echo htmlspecialchars(DB_NAME); ?></strong></p>
|
||||
<p>主机:<strong><?php echo htmlspecialchars(DB_HOST); ?></strong></p>
|
||||
<form method="post" onsubmit="return confirm('确定要创建数据库备份吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="backup">
|
||||
<button type="submit" class="btn btn-success btn-lg btn-block">
|
||||
<i class="fa fa-database"></i> 立即备份数据库
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="box-footer text-muted">
|
||||
<small><i class="fa fa-info-circle"></i> 备份将包含所有表结构和数据(排除 jp_ 前缀的表)</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-info-circle"></i> 说明</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<ul>
|
||||
<li><strong>备份</strong>:将数据库完整导出为 .sql 文件保存到服务器本地</li>
|
||||
<li><strong>恢复</strong>:选择一个备份文件,将其数据恢复到当前数据库</li>
|
||||
<li><strong>下载</strong>:将备份文件下载到本地电脑保存</li>
|
||||
<li><strong>删除</strong>:删除服务器上的备份文件</li>
|
||||
</ul>
|
||||
<div class="callout callout-warning">
|
||||
<h4><i class="fa fa-warning"></i> 注意</h4>
|
||||
<p>恢复操作会<strong>覆盖当前数据库</strong>中已存在的同名表!请在恢复前确认已做好最新备份。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 备份文件列表 -->
|
||||
<div class="col-md-7">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-files-o"></i> 备份文件列表</h3>
|
||||
<div class="box-tools">
|
||||
<span class="badge bg-blue">共 <?php echo count($backupFiles); ?> 个备份</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<?php if (empty($backupFiles)): ?>
|
||||
<div class="text-center" style="padding:40px;">
|
||||
<i class="fa fa-inbox" style="font-size:48px; color:#ddd;"></i>
|
||||
<p class="text-muted" style="margin-top:10px;">暂无备份文件,请先创建备份</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>文件名</th>
|
||||
<th>大小</th>
|
||||
<th>备份时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($backupFiles as $file): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<i class="fa fa-file-code-o text-primary"></i>
|
||||
<code><?php echo htmlspecialchars($file['name']); ?></code>
|
||||
</td>
|
||||
<td><span class="badge bg-light-blue"><?php echo $file['size']; ?></span></td>
|
||||
<td><?php echo $file['time']; ?></td>
|
||||
<td>
|
||||
<!-- 恢复 -->
|
||||
<form method="post" style="display:inline;" onsubmit="return confirm('确定要恢复此备份吗?\n\n⚠ 此操作会覆盖当前数据库中的数据!\n建议先创建最新备份。');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="restore">
|
||||
<input type="hidden" name="file" value="<?php echo htmlspecialchars($file['name']); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-warning" title="恢复此备份">
|
||||
<i class="fa fa-cloud-upload"></i> 恢复
|
||||
</button>
|
||||
</form>
|
||||
<!-- 下载 -->
|
||||
<form method="post" style="display:inline;">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="download">
|
||||
<input type="hidden" name="file" value="<?php echo htmlspecialchars($file['name']); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-primary" title="下载到本地">
|
||||
<i class="fa fa-download"></i> 下载
|
||||
</button>
|
||||
</form>
|
||||
<!-- 删除 -->
|
||||
<form method="post" style="display:inline;" onsubmit="return confirm('确定要删除备份文件 <?php echo htmlspecialchars($file['name']); ?> 吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="file" value="<?php echo htmlspecialchars($file['name']); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="删除备份文件">
|
||||
<i class="fa fa-trash"></i> 删除
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
$activeMenu = 'database';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-edit"></i> 编辑记录 — 表:<code><?php echo htmlspecialchars($table); ?></code> — ID:<?php echo $row['id']; ?>
|
||||
</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseView/<?php echo $idx; ?>" class="btn btn-default btn-sm">
|
||||
<i class="fa fa-arrow-left"></i> 返回
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php foreach ($columns as $col): ?>
|
||||
<?php $field = $col['Field']; ?>
|
||||
<?php $isSensitive = in_array($field, $sensitiveFields ?? [], true); ?>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<strong><?php echo htmlspecialchars($field); ?></strong>
|
||||
<small class="text-muted">(<?php echo htmlspecialchars($col['Type']); ?><?php echo $col['Key'] === 'PRI' ? ', 主键' : ''; ?><?php echo $isSensitive ? ', 已脱敏不可编辑' : ''; ?>)</small>
|
||||
</label>
|
||||
<?php if ($field === 'id'): ?>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($row[$field] ?? ''); ?>" disabled>
|
||||
<?php elseif ($isSensitive): ?>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($row[$field] ?? ''); ?>" disabled>
|
||||
<p class="text-warning" style="margin-top:4px;"><i class="fa fa-lock"></i> 敏感字段已脱敏,无法在此查看或修改</p>
|
||||
<?php elseif (stripos($col['Type'], 'text') !== false): ?>
|
||||
<textarea name="<?php echo htmlspecialchars($field); ?>" class="form-control" rows="4"><?php echo htmlspecialchars($row[$field] ?? ''); ?></textarea>
|
||||
<?php elseif (stripos($col['Type'], 'enum') !== false): ?>
|
||||
<?php
|
||||
// 解析 ENUM 值
|
||||
preg_match("/^enum\((.*)\)$/i", $col['Type'], $m);
|
||||
$enumVals = [];
|
||||
if (!empty($m[1])) {
|
||||
foreach (explode(',', $m[1]) as $ev) {
|
||||
$enumVals[] = trim($ev, "'\"");
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php if (!empty($enumVals)): ?>
|
||||
<select name="<?php echo htmlspecialchars($field); ?>" class="form-control">
|
||||
<?php foreach ($enumVals as $ev): ?>
|
||||
<option value="<?php echo htmlspecialchars($ev); ?>" <?php echo ($row[$field] ?? '') === $ev ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($ev); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php else: ?>
|
||||
<input type="text" name="<?php echo htmlspecialchars($field); ?>" class="form-control" value="<?php echo htmlspecialchars($row[$field] ?? ''); ?>">
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<input type="text" name="<?php echo htmlspecialchars($field); ?>" class="form-control" value="<?php echo htmlspecialchars($row[$field] ?? ''); ?>">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-warning"><i class="fa fa-save"></i> 保存修改</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseView/<?php echo $idx; ?>" class="btn btn-default">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
$activeMenu = 'databaseUpgrade';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<style>
|
||||
.sql-preview {
|
||||
background: #1e1e1e;
|
||||
color: #d4d4d4;
|
||||
font-family: 'Consolas', 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
padding: 10px 15px;
|
||||
border-radius: 4px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
.sql-preview::-webkit-scrollbar { width: 6px; }
|
||||
.sql-preview::-webkit-scrollbar-track { background: #2d2d2d; }
|
||||
.sql-preview::-webkit-scrollbar-thumb { background: #555; border-radius: 3px; }
|
||||
.badge-status { font-size: 12px; }
|
||||
.btn-execute-all { margin-left: 10px; }
|
||||
</style>
|
||||
|
||||
<?php if (!empty($message)): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-<?php echo $messageType; ?> alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa fa-<?php echo $messageType === 'success' ? 'check' : ($messageType === 'danger' ? 'ban' : 'warning'); ?>"></i> 提示</h4>
|
||||
<?php echo nl2br(htmlspecialchars($message)); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-wrench"></i> 数据库升级/迁移</h3>
|
||||
<div class="box-tools">
|
||||
<?php if ($pendingCount > 0): ?>
|
||||
<span class="badge bg-yellow" style="font-size:13px;"><?php echo $pendingCount; ?> 个待执行</span>
|
||||
<form method="post" style="display:inline;" class="confirm-form" data-confirm="确定要一键执行所有未执行的迁移脚本吗?此操作将按文件名顺序依次执行所有未执行过的 .sql 文件。">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="execute_all">
|
||||
<button type="submit" class="btn btn-sm btn-success btn-execute-all">
|
||||
<i class="fa fa-bolt"></i> 一键全部执行
|
||||
</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-green" style="font-size:13px;">全部已执行</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="callout callout-info" style="margin-bottom: 15px;">
|
||||
<h4><i class="icon fa fa-info-circle"></i> 使用说明</h4>
|
||||
<p style="margin-bottom:0;">
|
||||
1. 系统会自动扫描 <code>sql/</code> 目录下的所有 <code>.sql</code> 文件。<br>
|
||||
2. 已执行过的脚本会标记为 <span class="label label-success">已执行</span>,不会重复执行。<br>
|
||||
3. 每个脚本在事务中执行,失败会自动回滚。<br>
|
||||
4. 点击文件名可展开查看 SQL 内容预览。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php if (empty($fileList)): ?>
|
||||
<div class="text-center" style="padding: 40px;">
|
||||
<i class="fa fa-inbox" style="font-size: 48px; color: #ccc;"></i>
|
||||
<p style="color: #999; margin-top: 10px;">sql/ 目录下没有找到 .sql 迁移文件</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">#</th>
|
||||
<th>文件名</th>
|
||||
<th style="width: 100px;">状态</th>
|
||||
<th style="width: 160px;">执行时间</th>
|
||||
<th style="width: 120px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $idx = 1; foreach ($fileList as $file): ?>
|
||||
<tr>
|
||||
<td><?php echo $idx++; ?></td>
|
||||
<td>
|
||||
<a href="#" class="sql-preview-link" data-preview="preview-<?php echo $idx; ?>" style="font-family: monospace;">
|
||||
<i class="fa fa-file-code-o"></i> <?php echo htmlspecialchars($file['name']); ?>
|
||||
</a>
|
||||
<div id="preview-<?php echo $idx; ?>" class="sql-preview" style="display:none; margin-top:8px;">
|
||||
<?php echo $file['preview']; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($file['is_migrated']): ?>
|
||||
<?php if ($file['status'] == 1): ?>
|
||||
<span class="label label-success">已执行</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger" title="<?php echo htmlspecialchars($file['error_msg']); ?>">执行失败</span>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<span class="label label-warning">待执行</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($file['is_migrated'] && $file['executed_at']): ?>
|
||||
<small><?php echo htmlspecialchars($file['executed_at']); ?></small>
|
||||
<?php else: ?>
|
||||
<small style="color:#999;">—</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (!$file['is_migrated'] || $file['status'] == 0): ?>
|
||||
<form method="post" style="display:inline;" class="confirm-form" data-confirm="确定要执行该迁移脚本吗?">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="execute">
|
||||
<input type="hidden" name="file" value="<?php echo htmlspecialchars($file['name']); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-primary">
|
||||
<i class="fa fa-play"></i> 执行
|
||||
</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<button class="btn btn-sm btn-default" disabled>
|
||||
<i class="fa fa-check"></i> 已完成
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($file['is_migrated'] && $file['status'] == 0 && !empty($file['error_msg'])): ?>
|
||||
<br><small class="text-danger" style="display:inline-block;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="<?php echo htmlspecialchars($file['error_msg']); ?>"><?php echo htmlspecialchars($file['error_msg']); ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
function togglePreview(link, previewId) {
|
||||
var preview = document.getElementById(previewId);
|
||||
var icon = link.querySelector('i');
|
||||
if (preview.style.display === 'none' || preview.style.display === '') {
|
||||
preview.style.display = 'block';
|
||||
if (icon) {
|
||||
icon.className = 'fa fa-file-code-o';
|
||||
}
|
||||
} else {
|
||||
preview.style.display = 'none';
|
||||
if (icon) {
|
||||
icon.className = 'fa fa-file-code-o';
|
||||
}
|
||||
}
|
||||
}
|
||||
// CSP:文件名预览切换改为事件委托(替代内联 onclick / javascript:)
|
||||
document.addEventListener('click', function (e) {
|
||||
var link = e.target.closest ? e.target.closest('.sql-preview-link') : null;
|
||||
if (!link) return;
|
||||
e.preventDefault();
|
||||
togglePreview(link, link.getAttribute('data-preview'));
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
$activeMenu = 'database';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-table"></i> 表:<code><?php echo htmlspecialchars($table); ?></code>
|
||||
</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/database" class="btn btn-default btn-sm"><i class="fa fa-arrow-left"></i> 返回列表</a>
|
||||
<span class="badge bg-blue" style="margin-left:10px;">共 <?php echo $totalCount; ?> 条</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach ($columns as $col): ?>
|
||||
<th title="<?php echo htmlspecialchars($col['Type']); ?>">
|
||||
<?php echo htmlspecialchars($col['Field']); ?>
|
||||
</th>
|
||||
<?php endforeach; ?>
|
||||
<th style="width:140px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($rows as $row): ?>
|
||||
<tr>
|
||||
<?php foreach ($columns as $col): ?>
|
||||
<td style="max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
|
||||
<?php
|
||||
$val = $row[$col['Field']] ?? '';
|
||||
if ($val === null) {
|
||||
echo '<span class="text-muted">NULL</span>';
|
||||
} elseif ($val === '') {
|
||||
echo '<span class="text-muted">-</span>';
|
||||
} else {
|
||||
echo htmlspecialchars($val);
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseEdit/<?php echo $idx; ?>/<?php echo $row['id']; ?>"
|
||||
class="btn btn-xs btn-warning"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/databaseDelete/<?php echo $idx; ?>/<?php echo $row['id']; ?>" style="display:inline;" onsubmit="return confirm('确定删除 ID=<?php echo $row['id']; ?> 的记录吗?此操作不可恢复!');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($rows)): ?>
|
||||
<tr>
|
||||
<td colspan="<?php echo count($columns) + 1; ?>" class="text-center text-muted">
|
||||
暂无数据
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="box-footer clearfix">
|
||||
<ul class="pagination pagination-sm no-margin pull-right">
|
||||
<?php if ($page > 1): ?>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/databaseView/<?php echo $idx; ?>?page=<?php echo $page - 1; ?>">«</a></li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$range = 2;
|
||||
$start = max(1, $page - $range);
|
||||
$end = min($totalPages, $page + $range);
|
||||
if ($start > 1) { echo '<li><a href="<?php echo BASE_URL; ?>/Admin/databaseView/'.$idx.'?page=1">1</a></li>'; if ($start > 2) echo '<li><span>...</span></li>'; }
|
||||
for ($p = $start; $p <= $end; $p++):
|
||||
?>
|
||||
<li class="<?php echo $p == $page ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseView/<?php echo $idx; ?>?page=<?php echo $p; ?>"><?php echo $p; ?></a>
|
||||
</li>
|
||||
<?php endfor;
|
||||
if ($end < $totalPages) { if ($end < $totalPages - 1) echo '<li><span>...</span></li>'; echo '<li><a href="<?php echo BASE_URL; ?>/Admin/databaseView/'.$idx.'?page='.$totalPages.'">'.$totalPages.'</a></li>'; }
|
||||
?>
|
||||
|
||||
<?php if ($page < $totalPages): ?>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/databaseView/<?php echo $idx; ?>?page=<?php echo $page + 1; ?>">»</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
$activeMenu = 'employee';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 员工列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加员工</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:60px">序号</th>
|
||||
<th>员工编号</th>
|
||||
<th>姓名</th>
|
||||
<th>权限</th>
|
||||
<th>管理类目</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:200px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($employees)): ?>
|
||||
<?php foreach ($employees as $emp): ?>
|
||||
<tr>
|
||||
<td><?php echo $emp['id']; ?></td>
|
||||
<td><code><?php echo htmlspecialchars($emp['emp_no']); ?></code></td>
|
||||
<td><?php echo htmlspecialchars($emp['emp_name']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$roleNames = \core\base\Controller::ROLE_NAMES;
|
||||
$roleClass = [
|
||||
\core\base\Controller::ROLE_SUPER_ADMIN => 'danger',
|
||||
\core\base\Controller::ROLE_ADMIN => 'warning',
|
||||
\core\base\Controller::ROLE_OPERATOR => 'info',
|
||||
];
|
||||
$cls = $roleClass[$emp['role']] ?? 'default';
|
||||
?>
|
||||
<span class="label label-<?php echo $cls; ?>">
|
||||
<?php echo htmlspecialchars($roleNames[$emp['role']] ?? $emp['role']); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$catNames = \core\base\Controller::CATEGORY_NAMES;
|
||||
$cat = $emp['category'] ?? 'mes';
|
||||
if ($emp['role'] === \core\base\Controller::ROLE_SUPER_ADMIN) {
|
||||
echo '<span class="label label-danger">全部类目</span>';
|
||||
} else {
|
||||
echo '<span class="label label-primary">' . htmlspecialchars($catNames[$cat] ?? $cat) . '</span>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($emp['created_by'] ?? '-'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
// 只有超级管理员可以操作
|
||||
$canOperate = ($user['role'] === \core\base\Controller::ROLE_SUPER_ADMIN);
|
||||
// 不能操作自己
|
||||
if ($canOperate && (int)$emp['id'] === (int)$user['id']) {
|
||||
$canOperate = false;
|
||||
}
|
||||
?>
|
||||
<?php if ($canOperate): ?>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeePermission/<?php echo $emp['id']; ?>" class="btn btn-xs btn-success"><i class="fa fa-shield"></i> 工位权限</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeEdit/<?php echo $emp['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeResetPwd/<?php echo $emp['id']; ?>" class="btn btn-xs btn-warning"><i class="fa fa-key"></i> 重置密码</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/employeeDelete/<?php echo $emp['id']; ?>" style="display:inline;" onsubmit="return confirm('确定删除该员工?')">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">无操作权限</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="7" class="text-center text-muted">暂无员工数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
$activeMenu = 'employee';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-user-plus"></i> 添加员工</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-group">
|
||||
<label>员工编号 <small class="text-muted">(自动生成)</small></label>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($nextEmpNo); ?>" readonly style="background:#eee;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>姓名 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="emp_name" class="form-control" placeholder="如:张三" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码 <span class="text-danger">*</span></label>
|
||||
<input type="password" name="password" class="form-control" placeholder="默认密码 123456" value="123456" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>权限 <span class="text-danger">*</span></label>
|
||||
<select name="role" id="roleSelect" class="form-control" onchange="toggleCategory()">
|
||||
<?php
|
||||
$roleNames = \core\base\Controller::ROLE_NAMES;
|
||||
$manageableRoles = $manageableRoles ?? [\core\base\Controller::ROLE_OPERATOR, \core\base\Controller::ROLE_ADMIN];
|
||||
foreach ($manageableRoles as $r):
|
||||
?>
|
||||
<option value="<?php echo $r; ?>"><?php echo htmlspecialchars($roleNames[$r] ?? $r); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="categoryGroup">
|
||||
<label>管理类目 <span class="text-danger">*</span> <small class="text-muted">(管理员/操作员必须选择单一类目)</small></label>
|
||||
<select name="category" class="form-control">
|
||||
<?php
|
||||
$catNames = \core\base\Controller::CATEGORY_NAMES;
|
||||
foreach ($catNames as $key => $name):
|
||||
?>
|
||||
<option value="<?php echo $key; ?>"><?php echo htmlspecialchars($name); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<script>
|
||||
function toggleCategory() {
|
||||
var role = document.getElementById('roleSelect').value;
|
||||
var catGroup = document.getElementById('categoryGroup');
|
||||
if (role === 'super_admin') {
|
||||
catGroup.style.display = 'none';
|
||||
} else {
|
||||
catGroup.style.display = 'block';
|
||||
}
|
||||
}
|
||||
// 页面加载时执行一次
|
||||
toggleCategory();
|
||||
</script>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employee" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
$activeMenu = 'employee';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑员工</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>员工编号</label>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($emp['emp_no']); ?>" disabled>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>姓名</label>
|
||||
<input type="text" name="emp_name" class="form-control" value="<?php echo htmlspecialchars($emp['emp_name']); ?>" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>权限 <span class="text-danger">*</span></label>
|
||||
<select name="role" id="roleSelect" class="form-control" onchange="toggleCategory()">
|
||||
<?php
|
||||
$roleNames = \core\base\Controller::ROLE_NAMES;
|
||||
$manageableRoles = $manageableRoles ?? [\core\base\Controller::ROLE_OPERATOR, \core\base\Controller::ROLE_ADMIN];
|
||||
foreach ($manageableRoles as $r):
|
||||
?>
|
||||
<option value="<?php echo $r; ?>" <?php echo ($emp['role'] ?? '') === $r ? 'selected' : ''; ?>><?php echo htmlspecialchars($roleNames[$r] ?? $r); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="categoryGroup">
|
||||
<label>管理类目 <span class="text-danger">*</span></label>
|
||||
<select name="category" class="form-control">
|
||||
<?php
|
||||
$catNames = \core\base\Controller::CATEGORY_NAMES;
|
||||
foreach ($catNames as $key => $name):
|
||||
?>
|
||||
<option value="<?php echo $key; ?>" <?php echo ($emp['category'] ?? 'mes') === $key ? 'selected' : ''; ?>><?php echo htmlspecialchars($name); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<script>
|
||||
function toggleCategory() {
|
||||
var role = document.getElementById('roleSelect').value;
|
||||
var catGroup = document.getElementById('categoryGroup');
|
||||
if (role === 'super_admin') {
|
||||
catGroup.style.display = 'none';
|
||||
} else {
|
||||
catGroup.style.display = 'block';
|
||||
}
|
||||
}
|
||||
toggleCategory();
|
||||
</script>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-warning"><i class="fa fa-save"></i> 更新</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employee" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
$activeMenu = 'employee';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<?php if ($saved): ?>
|
||||
<div class="alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa fa-check"></i> 保存成功!</h4>
|
||||
员工 <strong><?php echo htmlspecialchars($emp['emp_name']); ?></strong> 的工位权限已更新。
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-lock"></i>
|
||||
工位权限设置 -
|
||||
<strong><?php echo htmlspecialchars($emp['emp_name']); ?></strong>
|
||||
<small class="text-muted">(<?php echo htmlspecialchars($emp['emp_no']); ?>)</small>
|
||||
</h3>
|
||||
<div class="box-tools">
|
||||
<?php
|
||||
$roleNames = \core\base\Controller::ROLE_NAMES;
|
||||
$isAdminRole = ($emp['role'] === \core\base\Controller::ROLE_SUPER_ADMIN || $emp['role'] === \core\base\Controller::ROLE_ADMIN);
|
||||
$labelClass = $emp['role'] === \core\base\Controller::ROLE_SUPER_ADMIN ? 'danger' : ($emp['role'] === \core\base\Controller::ROLE_ADMIN ? 'warning' : 'info');
|
||||
?>
|
||||
<span class="label label-<?php echo $labelClass; ?>">
|
||||
<?php echo htmlspecialchars($roleNames[$emp['role']] ?? $emp['role']); ?>
|
||||
<?php echo $isAdminRole ? '(默认拥有全部权限)' : ''; ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php if ($isAdminRole): ?>
|
||||
<div class="callout callout-info">
|
||||
<h4><i class="icon fa fa-info"></i> 提示</h4>
|
||||
<p>超级管理员和管理员默认拥有所有工位的访问权限,无需单独设置。</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="callout callout-warning">
|
||||
<h4><i class="icon fa fa-exclamation-triangle"></i> 权限说明</h4>
|
||||
<ul style="margin-bottom:0;">
|
||||
<li><strong>勾选</strong>:允许该员工访问对应工位</li>
|
||||
<li><strong>不勾选</strong>:该员工无法进入对应工位(前台左侧菜单不显示,直接访问会提示无权限)</li>
|
||||
<li>如果员工没有任何工位被勾选,则默认允许访问所有<strong>已启用</strong>工位</li>
|
||||
<li><span class="label label-danger">禁用</span> 状态的工位<strong>所有人都无法访问</strong>,即使勾选了也无效</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:60px;text-align:center;">
|
||||
<input type="checkbox" id="checkAll" onclick="toggleAll(this)">
|
||||
</th>
|
||||
<th style="width:60px;">#</th>
|
||||
<th>工位编码</th>
|
||||
<th>工位名称</th>
|
||||
<th>工位类型</th>
|
||||
<th style="width:80px;">状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($stations)): ?>
|
||||
<?php foreach ($stations as $i => $station):
|
||||
$stype = $station['station_type'];
|
||||
$isDisabled = $station['status'] == 0;
|
||||
$isChecked = isset($currentPermissions[$stype])
|
||||
? ($currentPermissions[$stype] === 1)
|
||||
: true; // 未配置时默认允许
|
||||
?>
|
||||
<tr class="<?php echo $isDisabled ? 'text-muted' : ''; ?>" style="<?php echo $isDisabled ? 'background:#f5f5f5;' : ''; ?>">
|
||||
<td style="text-align:center;">
|
||||
<input type="checkbox" name="allow[]" value="<?php echo htmlspecialchars($stype); ?>"
|
||||
class="station-check" <?php echo $isChecked ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
<td><?php echo $i + 1; ?></td>
|
||||
<td><code><?php echo htmlspecialchars($station['station_code']); ?></code></td>
|
||||
<td>
|
||||
<?php echo htmlspecialchars($station['station_name']); ?>
|
||||
<?php if ($isDisabled): ?>
|
||||
<small class="text-danger"><i class="fa fa-ban"></i> 已禁用,权限无效</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><span class="label label-default"><?php echo htmlspecialchars($stype); ?></span></td>
|
||||
<td>
|
||||
<?php if ($station['status'] == 1): ?>
|
||||
<span class="label label-success">启用</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger">禁用</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="6" class="text-center text-muted">暂无工位数据,请先在「工位管理」中添加</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
<i class="fa fa-save"></i> 保存权限设置
|
||||
</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employee" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-arrow-left"></i> 返回员工列表
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleAll(source) {
|
||||
var checkboxes = document.querySelectorAll('.station-check');
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].checked = source.checked;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
$activeMenu = 'employee';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-key"></i> 重置密码</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>员工编号</label>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($emp['emp_no']); ?>" disabled>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>姓名</label>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($emp['emp_name']); ?>" disabled>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>新密码</label>
|
||||
<input type="password" name="new_password" class="form-control" placeholder="请输入新密码" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>确认密码</label>
|
||||
<input type="password" name="confirm_password" class="form-control" placeholder="请再次输入新密码" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-warning"><i class="fa fa-key"></i> 重置密码</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employee" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><?php echo $title; ?> - MES</title>
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/AdminLTE.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/_all-skins.min.css">
|
||||
</head>
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<div class="wrapper">
|
||||
<?php include 'header.php'; ?>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1><?php echo $title; ?></h1>
|
||||
</section>
|
||||
|
||||
<section class="content">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">员工列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeAdd" class="btn btn-primary btn-sm">
|
||||
<i class="fa fa-plus"></i> 添加员工
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>员工编号</th>
|
||||
<th>姓名</th>
|
||||
<th>权限</th>
|
||||
<th>操作人</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($employees as $i => $emp): ?>
|
||||
<tr>
|
||||
<td><?php echo $emp['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($emp['emp_no']); ?></td>
|
||||
<td><?php echo htmlspecialchars($emp['emp_name']); ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $emp['role'] === 'admin' ? 'danger' : 'info'; ?>">
|
||||
<?php echo $emp['role'] === 'admin' ? '管理员' : '操作员'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($emp['created_by']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeEdit/<?php echo $emp['id']; ?>" class="btn btn-xs btn-info">编辑</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeResetPwd/<?php echo $emp['id']; ?>" class="btn btn-xs btn-warning">重置密码</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeDelete/<?php echo $emp['id']; ?>" class="btn btn-xs btn-danger confirm-link" data-confirm="确定删除?">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<?php include 'footer.php'; ?>
|
||||
</div>
|
||||
|
||||
<script src="../static/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="../static/js/bootstrap.min.js"></script>
|
||||
<script src="../static/js/app.min.js"></script>
|
||||
<?php // v3-P2 CSP:全局事件委托(替代内联 onclick 等) ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/csp_global.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
<footer class="main-footer">
|
||||
<div class="pull-right hidden-xs"><b>Version</b> 1.0.0</div>
|
||||
<strong>Copyright © 2024 MES.</strong> All rights reserved.
|
||||
</footer>
|
||||
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/app.min.js"></script>
|
||||
@@ -0,0 +1,39 @@
|
||||
<header class="main-header">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index" class="logo">
|
||||
<span class="logo-mini"><b>MES</b></span>
|
||||
<span class="logo-lg"><b>MES</b> 后台管理</span>
|
||||
</a>
|
||||
<nav class="navbar navbar-static-top">
|
||||
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
|
||||
<span class="sr-only">切换导航</span>
|
||||
</a>
|
||||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="hidden-xs"><?php echo htmlspecialchars($user['emp_name']); ?></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="<?php echo BASE_URL; ?>/Login/logout"><i class="fa fa-power-off"></i> 退出登录</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<aside class="main-sidebar">
|
||||
<section class="sidebar">
|
||||
<ul class="sidebar-menu">
|
||||
<li class="header">导航菜单</li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/index"><i class="fa fa-dashboard"></i> <span>控制台</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/employee"><i class="fa fa-users"></i> <span>员工管理</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/customer"><i class="fa fa-building"></i> <span>客户管理</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/productModel"><i class="fa fa-cube"></i> <span>产品型号</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/workstation"><i class="fa fa-th"></i> <span>工位管理</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/config"><i class="fa fa-cog"></i> <span>系统配置</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/import"><i class="fa fa-upload"></i> <span>批量导入</span></a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/Front/index"><i class="fa fa-desktop"></i> <span>前台工位</span></a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</aside>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
$activeMenu = 'import';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<?php if (!empty($msg)): ?>
|
||||
<div class="alert alert-<?php echo strpos($msg, '成功') !== false ? 'success' : 'danger'; ?> alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<i class="fa fa-info-circle"></i> <?php echo htmlspecialchars($msg); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-upload"></i> 批量导入</h3>
|
||||
</div>
|
||||
<form method="post" action="" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>数据表类型</label>
|
||||
<select name="table_type" class="form-control" required>
|
||||
<option value="">请选择</option>
|
||||
<option value="employee">员工数据</option>
|
||||
<option value="customer">客户数据</option>
|
||||
<option value="product_model">产品型号</option>
|
||||
<option value="inbound">半成品入库工位数据</option>
|
||||
<option value="pcb_test">PCB 测试数据</option>
|
||||
<option value="battery">电池状态数据</option>
|
||||
<option value="assembly">产品组装数据</option>
|
||||
<option value="finished_test">成品测试数据</option>
|
||||
<option value="warehouse">成品入库数据</option>
|
||||
<option value="delivery">出货登记数据</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>选择文件 (CSV)</label>
|
||||
<input type="file" name="import_file" class="form-control" accept=".csv" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-upload"></i> 开始导入</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-download"></i> 导入模板下载</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="list-group">
|
||||
<?php
|
||||
$templates = [
|
||||
'employee' => '员工数据模板',
|
||||
'customer' => '客户数据模板',
|
||||
'product_model' => '产品型号模板',
|
||||
'inbound' => '入库工位数据模板',
|
||||
'pcb_test' => 'PCB 测试数据模板',
|
||||
'battery' => '电池状态数据模板',
|
||||
'assembly' => '产品组装数据模板',
|
||||
'finished_test' => '成品测试数据模板',
|
||||
'warehouse' => '入库数据模板',
|
||||
'delivery' => '出货登记数据模板',
|
||||
];
|
||||
foreach ($templates as $key => $label):
|
||||
?>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/importTemplate/<?php echo $key; ?>" class="list-group-item">
|
||||
<i class="fa fa-download text-primary"></i> <?php echo $label; ?> (CSV)
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
$activeMenu = 'index';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner">
|
||||
<h3><?php echo isset($employeeCount) ? $employeeCount : 0; ?></h3>
|
||||
<p>员工总数</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-users"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employee" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h3><?php echo isset($customerCount) ? $customerCount : 0; ?></h3>
|
||||
<p>客户数量</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-building"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/customer" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner">
|
||||
<h3><?php echo isset($modelCount) ? $modelCount : 0; ?></h3>
|
||||
<p>产品型号</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-cube"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModel" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h3><?php echo isset($stationCount) ? $stationCount : 0; ?></h3>
|
||||
<p>工位数量</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-th"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstation" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-info-circle"></i> 系统信息</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>公司名称</dt><dd><?php echo isset($sysConfig) ? htmlspecialchars($sysConfig['company_name']) : '-'; ?></dd>
|
||||
<dt>系统名称</dt><dd><?php echo isset($sysConfig) ? htmlspecialchars($sysConfig['mes_name']) : '-'; ?></dd>
|
||||
<dt>当前用户</dt><dd><?php echo htmlspecialchars($user['emp_name']); ?></dd>
|
||||
<dt>用户角色</dt><dd><span class="label label-info"><?php echo $user['role'] === 'admin' ? '管理员' : '操作员'; ?></span></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-rocket"></i> 快捷操作</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employeeAdd" class="btn btn-primary"><i class="fa fa-user-plus"></i> 添加员工</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstationAdd" class="btn btn-success"><i class="fa fa-plus-square"></i> 添加工位</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/import" class="btn btn-warning"><i class="fa fa-upload"></i> 批量导入</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="btn btn-info"><i class="fa fa-desktop"></i> 进入前台</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
$activeMenu = 'productModel';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
|
||||
// 构建类型颜色和列定义(统一从 typeConfigs 或 getDefaultConfigs 获取)
|
||||
$typeColors = [];
|
||||
$typeColumns = [];
|
||||
|
||||
// 统一数据源:typeConfigs 为空时回退到默认配置
|
||||
$allConfigs = !empty($typeConfigs) ? $typeConfigs : \app\models\ProductTypeConfig::getDefaultConfigs();
|
||||
|
||||
foreach ($allConfigs as $cfg) {
|
||||
$typeColors[$cfg['type_name']] = $cfg['color'] ?? 'default';
|
||||
$cols = [];
|
||||
if (!empty($cfg['display_columns'])) {
|
||||
$decoded = json_decode($cfg['display_columns'], true);
|
||||
if (is_array($decoded)) {
|
||||
$cols = $decoded;
|
||||
}
|
||||
}
|
||||
// 确保有序号列在最前
|
||||
$hasId = false;
|
||||
foreach ($cols as $c) {
|
||||
if (($c['key'] ?? '') === 'id') { $hasId = true; break; }
|
||||
}
|
||||
if (!$hasId) {
|
||||
array_unshift($cols, ['key'=>'id','label'=>'序号','width'=>'60px']);
|
||||
}
|
||||
// 补充 width 字段
|
||||
foreach ($cols as &$c) {
|
||||
if (!isset($c['width'])) $c['width'] = '';
|
||||
}
|
||||
unset($c);
|
||||
$typeColumns[$cfg['type_name']] = $cols;
|
||||
}
|
||||
|
||||
// 通用 fallback 列(所有类型都可用的字段集合)
|
||||
$defaultColumns = [
|
||||
['key'=>'id','label'=>'序号','width'=>'60px'],
|
||||
['key'=>'type','label'=>'类型','width'=>'80px'],
|
||||
['key'=>'model_code','label'=>'产品型号','width'=>''],
|
||||
['key'=>'model_desc','label'=>'产品说明','width'=>''],
|
||||
];
|
||||
|
||||
function renderModelTableRow($model, $columns, $typeName, $idx, $csrfToken) {
|
||||
$html = '<tr>';
|
||||
foreach ($columns as $col) {
|
||||
$key = $col['key'];
|
||||
$val = '';
|
||||
if ($key === 'id') {
|
||||
$val = $idx;
|
||||
} elseif ($key === 'type') {
|
||||
$val = htmlspecialchars($typeName);
|
||||
} elseif (isset($model[$key])) {
|
||||
$val = htmlspecialchars($model[$key]);
|
||||
} else {
|
||||
$val = '-';
|
||||
}
|
||||
$html .= '<td>' . $val . '</td>';
|
||||
}
|
||||
$html .= '<td style="width:150px">
|
||||
<a href="' . BASE_URL . '/Admin/productModelEdit/' . $model['id'] . '" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="POST" action="' . BASE_URL . '/Admin/productModelDelete/' . $model['id'] . '" style="display:inline" onsubmit="return confirm(\'确定删除该型号?\')">
|
||||
<input type="hidden" name="csrf_token" value="' . ($csrfToken ?? '') . '">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>';
|
||||
$html .= '</tr>';
|
||||
return $html;
|
||||
}
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 产品型号列表</h3>
|
||||
<div class="box-tools" style="display:flex; align-items:center; gap:8px;">
|
||||
<span class="column-adjuster" title="调整类型卡片列数" style="display:inline-flex; gap:4px;">
|
||||
<button type="button" class="btn btn-default btn-xs col-btn" data-cols="1" title="1列"><i class="fa fa-align-justify"></i></button>
|
||||
<button type="button" class="btn btn-default btn-xs col-btn active" data-cols="2" title="2列"><i class="fa fa-columns"></i> 2</button>
|
||||
<button type="button" class="btn btn-default btn-xs col-btn" data-cols="3" title="3列"><i class="fa fa-columns"></i> 3</button>
|
||||
<button type="button" class="btn btn-default btn-xs col-btn" data-cols="auto" title="自适应"><i class="fa fa-arrows-h"></i> 自动</button>
|
||||
</span>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productTypeConfig" class="btn btn-warning btn-sm"><i class="fa fa-cogs"></i> 类型配置</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModelAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加产品型号</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($groupedModels)): ?>
|
||||
<div class="type-grid" id="typeGrid">
|
||||
<?php foreach ($groupedModels as $typeName => $models): ?>
|
||||
<div class="box box-<?php echo $typeColors[$typeName] ?? 'default'; ?> type-grid-item">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-tags"></i>
|
||||
<?php echo htmlspecialchars($typeName); ?>
|
||||
<span class="badge bg-<?php echo $typeColors[$typeName] ?? 'default'; ?>"><?php echo count($models); ?></span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php $cols = $typeColumns[$typeName] ?? $defaultColumns; ?>
|
||||
<?php foreach ($cols as $col): ?>
|
||||
<th<?php if ($col['width']) echo ' style="width:' . $col['width'] . '"'; ?>><?php echo $col['label']; ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $idx = 0; ?>
|
||||
<?php foreach ($models as $model): ?>
|
||||
<?php echo renderModelTableRow($model, $cols, $typeName, ++$idx, $csrfToken); ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="box">
|
||||
<div class="box-body text-center text-muted" style="padding:40px;">
|
||||
<i class="fa fa-inbox fa-3x"></i>
|
||||
<p style="margin-top:10px;">暂无产品型号数据</p>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModelAdd" class="btn btn-primary"><i class="fa fa-plus"></i> 添加产品型号</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ========== 类型卡片列数调节 ==========
|
||||
$(function() {
|
||||
var $grid = $('#typeGrid');
|
||||
if (!$grid.length) return;
|
||||
var COL_KEY = 'admin_type_grid_cols';
|
||||
|
||||
function applyColumns(cols) {
|
||||
$grid.attr('data-columns', cols);
|
||||
$('.column-adjuster .col-btn').removeClass('active');
|
||||
$('.column-adjuster .col-btn[data-cols="' + cols + '"]').addClass('active');
|
||||
try { localStorage.setItem(COL_KEY, cols); } catch(e) {}
|
||||
}
|
||||
|
||||
var savedCols = localStorage.getItem(COL_KEY) || '2';
|
||||
applyColumns(savedCols);
|
||||
|
||||
$('.column-adjuster .col-btn').click(function() {
|
||||
applyColumns($(this).data('cols'));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
$activeMenu = 'productModel';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加产品型号</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="icon fa fa-ban"></i> <?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-group">
|
||||
<label>类型 <span class="text-danger">*</span></label>
|
||||
<select name="type" id="typeSelect" class="form-control" required>
|
||||
<option value="">-- 请选择类型 --</option>
|
||||
<?php if (!empty($typeConfigs)): ?>
|
||||
<?php foreach ($typeConfigs as $cfg): ?>
|
||||
<option value="<?php echo htmlspecialchars($cfg['type_name']); ?>"><?php echo htmlspecialchars($cfg['type_name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<option value="成品">成品</option>
|
||||
<option value="电池">电池</option>
|
||||
<option value="外壳">外壳</option>
|
||||
<option value="外壳颜色">外壳颜色</option>
|
||||
<option value="包装">包装</option>
|
||||
<option value="半成品">半成品</option>
|
||||
<option value="配件">配件</option>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="productTypeGroup">
|
||||
<label id="productTypeLabel">产品类型 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="product_type" id="productTypeInput" class="form-control" placeholder="如:电池、外壳,成品" required>
|
||||
</div>
|
||||
<div class="form-group" id="modelCodeGroup">
|
||||
<label>产品型号 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="model_code" id="modelCodeInput" class="form-control" placeholder="如:T8" required>
|
||||
</div>
|
||||
<div class="form-group" id="colorGroup">
|
||||
<label>颜色</label>
|
||||
<input type="text" name="color" id="colorInput" class="form-control" placeholder="如:珍珠白、深空灰">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>产品说明</label>
|
||||
<textarea name="description" class="form-control" rows="3" placeholder="产品描述信息"></textarea>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var $typeSel = $('#typeSelect');
|
||||
var $ptGroup = $('#productTypeGroup');
|
||||
var $ptLabel = $('#productTypeLabel');
|
||||
var $ptInput = $('#productTypeInput');
|
||||
var $modelCodeGroup = $('#modelCodeGroup');
|
||||
var $modelCodeInput = $('#modelCodeInput');
|
||||
var $colorGroup = $('#colorGroup');
|
||||
var $colorInput = $('#colorInput');
|
||||
|
||||
// 类型配置数据(从服务端传入)
|
||||
var typeConfigs = <?php echo json_encode($typeConfigs ?? [], JSON_UNESCAPED_UNICODE); ?>;
|
||||
|
||||
// 构建类型名→配置映射
|
||||
var typeConfigMap = {};
|
||||
if (Array.isArray(typeConfigs)) {
|
||||
typeConfigs.forEach(function(cfg) {
|
||||
typeConfigMap[cfg.type_name] = cfg;
|
||||
});
|
||||
}
|
||||
|
||||
function updateProductTypeField() {
|
||||
var t = $typeSel.val();
|
||||
var cfg = typeConfigMap[t] || {};
|
||||
|
||||
// 产品类型输入框(三态:hidden/readonly/editable)
|
||||
var ptState = cfg.product_type_state || 'editable';
|
||||
var field = cfg.product_type_field || 'product_type';
|
||||
// 当 product_type_field === 'color' 且颜色框可见时,
|
||||
// 隐藏产品类型输入框,避免与颜色输入框 name="color" 冲突
|
||||
var cState = cfg.color_state || 'editable';
|
||||
var hidePtForColor = (field === 'color' && cState !== 'hidden');
|
||||
if (ptState === 'hidden' || hidePtForColor) {
|
||||
$ptGroup.hide();
|
||||
$ptInput.removeAttr('required');
|
||||
} else {
|
||||
$ptGroup.show();
|
||||
var label = cfg.product_type_label || '产品类型';
|
||||
var placeholder = cfg.product_type_placeholder || '';
|
||||
if (!placeholder) {
|
||||
placeholder = '如:' + label;
|
||||
}
|
||||
$ptLabel.html(label + (ptState === 'editable' ? ' <span class="text-danger">*</span>' : ''));
|
||||
$ptInput.attr({name: field, placeholder: placeholder});
|
||||
if (ptState === 'readonly') {
|
||||
$ptInput.prop({readonly: true, required: false});
|
||||
} else {
|
||||
$ptInput.prop({readonly: false, required: true});
|
||||
}
|
||||
}
|
||||
|
||||
// 产品型号输入框(三态:hidden/readonly/editable)
|
||||
var mcState = cfg.model_code_state || 'editable';
|
||||
if (mcState === 'hidden') {
|
||||
$modelCodeGroup.hide();
|
||||
$modelCodeInput.removeAttr('required').val('');
|
||||
} else {
|
||||
$modelCodeGroup.show();
|
||||
if (mcState === 'readonly') {
|
||||
$modelCodeInput.prop({readonly: true, required: false});
|
||||
} else {
|
||||
$modelCodeInput.prop({readonly: false, required: true});
|
||||
}
|
||||
}
|
||||
|
||||
// 颜色输入框(三态:hidden/readonly/editable)
|
||||
var cState = cfg.color_state || 'editable';
|
||||
if (cState === 'hidden') {
|
||||
$colorGroup.hide();
|
||||
$colorInput.val('');
|
||||
} else {
|
||||
$colorGroup.show();
|
||||
if (cState === 'readonly') {
|
||||
$colorInput.prop('readonly', true);
|
||||
} else {
|
||||
$colorInput.prop('readonly', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$typeSel.on('change', updateProductTypeField);
|
||||
updateProductTypeField();
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModel" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
$activeMenu = 'productModel';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑产品型号</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="icon fa fa-ban"></i> <?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-group">
|
||||
<label>类型 <span class="text-danger">*</span></label>
|
||||
<select name="type" id="typeSelect" class="form-control" required>
|
||||
<option value="">-- 请选择类型 --</option>
|
||||
<?php if (!empty($typeConfigs)): ?>
|
||||
<?php foreach ($typeConfigs as $cfg): ?>
|
||||
<option value="<?php echo htmlspecialchars($cfg['type_name']); ?>" <?php echo (($model['type'] ?? '') === $cfg['type_name']) ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($cfg['type_name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<?php foreach (['成品', '电池', '外壳', '外壳颜色', '包装', '半成品', '配件'] as $t): ?>
|
||||
<option value="<?php echo $t; ?>" <?php echo (($model['type'] ?? '') === $t) ? 'selected' : ''; ?>>
|
||||
<?php echo $t; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="productTypeGroup">
|
||||
<label id="productTypeLabel">产品类型 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="product_type" id="productTypeInput" class="form-control" value="<?php echo htmlspecialchars($model['product_type'] ?? ''); ?>" placeholder="如:电池、外壳,成品" required>
|
||||
</div>
|
||||
<div class="form-group" id="modelCodeGroup">
|
||||
<label>产品型号 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="model_code" id="modelCodeInput" class="form-control" value="<?php echo htmlspecialchars($model['model_code']); ?>" required>
|
||||
</div>
|
||||
<div class="form-group" id="colorGroup">
|
||||
<label>颜色</label>
|
||||
<input type="text" name="color" id="colorInput" class="form-control" value="<?php echo htmlspecialchars($model['color'] ?? ''); ?>" placeholder="如:珍珠白、深空灰">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>产品说明</label>
|
||||
<textarea name="description" class="form-control" rows="3"><?php echo htmlspecialchars($model['model_desc'] ?? ''); ?></textarea>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var $typeSel = $('#typeSelect');
|
||||
var $ptGroup = $('#productTypeGroup');
|
||||
var $ptLabel = $('#productTypeLabel');
|
||||
var $ptInput = $('#productTypeInput');
|
||||
var $modelCodeGroup = $('#modelCodeGroup');
|
||||
var $modelCodeInput = $('#modelCodeInput');
|
||||
var $colorGroup = $('#colorGroup');
|
||||
var $colorInput = $('#colorInput');
|
||||
|
||||
// 编辑时原始值
|
||||
var editProductType = <?php echo json_encode($model['product_type'] ?? '', JSON_UNESCAPED_UNICODE); ?>;
|
||||
var editModelCode = <?php echo json_encode($model['model_code'] ?? '', JSON_UNESCAPED_UNICODE); ?>;
|
||||
var editColor = <?php echo json_encode($model['color'] ?? '', JSON_UNESCAPED_UNICODE); ?>;
|
||||
|
||||
// 类型配置数据(从服务端传入)
|
||||
var typeConfigs = <?php echo json_encode($typeConfigs ?? [], JSON_UNESCAPED_UNICODE); ?>;
|
||||
|
||||
// 构建类型名→配置映射
|
||||
var typeConfigMap = {};
|
||||
if (Array.isArray(typeConfigs)) {
|
||||
typeConfigs.forEach(function(cfg) {
|
||||
typeConfigMap[cfg.type_name] = cfg;
|
||||
});
|
||||
}
|
||||
|
||||
function updateProductTypeField() {
|
||||
var t = $typeSel.val();
|
||||
var cfg = typeConfigMap[t] || {};
|
||||
|
||||
// 产品类型输入框(三态:hidden/readonly/editable)
|
||||
var ptState = cfg.product_type_state || 'editable';
|
||||
if (ptState === 'hidden') {
|
||||
$ptGroup.hide();
|
||||
$ptInput.removeAttr('required').val('');
|
||||
} else {
|
||||
$ptGroup.show();
|
||||
var label = cfg.product_type_label || '产品类型';
|
||||
var field = cfg.product_type_field || 'product_type';
|
||||
var placeholder = cfg.product_type_placeholder || '';
|
||||
if (!placeholder) {
|
||||
placeholder = '如:' + label;
|
||||
}
|
||||
$ptLabel.html(label + (ptState === 'editable' ? ' <span class="text-danger">*</span>' : ''));
|
||||
$ptInput.attr({name: field, placeholder: placeholder});
|
||||
if (ptState === 'readonly') {
|
||||
$ptInput.prop({readonly: true, required: false});
|
||||
} else {
|
||||
$ptInput.prop({readonly: false, required: true});
|
||||
}
|
||||
// 编辑时恢复原始值
|
||||
if (editProductType) {
|
||||
$ptInput.val(editProductType);
|
||||
}
|
||||
}
|
||||
|
||||
// 产品型号输入框(三态:hidden/readonly/editable)
|
||||
var mcState = cfg.model_code_state || 'editable';
|
||||
if (mcState === 'hidden') {
|
||||
$modelCodeGroup.hide();
|
||||
$modelCodeInput.removeAttr('required').val('');
|
||||
} else {
|
||||
$modelCodeGroup.show();
|
||||
if (mcState === 'readonly') {
|
||||
$modelCodeInput.prop({readonly: true, required: false});
|
||||
} else {
|
||||
$modelCodeInput.prop({readonly: false, required: true});
|
||||
}
|
||||
if (editModelCode) {
|
||||
$modelCodeInput.val(editModelCode);
|
||||
}
|
||||
}
|
||||
|
||||
// 颜色输入框(三态:hidden/readonly/editable)
|
||||
var cState = cfg.color_state || 'editable';
|
||||
if (cState === 'hidden') {
|
||||
$colorGroup.hide();
|
||||
$colorInput.val('');
|
||||
} else {
|
||||
$colorGroup.show();
|
||||
if (cState === 'readonly') {
|
||||
$colorInput.prop('readonly', true);
|
||||
} else {
|
||||
$colorInput.prop('readonly', false);
|
||||
}
|
||||
if (editColor) {
|
||||
$colorInput.val(editColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$typeSel.on('change', updateProductTypeField);
|
||||
updateProductTypeField();
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-warning"><i class="fa fa-save"></i> 更新</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModel" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
$activeMenu = 'productSearch';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
<!-- 产品追溯搜索 -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-search"></i> 产品追溯查询</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<form method="GET" action="<?php echo BASE_URL; ?>/Admin/productSearch" class="form-inline">
|
||||
<div class="form-group" style="width:70%;">
|
||||
<div class="input-group" style="width:100%;">
|
||||
<input type="text" name="keyword" class="form-control input-lg"
|
||||
placeholder="输入成品序列号 / 电池序列号 / PCB序列号 / 产品型号 进行查询..."
|
||||
value="<?php echo htmlspecialchars($keyword); ?>" autofocus>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-primary btn-lg"><i class="fa fa-search"></i> 查询</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<small class="help-block" style="margin-left:5px; color:#999;">
|
||||
<i class="fa fa-info-circle"></i> 支持模糊搜索:成品序列号、电池序列号、PCB序列号、产品型号
|
||||
</small>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($searched): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">
|
||||
<i class="fa fa-list"></i> 查询结果
|
||||
<small class="label label-primary">共 <?php echo count($results); ?> 条记录</small>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<?php if (empty($results)): ?>
|
||||
<div class="callout callout-warning" style="margin:15px;">
|
||||
<h4><i class="fa fa-warning"></i> 未找到匹配记录</h4>
|
||||
<p>关键词 "<?php echo htmlspecialchars($keyword); ?>" 未匹配到任何产品记录,请检查输入。</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<table class="table table-bordered table-hover table-striped" style="font-size:13px;">
|
||||
<thead>
|
||||
<tr style="background:#3c8dbc; color:#fff;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">成品序列号</th>
|
||||
<th style="text-align:center;">产品型号</th>
|
||||
<th style="text-align:center;">电池序列号</th>
|
||||
<th style="text-align:center;">PCB序列号</th>
|
||||
<th style="text-align:center;">操作员</th>
|
||||
<th style="text-align:center;">组装时间</th>
|
||||
<th style="text-align:center;">电池电压平台</th>
|
||||
<th style="text-align:center;">PCB测试结果</th>
|
||||
<th style="text-align:center;">成品测试结果</th>
|
||||
<th style="text-align:center;">入库时间</th>
|
||||
<th style="text-align:center;">出货客户</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $i = 1; foreach ($results as $row): ?>
|
||||
<tr>
|
||||
<td style="text-align:center;"><?php echo $i++; ?></td>
|
||||
<td style="text-align:center; font-weight:bold; color:#3c8dbc;">
|
||||
<?php echo htmlspecialchars($row['finished_serial']); ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<span class="label label-info"><?php echo htmlspecialchars($row['product_model']); ?></span>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo htmlspecialchars($row['battery_serial']); ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo htmlspecialchars($row['pcb_serial']); ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo htmlspecialchars($row['operator']); ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo htmlspecialchars($row['assembly_time']); ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo htmlspecialchars($row['voltage_platform']); ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php if (!empty($row['pcb_test_status'])): ?>
|
||||
<span class="label label-<?php echo stripos($row['pcb_test_status'], 'OK') !== false || stripos($row['pcb_test_status'], '合格') !== false || stripos($row['pcb_test_status'], 'pass') !== false ? 'success' : 'danger'; ?>">
|
||||
<?php echo htmlspecialchars($row['pcb_test_status']); ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php if (!empty($row['finished_test_result'])): ?>
|
||||
<span class="label label-<?php echo stripos($row['finished_test_result'], 'OK') !== false || stripos($row['finished_test_result'], '合格') !== false || stripos($row['finished_test_result'], 'pass') !== false ? 'success' : 'danger'; ?>">
|
||||
<?php echo htmlspecialchars($row['finished_test_result']); ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo !empty($row['warehouse_time']) ? htmlspecialchars($row['warehouse_time']) : '<span class="text-muted">未入库</span>'; ?>
|
||||
</td>
|
||||
<td style="text-align:center;">
|
||||
<?php echo !empty($row['delivery_customer']) ? htmlspecialchars($row['delivery_customer']) : '<span class="text-muted">未出货</span>'; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
|
||||
@@ -0,0 +1,568 @@
|
||||
<?php
|
||||
$activeMenu = 'productModel';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
|
||||
// 构建类型配置完整数据,包含解析后的 display_columns
|
||||
$configsWithParsed = [];
|
||||
if (!empty($configs)) {
|
||||
foreach ($configs as $cfg) {
|
||||
$cfg['_columns'] = [];
|
||||
if (!empty($cfg['display_columns'])) {
|
||||
$decoded = json_decode($cfg['display_columns'], true);
|
||||
if (is_array($decoded)) {
|
||||
$cfg['_columns'] = $decoded;
|
||||
}
|
||||
}
|
||||
// 确保有序号列
|
||||
$hasId = false;
|
||||
foreach ($cfg['_columns'] as $c) {
|
||||
if (($c['key'] ?? '') === 'id') { $hasId = true; break; }
|
||||
}
|
||||
if (!$hasId) {
|
||||
array_unshift($cfg['_columns'], ['key' => 'id', 'label' => '序号', 'width' => '60px']);
|
||||
}
|
||||
$configsWithParsed[] = $cfg;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-cogs"></i> 产品类型配置</h3>
|
||||
<div class="box-tools">
|
||||
<button type="button" class="btn btn-success btn-sm" id="addTypeBtn"><i class="fa fa-plus"></i> 添加类型</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModel" class="btn btn-default btn-sm"><i class="fa fa-arrow-left"></i> 返回型号列表</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:50px">排序</th>
|
||||
<th>类型名称</th>
|
||||
<th>列表显示列</th>
|
||||
<th style="width:90px">产品类型输入框</th>
|
||||
<th>输入框标签</th>
|
||||
<th>提交字段</th>
|
||||
<th style="width:70px">颜色</th>
|
||||
<th style="width:60px">启用</th>
|
||||
<th style="width:80px">入库显示</th>
|
||||
<th style="width:120px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($configsWithParsed)): ?>
|
||||
<?php foreach ($configsWithParsed as $cfg): ?>
|
||||
<tr>
|
||||
<td><?php echo $cfg['sort_order']; ?></td>
|
||||
<td><strong><?php echo htmlspecialchars($cfg['type_name']); ?></strong></td>
|
||||
<td>
|
||||
<?php
|
||||
$colLabels = [];
|
||||
foreach ($cfg['_columns'] as $col) {
|
||||
$colLabels[] = htmlspecialchars($col['label'] ?? $col['key']);
|
||||
}
|
||||
echo implode(' → ', $colLabels);
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$ptState = $cfg['product_type_state'] ?? 'editable';
|
||||
if ($ptState === 'hidden'): ?>
|
||||
<span class="label label-default">隐藏</span>
|
||||
<?php elseif ($ptState === 'readonly'): ?>
|
||||
<span class="label label-warning">只读</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-success">可编辑</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($cfg['product_type_label'] ?? '产品类型'); ?></td>
|
||||
<td><code><?php echo htmlspecialchars($cfg['product_type_field'] ?? 'product_type'); ?></code></td>
|
||||
<td><span class="label label-<?php echo htmlspecialchars($cfg['color'] ?? 'default'); ?>"><?php echo htmlspecialchars($cfg['color'] ?? 'default'); ?></span></td>
|
||||
<td><?php echo $cfg['enabled'] ? '<span class="label label-success">启用</span>' : '<span class="label label-danger">禁用</span>'; ?></td>
|
||||
<td><?php echo ($cfg['show_in_inbound'] ?? 1) ? '<span class="label label-success">显示</span>' : '<span class="label label-default">隐藏</span>'; ?></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-xs btn-info pt-edit-btn" data-id="<?php echo $cfg['id']; ?>"><i class="fa fa-edit"></i> 编辑</button>
|
||||
<button type="button" class="btn btn-xs btn-danger pt-del-btn" data-id="<?php echo $cfg['id']; ?>" data-name="<?php echo htmlspecialchars($cfg['type_name'], ENT_QUOTES); ?>"><i class="fa fa-trash"></i> 删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="10" class="text-center text-muted" style="padding:30px;">暂无配置,请先执行 SQL 初始化或点击"添加类型"</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑/添加弹窗 -->
|
||||
<div class="modal fade" id="configModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title" id="configModalTitle">编辑类型配置</h4>
|
||||
</div>
|
||||
<form id="configForm">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="id" id="cfgId" value="0">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>类型名称 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="type_name" id="cfgTypeName" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>排序</label>
|
||||
<input type="number" name="sort_order" id="cfgSortOrder" class="form-control" value="0" min="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Box颜色</label>
|
||||
<select name="color" id="cfgColor" class="form-control">
|
||||
<option value="default">default(灰)</option>
|
||||
<option value="success">success(绿)</option>
|
||||
<option value="primary">primary(蓝)</option>
|
||||
<option value="info">info(青)</option>
|
||||
<option value="warning">warning(黄)</option>
|
||||
<option value="danger">danger(红)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>输入框标签</label>
|
||||
<input type="text" name="product_type_label" id="cfgPtLabel" class="form-control" placeholder="如:容量、颜色">
|
||||
<small class="text-muted">添加/编辑页面第二个输入框的标签文字</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>提交字段名</label>
|
||||
<input type="text" name="product_type_field" id="cfgPtField" class="form-control" placeholder="product_type / capacity / color">
|
||||
<small class="text-muted">表单提交时的字段名(后端据此识别)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>输入框占位提示</label>
|
||||
<input type="text" name="product_type_placeholder" id="cfgPtPlaceholder" class="form-control" placeholder="如:2000mAh">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>产品类型输入框</label>
|
||||
<select name="product_type_state" id="cfgProductTypeState" class="form-control">
|
||||
<option value="editable">可编辑</option>
|
||||
<option value="readonly">只读</option>
|
||||
<option value="hidden">隐藏</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>产品型号输入框</label>
|
||||
<select name="model_code_state" id="cfgModelCodeState" class="form-control">
|
||||
<option value="editable">可编辑</option>
|
||||
<option value="readonly">只读</option>
|
||||
<option value="hidden">隐藏</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>颜色输入框</label>
|
||||
<select name="color_state" id="cfgColorState" class="form-control">
|
||||
<option value="editable">可编辑</option>
|
||||
<option value="readonly">只读</option>
|
||||
<option value="hidden">隐藏</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>启用</label>
|
||||
<select name="enabled" id="cfgEnabled" class="form-control">
|
||||
<option value="1">启用</option>
|
||||
<option value="0">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>入库页显示</label>
|
||||
<select name="show_in_inbound" id="cfgShowInInbound" class="form-control">
|
||||
<option value="1">显示</option>
|
||||
<option value="0">隐藏</option>
|
||||
</select>
|
||||
<small class="text-muted">控制该类型在入库工位的下拉选项中是否可见</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 列表显示列 - 复选框编辑器 -->
|
||||
<div class="form-group">
|
||||
<label>列表显示列</label>
|
||||
<div class="well well-sm" style="margin-bottom:8px; padding:8px 10px;">
|
||||
<small class="text-muted"><i class="fa fa-info-circle"></i> 勾选需要在列表页显示的列。序号列自动包含,无需选择。拖拽调整顺序。</small>
|
||||
</div>
|
||||
|
||||
<!-- 可选字段区 -->
|
||||
<div style="margin-bottom:8px;">
|
||||
<label class="text-muted" style="font-weight:normal; margin-right:8px;">可选字段:</label>
|
||||
<label class="checkbox-inline" style="margin-right:10px;">
|
||||
<input type="checkbox" class="col-checkbox" data-key="type" data-label="类型" data-width="80px"> 类型
|
||||
</label>
|
||||
<label class="checkbox-inline" style="margin-right:10px;">
|
||||
<input type="checkbox" class="col-checkbox" data-key="model_code" data-label="产品型号" data-width=""> 产品型号
|
||||
</label>
|
||||
<label class="checkbox-inline" style="margin-right:10px;">
|
||||
<input type="checkbox" class="col-checkbox" data-key="color" data-label="颜色" data-width="120px"> 颜色
|
||||
</label>
|
||||
<label class="checkbox-inline" style="margin-right:10px;">
|
||||
<input type="checkbox" class="col-checkbox" data-key="capacity" data-label="容量" data-width="120px"> 容量
|
||||
</label>
|
||||
<label class="checkbox-inline" style="margin-right:10px;">
|
||||
<input type="checkbox" class="col-checkbox" data-key="model_desc" data-label="产品说明" data-width=""> 产品说明
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- 已选列预览 -->
|
||||
<div id="selectedColumnsPreview" style="min-height:36px; padding:6px 8px; border:1px dashed #ccc; border-radius:4px; background:#fafafa;">
|
||||
<span id="noColumnsHint" class="text-muted">暂未选择列</span>
|
||||
</div>
|
||||
<div style="margin-top:5px;">
|
||||
<button type="button" class="btn btn-xs btn-warning" id="resetColsBtn"><i class="fa fa-refresh"></i> 恢复默认</button>
|
||||
<button type="button" class="btn btn-xs btn-default" id="clearColsBtn"><i class="fa fa-times"></i> 清空</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="display_columns" id="cfgDisplayCols" value="">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
var BASE_URL = '<?php echo BASE_URL; ?>';
|
||||
var configsData = <?php echo json_encode($configs ?? [], JSON_UNESCAPED_UNICODE); ?>;
|
||||
|
||||
// 当前编辑中的列数据(按显示顺序)
|
||||
var editColumns = [];
|
||||
|
||||
// 所有可用字段定义
|
||||
var allFields = [
|
||||
{key:'type', label:'类型', width:'80px'},
|
||||
{key:'model_code', label:'产品型号', width:''},
|
||||
{key:'color', label:'颜色', width:'120px'},
|
||||
{key:'capacity', label:'容量', width:'120px'},
|
||||
{key:'model_desc', label:'产品说明', width:''}
|
||||
];
|
||||
|
||||
// 构建 key→field 映射
|
||||
var fieldMap = {};
|
||||
allFields.forEach(function(f) { fieldMap[f.key] = f; });
|
||||
|
||||
// 默认列模板(按类型名,返回 key 数组)
|
||||
function getDefaultKeys(typeName) {
|
||||
var tn = (typeName || '').trim();
|
||||
if (tn === '电池') {
|
||||
return ['model_code', 'capacity', 'model_desc'];
|
||||
} else if (tn === '外壳') {
|
||||
return ['model_code', 'color', 'model_desc'];
|
||||
} else if (tn === '外壳颜色') {
|
||||
return ['color', 'model_desc'];
|
||||
} else {
|
||||
return ['type', 'model_code', 'model_desc'];
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultColumns(typeName) {
|
||||
var keys = getDefaultKeys(typeName);
|
||||
return keys.map(function(k) {
|
||||
var f = fieldMap[k] || {key:k, label:k, width:''};
|
||||
return {key: f.key, label: f.label, width: f.width};
|
||||
});
|
||||
}
|
||||
|
||||
// 根据 editColumns 刷新复选框状态和预览
|
||||
function syncCheckboxesFromColumns() {
|
||||
var selectedKeys = {};
|
||||
editColumns.forEach(function(c) { selectedKeys[c.key] = true; });
|
||||
|
||||
$('.col-checkbox').each(function() {
|
||||
$(this).prop('checked', !!selectedKeys[$(this).data('key')]);
|
||||
});
|
||||
renderPreview();
|
||||
updateHiddenInput();
|
||||
}
|
||||
|
||||
// 根据复选框状态重建 editColumns(保持已有顺序,新增追加末尾,取消的移除)
|
||||
function syncColumnsFromCheckboxes() {
|
||||
var checkedKeys = {};
|
||||
$('.col-checkbox:checked').each(function() {
|
||||
checkedKeys[$(this).data('key')] = true;
|
||||
});
|
||||
|
||||
// 移除已取消的
|
||||
editColumns = editColumns.filter(function(c) { return checkedKeys[c.key]; });
|
||||
|
||||
// 追加新勾选的
|
||||
$('.col-checkbox:checked').each(function() {
|
||||
var key = $(this).data('key');
|
||||
if (!editColumns.some(function(c) { return c.key === key; })) {
|
||||
var label = $(this).data('label');
|
||||
var width = $(this).data('width') || '';
|
||||
editColumns.push({key: key, label: label, width: width});
|
||||
}
|
||||
});
|
||||
|
||||
renderPreview();
|
||||
updateHiddenInput();
|
||||
}
|
||||
|
||||
// 渲染已选列预览(可拖拽排序的标签)
|
||||
function renderPreview() {
|
||||
var container = document.getElementById('selectedColumnsPreview');
|
||||
var hint = document.getElementById('noColumnsHint');
|
||||
|
||||
if (!editColumns.length) {
|
||||
container.innerHTML = '';
|
||||
container.appendChild(hint || createHint());
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
editColumns.forEach(function(col, i) {
|
||||
html += '<span class="label label-primary column-tag" draggable="true" data-idx="' + i + '" style="display:inline-block; margin:2px 4px; padding:6px 10px; font-size:13px; cursor:grab; user-select:none;">';
|
||||
html += escHtml(col.label);
|
||||
html += ' <a href="#" class="column-remove" data-idx="' + i + '" style="color:#fff; opacity:0.7; margin-left:4px;" title="移除">×</a>';
|
||||
html += '</span>';
|
||||
});
|
||||
container.innerHTML = html;
|
||||
|
||||
// 拖拽排序
|
||||
var tags = container.querySelectorAll('.column-tag');
|
||||
var dragSrc = null;
|
||||
|
||||
tags.forEach(function(tag) {
|
||||
tag.addEventListener('dragstart', function(e) {
|
||||
dragSrc = this;
|
||||
this.style.opacity = '0.4';
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
});
|
||||
tag.addEventListener('dragend', function(e) {
|
||||
this.style.opacity = '1';
|
||||
tags.forEach(function(t) { t.style.borderTop = ''; });
|
||||
});
|
||||
tag.addEventListener('dragover', function(e) {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
this.style.borderTop = '2px solid #3c8dbc';
|
||||
});
|
||||
tag.addEventListener('dragleave', function(e) {
|
||||
this.style.borderTop = '';
|
||||
});
|
||||
tag.addEventListener('drop', function(e) {
|
||||
e.preventDefault();
|
||||
this.style.borderTop = '';
|
||||
if (dragSrc !== this) {
|
||||
var fromIdx = parseInt(dragSrc.getAttribute('data-idx'));
|
||||
var toIdx = parseInt(this.getAttribute('data-idx'));
|
||||
var moved = editColumns.splice(fromIdx, 1)[0];
|
||||
editColumns.splice(toIdx, 0, moved);
|
||||
renderPreview();
|
||||
updateHiddenInput();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createHint() {
|
||||
var span = document.createElement('span');
|
||||
span.id = 'noColumnsHint';
|
||||
span.className = 'text-muted';
|
||||
span.textContent = '暂未选择列';
|
||||
return span;
|
||||
}
|
||||
|
||||
function removeColumn(idx) {
|
||||
var key = editColumns[idx].key;
|
||||
editColumns.splice(idx, 1);
|
||||
// 同步取消复选框
|
||||
$('.col-checkbox[data-key="' + key + '"]').prop('checked', false);
|
||||
renderPreview();
|
||||
updateHiddenInput();
|
||||
}
|
||||
|
||||
function clearAllColumns() {
|
||||
editColumns = [];
|
||||
$('.col-checkbox').prop('checked', false);
|
||||
renderPreview();
|
||||
updateHiddenInput();
|
||||
}
|
||||
|
||||
function resetColumnsToDefault() {
|
||||
var typeName = $('#cfgTypeName').val().trim();
|
||||
editColumns = JSON.parse(JSON.stringify(getDefaultColumns(typeName)));
|
||||
syncCheckboxesFromColumns();
|
||||
}
|
||||
|
||||
function updateHiddenInput() {
|
||||
document.getElementById('cfgDisplayCols').value = JSON.stringify(editColumns);
|
||||
}
|
||||
|
||||
function escHtml(s) { return (s||'').replace(/&/g,'&').replace(/"/g,'"').replace(/</g,'<').replace(/>/g,'>'); }
|
||||
|
||||
// ===== 轻量 Modal Polyfill(不依赖 Bootstrap JS) =====
|
||||
var _modalPolyfill = {
|
||||
show: function(modalId) {
|
||||
var $modal = $(modalId);
|
||||
if (!$modal.length) return;
|
||||
if (!$('.modal-backdrop').length) {
|
||||
$('body').append('<div class="modal-backdrop fade in" style="z-index:1040;"></div>');
|
||||
}
|
||||
$modal.css({display:'block', 'z-index':1050}).addClass('in');
|
||||
$('body').addClass('modal-open');
|
||||
$modal.find('[data-dismiss="modal"]').off('click.modalPolyfill').on('click.modalPolyfill', function(){
|
||||
_modalPolyfill.hide(modalId);
|
||||
});
|
||||
$('.modal-backdrop').off('click.modalPolyfill').on('click.modalPolyfill', function(){
|
||||
_modalPolyfill.hide(modalId);
|
||||
});
|
||||
$(document).off('keydown.modalPolyfill').on('keydown.modalPolyfill', function(e){
|
||||
if (e.keyCode === 27) _modalPolyfill.hide(modalId);
|
||||
});
|
||||
},
|
||||
hide: function(modalId) {
|
||||
var $modal = $(modalId);
|
||||
$modal.removeClass('in').css('display', '');
|
||||
$('.modal-backdrop').remove();
|
||||
$('body').removeClass('modal-open');
|
||||
$(document).off('keydown.modalPolyfill');
|
||||
}
|
||||
};
|
||||
|
||||
function safeModal(action, modalId) {
|
||||
if (typeof $.fn.modal === 'function') {
|
||||
$(modalId).modal(action);
|
||||
} else {
|
||||
if (action === 'show') _modalPolyfill.show(modalId);
|
||||
else if (action === 'hide') _modalPolyfill.hide(modalId);
|
||||
}
|
||||
}
|
||||
|
||||
function openEditModal(id) {
|
||||
var cfg = {};
|
||||
if (id > 0) {
|
||||
for (var i = 0; i < configsData.length; i++) {
|
||||
if (configsData[i].id == id) { cfg = configsData[i]; break; }
|
||||
}
|
||||
$('#configModalTitle').text('编辑类型配置');
|
||||
} else {
|
||||
$('#configModalTitle').text('添加类型配置');
|
||||
cfg = {
|
||||
id: 0, type_name: '', sort_order: configsData.length + 1,
|
||||
display_columns: '', product_type_state: 'editable',
|
||||
product_type_label: '产品类型', product_type_field: 'product_type',
|
||||
product_type_placeholder: '', model_code_state: 'editable',
|
||||
color_state: 'editable', color: 'default', enabled: 1,
|
||||
show_in_inbound: 1
|
||||
};
|
||||
}
|
||||
$('#cfgId').val(cfg.id || 0);
|
||||
$('#cfgTypeName').val(cfg.type_name || '');
|
||||
$('#cfgSortOrder').val(cfg.sort_order || 0);
|
||||
$('#cfgProductTypeState').val(cfg.product_type_state || 'editable');
|
||||
$('#cfgPtLabel').val(cfg.product_type_label || '产品类型');
|
||||
$('#cfgPtField').val(cfg.product_type_field || 'product_type');
|
||||
$('#cfgPtPlaceholder').val(cfg.product_type_placeholder || '');
|
||||
$('#cfgModelCodeState').val(cfg.model_code_state || 'editable');
|
||||
$('#cfgColorState').val(cfg.color_state || 'editable');
|
||||
$('#cfgColor').val(cfg.color || 'default');
|
||||
$('#cfgEnabled').val(cfg.enabled !== undefined ? cfg.enabled : 1);
|
||||
$('#cfgShowInInbound').val(cfg.show_in_inbound !== undefined ? cfg.show_in_inbound : 1);
|
||||
|
||||
// 解析 display_columns JSON
|
||||
editColumns = [];
|
||||
if (cfg.display_columns) {
|
||||
try {
|
||||
var parsed = JSON.parse(cfg.display_columns);
|
||||
if (Array.isArray(parsed)) {
|
||||
editColumns = parsed.filter(function(c) { return c.key !== 'id'; });
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
if (!editColumns.length) {
|
||||
editColumns = JSON.parse(JSON.stringify(getDefaultColumns(cfg.type_name || '')));
|
||||
}
|
||||
syncCheckboxesFromColumns();
|
||||
|
||||
safeModal('show', '#configModal');
|
||||
}
|
||||
|
||||
// 复选框变化时同步
|
||||
$(document).on('change', '.col-checkbox', function() {
|
||||
syncColumnsFromCheckboxes();
|
||||
});
|
||||
|
||||
// ===== CSP:事件绑定(替代内联 onclick/javascript:) =====
|
||||
$('#addTypeBtn').on('click', function() { openEditModal(0); });
|
||||
$('#resetColsBtn').on('click', resetColumnsToDefault);
|
||||
$('#clearColsBtn').on('click', clearAllColumns);
|
||||
$(document).on('click', '.pt-edit-btn', function() { openEditModal($(this).data('id')); });
|
||||
$(document).on('click', '.pt-del-btn', function() { deleteConfig($(this).data('id'), $(this).data('name')); });
|
||||
$('#selectedColumnsPreview').on('click', '.column-remove', function(e) {
|
||||
e.preventDefault();
|
||||
removeColumn(parseInt($(this).attr('data-idx'), 10));
|
||||
});
|
||||
|
||||
function deleteConfig(id, name) {
|
||||
if (!confirm('确定删除类型「' + name + '」吗?\n注意:已使用该类型的产品型号不会受影响,但添加新型号时不再显示此类型。')) return;
|
||||
$.ajax({
|
||||
url: window.location.href, type: 'POST',
|
||||
data: { csrf_token: $('input[name="csrf_token"]').val(), action: 'delete', id: id },
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
if (res.success) location.reload();
|
||||
else alert('删除失败: ' + (res.error || '未知错误'));
|
||||
},
|
||||
error: function() { alert('网络错误'); }
|
||||
});
|
||||
}
|
||||
|
||||
$('#configForm').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
updateHiddenInput();
|
||||
var data = $(this).serialize() + '&action=save';
|
||||
$.ajax({
|
||||
url: window.location.href, type: 'POST', data: data, dataType: 'json',
|
||||
success: function(res) {
|
||||
if (res.success) location.reload();
|
||||
else alert('保存失败: ' + (res.error || '未知错误'));
|
||||
},
|
||||
error: function() { alert('网络错误'); }
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
$activeMenu = 'workstation';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 工位列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstationAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加工位</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:60px">序号</th>
|
||||
<th>工位名称</th>
|
||||
<th>工位编码</th>
|
||||
<th>工位类型</th>
|
||||
<th>排序</th>
|
||||
<th>状态</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($stations)): ?>
|
||||
<?php foreach ($stations as $station): ?>
|
||||
<tr>
|
||||
<td><?php echo $station['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($station['station_name']); ?></td>
|
||||
<td><code><?php echo htmlspecialchars($station['station_code']); ?></code></td>
|
||||
<td><?php echo htmlspecialchars($station['station_type']); ?></td>
|
||||
<td><?php echo $station['sort_order']; ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $station['status'] == 1 ? 'success' : 'danger'; ?>">
|
||||
<?php echo $station['status'] == 1 ? '启用' : '禁用'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstationEdit/<?php echo $station['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Admin/workstationDelete/<?php echo $station['id']; ?>" style="display:inline;" onsubmit="return confirm('确定删除该工位?')">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="7" class="text-center text-muted">暂无工位数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
$activeMenu = 'workstation';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加工位</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa fa-ban"></i> 操作失败</h4>
|
||||
<?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-group">
|
||||
<label>工位名称 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="station_name" class="form-control" placeholder="如:入库工位" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>工位编码 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="station_code" class="form-control" placeholder="如:STATION_INBOUND" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>工位类型 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="station_type" class="form-control" placeholder="英文标识,如:painting、welding" required
|
||||
pattern="[a-zA-Z][a-zA-Z0-9_]*" title="必须以字母开头,只能包含字母、数字和下划线">
|
||||
<small class="text-muted">用于系统路由和权限识别,必须以字母开头,建议使用英文小写+下划线</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>字段配置模板 <small class="text-muted">(可选,从已有工位复制)</small></label>
|
||||
<select name="template_station" class="form-control" onchange="handleTemplateChange(this.value)">
|
||||
<option value="">不复制(空白工位)</option>
|
||||
<option value="inbound">半成品入库工位</option>
|
||||
<option value="pcb_test">PCB 测试</option>
|
||||
<option value="battery">电池状态</option>
|
||||
<option value="assembly">产品组装</option>
|
||||
<option value="finished_test">成品测试</option>
|
||||
<option value="warehouse">成品入库工位</option>
|
||||
<option value="delivery">出货登记</option>
|
||||
</select>
|
||||
<small class="text-muted">选择后将复制该工位的字段配置,后续可在编辑中修改</small>
|
||||
</div>
|
||||
<div id="templatePreview" style="display:none; margin-top:10px; padding:10px; background:#f9f9f9; border-radius:4px;">
|
||||
<strong><i class="fa fa-clone"></i> 将复制的字段:</strong>
|
||||
<span id="templateFieldsPreview" style="margin-left:8px; color:#666;"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>排序</label>
|
||||
<input type="number" name="sort_order" class="form-control" value="1" min="1">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="1">启用</option>
|
||||
<option value="0">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstation" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 工位类型模板预览
|
||||
var templateFieldsConfig = <?php echo json_encode($templateFieldsMap ?? [], JSON_UNESCAPED_UNICODE); ?>;
|
||||
|
||||
function handleTemplateChange(templateType) {
|
||||
var preview = document.getElementById('templatePreview');
|
||||
var fieldsSpan = document.getElementById('templateFieldsPreview');
|
||||
|
||||
if (!templateType) {
|
||||
preview.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
var fields = templateFieldsConfig[templateType] || [];
|
||||
if (fields.length > 0) {
|
||||
var names = fields.map(function(f) { return f.label || f.name; });
|
||||
fieldsSpan.textContent = names.join('、');
|
||||
preview.style.display = 'block';
|
||||
} else {
|
||||
fieldsSpan.textContent = '(该工位暂无字段配置)';
|
||||
preview.style.display = 'block';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
$activeMenu = 'workstation';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑工位</h3>
|
||||
</div>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa fa-ban"></i> 操作失败</h4>
|
||||
<?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>工位名称 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="station_name" class="form-control" value="<?php echo htmlspecialchars($station['station_name']); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>工位编码</label>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($station['station_code']); ?>" disabled>
|
||||
<small class="text-muted">编码不可修改</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>工位类型</label>
|
||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($station['station_type']); ?>" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>排序</label>
|
||||
<input type="number" name="sort_order" class="form-control" value="<?php echo $station['sort_order']; ?>" min="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="1" <?php echo $station['status'] == 1 ? 'selected' : ''; ?>>启用</option>
|
||||
<option value="0" <?php echo $station['status'] == 0 ? 'selected' : ''; ?>>禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 字段配置编辑器 -->
|
||||
<?php echo $fieldEditor ?? ''; ?>
|
||||
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-warning"><i class="fa fa-save"></i> 更新</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstation" class="btn btn-default"><i class="fa fa-arrow-left"></i> 返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,319 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>前台工位看板 - <?php echo htmlspecialchars($sysConfig['company_name'] ?? 'MES'); ?></title>
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<style>
|
||||
:root {
|
||||
--bg: #0f1923;
|
||||
--card-bg: #1a2736;
|
||||
--text: #c8d6e5;
|
||||
--text-light: #8395a7;
|
||||
--primary: #0abde3;
|
||||
--success: #10ac84;
|
||||
--warning: #feca57;
|
||||
--danger: #ee5253;
|
||||
--border: #2d3a4a;
|
||||
}
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { height: 100%; }
|
||||
body {
|
||||
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 顶部导航栏 */
|
||||
.topbar {
|
||||
background: var(--card-bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 12px 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.topbar .logo {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: var(--primary);
|
||||
}
|
||||
.topbar .logo i { margin-right: 8px; }
|
||||
.topbar .user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.topbar .user-info .clock {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: var(--text);
|
||||
}
|
||||
.topbar .user-info .user-name {
|
||||
color: var(--primary);
|
||||
}
|
||||
.topbar .btn-back {
|
||||
color: var(--text-light);
|
||||
text-decoration: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.topbar .btn-back:hover {
|
||||
color: var(--primary);
|
||||
border-color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 内容区 */
|
||||
.content {
|
||||
padding: 20px 24px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 概览卡片 */
|
||||
.overview-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.overview-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.overview-card:hover { transform: translateY(-2px); }
|
||||
.overview-card .card-icon {
|
||||
font-size: 32px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.overview-card .card-value {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.overview-card .card-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.overview-card.total .card-value { color: var(--primary); }
|
||||
.overview-card.total .card-icon { color: var(--primary); }
|
||||
|
||||
/* 工位网格 */
|
||||
.station-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.station-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.station-card:hover {
|
||||
border-color: var(--primary);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 20px rgba(10, 189, 227, 0.15);
|
||||
}
|
||||
.station-card.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.station-card .station-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.station-card .station-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.station-card .station-code {
|
||||
font-size: 11px;
|
||||
color: var(--text-light);
|
||||
background: rgba(255,255,255,0.05);
|
||||
padding: 2px 8px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.station-card .station-count {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.station-card .station-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.station-card .status-badge {
|
||||
display: inline-block;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.status-active { background: rgba(16, 172, 132, 0.2); color: var(--success); }
|
||||
.status-inactive { background: rgba(238, 82, 83, 0.2); color: var(--danger); }
|
||||
|
||||
/* 底部 */
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: var(--text-light);
|
||||
font-size: 12px;
|
||||
border-top: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 响应式 */
|
||||
@media (max-width: 768px) {
|
||||
.overview-cards { grid-template-columns: repeat(2, 1fr); }
|
||||
.station-grid { grid-template-columns: 1fr; }
|
||||
.topbar { flex-direction: column; gap: 8px; }
|
||||
}
|
||||
|
||||
/* 刷新动画 */
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
.refreshing { animation: pulse 0.6s ease-in-out; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="topbar">
|
||||
<div>
|
||||
<span class="logo">
|
||||
<i class="fa fa-industry"></i>
|
||||
<?php echo htmlspecialchars($sysConfig['company_name'] ?? 'MES'); ?> - 前台工位看板
|
||||
</span>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<span class="clock" id="liveClock"><?php echo date('Y-m-d H:i:s'); ?></span>
|
||||
<span><i class="fa fa-user"></i> <span class="user-name"><?php echo htmlspecialchars($user['emp_name']); ?></span></span>
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="btn-back"><i class="fa fa-th"></i> 进入工位</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index" class="btn-back"><i class="fa fa-cog"></i> 后台管理</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Login/logout" class="btn-back confirm-link" data-confirm="确定退出?"><i class="fa fa-sign-out"></i> 退出</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<!-- 概览卡片 -->
|
||||
<div class="overview-cards">
|
||||
<div class="overview-card total">
|
||||
<div class="card-icon"><i class="fa fa-list-alt"></i></div>
|
||||
<div class="card-value"><?php echo $totalRecords; ?></div>
|
||||
<div class="card-label">今日总记录</div>
|
||||
</div>
|
||||
<div class="overview-card total">
|
||||
<div class="card-icon"><i class="fa fa-calendar"></i></div>
|
||||
<div class="card-value" id="todayDisplay"><?php echo $today; ?></div>
|
||||
<div class="card-label">当前日期</div>
|
||||
</div>
|
||||
<div class="overview-card total">
|
||||
<div class="card-icon"><i class="fa fa-th-large"></i></div>
|
||||
<div class="card-value"><?php echo count($stations); ?></div>
|
||||
<div class="card-label">工位总数</div>
|
||||
</div>
|
||||
<div class="overview-card total">
|
||||
<div class="card-icon"><i class="fa fa-check-circle"></i></div>
|
||||
<?php
|
||||
$activeCount = 0;
|
||||
foreach ($stations as $s) { if ($s['status'] == 1) $activeCount++; }
|
||||
?>
|
||||
<div class="card-value"><?php echo $activeCount; ?></div>
|
||||
<div class="card-label">启用工位</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工位网格 -->
|
||||
<div class="station-grid">
|
||||
<?php
|
||||
$icons = [
|
||||
'inbound' => 'fa-sign-in',
|
||||
'pcb_test' => 'fa-microchip',
|
||||
'battery' => 'fa-battery-full',
|
||||
'assembly' => 'fa-cogs',
|
||||
'finished_test' => 'fa-check-circle',
|
||||
'warehouse' => 'fa-warehouse',
|
||||
'delivery' => 'fa-truck',
|
||||
];
|
||||
foreach ($stations as $station):
|
||||
$type = $station['station_type'];
|
||||
$icon = $icons[$type] ?? 'fa-circle-o';
|
||||
$stat = $stats[$type] ?? ['count' => 0, 'name' => $station['station_name']];
|
||||
?>
|
||||
<div class="station-card <?php echo $station['status'] == 0 ? 'disabled' : ''; ?>"
|
||||
<?php echo $station['status'] == 1 ? 'data-href="' . BASE_URL . '/Front/' . $type . '"' : ''; ?>>
|
||||
<div class="station-header">
|
||||
<span class="station-name">
|
||||
<i class="fa <?php echo $icon; ?>"></i> <?php echo htmlspecialchars($stat['name']); ?>
|
||||
</span>
|
||||
<span class="station-code"><?php echo htmlspecialchars($station['station_code']); ?></span>
|
||||
</div>
|
||||
<div class="station-count"><?php echo $stat['count']; ?></div>
|
||||
<div class="station-label">今日处理量</div>
|
||||
<div style="margin-top: 12px;">
|
||||
<span class="status-badge <?php echo $station['status'] == 1 ? 'status-active' : 'status-inactive'; ?>">
|
||||
<?php echo $station['status'] == 1 ? '● 启用' : '● 禁用'; ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
©2026深圳市云创芯电子有限公司版权所有
|
||||
<br><span class="beian">备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">粤ICP备16118477号-1</a></span>
|
||||
<br><span class="beian">公安网备:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=44030002015390" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;gap:4px;"><img src="<?php echo BASE_URL; ?>/static/images/gongan_badge.png" width="16" height="17" alt="公安网备" loading="lazy" style="vertical-align:middle;" onerror="this.onerror=null;this.outerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 24 24"><path d="M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z" fill="#1a3a8f" stroke="#d4af37" stroke-width="1"/><polygon points="12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5" fill="#ffffff"/></svg>'">粤公网安备44030002015390号</a></span>
|
||||
</div>
|
||||
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/jquery-3.7.1.min.js"></script>
|
||||
<?php // v3-P2 CSP:全局事件委托(替代内联 onclick 等) ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/csp_global.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
// 实时时钟
|
||||
function updateClock() {
|
||||
var now = new Date();
|
||||
var str = now.getFullYear() + '-' +
|
||||
String(now.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(now.getDate()).padStart(2, '0') + ' ' +
|
||||
String(now.getHours()).padStart(2, '0') + ':' +
|
||||
String(now.getMinutes()).padStart(2, '0') + ':' +
|
||||
String(now.getSeconds()).padStart(2, '0');
|
||||
document.getElementById('liveClock').textContent = str;
|
||||
}
|
||||
setInterval(updateClock, 1000);
|
||||
updateClock();
|
||||
|
||||
// 自动刷新(每30秒)
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 账务记录</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accountsAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加记录</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<form method="get" class="form-inline" style="margin-bottom:15px;">
|
||||
<div class="form-group">
|
||||
<label>类型:</label>
|
||||
<select name="type" class="form-control input-sm">
|
||||
<option value="">全部</option>
|
||||
<option value="income" <?php echo ($typeFilter ?? '') === 'income' ? 'selected' : ''; ?>>收入</option>
|
||||
<option value="expense" <?php echo ($typeFilter ?? '') === 'expense' ? 'selected' : ''; ?>>支出</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>起始日期:</label>
|
||||
<input type="date" name="start_date" class="form-control input-sm" value="<?php echo htmlspecialchars($startDate ?? date('Y-m-01')); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>截止日期:</label>
|
||||
<input type="date" name="end_date" class="form-control input-sm" value="<?php echo htmlspecialchars($endDate ?? date('Y-m-d')); ?>">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-info btn-sm"><i class="fa fa-search"></i> 查询</button>
|
||||
</form>
|
||||
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>凭证号</th>
|
||||
<th>类型</th>
|
||||
<th>类别</th>
|
||||
<th>金额</th>
|
||||
<th>日期</th>
|
||||
<th>摘要</th>
|
||||
<th>往来单位</th>
|
||||
<th>支付方式</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($records)): ?>
|
||||
<?php foreach ($records as $r): ?>
|
||||
<tr>
|
||||
<td><?php echo $r['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($r['record_no']); ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $r['type'] === 'income' ? 'success' : 'danger'; ?>">
|
||||
<?php echo $r['type'] === 'income' ? '收入' : '支出'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($r['category']); ?></td>
|
||||
<td>¥<?php echo number_format($r['amount'], 2); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['record_date']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['description']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['related_party']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['payment_method']); ?></td>
|
||||
<td><?php echo htmlspecialchars($r['operator']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accountsEdit?id=<?php echo $r['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Finance/accountsDelete" style="display:inline" onsubmit="return confirm('确定删除吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $r['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="11" class="text-center text-muted">暂无账务记录</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加账务记录</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>凭证号</label>
|
||||
<input type="text" name="record_no" class="form-control" value="CW<?php echo date('YmdHis'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>类型 <span class="text-red">*</span></label>
|
||||
<select name="type" class="form-control">
|
||||
<option value="income">收入</option>
|
||||
<option value="expense">支出</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>费用类别</label>
|
||||
<input type="text" name="category" class="form-control" placeholder="如:原材料采购、办公费、销售回款">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>金额 <span class="text-red">*</span></label>
|
||||
<input type="number" name="amount" class="form-control" value="0" step="0.01" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>日期</label>
|
||||
<input type="date" name="record_date" class="form-control" value="<?php echo date('Y-m-d'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>摘要 <span class="text-red">*</span></label>
|
||||
<input type="text" name="description" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>往来单位</label>
|
||||
<input type="text" name="related_party" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>支付方式</label>
|
||||
<select name="payment_method" class="form-control">
|
||||
<option value="">-- 请选择 --</option>
|
||||
<option value="银行转账">银行转账</option>
|
||||
<option value="现金">现金</option>
|
||||
<option value="微信">微信</option>
|
||||
<option value="支付宝">支付宝</option>
|
||||
<option value="支票">支票</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accounts" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑账务记录</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>凭证号</label>
|
||||
<input type="text" name="record_no" class="form-control" value="<?php echo htmlspecialchars($record['record_no']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>类型 <span class="text-red">*</span></label>
|
||||
<select name="type" class="form-control">
|
||||
<option value="income" <?php echo $record['type'] === 'income' ? 'selected' : ''; ?>>收入</option>
|
||||
<option value="expense" <?php echo $record['type'] === 'expense' ? 'selected' : ''; ?>>支出</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>费用类别</label>
|
||||
<input type="text" name="category" class="form-control" value="<?php echo htmlspecialchars($record['category']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>金额 <span class="text-red">*</span></label>
|
||||
<input type="number" name="amount" class="form-control" value="<?php echo $record['amount']; ?>" step="0.01" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>日期</label>
|
||||
<input type="date" name="record_date" class="form-control" value="<?php echo htmlspecialchars($record['record_date']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>摘要 <span class="text-red">*</span></label>
|
||||
<input type="text" name="description" class="form-control" value="<?php echo htmlspecialchars($record['description']); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>往来单位</label>
|
||||
<input type="text" name="related_party" class="form-control" value="<?php echo htmlspecialchars($record['related_party']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>支付方式</label>
|
||||
<select name="payment_method" class="form-control">
|
||||
<option value="">-- 请选择 --</option>
|
||||
<?php
|
||||
$methods = ['银行转账','现金','微信','支付宝','支票'];
|
||||
foreach ($methods as $m):
|
||||
$sel = ($record['payment_method'] ?? '') === $m ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $m; ?>" <?php echo $sel; ?>><?php echo $m; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($record['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accounts" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h3>¥<?php echo number_format($incomeTotal, 2); ?></h3>
|
||||
<p>本月收入</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-arrow-up"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h3>¥<?php echo number_format($expenseTotal, 2); ?></h3>
|
||||
<p>本月支出</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-arrow-down"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-<?php echo $profit >= 0 ? 'aqua' : 'yellow'; ?>">
|
||||
<div class="inner">
|
||||
<h3>¥<?php echo number_format($profit, 2); ?></h3>
|
||||
<p>本月利润</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-line-chart"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-purple">
|
||||
<div class="inner">
|
||||
<h3><?php echo $recordCount ?? 0; ?></h3>
|
||||
<p>账务记录</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-book"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accounts" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="box box-info">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-arrow-down"></i> 应收账款</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<h2 class="text-center text-info">¥<?php echo number_format($receivableTotal, 2); ?></h2>
|
||||
<div class="text-center">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivable" class="btn btn-info btn-sm">查看详情</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box box-warning">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-arrow-up"></i> 应付账款</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<h2 class="text-center text-warning">¥<?php echo number_format($payableTotal, 2); ?></h2>
|
||||
<div class="text-center">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payable" class="btn btn-warning btn-sm">查看详情</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-rocket"></i> 快捷操作</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accountsAdd" class="btn btn-primary"><i class="fa fa-plus"></i> 添加账务记录</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivableAdd" class="btn btn-info"><i class="fa fa-arrow-down"></i> 添加应收账款</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payableAdd" class="btn btn-warning"><i class="fa fa-arrow-up"></i> 添加应付账款</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/report" class="btn btn-success"><i class="fa fa-bar-chart"></i> 财务报表</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 应付账款列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payableAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加应付</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>往来单位</th>
|
||||
<th>应付金额</th>
|
||||
<th>已付金额</th>
|
||||
<th>未付金额</th>
|
||||
<th>到期日期</th>
|
||||
<th>状态</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($records)): ?>
|
||||
<?php foreach ($records as $r): ?>
|
||||
<?php
|
||||
$unpaid = (float)$r['amount'] - (float)($r['paid_amount'] ?? 0);
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $r['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($r['party_name']); ?></td>
|
||||
<td>¥<?php echo number_format($r['amount'], 2); ?></td>
|
||||
<td>¥<?php echo number_format($r['paid_amount'] ?? 0, 2); ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $unpaid > 0 ? 'warning' : 'success'; ?>">
|
||||
¥<?php echo number_format($unpaid, 2); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($r['due_date']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['pending'=>'待付','partial'=>'部分付','paid'=>'已付','overdue'=>'逾期'];
|
||||
$statusColors = ['pending'=>'warning','partial'=>'info','paid'=>'success','overdue'=>'danger'];
|
||||
$st = $r['status'] ?? 'pending';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($r['operator']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payableEdit?id=<?php echo $r['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Finance/payableDelete" style="display:inline" onsubmit="return confirm('确定删除吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $r['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="9" class="text-center text-muted">暂无应付账款</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加应付账款</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>往来单位 <span class="text-red">*</span></label>
|
||||
<input type="text" name="party_name" class="form-control" required>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>应付金额 <span class="text-red">*</span></label>
|
||||
<input type="number" name="amount" class="form-control" value="0" step="0.01" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>已付金额</label>
|
||||
<input type="number" name="paid_amount" class="form-control" value="0" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>到期日期</label>
|
||||
<input type="date" name="due_date" class="form-control" value="<?php echo date('Y-m-d', strtotime('+30 days')); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="pending">待付</option>
|
||||
<option value="partial">部分付</option>
|
||||
<option value="paid">已付</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>说明</label>
|
||||
<input type="text" name="description" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payable" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑应付账款</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>往来单位 <span class="text-red">*</span></label>
|
||||
<input type="text" name="party_name" class="form-control" value="<?php echo htmlspecialchars($record['party_name']); ?>" required>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>应付金额</label>
|
||||
<input type="number" name="amount" class="form-control" value="<?php echo $record['amount']; ?>" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>已付金额</label>
|
||||
<input type="number" name="paid_amount" class="form-control" value="<?php echo $record['paid_amount'] ?? 0; ?>" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>到期日期</label>
|
||||
<input type="date" name="due_date" class="form-control" value="<?php echo htmlspecialchars($record['due_date']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<?php
|
||||
$statuses = ['pending'=>'待付','partial'=>'部分付','paid'=>'已付','overdue'=>'逾期'];
|
||||
foreach ($statuses as $k => $v):
|
||||
$sel = ($record['status'] ?? '') === $k ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $k; ?>" <?php echo $sel; ?>><?php echo $v; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>说明</label>
|
||||
<input type="text" name="description" class="form-control" value="<?php echo htmlspecialchars($record['description']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($record['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payable" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 应收账款列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivableAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加应收</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>往来单位</th>
|
||||
<th>应收金额</th>
|
||||
<th>已收金额</th>
|
||||
<th>未收金额</th>
|
||||
<th>到期日期</th>
|
||||
<th>状态</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($records)): ?>
|
||||
<?php foreach ($records as $r): ?>
|
||||
<?php
|
||||
$unpaid = (float)$r['amount'] - (float)($r['paid_amount'] ?? 0);
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $r['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($r['party_name']); ?></td>
|
||||
<td>¥<?php echo number_format($r['amount'], 2); ?></td>
|
||||
<td>¥<?php echo number_format($r['paid_amount'] ?? 0, 2); ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $unpaid > 0 ? 'warning' : 'success'; ?>">
|
||||
¥<?php echo number_format($unpaid, 2); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($r['due_date']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['pending'=>'待收','partial'=>'部分收','paid'=>'已收','overdue'=>'逾期'];
|
||||
$statusColors = ['pending'=>'warning','partial'=>'info','paid'=>'success','overdue'=>'danger'];
|
||||
$st = $r['status'] ?? 'pending';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($r['operator']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivableEdit?id=<?php echo $r['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Finance/receivableDelete" style="display:inline" onsubmit="return confirm('确定删除吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $r['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="9" class="text-center text-muted">暂无应收账款</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加应收账款</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>往来单位 <span class="text-red">*</span></label>
|
||||
<input type="text" name="party_name" class="form-control" required>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>应收金额 <span class="text-red">*</span></label>
|
||||
<input type="number" name="amount" class="form-control" value="0" step="0.01" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>已收金额</label>
|
||||
<input type="number" name="paid_amount" class="form-control" value="0" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>到期日期</label>
|
||||
<input type="date" name="due_date" class="form-control" value="<?php echo date('Y-m-d', strtotime('+30 days')); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="pending">待收</option>
|
||||
<option value="partial">部分收</option>
|
||||
<option value="paid">已收</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>说明</label>
|
||||
<input type="text" name="description" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivable" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑应收账款</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>往来单位 <span class="text-red">*</span></label>
|
||||
<input type="text" name="party_name" class="form-control" value="<?php echo htmlspecialchars($record['party_name']); ?>" required>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>应收金额</label>
|
||||
<input type="number" name="amount" class="form-control" value="<?php echo $record['amount']; ?>" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>已收金额</label>
|
||||
<input type="number" name="paid_amount" class="form-control" value="<?php echo $record['paid_amount'] ?? 0; ?>" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>到期日期</label>
|
||||
<input type="date" name="due_date" class="form-control" value="<?php echo htmlspecialchars($record['due_date']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<?php
|
||||
$statuses = ['pending'=>'待收','partial'=>'部分收','paid'=>'已收','overdue'=>'逾期'];
|
||||
foreach ($statuses as $k => $v):
|
||||
$sel = ($record['status'] ?? '') === $k ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $k; ?>" <?php echo $sel; ?>><?php echo $v; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>说明</label>
|
||||
<input type="text" name="description" class="form-control" value="<?php echo htmlspecialchars($record['description']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($record['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivable" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-bar-chart"></i> 财务报表</h3>
|
||||
<div class="box-tools">
|
||||
<form method="get" class="form-inline">
|
||||
<div class="form-group">
|
||||
<input type="month" name="month" class="form-control input-sm auto-submit" value="<?php echo htmlspecialchars($month); ?>">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="info-box bg-green">
|
||||
<span class="info-box-icon"><i class="fa fa-arrow-up"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">收入合计</span>
|
||||
<span class="info-box-number">¥<?php echo number_format($incomeTotal, 2); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="info-box bg-red">
|
||||
<span class="info-box-icon"><i class="fa fa-arrow-down"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">支出合计</span>
|
||||
<span class="info-box-number">¥<?php echo number_format($expenseTotal, 2); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="info-box bg-<?php echo $profit >= 0 ? 'aqua' : 'yellow'; ?>">
|
||||
<span class="info-box-icon"><i class="fa fa-line-chart"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">利润</span>
|
||||
<span class="info-box-number">¥<?php echo number_format($profit, 2); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($categorySummary)): ?>
|
||||
<h4>费用类别明细</h4>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>类别</th>
|
||||
<th>收入</th>
|
||||
<th>支出</th>
|
||||
<th>小计</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($categorySummary as $cat => $vals): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($cat); ?></td>
|
||||
<td>¥<?php echo number_format($vals['income'], 2); ?></td>
|
||||
<td>¥<?php echo number_format($vals['expense'], 2); ?></td>
|
||||
<td>¥<?php echo number_format($vals['income'] - $vals['expense'], 2); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<p class="text-center text-muted">该月份暂无财务数据</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
$activeStation = '';
|
||||
// 确保 sysConfig 可用
|
||||
if (!isset($sysConfig)) {
|
||||
$cfgModel = new app\models\SysConfig();
|
||||
$sysConfig = $cfgModel->getConfig();
|
||||
}
|
||||
include APP_PATH . 'app/views/layouts/station_header.php';
|
||||
?>
|
||||
|
||||
<div class="content">
|
||||
<!-- 用户信息提示 -->
|
||||
<div class="alert alert-info" style="margin-bottom:16px; display:flex; align-items:center; gap:8px; flex-wrap:wrap;">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<span>当前登录:<strong><?php echo htmlspecialchars($user['emp_name']); ?></strong></span>
|
||||
<span style="color:var(--text-light);">| 角色:<?php echo htmlspecialchars(\core\base\Controller::ROLE_NAMES[$user['role']] ?? $user['role']); ?></span>
|
||||
<span style="color:var(--text-light);">| 选择下方工位开始操作</span>
|
||||
<span style="margin-left:auto;" class="column-adjuster" title="调整工位卡片列数">
|
||||
<button type="button" class="col-btn" data-cols="1" title="1列"><i class="fa fa-align-justify"></i></button>
|
||||
<button type="button" class="col-btn" data-cols="2" title="2列"><i class="fa fa-columns"></i>2</button>
|
||||
<button type="button" class="col-btn" data-cols="3" title="3列"><i class="fa fa-columns"></i>3</button>
|
||||
<button type="button" class="col-btn active" data-cols="auto" title="自适应"><i class="fa fa-arrows-h"></i> 自动</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 工位网格 -->
|
||||
<div class="station-grid" id="stationGrid">
|
||||
<?php
|
||||
$stationIcons = [
|
||||
'inbound' => 'fa-sign-in',
|
||||
'pcb_test' => 'fa-microchip',
|
||||
'battery' => 'fa-battery-full',
|
||||
'assembly' => 'fa-cogs',
|
||||
'finished_test' => 'fa-check-circle',
|
||||
'warehouse' => 'fa-warehouse',
|
||||
'delivery' => 'fa-truck',
|
||||
'document_manage' => 'fa-folder-open',
|
||||
];
|
||||
$iconColors = [
|
||||
'inbound' => ['#10ac84', 'rgba(16,172,132,0.2)'],
|
||||
'pcb_test' => ['#0abde3', 'rgba(10,189,227,0.2)'],
|
||||
'battery' => ['#feca57', 'rgba(254,202,87,0.2)'],
|
||||
'assembly' => ['#a29bfe', 'rgba(162,155,254,0.2)'],
|
||||
'finished_test' => ['#55efc4', 'rgba(85,239,196,0.2)'],
|
||||
'warehouse' => ['#fd79a8', 'rgba(253,121,168,0.2)'],
|
||||
'delivery' => ['#74b9ff', 'rgba(116,185,255,0.2)'],
|
||||
'document_manage' => ['#e17055', 'rgba(225,112,85,0.2)'],
|
||||
];
|
||||
|
||||
foreach ($stations as $station):
|
||||
$type = $station['station_type'];
|
||||
$icon = $stationIcons[$type] ?? 'fa-circle-o';
|
||||
$color = $iconColors[$type] ?? ['#0abde3', 'rgba(10,189,227,0.2)'];
|
||||
$disabled = $station['status'] == 0;
|
||||
?>
|
||||
<a href="<?php echo $disabled ? '#' : BASE_URL . '/Front/' . $type; ?>"
|
||||
class="station-card"
|
||||
style="<?php echo $disabled ? 'opacity:0.5; cursor:not-allowed;' : ''; ?>"
|
||||
<?php echo $disabled ? 'onclick="return false;"' : ''; ?>>
|
||||
<div class="station-icon" style="background:<?php echo $color[1]; ?>; color:<?php echo $color[0]; ?>;">
|
||||
<i class="fa <?php echo $icon; ?>"></i>
|
||||
</div>
|
||||
<div class="station-name"><?php echo htmlspecialchars($station['station_name']); ?></div>
|
||||
<div class="station-code"><?php echo htmlspecialchars($station['station_code']); ?></div>
|
||||
<div class="station-status">
|
||||
<span style="color:<?php echo $station['status'] == 1 ? 'var(--success)' : 'var(--danger)'; ?>">
|
||||
<?php echo $station['status'] == 1 ? '● 启用' : '● 禁用'; ?>
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/station_footer.php'; ?>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
if (!isset($sysConfig)) {
|
||||
$cfgModel = new app\models\SysConfig();
|
||||
$sysConfig = $cfgModel->getConfig();
|
||||
}
|
||||
include APP_PATH . 'app/views/layouts/station_header.php';
|
||||
?>
|
||||
|
||||
<div class="content">
|
||||
<div class="card" style="max-width:600px; margin:60px auto;">
|
||||
<div class="card-body" style="text-align:center; padding:60px 20px;">
|
||||
<i class="fa fa-lock" style="font-size:80px; color:var(--danger);"></i>
|
||||
<h2 style="margin-top:20px; color:var(--danger);">抱歉,您没有访问该工位的权限</h2>
|
||||
<p style="color:var(--text-light); font-size:16px; margin-top:12px;">
|
||||
工位类型:<code><?php echo htmlspecialchars($stationType ?? '未知'); ?></code>
|
||||
</p>
|
||||
<?php if (!empty($message)): ?>
|
||||
<p style="color:var(--text-light); font-size:16px;"><?php echo htmlspecialchars($message); ?></p>
|
||||
<?php else: ?>
|
||||
<p style="color:var(--text-light);">请联系管理员为您开通对应工位的访问权限。</p>
|
||||
<?php endif; ?>
|
||||
<br>
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="btn btn-primary btn-lg">
|
||||
<i class="fa fa-home"></i> 返回工位首页
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/station_footer.php'; ?>
|
||||
@@ -0,0 +1,350 @@
|
||||
<?php
|
||||
/**
|
||||
* 文件管理工位视图
|
||||
*
|
||||
* 管理员:可上传、删除、打开文件
|
||||
* 操作员:只能查看和打开文件
|
||||
*
|
||||
* 所需变量:
|
||||
* $user - 当前用户
|
||||
* $sysConfig - 系统配置
|
||||
* $stations - 所有工位列表
|
||||
* $documents - 文档列表
|
||||
* $categories - 文档分类列表
|
||||
* $csrfToken - CSRF token
|
||||
* $isAdmin - 是否为管理员
|
||||
*/
|
||||
|
||||
$activeStation = 'document_manage';
|
||||
$title = '文件管理';
|
||||
include APP_PATH . 'app/views/layouts/station_header.php';
|
||||
|
||||
// 权限判断
|
||||
$isAdmin = ($user['role'] === \core\base\Controller::ROLE_SUPER_ADMIN
|
||||
|| $user['role'] === \core\base\Controller::ROLE_ADMIN);
|
||||
?>
|
||||
|
||||
<div class="content">
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="back-link"><i class="fa fa-arrow-left"></i> 返回工位选择</a>
|
||||
|
||||
<div class="page-title-bar">
|
||||
<div>
|
||||
<h1><i class="fa fa-folder-open"></i> 文件管理</h1>
|
||||
</div>
|
||||
<div class="today-count-badge">
|
||||
<i class="fa fa-user"></i> <?php echo htmlspecialchars($user['emp_name'] ?? ''); ?>
|
||||
共:<span class="count-num" id="docCount"><?php echo count($documents); ?></span> 个文件
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 搜索和筛选区 -->
|
||||
<div class="card" style="margin-bottom:12px;">
|
||||
<div class="card-body" style="padding:12px 16px;">
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
|
||||
<input type="text" id="searchInput" class="form-control" placeholder="搜索文件名称..."
|
||||
style="max-width:300px;">
|
||||
<select id="categoryFilter" class="form-control" style="max-width:200px;">
|
||||
<option value="">全部分类</option>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?php echo htmlspecialchars($cat['category']); ?>">
|
||||
<?php echo htmlspecialchars($cat['category']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php if ($isAdmin): ?>
|
||||
<button type="button" class="btn btn-primary" id="uploadBtn" style="margin-left:auto;">
|
||||
<i class="fa fa-upload"></i> 上传文件
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($isAdmin): ?>
|
||||
<!-- 上传表单(默认隐藏) -->
|
||||
<div class="card" id="uploadCard" style="display:none;margin-bottom:12px;">
|
||||
<div class="card-header">
|
||||
<h3><i class="fa fa-upload"></i> 上传文件</h3>
|
||||
<button type="button" class="btn btn-sm btn-warning" id="cancelUploadBtn">
|
||||
<i class="fa fa-times"></i> 取消
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="uploadForm" method="post" enctype="multipart/form-data" action="<?php echo BASE_URL; ?>/Front/documentManageUpload">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="row" style="display:flex;flex-wrap:wrap;gap:12px;">
|
||||
<div class="station-field-item" style="flex:1;min-width:200px;">
|
||||
<label>文档标题 <span class="text-danger">*</span></label>
|
||||
<input type="text" name="title" class="form-control" placeholder="输入文档标题" required>
|
||||
</div>
|
||||
<div class="station-field-item" style="flex:1;min-width:150px;">
|
||||
<label>文档编号</label>
|
||||
<input type="text" name="doc_no" class="form-control" placeholder="如:SOP-001">
|
||||
</div>
|
||||
<div class="station-field-item" style="flex:1;min-width:150px;">
|
||||
<label>分类</label>
|
||||
<input type="text" name="category" class="form-control" placeholder="如:操作规程" list="categoryList">
|
||||
<datalist id="categoryList">
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<option value="<?php echo htmlspecialchars($cat['category']); ?>">
|
||||
<?php endforeach; ?>
|
||||
</datalist>
|
||||
</div>
|
||||
<div class="station-field-item" style="flex:1;min-width:100px;">
|
||||
<label>版本</label>
|
||||
<input type="text" name="version" class="form-control" value="1.0" placeholder="版本号">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="display:flex;flex-wrap:wrap;gap:12px;margin-top:12px;">
|
||||
<div class="station-field-item" style="flex:1;min-width:200px;">
|
||||
<label>选择文件 <span class="text-danger">*</span></label>
|
||||
<input type="file" name="doc_file" class="form-control" required
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.csv,.zip,.rar,.jpg,.jpeg,.png,.gif">
|
||||
</div>
|
||||
<div class="station-field-item" style="flex:1;min-width:200px;">
|
||||
<label>描述</label>
|
||||
<input type="text" name="description" class="form-control" placeholder="简要描述">
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:12px;">
|
||||
<button type="submit" class="btn btn-success btn-lg">
|
||||
<i class="fa fa-cloud-upload"></i> 确认上传
|
||||
</button>
|
||||
<span id="uploadStatus" style="margin-left:10px;color:var(--primary);display:none;">
|
||||
<i class="fa fa-spinner fa-spin"></i> 上传中...
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fa fa-list"></i> 文件列表</h3>
|
||||
</div>
|
||||
<div class="card-body no-padding">
|
||||
<div class="table-wrap">
|
||||
<table class="table" id="docTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-col="title" style="text-align:left;padding-left:16px;">文件名称</th>
|
||||
<th data-col="category">分类</th>
|
||||
<th data-col="version">版本</th>
|
||||
<th data-col="file_size">大小</th>
|
||||
<th data-col="operator">上传人</th>
|
||||
<th data-col="created_at">上传时间</th>
|
||||
<th data-col="actions">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($documents)): ?>
|
||||
<?php foreach ($documents as $doc):
|
||||
$sizeStr = '';
|
||||
$fs = (int)($doc['file_size'] ?? 0);
|
||||
if ($fs > 1048576) $sizeStr = round($fs / 1048576, 1) . ' MB';
|
||||
elseif ($fs > 1024) $sizeStr = round($fs / 1024, 1) . ' KB';
|
||||
else $sizeStr = $fs . ' B';
|
||||
$fileExt = strtolower($doc['file_type'] ?? '');
|
||||
$fileIcon = 'fa-file-o';
|
||||
if (in_array($fileExt, ['pdf'])) $fileIcon = 'fa-file-pdf-o';
|
||||
elseif (in_array($fileExt, ['doc','docx'])) $fileIcon = 'fa-file-word-o';
|
||||
elseif (in_array($fileExt, ['xls','xlsx','csv'])) $fileIcon = 'fa-file-excel-o';
|
||||
elseif (in_array($fileExt, ['ppt','pptx'])) $fileIcon = 'fa-file-powerpoint-o';
|
||||
elseif (in_array($fileExt, ['jpg','jpeg','png','gif'])) $fileIcon = 'fa-file-image-o';
|
||||
elseif (in_array($fileExt, ['zip','rar'])) $fileIcon = 'fa-file-archive-o';
|
||||
elseif (in_array($fileExt, ['txt'])) $fileIcon = 'fa-file-text-o';
|
||||
?>
|
||||
<tr class="doc-row" data-title="<?php echo htmlspecialchars(mb_strtolower($doc['title'] ?? '')); ?>"
|
||||
data-category="<?php echo htmlspecialchars($doc['category'] ?? ''); ?>">
|
||||
<td data-col="title" style="text-align:left;padding-left:16px;">
|
||||
<i class="fa <?php echo $fileIcon; ?>" style="color:var(--primary);margin-right:6px;"></i>
|
||||
<strong><?php echo htmlspecialchars($doc['title']); ?></strong>
|
||||
<?php if (!empty($doc['description'])): ?>
|
||||
<br><small class="text-muted"><?php echo htmlspecialchars(mb_substr($doc['description'], 0, 60)); ?><?php echo mb_strlen($doc['description']) > 60 ? '...' : ''; ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td data-col="category">
|
||||
<?php if (!empty($doc['category'])): ?>
|
||||
<span class="label label-info"><?php echo htmlspecialchars($doc['category']); ?></span>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td data-col="version"><?php echo htmlspecialchars($doc['version'] ?? '1.0'); ?></td>
|
||||
<td data-col="file_size"><?php echo $sizeStr; ?></td>
|
||||
<td data-col="operator"><?php echo htmlspecialchars($doc['operator'] ?? '-'); ?></td>
|
||||
<td data-col="created_at"><?php echo htmlspecialchars($doc['created_at'] ?? '-'); ?></td>
|
||||
<td data-col="actions">
|
||||
<?php if (!empty($doc['file_path'])): ?>
|
||||
<a href="<?php echo BASE_URL . htmlspecialchars($doc['file_path']); ?>"
|
||||
class="btn btn-xs btn-info" target="_blank" title="打开文件">
|
||||
<i class="fa fa-external-link"></i> 打开
|
||||
</a>
|
||||
<a href="<?php echo BASE_URL . htmlspecialchars($doc['file_path']); ?>"
|
||||
class="btn btn-xs btn-info" download title="下载文件">
|
||||
<i class="fa fa-download"></i> 下载
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">无文件</span>
|
||||
<?php endif; ?>
|
||||
<?php if ($isAdmin): ?>
|
||||
<button type="button" class="btn btn-xs btn-danger doc-del-btn"
|
||||
data-id="<?php echo $doc['id']; ?>" data-title="<?php echo htmlspecialchars($doc['title'], ENT_QUOTES); ?>"
|
||||
title="删除文件">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<div class="empty-state">
|
||||
<i class="fa fa-folder-open-o"></i>
|
||||
<p>暂无文件,<?php echo $isAdmin ? '请点击「上传文件」添加' : '请联系管理员上传'; ?></p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
var BASE_URL = '<?php echo BASE_URL; ?>';
|
||||
|
||||
// ========== 搜索和筛选 ==========
|
||||
function filterDocuments() {
|
||||
var searchText = ($('#searchInput').val() || '').toLowerCase();
|
||||
var category = $('#categoryFilter').val() || '';
|
||||
|
||||
var visibleCount = 0;
|
||||
$('#docTable .doc-row').each(function() {
|
||||
var title = $(this).data('title') || '';
|
||||
var rowCat = $(this).data('category') || '';
|
||||
var match = true;
|
||||
|
||||
if (searchText && title.indexOf(searchText) < 0) match = false;
|
||||
if (category && rowCat !== category) match = false;
|
||||
|
||||
if (match) {
|
||||
$(this).show();
|
||||
visibleCount++;
|
||||
} else {
|
||||
$(this).hide();
|
||||
}
|
||||
});
|
||||
$('#docCount').text(visibleCount);
|
||||
}
|
||||
|
||||
// CSP:搜索/筛选事件绑定(替代内联 oninput/onchange)
|
||||
$('#searchInput').on('input', filterDocuments);
|
||||
$('#categoryFilter').on('change', filterDocuments);
|
||||
|
||||
<?php if ($isAdmin): ?>
|
||||
// ========== 上传表单 ==========
|
||||
function showUploadForm() {
|
||||
$('#uploadCard').slideDown(300);
|
||||
}
|
||||
function hideUploadForm() {
|
||||
$('#uploadCard').slideUp(300);
|
||||
}
|
||||
function updateFileName(input) {
|
||||
// 如果标题为空,自动用文件名填充
|
||||
var fileName = input.files[0] ? input.files[0].name.replace(/\.[^/.]+$/, '') : '';
|
||||
if (fileName && !$('#uploadForm input[name="title"]').val()) {
|
||||
$('#uploadForm input[name="title"]').val(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
// 上传表单提交
|
||||
$('#uploadForm').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
var $form = $(this);
|
||||
var title = $form.find('input[name="title"]').val().trim();
|
||||
if (!title) {
|
||||
alert('请输入文档标题');
|
||||
return;
|
||||
}
|
||||
if (!$form.find('input[name="doc_file"]').val()) {
|
||||
alert('请选择要上传的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
$('#uploadStatus').show();
|
||||
|
||||
var formData = new FormData($form[0]);
|
||||
$.ajax({
|
||||
url: $form.attr('action'),
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
$('#uploadStatus').hide();
|
||||
if (res.success) {
|
||||
alert('文件上传成功!');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('上传失败: ' + (res.error || '未知错误'));
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
$('#uploadStatus').hide();
|
||||
var msg = '网络错误,请重试';
|
||||
try {
|
||||
var r = JSON.parse(xhr.responseText);
|
||||
if (r && r.error) msg = r.error;
|
||||
else if (xhr.responseText) msg = xhr.responseText;
|
||||
} catch (e) {
|
||||
if (xhr.responseText) msg = xhr.responseText;
|
||||
}
|
||||
alert(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ========== 删除文件 ==========
|
||||
function deleteDocument(id, title) {
|
||||
if (!confirm('确定删除文件「' + title + '」吗?\n此操作不可撤销。')) return;
|
||||
|
||||
$.ajax({
|
||||
url: BASE_URL + '/Front/documentManageDelete',
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id,
|
||||
csrf_token: '<?php echo htmlspecialchars($csrfToken); ?>'
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
if (res.success) {
|
||||
alert('文件已删除');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('删除失败: ' + (res.error || '未知错误'));
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('网络错误,请重试');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// CSP:上传/删除相关事件绑定(替代内联 onclick/onchange)
|
||||
$('#uploadBtn').on('click', showUploadForm);
|
||||
$('#cancelUploadBtn').on('click', hideUploadForm);
|
||||
$('#uploadForm input[name="doc_file"]').on('change', function () { updateFileName(this); });
|
||||
$('#docTable').on('click', '.doc-del-btn', function () {
|
||||
deleteDocument($(this).attr('data-id'), $(this).attr('data-title'));
|
||||
});
|
||||
<?php endif; ?>
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/station_footer.php'; ?>
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* 通用工位操作视图(唯一工位视图文件)
|
||||
*
|
||||
* 所有工位(内置和动态添加)都通过此视图渲染。
|
||||
*
|
||||
* 所需变量(由 FrontController::handleStation 传入):
|
||||
* $stationType - 工位类型标识
|
||||
* $currentStation - 当前工位的数据库记录
|
||||
* $bizConfig - 业务配置(内置工位有,动态工位为 null)
|
||||
* $fieldConfigs - 字段配置数组
|
||||
* $models - 产品型号列表
|
||||
* $types - 产品类型列表
|
||||
* $customers - 客户列表
|
||||
* $records - 操作记录
|
||||
* $filterType - 筛选类型
|
||||
* $filterModel - 筛选型号
|
||||
* $todayCount - 今日计数
|
||||
* $shellColors - 外壳颜色(assembly 工位)
|
||||
* $user - 当前用户
|
||||
* $sysConfig - 系统配置
|
||||
* $stations - 所有工位列表
|
||||
*/
|
||||
|
||||
require_once APP_PATH . 'app/helpers/station_template_helper.php';
|
||||
|
||||
// 获取工位名称
|
||||
$stationName = $currentStation['station_name'] ?? $stationType;
|
||||
$stationCode = $currentStation['station_code'] ?? $stationType;
|
||||
|
||||
// ========== 内置工位:使用 bizConfig ==========
|
||||
if ($bizConfig) {
|
||||
// 解析记录(内置工位使用专用表,记录结构已完整,无需 JSON 解析)
|
||||
$parsedRecords = $records;
|
||||
|
||||
// 构建 stationConfig(从 bizConfig.view 继承)
|
||||
$stationConfig = array_merge([
|
||||
'stationKey' => $stationType,
|
||||
'pageTitle' => $stationName,
|
||||
'pageIcon' => 'cube',
|
||||
'cardTitle' => '快速录入',
|
||||
'tableTitle' => '操作记录',
|
||||
'dataSources' => [
|
||||
'types' => $types ?? [],
|
||||
'models' => $models ?? [],
|
||||
'customers' => $customers ?? [],
|
||||
],
|
||||
'submitMode' => 'auto',
|
||||
'codeFields' => ['serial_no'],
|
||||
'labelFields' => [],
|
||||
'emptyText' => '暂无记录,请在扫描框中录入第一条数据',
|
||||
'reloadAfterSubmit' => true,
|
||||
'enableFilter' => false,
|
||||
], $bizConfig['view'] ?? []);
|
||||
|
||||
// 注入全局变量
|
||||
$GLOBALS['records'] = $parsedRecords;
|
||||
$GLOBALS['fieldConfigs'] = $fieldConfigs;
|
||||
$GLOBALS['types'] = $types ?? [];
|
||||
$GLOBALS['models'] = $models ?? [];
|
||||
$GLOBALS['customers'] = $customers ?? [];
|
||||
$GLOBALS['user'] = $user;
|
||||
$GLOBALS['sysConfig'] = $sysConfig;
|
||||
$GLOBALS['stationType'] = $stationType;
|
||||
$GLOBALS['bizConfig'] = $bizConfig;
|
||||
$GLOBALS['filterType'] = $filterType ?? '';
|
||||
$GLOBALS['filterModel'] = $filterModel ?? '';
|
||||
$GLOBALS['todayCount'] = $todayCount ?? 0;
|
||||
$GLOBALS['totalCount'] = $totalCount ?? 0;
|
||||
$GLOBALS['shellColors'] = $shellColors ?? [];
|
||||
$GLOBALS['csrfToken'] = $csrfToken;
|
||||
$GLOBALS['stationError'] = $stationError ?? '';
|
||||
|
||||
renderStationTemplate($stationConfig);
|
||||
|
||||
} else {
|
||||
// ========== 动态工位:使用 station_records 表(JSON 存储) ==========
|
||||
|
||||
// 解析记录中的 JSON 数据
|
||||
$parsedRecords = [];
|
||||
if (!empty($records)) {
|
||||
foreach ($records as $rec) {
|
||||
$row = ['id' => $rec['id'], 'operator' => $rec['operator'], 'created_at' => $rec['created_at']];
|
||||
$jsonData = json_decode($rec['record_data'], true);
|
||||
if (is_array($jsonData)) {
|
||||
$row = array_merge($row, $jsonData);
|
||||
}
|
||||
$parsedRecords[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// 配置工位模板
|
||||
$stationConfig = [
|
||||
'stationKey' => $stationType,
|
||||
'pageTitle' => $stationName,
|
||||
'pageIcon' => 'cube',
|
||||
'cardTitle' => '快速录入',
|
||||
'tableTitle' => '操作记录',
|
||||
'dataSources' => [
|
||||
'types' => $types ?? [],
|
||||
'models' => $models ?? [],
|
||||
'customers' => $customers ?? [],
|
||||
],
|
||||
'submitMode' => 'auto', // 扫描回车直接提交
|
||||
'codeFields' => ['serial_no'], // 序列号类字段 code 样式
|
||||
'labelFields' => [],
|
||||
'emptyText' => '暂无记录,请在扫描框中录入第一条数据',
|
||||
'reloadAfterSubmit' => true, // 提交后刷新页面
|
||||
'enableFilter' => false, // 不启用联动筛选
|
||||
];
|
||||
|
||||
// 将解析后的记录和字段配置注入全局,供 renderStationTemplate 使用
|
||||
$GLOBALS['records'] = $parsedRecords;
|
||||
$GLOBALS['fieldConfigs'] = $fieldConfigs;
|
||||
$GLOBALS['types'] = $types ?? [];
|
||||
$GLOBALS['models'] = $models ?? [];
|
||||
$GLOBALS['customers'] = $customers ?? [];
|
||||
$GLOBALS['user'] = $user;
|
||||
$GLOBALS['sysConfig'] = $sysConfig;
|
||||
$GLOBALS['stationType'] = $stationType;
|
||||
$GLOBALS['bizConfig'] = null;
|
||||
$GLOBALS['filterType'] = '';
|
||||
$GLOBALS['filterModel'] = '';
|
||||
$GLOBALS['todayCount'] = 0;
|
||||
$GLOBALS['totalCount'] = $totalCount ?? count($parsedRecords);
|
||||
$GLOBALS['shellColors'] = [];
|
||||
$GLOBALS['csrfToken'] = $csrfToken;
|
||||
$GLOBALS['stationError'] = '';
|
||||
|
||||
renderStationTemplate($stationConfig);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 资产列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/General/assetAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加资产</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>资产编号</th>
|
||||
<th>资产名称</th>
|
||||
<th>类别</th>
|
||||
<th>规格型号</th>
|
||||
<th>数量</th>
|
||||
<th>购置价格</th>
|
||||
<th>使用部门</th>
|
||||
<th>使用人</th>
|
||||
<th>状态</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($assets)): ?>
|
||||
<?php foreach ($assets as $a): ?>
|
||||
<tr>
|
||||
<td><?php echo $a['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($a['asset_no']); ?></td>
|
||||
<td><?php echo htmlspecialchars($a['name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($a['category']); ?></td>
|
||||
<td><?php echo htmlspecialchars($a['model']); ?></td>
|
||||
<td><?php echo $a['quantity']; ?></td>
|
||||
<td>¥<?php echo number_format($a['purchase_price'], 2); ?></td>
|
||||
<td><?php echo htmlspecialchars($a['department']); ?></td>
|
||||
<td><?php echo htmlspecialchars($a['user_name']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['normal'=>'正常','scrapped'=>'报废','repairing'=>'维修中','borrowed'=>'借用中'];
|
||||
$statusColors = ['normal'=>'success','scrapped'=>'default','repairing'=>'warning','borrowed'=>'info'];
|
||||
$st = $a['status'] ?? 'normal';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/General/assetEdit?id=<?php echo $a['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/General/assetDelete" style="display:inline" onsubmit="return confirm('确定删除该资产吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $a['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="11" class="text-center text-muted">暂无资产数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加资产</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>资产编号</label><input type="text" name="asset_no" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>资产名称 <span class="text-red">*</span></label><input type="text" name="name" class="form-control" required></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>类别</label><input type="text" name="category" class="form-control" placeholder="如:电子设备、办公家具"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>规格型号</label><input type="text" name="model" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group"><label>数量</label><input type="number" name="quantity" class="form-control" value="1"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group"><label>单位</label><input type="text" name="unit" class="form-control" value="台"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group"><label>购置价格</label><input type="number" name="purchase_price" class="form-control" value="0" step="0.01"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>购置日期</label><input type="date" name="purchase_date" class="form-control" value="<?php echo date('Y-m-d'); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>供应商</label><input type="text" name="supplier" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>使用部门</label><input type="text" name="department" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>使用人</label><input type="text" name="user_name" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>存放位置</label><input type="text" name="location" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>状态</label>
|
||||
<select name="status" class="form-control"><option value="normal">正常</option><option value="repairing">维修中</option><option value="borrowed">借用中</option></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>保修到期</label><input type="date" name="warranty_expire" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"><label>备注</label><textarea name="remark" class="form-control" rows="2"></textarea></div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/General/asset" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑资产</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>资产编号</label><input type="text" name="asset_no" class="form-control" value="<?php echo htmlspecialchars($record['asset_no']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>资产名称 <span class="text-red">*</span></label><input type="text" name="name" class="form-control" value="<?php echo htmlspecialchars($record['name']); ?>" required></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>类别</label><input type="text" name="category" class="form-control" value="<?php echo htmlspecialchars($record['category']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>规格型号</label><input type="text" name="model" class="form-control" value="<?php echo htmlspecialchars($record['model']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group"><label>数量</label><input type="number" name="quantity" class="form-control" value="<?php echo $record['quantity']; ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group"><label>单位</label><input type="text" name="unit" class="form-control" value="<?php echo htmlspecialchars($record['unit']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group"><label>购置价格</label><input type="number" name="purchase_price" class="form-control" value="<?php echo $record['purchase_price']; ?>" step="0.01"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>购置日期</label><input type="date" name="purchase_date" class="form-control" value="<?php echo htmlspecialchars($record['purchase_date']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>供应商</label><input type="text" name="supplier" class="form-control" value="<?php echo htmlspecialchars($record['supplier']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>使用部门</label><input type="text" name="department" class="form-control" value="<?php echo htmlspecialchars($record['department']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>使用人</label><input type="text" name="user_name" class="form-control" value="<?php echo htmlspecialchars($record['user_name']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>存放位置</label><input type="text" name="location" class="form-control" value="<?php echo htmlspecialchars($record['location']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<?php
|
||||
$statuses = ['normal'=>'正常','scrapped'=>'报废','repairing'=>'维修中','borrowed'=>'借用中'];
|
||||
foreach ($statuses as $k => $v):
|
||||
$sel = ($record['status'] ?? '') === $k ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $k; ?>" <?php echo $sel; ?>><?php echo $v; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>保修到期</label><input type="date" name="warranty_expire" class="form-control" value="<?php echo htmlspecialchars($record['warranty_expire']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"><label>备注</label><textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($record['remark']); ?></textarea></div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/General/asset" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 文档列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/General/documentAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加文档</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>文档编号</th>
|
||||
<th>标题</th>
|
||||
<th>分类</th>
|
||||
<th>版本</th>
|
||||
<th>作者</th>
|
||||
<th>部门</th>
|
||||
<th>状态</th>
|
||||
<th>创建时间</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($documents)): ?>
|
||||
<?php foreach ($documents as $d): ?>
|
||||
<tr>
|
||||
<td><?php echo $d['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($d['doc_no']); ?></td>
|
||||
<td>
|
||||
<?php if (!empty($d['file_path'])): ?>
|
||||
<a href="<?php echo BASE_URL . htmlspecialchars($d['file_path']); ?>" target="_blank"><?php echo htmlspecialchars($d['title']); ?></a>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars($d['title']); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($d['category']); ?></td>
|
||||
<td><?php echo htmlspecialchars($d['version']); ?></td>
|
||||
<td><?php echo htmlspecialchars($d['author']); ?></td>
|
||||
<td><?php echo htmlspecialchars($d['department']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['active'=>'启用','archived'=>'归档','obsolete'=>'作废'];
|
||||
$statusColors = ['active'=>'success','archived'=>'info','obsolete'=>'default'];
|
||||
$st = $d['status'] ?? 'active';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($d['created_at']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/General/documentEdit?id=<?php echo $d['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/General/documentDelete" style="display:inline" onsubmit="return confirm('确定删除该文档吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $d['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="10" class="text-center text-muted">暂无文档数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加文档</h3>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group"><label>文档标题 <span class="text-red">*</span></label><input type="text" name="title" class="form-control" required></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>文档编号</label><input type="text" name="doc_no" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>版本号</label><input type="text" name="version" class="form-control" value="1.0"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>分类</label><input type="text" name="category" class="form-control" placeholder="如:技术文档、管理制度"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>作者</label><input type="text" name="author" class="form-control" value="<?php echo htmlspecialchars($user['emp_name']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>部门</label><input type="text" name="department" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group"><label>关键词</label><input type="text" name="keywords" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>状态</label>
|
||||
<select name="status" class="form-control"><option value="active">启用</option><option value="archived">归档</option></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>上传文件</label><input type="file" name="doc_file" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"><label>描述</label><textarea name="description" class="form-control" rows="3"></textarea></div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/General/document" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑文档</h3>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group"><label>文档标题 <span class="text-red">*</span></label><input type="text" name="title" class="form-control" value="<?php echo htmlspecialchars($record['title']); ?>" required></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>文档编号</label><input type="text" name="doc_no" class="form-control" value="<?php echo htmlspecialchars($record['doc_no']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>版本号</label><input type="text" name="version" class="form-control" value="<?php echo htmlspecialchars($record['version']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>分类</label><input type="text" name="category" class="form-control" value="<?php echo htmlspecialchars($record['category']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>作者</label><input type="text" name="author" class="form-control" value="<?php echo htmlspecialchars($record['author']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>部门</label><input type="text" name="department" class="form-control" value="<?php echo htmlspecialchars($record['department']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group"><label>关键词</label><input type="text" name="keywords" class="form-control" value="<?php echo htmlspecialchars($record['keywords']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="active" <?php echo ($record['status'] ?? '') === 'active' ? 'selected' : ''; ?>>启用</option>
|
||||
<option value="archived" <?php echo ($record['status'] ?? '') === 'archived' ? 'selected' : ''; ?>>归档</option>
|
||||
<option value="obsolete" <?php echo ($record['status'] ?? '') === 'obsolete' ? 'selected' : ''; ?>>作废</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>上传新文件</label><input type="file" name="doc_file" class="form-control">
|
||||
<?php if (!empty($record['file_name'])): ?>
|
||||
<small class="text-muted">当前文件:<?php echo htmlspecialchars($record['file_name']); ?></small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"><label>描述</label><textarea name="description" class="form-control" rows="3"><?php echo htmlspecialchars($record['description']); ?></textarea></div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/General/document" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 员工列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/General/hrAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加员工</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>工号</th>
|
||||
<th>姓名</th>
|
||||
<th>性别</th>
|
||||
<th>部门</th>
|
||||
<th>职位</th>
|
||||
<th>手机号</th>
|
||||
<th>入职日期</th>
|
||||
<th>状态</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($employees)): ?>
|
||||
<?php foreach ($employees as $e): ?>
|
||||
<tr>
|
||||
<td><?php echo $e['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($e['emp_no']); ?></td>
|
||||
<td><?php echo htmlspecialchars($e['name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($e['gender']); ?></td>
|
||||
<td><?php echo htmlspecialchars($e['department']); ?></td>
|
||||
<td><?php echo htmlspecialchars($e['position']); ?></td>
|
||||
<td><?php echo htmlspecialchars($e['phone']); ?></td>
|
||||
<td><?php echo htmlspecialchars($e['entry_date']); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['active'=>'在职','resigned'=>'离职','suspended'=>'停职'];
|
||||
$statusColors = ['active'=>'success','resigned'=>'default','suspended'=>'warning'];
|
||||
$st = $e['status'] ?? 'active';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/General/hrEdit?id=<?php echo $e['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/General/hrDelete" style="display:inline" onsubmit="return confirm('确定删除该员工吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $e['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="10" class="text-center text-muted">暂无员工数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加员工</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>工号</label><input type="text" name="emp_no" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>姓名 <span class="text-red">*</span></label><input type="text" name="name" class="form-control" required></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>性别</label>
|
||||
<select name="gender" class="form-control"><option value="">-- 请选择 --</option><option value="男">男</option><option value="女">女</option></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>部门</label><input type="text" name="department" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>职位</label><input type="text" name="position" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>学历</label>
|
||||
<select name="education" class="form-control"><option value="">-- 请选择 --</option><option value="初中">初中</option><option value="高中">高中</option><option value="大专">大专</option><option value="本科">本科</option><option value="硕士">硕士</option></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>手机号</label><input type="text" name="phone" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>邮箱</label><input type="email" name="email" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>身份证号</label><input type="text" name="id_card" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>入职日期</label><input type="date" name="entry_date" class="form-control" value="<?php echo date('Y-m-d'); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>状态</label>
|
||||
<select name="status" class="form-control"><option value="active">在职</option><option value="suspended">停职</option></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>紧急联系人</label><input type="text" name="emergency_contact" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>紧急联系电话</label><input type="text" name="emergency_phone" class="form-control"></div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="form-group"><label>住址</label><input type="text" name="address" class="form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"><label>备注</label><textarea name="remark" class="form-control" rows="2"></textarea></div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/General/hr" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑员工</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>工号</label><input type="text" name="emp_no" class="form-control" value="<?php echo htmlspecialchars($record['emp_no']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>姓名 <span class="text-red">*</span></label><input type="text" name="name" class="form-control" value="<?php echo htmlspecialchars($record['name']); ?>" required></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>性别</label>
|
||||
<select name="gender" class="form-control"><option value="">-- 请选择 --</option><option value="男" <?php echo ($record['gender'] ?? '') === '男' ? 'selected' : ''; ?>>男</option><option value="女" <?php echo ($record['gender'] ?? '') === '女' ? 'selected' : ''; ?>>女</option></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>部门</label><input type="text" name="department" class="form-control" value="<?php echo htmlspecialchars($record['department']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>职位</label><input type="text" name="position" class="form-control" value="<?php echo htmlspecialchars($record['position']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>学历</label>
|
||||
<select name="education" class="form-control">
|
||||
<option value="">-- 请选择 --</option>
|
||||
<?php $edus = ['初中','高中','大专','本科','硕士'];
|
||||
foreach ($edus as $edu): $sel = ($record['education'] ?? '') === $edu ? 'selected' : ''; ?>
|
||||
<option value="<?php echo $edu; ?>" <?php echo $sel; ?>><?php echo $edu; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>手机号</label><input type="text" name="phone" class="form-control" value="<?php echo htmlspecialchars($record['phone']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>邮箱</label><input type="email" name="email" class="form-control" value="<?php echo htmlspecialchars($record['email']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>身份证号</label><input type="text" name="id_card" class="form-control" value="<?php echo htmlspecialchars($record['id_card']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>入职日期</label><input type="date" name="entry_date" class="form-control" value="<?php echo htmlspecialchars($record['entry_date']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>离职日期</label><input type="date" name="leave_date" class="form-control" value="<?php echo htmlspecialchars($record['leave_date']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="active" <?php echo ($record['status'] ?? '') === 'active' ? 'selected' : ''; ?>>在职</option>
|
||||
<option value="resigned" <?php echo ($record['status'] ?? '') === 'resigned' ? 'selected' : ''; ?>>离职</option>
|
||||
<option value="suspended" <?php echo ($record['status'] ?? '') === 'suspended' ? 'selected' : ''; ?>>停职</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group"><label>紧急联系人</label><input type="text" name="emergency_contact" class="form-control" value="<?php echo htmlspecialchars($record['emergency_contact']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group"><label>紧急联系电话</label><input type="text" name="emergency_phone" class="form-control" value="<?php echo htmlspecialchars($record['emergency_phone']); ?>"></div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="form-group"><label>住址</label><input type="text" name="address" class="form-control" value="<?php echo htmlspecialchars($record['address']); ?>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group"><label>备注</label><textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($record['remark']); ?></textarea></div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/General/hr" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-xs-6">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner">
|
||||
<h3><?php echo $employeeCount ?? 0; ?></h3>
|
||||
<p>员工总数</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-users"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/General/hr" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-xs-6">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h3><?php echo isset($assetStats['cnt']) ? $assetStats['cnt'] : 0; ?></h3>
|
||||
<p>资产总数</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-laptop"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/General/asset" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-xs-6">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner">
|
||||
<h3><?php echo $documentCount ?? 0; ?></h3>
|
||||
<p>文档总数</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-file-text"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/General/document" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (isset($assetStats['total_value'])): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-info-circle"></i> 资产总价值</h3>
|
||||
</div>
|
||||
<div class="box-body text-center">
|
||||
<h2 style="color:#3c8dbc; font-weight:bold;">¥<?php echo number_format($assetStats['total_value'], 2); ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-rocket"></i> 快捷操作</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<a href="<?php echo BASE_URL; ?>/General/hrAdd" class="btn btn-primary"><i class="fa fa-user-plus"></i> 添加员工</a>
|
||||
<a href="<?php echo BASE_URL; ?>/General/assetAdd" class="btn btn-success"><i class="fa fa-plus"></i> 添加资产</a>
|
||||
<a href="<?php echo BASE_URL; ?>/General/documentAdd" class="btn btn-warning"><i class="fa fa-file"></i> 添加文档</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner">
|
||||
<h3><?php echo $supplierCount ?? 0; ?></h3>
|
||||
<p>供应商数量</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-address-book"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplier" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h3><?php echo $purchaseCount ?? 0; ?></h3>
|
||||
<p>采购订单</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-truck"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchase" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner">
|
||||
<h3><?php echo isset($stockCount['cnt']) ? $stockCount['cnt'] : 0; ?></h3>
|
||||
<p>库存品类</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-archive"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stock" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h3><?php echo $salesCount ?? 0; ?></h3>
|
||||
<p>销售订单</p>
|
||||
</div>
|
||||
<div class="icon"><i class="fa fa-shopping-cart"></i></div>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/sales" class="small-box-footer">进入管理 <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($lowStockItems)): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-danger">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-exclamation-triangle"></i> 低库存预警</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th>规格型号</th>
|
||||
<th>当前库存</th>
|
||||
<th>最低库存</th>
|
||||
<th>仓库</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($lowStockItems as $item): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($item['product_model']); ?></td>
|
||||
<td><span class="label label-danger"><?php echo $item['quantity']; ?></span></td>
|
||||
<td><?php echo $item['min_stock']; ?></td>
|
||||
<td><?php echo htmlspecialchars($item['warehouse']); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-rocket"></i> 快捷操作</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplierAdd" class="btn btn-primary"><i class="fa fa-plus"></i> 添加供应商</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchaseAdd" class="btn btn-success"><i class="fa fa-truck"></i> 新建采购单</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stockAdd" class="btn btn-warning"><i class="fa fa-archive"></i> 添加库存</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/salesAdd" class="btn btn-danger"><i class="fa fa-shopping-cart"></i> 新建销售单</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 采购订单列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchaseAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 新建采购单</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>采购单号</th>
|
||||
<th>供应商</th>
|
||||
<th>采购日期</th>
|
||||
<th>总金额</th>
|
||||
<th>状态</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:180px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($orders)): ?>
|
||||
<?php foreach ($orders as $o): ?>
|
||||
<tr>
|
||||
<td><?php echo $o['id']; ?></td>
|
||||
<td><code><?php echo htmlspecialchars($o['order_no']); ?></code></td>
|
||||
<td><?php echo htmlspecialchars($o['supplier_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($o['order_date']); ?></td>
|
||||
<td>¥<?php echo number_format($o['total_amount'], 2); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['pending'=>'待确认','confirmed'=>'已确认','received'=>'已收货','cancelled'=>'已取消'];
|
||||
$statusColors = ['pending'=>'warning','confirmed'=>'info','received'=>'success','cancelled'=>'default'];
|
||||
$st = $o['status'] ?? 'pending';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($o['operator']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchaseDetail?id=<?php echo $o['id']; ?>" class="btn btn-xs btn-primary"><i class="fa fa-eye"></i> 详情</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchaseEdit?id=<?php echo $o['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Inventory/purchaseDelete" style="display:inline" onsubmit="return confirm('确定删除该采购单吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $o['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="8" class="text-center text-muted">暂无采购订单</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 新建采购订单</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>采购单号 <span class="text-red">*</span></label>
|
||||
<input type="text" name="order_no" class="form-control" value="CG<?php echo date('YmdHis'); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>供应商</label>
|
||||
<select name="supplier_id" class="form-control">
|
||||
<option value="">-- 请选择 --</option>
|
||||
<?php foreach ($suppliers as $s): ?>
|
||||
<option value="<?php echo $s['id']; ?>"><?php echo htmlspecialchars($s['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>采购日期</label>
|
||||
<input type="date" name="order_date" class="form-control" value="<?php echo date('Y-m-d'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="pending">待确认</option>
|
||||
<option value="confirmed">已确认</option>
|
||||
<option value="received">已收货</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>采购明细</h4>
|
||||
<table class="table table-bordered" id="itemsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th style="width:120px">规格型号</th>
|
||||
<th style="width:80px">数量</th>
|
||||
<th style="width:80px">单位</th>
|
||||
<th style="width:100px">单价</th>
|
||||
<th style="width:100px">金额</th>
|
||||
<th style="width:60px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="itemsBody">
|
||||
<tr>
|
||||
<td><input type="text" name="product_name[]" class="form-control"></td>
|
||||
<td><input type="text" name="product_model[]" class="form-control"></td>
|
||||
<td><input type="number" name="quantity[]" class="form-control qty" value="1" min="1" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" name="unit[]" class="form-control" value="个"></td>
|
||||
<td><input type="number" name="unit_price[]" class="form-control price" value="0" step="0.01" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" class="form-control amount" readonly value="0.00"></td>
|
||||
<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<button type="button" class="btn btn-sm btn-success" onclick="addRow()"><i class="fa fa-plus"></i> 添加行</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchase" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addRow() {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
var row = document.createElement('tr');
|
||||
row.innerHTML = '<td><input type="text" name="product_name[]" class="form-control"></td>' +
|
||||
'<td><input type="text" name="product_model[]" class="form-control"></td>' +
|
||||
'<td><input type="number" name="quantity[]" class="form-control qty" value="1" min="1" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" name="unit[]" class="form-control" value="个"></td>' +
|
||||
'<td><input type="number" name="unit_price[]" class="form-control price" value="0" step="0.01" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" class="form-control amount" readonly value="0.00"></td>' +
|
||||
'<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>';
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
function removeRow(btn) {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
if (tbody.rows.length > 1) {
|
||||
btn.closest('tr').remove();
|
||||
}
|
||||
}
|
||||
function calcRow(el) {
|
||||
var row = el.closest('tr');
|
||||
var qty = parseFloat(row.querySelector('.qty').value) || 0;
|
||||
var price = parseFloat(row.querySelector('.price').value) || 0;
|
||||
row.querySelector('.amount').value = (qty * price).toFixed(2);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-eye"></i> 采购订单详情 #<?php echo $order['id']; ?></h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchase" class="btn btn-default btn-sm"><i class="fa fa-arrow-left"></i> 返回列表</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>采购单号</dt><dd><code><?php echo htmlspecialchars($order['order_no']); ?></code></dd>
|
||||
<dt>供应商</dt><dd><?php echo htmlspecialchars($order['supplier_name']); ?></dd>
|
||||
<dt>采购日期</dt><dd><?php echo htmlspecialchars($order['order_date']); ?></dd>
|
||||
<dt>总金额</dt><dd><strong>¥<?php echo number_format($order['total_amount'], 2); ?></strong></dd>
|
||||
<dt>状态</dt><dd><?php echo htmlspecialchars($order['status']); ?></dd>
|
||||
<dt>操作人</dt><dd><?php echo htmlspecialchars($order['operator']); ?></dd>
|
||||
<dt>备注</dt><dd><?php echo htmlspecialchars($order['remark']); ?></dd>
|
||||
</dl>
|
||||
|
||||
<h4>采购明细</h4>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th>规格型号</th>
|
||||
<th>数量</th>
|
||||
<th>单位</th>
|
||||
<th>单价</th>
|
||||
<th>金额</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($items)): ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($item['product_model']); ?></td>
|
||||
<td><?php echo $item['quantity']; ?></td>
|
||||
<td><?php echo htmlspecialchars($item['unit']); ?></td>
|
||||
<td>¥<?php echo number_format($item['unit_price'], 2); ?></td>
|
||||
<td>¥<?php echo number_format($item['amount'], 2); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="6" class="text-center text-muted">无明细数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑采购订单</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>采购单号 <span class="text-red">*</span></label>
|
||||
<input type="text" name="order_no" class="form-control" value="<?php echo htmlspecialchars($order['order_no']); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>供应商</label>
|
||||
<select name="supplier_id" class="form-control">
|
||||
<?php foreach ($suppliers as $s): ?>
|
||||
<option value="<?php echo $s['id']; ?>" <?php echo $s['id'] == $order['supplier_id'] ? 'selected' : ''; ?>><?php echo htmlspecialchars($s['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>采购日期</label>
|
||||
<input type="date" name="order_date" class="form-control" value="<?php echo htmlspecialchars($order['order_date']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="pending" <?php echo ($order['status'] ?? '') === 'pending' ? 'selected' : ''; ?>>待确认</option>
|
||||
<option value="confirmed" <?php echo ($order['status'] ?? '') === 'confirmed' ? 'selected' : ''; ?>>已确认</option>
|
||||
<option value="received" <?php echo ($order['status'] ?? '') === 'received' ? 'selected' : ''; ?>>已收货</option>
|
||||
<option value="cancelled" <?php echo ($order['status'] ?? '') === 'cancelled' ? 'selected' : ''; ?>>已取消</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>采购明细</h4>
|
||||
<table class="table table-bordered" id="itemsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th style="width:120px">规格型号</th>
|
||||
<th style="width:80px">数量</th>
|
||||
<th style="width:80px">单位</th>
|
||||
<th style="width:100px">单价</th>
|
||||
<th style="width:100px">金额</th>
|
||||
<th style="width:60px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="itemsBody">
|
||||
<?php if (!empty($items)): ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><input type="text" name="product_name[]" class="form-control" value="<?php echo htmlspecialchars($item['product_name']); ?>"></td>
|
||||
<td><input type="text" name="product_model[]" class="form-control" value="<?php echo htmlspecialchars($item['product_model']); ?>"></td>
|
||||
<td><input type="number" name="quantity[]" class="form-control qty" value="<?php echo $item['quantity']; ?>" min="1" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" name="unit[]" class="form-control" value="<?php echo htmlspecialchars($item['unit']); ?>"></td>
|
||||
<td><input type="number" name="unit_price[]" class="form-control price" value="<?php echo $item['unit_price']; ?>" step="0.01" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" class="form-control amount" readonly value="<?php echo number_format($item['amount'], 2); ?>"></td>
|
||||
<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<button type="button" class="btn btn-sm btn-success" onclick="addRow()"><i class="fa fa-plus"></i> 添加行</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($order['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchase" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addRow() {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
var row = document.createElement('tr');
|
||||
row.innerHTML = '<td><input type="text" name="product_name[]" class="form-control"></td>' +
|
||||
'<td><input type="text" name="product_model[]" class="form-control"></td>' +
|
||||
'<td><input type="number" name="quantity[]" class="form-control qty" value="1" min="1" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" name="unit[]" class="form-control" value="个"></td>' +
|
||||
'<td><input type="number" name="unit_price[]" class="form-control price" value="0" step="0.01" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" class="form-control amount" readonly value="0.00"></td>' +
|
||||
'<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>';
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
function removeRow(btn) {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
if (tbody.rows.length > 1) {
|
||||
btn.closest('tr').remove();
|
||||
}
|
||||
}
|
||||
function calcRow(el) {
|
||||
var row = el.closest('tr');
|
||||
var qty = parseFloat(row.querySelector('.qty').value) || 0;
|
||||
var price = parseFloat(row.querySelector('.price').value) || 0;
|
||||
row.querySelector('.amount').value = (qty * price).toFixed(2);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 销售订单列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/salesAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 新建销售单</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>销售单号</th>
|
||||
<th>客户名称</th>
|
||||
<th>销售日期</th>
|
||||
<th>总金额</th>
|
||||
<th>状态</th>
|
||||
<th>操作人</th>
|
||||
<th style="width:180px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($orders)): ?>
|
||||
<?php foreach ($orders as $o): ?>
|
||||
<tr>
|
||||
<td><?php echo $o['id']; ?></td>
|
||||
<td><code><?php echo htmlspecialchars($o['order_no']); ?></code></td>
|
||||
<td><?php echo htmlspecialchars($o['customer_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($o['order_date']); ?></td>
|
||||
<td>¥<?php echo number_format($o['total_amount'], 2); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$statusLabels = ['pending'=>'待发货','shipped'=>'已发货','completed'=>'已完成','cancelled'=>'已取消'];
|
||||
$statusColors = ['pending'=>'warning','shipped'=>'info','completed'=>'success','cancelled'=>'default'];
|
||||
$st = $o['status'] ?? 'pending';
|
||||
?>
|
||||
<span class="label label-<?php echo $statusColors[$st] ?? 'default'; ?>">
|
||||
<?php echo $statusLabels[$st] ?? $st; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($o['operator']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/salesDetail?id=<?php echo $o['id']; ?>" class="btn btn-xs btn-primary"><i class="fa fa-eye"></i> 详情</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/salesEdit?id=<?php echo $o['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Inventory/salesDelete" style="display:inline" onsubmit="return confirm('确定删除该销售单吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $o['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="8" class="text-center text-muted">暂无销售订单</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 新建销售订单</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>销售单号 <span class="text-red">*</span></label>
|
||||
<input type="text" name="order_no" class="form-control" value="XS<?php echo date('YmdHis'); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>客户名称</label>
|
||||
<input type="text" name="customer_name" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>销售日期</label>
|
||||
<input type="date" name="order_date" class="form-control" value="<?php echo date('Y-m-d'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="pending">待发货</option>
|
||||
<option value="shipped">已发货</option>
|
||||
<option value="completed">已完成</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>销售明细</h4>
|
||||
<table class="table table-bordered" id="itemsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th style="width:120px">规格型号</th>
|
||||
<th style="width:80px">数量</th>
|
||||
<th style="width:80px">单位</th>
|
||||
<th style="width:100px">单价</th>
|
||||
<th style="width:100px">金额</th>
|
||||
<th style="width:60px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="itemsBody">
|
||||
<tr>
|
||||
<td><input type="text" name="product_name[]" class="form-control"></td>
|
||||
<td><input type="text" name="product_model[]" class="form-control"></td>
|
||||
<td><input type="number" name="quantity[]" class="form-control qty" value="1" min="1" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" name="unit[]" class="form-control" value="个"></td>
|
||||
<td><input type="number" name="unit_price[]" class="form-control price" value="0" step="0.01" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" class="form-control amount" readonly value="0.00"></td>
|
||||
<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<button type="button" class="btn btn-sm btn-success" onclick="addRow()"><i class="fa fa-plus"></i> 添加行</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/sales" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addRow() {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
var row = document.createElement('tr');
|
||||
row.innerHTML = '<td><input type="text" name="product_name[]" class="form-control"></td>' +
|
||||
'<td><input type="text" name="product_model[]" class="form-control"></td>' +
|
||||
'<td><input type="number" name="quantity[]" class="form-control qty" value="1" min="1" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" name="unit[]" class="form-control" value="个"></td>' +
|
||||
'<td><input type="number" name="unit_price[]" class="form-control price" value="0" step="0.01" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" class="form-control amount" readonly value="0.00"></td>' +
|
||||
'<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>';
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
function removeRow(btn) {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
if (tbody.rows.length > 1) btn.closest('tr').remove();
|
||||
}
|
||||
function calcRow(el) {
|
||||
var row = el.closest('tr');
|
||||
var qty = parseFloat(row.querySelector('.qty').value) || 0;
|
||||
var price = parseFloat(row.querySelector('.price').value) || 0;
|
||||
row.querySelector('.amount').value = (qty * price).toFixed(2);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-eye"></i> 销售订单详情 #<?php echo $order['id']; ?></h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/sales" class="btn btn-default btn-sm"><i class="fa fa-arrow-left"></i> 返回列表</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>销售单号</dt><dd><code><?php echo htmlspecialchars($order['order_no']); ?></code></dd>
|
||||
<dt>客户名称</dt><dd><?php echo htmlspecialchars($order['customer_name']); ?></dd>
|
||||
<dt>销售日期</dt><dd><?php echo htmlspecialchars($order['order_date']); ?></dd>
|
||||
<dt>总金额</dt><dd><strong>¥<?php echo number_format($order['total_amount'], 2); ?></strong></dd>
|
||||
<dt>状态</dt><dd><?php echo htmlspecialchars($order['status']); ?></dd>
|
||||
<dt>操作人</dt><dd><?php echo htmlspecialchars($order['operator']); ?></dd>
|
||||
<dt>备注</dt><dd><?php echo htmlspecialchars($order['remark']); ?></dd>
|
||||
</dl>
|
||||
|
||||
<h4>销售明细</h4>
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th>规格型号</th>
|
||||
<th>数量</th>
|
||||
<th>单位</th>
|
||||
<th>单价</th>
|
||||
<th>金额</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($items)): ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($item['product_model']); ?></td>
|
||||
<td><?php echo $item['quantity']; ?></td>
|
||||
<td><?php echo htmlspecialchars($item['unit']); ?></td>
|
||||
<td>¥<?php echo number_format($item['unit_price'], 2); ?></td>
|
||||
<td>¥<?php echo number_format($item['amount'], 2); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="6" class="text-center text-muted">无明细数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑销售订单</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>销售单号 <span class="text-red">*</span></label>
|
||||
<input type="text" name="order_no" class="form-control" value="<?php echo htmlspecialchars($order['order_no']); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>客户名称</label>
|
||||
<input type="text" name="customer_name" class="form-control" value="<?php echo htmlspecialchars($order['customer_name']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>销售日期</label>
|
||||
<input type="date" name="order_date" class="form-control" value="<?php echo htmlspecialchars($order['order_date']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="pending" <?php echo ($order['status'] ?? '') === 'pending' ? 'selected' : ''; ?>>待发货</option>
|
||||
<option value="shipped" <?php echo ($order['status'] ?? '') === 'shipped' ? 'selected' : ''; ?>>已发货</option>
|
||||
<option value="completed" <?php echo ($order['status'] ?? '') === 'completed' ? 'selected' : ''; ?>>已完成</option>
|
||||
<option value="cancelled" <?php echo ($order['status'] ?? '') === 'cancelled' ? 'selected' : ''; ?>>已取消</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>销售明细</h4>
|
||||
<table class="table table-bordered" id="itemsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>产品名称</th>
|
||||
<th style="width:120px">规格型号</th>
|
||||
<th style="width:80px">数量</th>
|
||||
<th style="width:80px">单位</th>
|
||||
<th style="width:100px">单价</th>
|
||||
<th style="width:100px">金额</th>
|
||||
<th style="width:60px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="itemsBody">
|
||||
<?php if (!empty($items)): ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><input type="text" name="product_name[]" class="form-control" value="<?php echo htmlspecialchars($item['product_name']); ?>"></td>
|
||||
<td><input type="text" name="product_model[]" class="form-control" value="<?php echo htmlspecialchars($item['product_model']); ?>"></td>
|
||||
<td><input type="number" name="quantity[]" class="form-control qty" value="<?php echo $item['quantity']; ?>" min="1" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" name="unit[]" class="form-control" value="<?php echo htmlspecialchars($item['unit']); ?>"></td>
|
||||
<td><input type="number" name="unit_price[]" class="form-control price" value="<?php echo $item['unit_price']; ?>" step="0.01" onchange="calcRow(this)"></td>
|
||||
<td><input type="text" class="form-control amount" readonly value="<?php echo number_format($item['amount'], 2); ?>"></td>
|
||||
<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<button type="button" class="btn btn-sm btn-success" onclick="addRow()"><i class="fa fa-plus"></i> 添加行</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($order['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/sales" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addRow() {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
var row = document.createElement('tr');
|
||||
row.innerHTML = '<td><input type="text" name="product_name[]" class="form-control"></td>' +
|
||||
'<td><input type="text" name="product_model[]" class="form-control"></td>' +
|
||||
'<td><input type="number" name="quantity[]" class="form-control qty" value="1" min="1" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" name="unit[]" class="form-control" value="个"></td>' +
|
||||
'<td><input type="number" name="unit_price[]" class="form-control price" value="0" step="0.01" onchange="calcRow(this)"></td>' +
|
||||
'<td><input type="text" class="form-control amount" readonly value="0.00"></td>' +
|
||||
'<td><button type="button" class="btn btn-xs btn-danger" onclick="removeRow(this)"><i class="fa fa-times"></i></button></td>';
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
function removeRow(btn) {
|
||||
var tbody = document.getElementById('itemsBody');
|
||||
if (tbody.rows.length > 1) btn.closest('tr').remove();
|
||||
}
|
||||
function calcRow(el) {
|
||||
var row = el.closest('tr');
|
||||
var qty = parseFloat(row.querySelector('.qty').value) || 0;
|
||||
var price = parseFloat(row.querySelector('.price').value) || 0;
|
||||
row.querySelector('.amount').value = (qty * price).toFixed(2);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 库存列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stockAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加库存</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>产品名称</th>
|
||||
<th>规格型号</th>
|
||||
<th>物料分类</th>
|
||||
<th>库存数量</th>
|
||||
<th>单位</th>
|
||||
<th>参考单价</th>
|
||||
<th>最低库存</th>
|
||||
<th>仓库</th>
|
||||
<th>库位</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($stocks)): ?>
|
||||
<?php foreach ($stocks as $s): ?>
|
||||
<?php
|
||||
$isLow = $s['min_stock'] > 0 && $s['quantity'] <= $s['min_stock'];
|
||||
?>
|
||||
<tr class="<?php echo $isLow ? 'danger' : ''; ?>">
|
||||
<td><?php echo $s['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($s['product_name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['product_model']); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['category']); ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $isLow ? 'danger' : 'success'; ?>">
|
||||
<?php echo $s['quantity']; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($s['unit']); ?></td>
|
||||
<td>¥<?php echo number_format($s['unit_price'], 2); ?></td>
|
||||
<td><?php echo $s['min_stock']; ?></td>
|
||||
<td><?php echo htmlspecialchars($s['warehouse']); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['location']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stockEdit?id=<?php echo $s['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Inventory/stockDelete" style="display:inline" onsubmit="return confirm('确定删除该库存记录吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $s['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="11" class="text-center text-muted">暂无库存数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加库存</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>产品名称 <span class="text-red">*</span></label>
|
||||
<input type="text" name="product_name" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>规格型号</label>
|
||||
<input type="text" name="product_model" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>物料分类</label>
|
||||
<input type="text" name="category" class="form-control" placeholder="如:原材料、半成品、成品">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>数量</label>
|
||||
<input type="number" name="quantity" class="form-control" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>单位</label>
|
||||
<input type="text" name="unit" class="form-control" value="个">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>参考单价</label>
|
||||
<input type="number" name="unit_price" class="form-control" value="0" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>最低库存预警</label>
|
||||
<input type="number" name="min_stock" class="form-control" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>最高库存</label>
|
||||
<input type="number" name="max_stock" class="form-control" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>仓库</label>
|
||||
<input type="text" name="warehouse" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>库位</label>
|
||||
<input type="text" name="location" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stock" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑库存</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>产品名称 <span class="text-red">*</span></label>
|
||||
<input type="text" name="product_name" class="form-control" value="<?php echo htmlspecialchars($record['product_name']); ?>" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label>规格型号</label>
|
||||
<input type="text" name="product_model" class="form-control" value="<?php echo htmlspecialchars($record['product_model']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>物料分类</label>
|
||||
<input type="text" name="category" class="form-control" value="<?php echo htmlspecialchars($record['category']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>数量</label>
|
||||
<input type="number" name="quantity" class="form-control" value="<?php echo $record['quantity']; ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<label>单位</label>
|
||||
<input type="text" name="unit" class="form-control" value="<?php echo htmlspecialchars($record['unit']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>参考单价</label>
|
||||
<input type="number" name="unit_price" class="form-control" value="<?php echo $record['unit_price']; ?>" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>最低库存预警</label>
|
||||
<input type="number" name="min_stock" class="form-control" value="<?php echo $record['min_stock']; ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>最高库存</label>
|
||||
<input type="number" name="max_stock" class="form-control" value="<?php echo $record['max_stock']; ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>仓库</label>
|
||||
<input type="text" name="warehouse" class="form-control" value="<?php echo htmlspecialchars($record['warehouse']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>库位</label>
|
||||
<input type="text" name="location" class="form-control" value="<?php echo htmlspecialchars($record['location']); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="2"><?php echo htmlspecialchars($record['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stock" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-list"></i> 供应商列表</h3>
|
||||
<div class="box-tools">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplierAdd" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> 添加供应商</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>供应商名称</th>
|
||||
<th>联系人</th>
|
||||
<th>联系电话</th>
|
||||
<th>地址</th>
|
||||
<th>状态</th>
|
||||
<th>备注</th>
|
||||
<th style="width:150px">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($suppliers)): ?>
|
||||
<?php foreach ($suppliers as $s): ?>
|
||||
<tr>
|
||||
<td><?php echo $s['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($s['name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['contact_person']); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['phone']); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['address']); ?></td>
|
||||
<td>
|
||||
<span class="label label-<?php echo $s['status'] ? 'success' : 'default'; ?>">
|
||||
<?php echo $s['status'] ? '正常' : '停用'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($s['remark']); ?></td>
|
||||
<td>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplierEdit?id=<?php echo $s['id']; ?>" class="btn btn-xs btn-info"><i class="fa fa-edit"></i> 编辑</a>
|
||||
<form method="post" action="<?php echo BASE_URL; ?>/Inventory/supplierDelete" style="display:inline" onsubmit="return confirm('确定删除该供应商吗?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken ?? ''); ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $s['id']; ?>">
|
||||
<button type="submit" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i> 删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="8" class="text-center text-muted">暂无供应商数据</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-plus"></i> 添加供应商</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>供应商名称 <span class="text-red">*</span></label>
|
||||
<input type="text" name="name" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系人</label>
|
||||
<input type="text" name="contact_person" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系电话</label>
|
||||
<input type="text" name="phone" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>地址</label>
|
||||
<input type="text" name="address" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="1">正常</option>
|
||||
<option value="0">停用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplier" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-edit"></i> 编辑供应商</h3>
|
||||
</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label>供应商名称 <span class="text-red">*</span></label>
|
||||
<input type="text" name="name" class="form-control" value="<?php echo htmlspecialchars($record['name']); ?>" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系人</label>
|
||||
<input type="text" name="contact_person" class="form-control" value="<?php echo htmlspecialchars($record['contact_person']); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>联系电话</label>
|
||||
<input type="text" name="phone" class="form-control" value="<?php echo htmlspecialchars($record['phone']); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>地址</label>
|
||||
<input type="text" name="address" class="form-control" value="<?php echo htmlspecialchars($record['address']); ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>状态</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="1" <?php echo $record['status'] == 1 ? 'selected' : ''; ?>>正常</option>
|
||||
<option value="0" <?php echo $record['status'] == 0 ? 'selected' : ''; ?>>停用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>备注</label>
|
||||
<textarea name="remark" class="form-control" rows="3"><?php echo htmlspecialchars($record['remark']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> 保存</button>
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplier" class="btn btn-default">返回</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
@@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MES 制造执行系统 - 登录</title>
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/AdminLTE.min.css">
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/skins/_all-skins.min.css">
|
||||
<style>
|
||||
body { background: #d2d6de; }
|
||||
.login-page { background: #d2d6de !important; }
|
||||
.login-box { width: 400px; margin: 8% auto; }
|
||||
.login-logo { font-size: 35px; text-align: center; margin-bottom: 25px; }
|
||||
.login-logo b { color: #3c8dbc; }
|
||||
.login-box-body { background: #fff; padding: 30px; border-radius: 5px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
||||
.login-box-msg { text-align: center; font-size: 16px; color: #666; margin-bottom: 20px; }
|
||||
.form-control-feedback { line-height: 34px; }
|
||||
.login-footer { text-align: center; margin-top: 20px; color: #999; font-size: 12px; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="hold-transition login-page">
|
||||
<div class="login-box">
|
||||
<div class="login-logo">
|
||||
<b>MES</b> 制造执行系统
|
||||
</div>
|
||||
<div class="login-box-body">
|
||||
<p class="login-box-msg"><i class="fa fa-lock"></i> 请使用员工账号登录</p>
|
||||
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<i class="fa fa-exclamation-circle"></i> <?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo isset($csrf_token) ? h($csrf_token) : ''; ?>">
|
||||
<div class="form-group has-feedback">
|
||||
<input type="text" name="emp_no" class="form-control input-lg" placeholder="员工编号" required autofocus>
|
||||
<span class="fa fa-user form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group has-feedback">
|
||||
<input type="password" name="password" class="form-control input-lg" placeholder="密码" required>
|
||||
<span class="fa fa-lock form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat btn-lg">
|
||||
<i class="fa fa-sign-in"></i> 登录
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="login-footer" style="margin-top: 15px;">
|
||||
©2026深圳市云创芯电子有限公司版权所有<br>
|
||||
<span class="beian">备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">粤ICP备16118477号-1</a></span>
|
||||
<br><span class="beian">公安网备:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=44030002015390" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;gap:4px;"><img src="<?php echo BASE_URL; ?>/static/images/gongan_badge.png" width="16" height="17" alt="公安网备" loading="lazy" style="vertical-align:middle;" onerror="this.onerror=null;this.outerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 24 24"><path d="M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z" fill="#1a3a8f" stroke="#d4af37" stroke-width="1"/><polygon points="12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5" fill="#ffffff"/></svg>'">粤公网安备44030002015390号</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/bootstrap.min.js"></script>
|
||||
<?php // v3-P2 CSP:全局事件委托(替代内联 onclick 等) ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/csp_global.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
// ===== 自动聚焦输入框 =====
|
||||
$(function() {
|
||||
// 如果有错误提示,自动聚焦到员工编号输入框方便重新输入
|
||||
<?php if (!empty($error)): ?>
|
||||
$('input[name="emp_no"]').focus();
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,19 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<footer class="main-footer">
|
||||
<div class="pull-right hidden-xs"><b>Version</b> 1.0.0</div>
|
||||
<strong>©2026深圳市云创芯电子有限公司版权所有</strong><br>
|
||||
<span class="beian">备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">粤ICP备16118477号-1</a></span>
|
||||
<span class="beian">公安网备:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=44030002015390" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;gap:4px;"><img src="<?php echo BASE_URL; ?>/static/images/gongan_badge.png" width="16" height="17" alt="公安网备" loading="lazy" style="vertical-align:middle;" onerror="this.onerror=null;this.outerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 24 24"><path d="M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z" fill="#1a3a8f" stroke="#d4af37" stroke-width="1"/><polygon points="12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5" fill="#ffffff"/></svg>'">粤公网安备44030002015390号</a></span>
|
||||
</footer>
|
||||
|
||||
<div class="control-sidebar-bg"></div>
|
||||
</div>
|
||||
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/plugins/slimScroll/jquery.slimscroll.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/plugins/fastclick/fastclick.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/app.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,340 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<title><?php echo htmlspecialchars($title); ?> - MES 后台管理</title>
|
||||
<!-- Bootstrap 3.3.6 -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/bootstrap.min.css">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<!-- Ionicons(已本地化,P3-14 消除外部 CDN 供应链风险) -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/ionicons.min.css">
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/AdminLTE.min.css">
|
||||
<!-- AdminLTE Skins -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/skins/_all-skins.min.css">
|
||||
<!-- iCheck -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/iCheck/flat/blue.css">
|
||||
<!-- Morris chart -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/morris/morris.css">
|
||||
<!-- jvectormap -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
|
||||
<!-- Date Picker -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/datepicker/datepicker3.css">
|
||||
<!-- Daterange picker -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/daterangepicker/daterangepicker-bs3.css">
|
||||
<!-- bootstrap wysihtml5 - text editor -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
|
||||
<style>
|
||||
/* 全局表格居中 */
|
||||
.table th,
|
||||
.table td {
|
||||
text-align: center !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
/* ========== 类型卡片 Grid 并列布局 (productModel) ========== */
|
||||
.type-grid {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
grid-template-columns: repeat(2, 1fr); /* 默认2列 */
|
||||
}
|
||||
.type-grid[data-columns="1"] { grid-template-columns: 1fr; }
|
||||
.type-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
|
||||
.type-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
|
||||
.type-grid[data-columns="auto"] { grid-template-columns: repeat(auto-fill, minmax(450px, 1fr)); }
|
||||
|
||||
.type-grid-item {
|
||||
margin-bottom: 0 !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.type-grid-item .box-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 列数调节按钮激活态 */
|
||||
.column-adjuster .col-btn.active {
|
||||
background-color: #3c8dbc !important;
|
||||
color: #fff !important;
|
||||
border-color: #367fa9 !important;
|
||||
}
|
||||
|
||||
/* 移动端降级 */
|
||||
@media (max-width: 992px) {
|
||||
.type-grid[data-columns="2"],
|
||||
.type-grid[data-columns="3"],
|
||||
.type-grid[data-columns="auto"] {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.type-grid,
|
||||
.type-grid[data-columns="2"],
|
||||
.type-grid[data-columns="3"],
|
||||
.type-grid[data-columns="auto"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/jquery-3.7.1.min.js"></script>
|
||||
<?php // v3-P2 CSP:全局事件委托(替代内联 onclick 等),配合 nonce 实现无 unsafe-inline ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/csp_global.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/html5shiv.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<div class="wrapper">
|
||||
|
||||
<header class="main-header">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index" class="logo">
|
||||
<span class="logo-mini"><b>MES</b></span>
|
||||
<span class="logo-lg"><b>MES</b> 后台管理</span>
|
||||
</a>
|
||||
<nav class="navbar navbar-static-top">
|
||||
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
|
||||
<span class="sr-only">切换导航</span>
|
||||
</a>
|
||||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="<?php echo BASE_URL; ?>/Dashboard/index"><i class="fa fa-tachometer"></i> <span class="hidden-xs">工位看板</span></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index"><i class="fa fa-desktop"></i> <span class="hidden-xs">前台工位</span></a>
|
||||
</li>
|
||||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-user"></i>
|
||||
<span class="hidden-xs"><?php echo htmlspecialchars($user['emp_name']); ?></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="user-header" style="background:#3c8dbc; color:#fff; padding:10px; text-align:center;">
|
||||
<p><?php echo htmlspecialchars($user['emp_name']); ?><br>
|
||||
<small><?php
|
||||
$roleNames = \core\base\Controller::ROLE_NAMES;
|
||||
echo htmlspecialchars($roleNames[$user['role']] ?? $user['role']);
|
||||
?></small></p>
|
||||
</li>
|
||||
<li class="user-footer">
|
||||
<div class="pull-right">
|
||||
<a href="<?php echo BASE_URL; ?>/Login/logout" class="btn btn-default btn-flat"><i class="fa fa-power-off"></i> 退出登录</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<aside class="main-sidebar">
|
||||
<section class="sidebar">
|
||||
<div class="user-panel" style="padding:10px; color:#fff; text-align:center; border-bottom:1px solid #4b646f;">
|
||||
<p style="margin:0;"><i class="fa fa-circle text-success"></i> <?php echo htmlspecialchars($user['emp_name']); ?></p>
|
||||
<small style="color:#b8c7ce;">
|
||||
<?php
|
||||
$roleNames = \core\base\Controller::ROLE_NAMES;
|
||||
echo htmlspecialchars($roleNames[$user['role']] ?? $user['role']);
|
||||
?>
|
||||
</small>
|
||||
</div>
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
<li class="header">导航菜单</li>
|
||||
<?php
|
||||
$role = $user['role'];
|
||||
$category = $user['category'] ?? 'mes';
|
||||
$ROLE_SUPER_ADMIN = \core\base\Controller::ROLE_SUPER_ADMIN;
|
||||
$ROLE_ADMIN = \core\base\Controller::ROLE_ADMIN;
|
||||
$isSuperAdmin = ($role === $ROLE_SUPER_ADMIN);
|
||||
$isMESAdmin = ($isSuperAdmin || ($role === $ROLE_ADMIN && $category === \core\base\Controller::CATEGORY_MES));
|
||||
$isInventoryAdmin = ($isSuperAdmin || ($role === $ROLE_ADMIN && $category === \core\base\Controller::CATEGORY_INVENTORY));
|
||||
$isFinanceAdmin = ($isSuperAdmin || ($role === $ROLE_ADMIN && $category === \core\base\Controller::CATEGORY_FINANCE));
|
||||
$isGeneralAdmin = ($isSuperAdmin || ($role === $ROLE_ADMIN && $category === \core\base\Controller::CATEGORY_GENERAL));
|
||||
|
||||
$catNames = \core\base\Controller::CATEGORY_NAMES;
|
||||
$catIcons = \core\base\Controller::CATEGORY_ICONS;
|
||||
$currentCat = isset($_GET['cat']) ? $_GET['cat'] : ($category === 'all' ? 'mes' : $category);
|
||||
?>
|
||||
|
||||
<?php if ($isSuperAdmin): ?>
|
||||
<!-- 超级管理员:类目切换菜单 -->
|
||||
<li class="header">管理类目切换</li>
|
||||
<li class="<?php echo $currentCat === 'mes' ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index?cat=mes">
|
||||
<i class="fa <?php echo $catIcons['mes']; ?>"></i>
|
||||
<span><?php echo htmlspecialchars($catNames['mes']); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?php echo $currentCat === 'inventory' ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/index?cat=inventory">
|
||||
<i class="fa <?php echo $catIcons['inventory']; ?>"></i>
|
||||
<span><?php echo htmlspecialchars($catNames['inventory']); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?php echo $currentCat === 'finance' ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/index?cat=finance">
|
||||
<i class="fa <?php echo $catIcons['finance']; ?>"></i>
|
||||
<span><?php echo htmlspecialchars($catNames['finance']); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?php echo $currentCat === 'general' ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/General/index?cat=general">
|
||||
<i class="fa <?php echo $catIcons['general']; ?>"></i>
|
||||
<span><?php echo htmlspecialchars($catNames['general']); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="header">全局管理</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ========== MES 类目菜单 ========== -->
|
||||
<?php if ($isMESAdmin): ?>
|
||||
<li class="header"><?php echo htmlspecialchars($catNames['mes']); ?></li>
|
||||
<li class="<?php echo (!isset($activeMenu) || $activeMenu === 'index') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index"><i class="fa fa-dashboard"></i> <span>控制台</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'customer') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/customer"><i class="fa fa-building"></i> <span>客户管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'productModel') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productModel"><i class="fa fa-cube"></i> <span>产品型号</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'workstation') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/workstation"><i class="fa fa-th"></i> <span>工位管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'config') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/config"><i class="fa fa-cog"></i> <span>系统配置</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'productSearch') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/productSearch"><i class="fa fa-search"></i> <span>产品追溯</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'asdTestData') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdTestData"><i class="fa fa-flask"></i> <span>测试数据</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'asdDeviceDebug') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/asdDeviceDebug"><i class="fa fa-plug"></i> <span>设备调试</span></a>
|
||||
</li>
|
||||
<?php if ($isSuperAdmin): ?>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'import') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/import"><i class="fa fa-upload"></i> <span>批量导入</span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ========== 进销存类目菜单 ========== -->
|
||||
<?php if ($isInventoryAdmin): ?>
|
||||
<li class="header"><?php echo htmlspecialchars($catNames['inventory']); ?></li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'inventory_dashboard') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/index"><i class="fa fa-dashboard"></i> <span>进销存概览</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'purchase') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/purchase"><i class="fa fa-truck"></i> <span>采购管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'stock') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/stock"><i class="fa fa-archive"></i> <span>库存管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'sales') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/sales"><i class="fa fa-shopping-cart"></i> <span>销售管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'supplier') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Inventory/supplier"><i class="fa fa-address-book"></i> <span>供应商管理</span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ========== 财务管理类目菜单 ========== -->
|
||||
<?php if ($isFinanceAdmin): ?>
|
||||
<li class="header"><?php echo htmlspecialchars($catNames['finance']); ?></li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'finance_dashboard') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/index"><i class="fa fa-dashboard"></i> <span>财务概览</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'accounts') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/accounts"><i class="fa fa-book"></i> <span>账务管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'receivable') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/receivable"><i class="fa fa-arrow-down"></i> <span>应收账款</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'payable') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/payable"><i class="fa fa-arrow-up"></i> <span>应付账款</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'report') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Finance/report"><i class="fa fa-bar-chart"></i> <span>财务报表</span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ========== 综合管理类目菜单 ========== -->
|
||||
<?php if ($isGeneralAdmin): ?>
|
||||
<li class="header"><?php echo htmlspecialchars($catNames['general']); ?></li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'general_dashboard') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/General/index"><i class="fa fa-dashboard"></i> <span>综合概览</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'hr') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/General/hr"><i class="fa fa-id-card"></i> <span>人事管理</span></a>
|
||||
</li>
|
||||
<?php if ($isSuperAdmin): ?>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'employee') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/employee"><i class="fa fa-users"></i> <span>账号管理</span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'asset') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/General/asset"><i class="fa fa-laptop"></i> <span>资产管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'document') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/General/document"><i class="fa fa-file-text"></i> <span>文档管理</span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($isSuperAdmin): ?>
|
||||
<li class="header">系统工具</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'database') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/database"><i class="fa fa-database"></i> <span>数据库管理</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'databaseBackup') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseBackup"><i class="fa fa-save"></i> <span>备份与恢复</span></a>
|
||||
</li>
|
||||
<li class="<?php echo (isset($activeMenu) && $activeMenu === 'databaseUpgrade') ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/databaseUpgrade"><i class="fa fa-wrench"></i> <span>数据库升级</span></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<li class="header">账户</li>
|
||||
<li>
|
||||
<a href="<?php echo BASE_URL; ?>/Login/logout" class="confirm-link" data-confirm="确定要退出登录吗?">
|
||||
<i class="fa fa-power-off text-red"></i> <span>退出登录</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1><?php echo htmlspecialchars($title); ?><small> MES</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="<?php echo BASE_URL; ?>/Admin/index"><i class="fa fa-dashboard"></i> 控制台</a></li>
|
||||
<li class="active"><?php echo htmlspecialchars($title); ?></li>
|
||||
</ol>
|
||||
</section>
|
||||
<section class="content">
|
||||
<!-- 公司名称 - 所有页面居中加高显示 -->
|
||||
<?php
|
||||
if (!isset($sysConfig)) {
|
||||
$cfgModel = new app\models\SysConfig();
|
||||
$sysConfig = $cfgModel->getConfig();
|
||||
}
|
||||
?>
|
||||
<div style="text-align:center; margin-bottom:20px;">
|
||||
<h2 style="font-size:48px; font-weight:bold; color:#3c8dbc; margin:0; line-height:1.5;">
|
||||
<i class="fa fa-industry"></i> <?php echo htmlspecialchars($sysConfig['company_name'] ?? 'MES'); ?>
|
||||
</h2>
|
||||
<?php if (!empty($sysConfig['mes_name'])): ?>
|
||||
<p style="font-size:20px; color:#999; margin-top:5px;"><?php echo htmlspecialchars($sysConfig['mes_name']); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<footer class="main-footer">
|
||||
<div class="pull-right hidden-xs"><b>Version</b> 1.0.0</div>
|
||||
<strong>©2026深圳市云创芯电子有限公司版权所有</strong><br>
|
||||
<span class="beian">备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">粤ICP备16118477号-1</a></span>
|
||||
<span class="beian">公安网备:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=44030002015390" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;gap:4px;"><img src="<?php echo BASE_URL; ?>/static/images/gongan_badge.png" width="16" height="17" alt="公安网备" loading="lazy" style="vertical-align:middle;" onerror="this.onerror=null;this.outerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 24 24"><path d="M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z" fill="#1a3a8f" stroke="#d4af37" stroke-width="1"/><polygon points="12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5" fill="#ffffff"/></svg>'">粤公网安备44030002015390号</a></span>
|
||||
</footer>
|
||||
|
||||
<div class="control-sidebar-bg"></div>
|
||||
</div>
|
||||
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/bootstrap.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/plugins/slimScroll/jquery.slimscroll.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/plugins/fastclick/fastclick.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/app.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<title><?php echo htmlspecialchars($title); ?> - MES 前台工位</title>
|
||||
<!-- Bootstrap 3.3.6 -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/bootstrap.min.css">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<!-- Ionicons(已本地化,P3-14 消除外部 CDN 供应链风险) -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/ionicons.min.css">
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/AdminLTE.min.css">
|
||||
<!-- AdminLTE Skins -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/skins/_all-skins.min.css">
|
||||
<!-- iCheck -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/iCheck/flat/blue.css">
|
||||
<!-- Morris chart -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/morris/morris.css">
|
||||
<!-- jvectormap -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
|
||||
<!-- Date Picker -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/datepicker/datepicker3.css">
|
||||
<!-- Daterange picker -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/daterangepicker/daterangepicker-bs3.css">
|
||||
<!-- bootstrap wysihtml5 - text editor -->
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
|
||||
<style>
|
||||
/* 全局表格居中 */
|
||||
.table th,
|
||||
.table td {
|
||||
text-align: center !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
/* 工位记录表 - 分色 */
|
||||
.record-table th,
|
||||
.record-table td {
|
||||
text-align: center !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
.record-table thead th {
|
||||
background: #3c8dbc !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.record-table tbody td:nth-child(1) { background: #FCE4EC; } /* 浅粉 */
|
||||
.record-table tbody td:nth-child(2) { background: #E3F2FD; } /* 浅蓝 */
|
||||
.record-table tbody td:nth-child(3) { background: #E8F5E9; } /* 浅绿 */
|
||||
.record-table tbody td:nth-child(4) { background: #FFF3E0; } /* 浅橙 */
|
||||
.record-table tbody td:nth-child(5) { background: #F3E5F5; } /* 浅紫 */
|
||||
.record-table tbody td:nth-child(6) { background: #E0F7FA; } /* 浅青 */
|
||||
.record-table tbody td:nth-child(7) { background: #FFF9C4; } /* 浅黄 */
|
||||
.record-table tbody td:nth-child(8) { background: #E8EAF6; } /* 靛蓝 */
|
||||
.record-table tbody td:nth-child(9) { background: #EFEBE9; } /* 浅棕 */
|
||||
</style>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/jquery-3.7.1.min.js"></script>
|
||||
<?php // v3-P2 CSP:全局事件委托(替代内联 onclick 等),配合 nonce 实现无 unsafe-inline ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/csp_global.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/html5shiv.min.js"></script>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body class="hold-transition skin-blue sidebar-mini">
|
||||
<div class="wrapper">
|
||||
|
||||
<header class="main-header">
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="logo">
|
||||
<span class="logo-mini"><b>MES</b></span>
|
||||
<span class="logo-lg"><b>MES</b> 前台工位</span>
|
||||
</a>
|
||||
<nav class="navbar navbar-static-top">
|
||||
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
|
||||
<span class="sr-only">切换导航</span>
|
||||
</a>
|
||||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index"><i class="fa fa-arrow-left"></i> <span class="hidden-xs">返回后台</span></a>
|
||||
</li>
|
||||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-user"></i>
|
||||
<span class="hidden-xs"><?php echo htmlspecialchars($user['emp_name']); ?></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="user-header" style="background:#3c8dbc; color:#fff; padding:10px; text-align:center;">
|
||||
<p><?php echo htmlspecialchars($user['emp_name']); ?></p>
|
||||
</li>
|
||||
<li class="user-footer">
|
||||
<div class="pull-right">
|
||||
<a href="<?php echo BASE_URL; ?>/Login/logout" class="btn btn-default btn-flat"><i class="fa fa-power-off"></i> 退出登录</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<aside class="main-sidebar">
|
||||
<section class="sidebar">
|
||||
<ul class="sidebar-menu" data-widget="tree">
|
||||
<li class="header">工位导航</li>
|
||||
<?php
|
||||
$stationIcons = [
|
||||
'inbound' => 'fa-sign-in',
|
||||
'pcb_test' => 'fa-microchip',
|
||||
'battery' => 'fa-battery-full',
|
||||
'assembly' => 'fa-cogs',
|
||||
'finished_test' => 'fa-check-circle',
|
||||
'warehouse' => 'fa-warehouse',
|
||||
'delivery' => 'fa-truck'
|
||||
];
|
||||
// 工位显示名称映射
|
||||
$stationNameMap = [
|
||||
'inbound' => '半成品入库',
|
||||
'warehouse' => '成品入库',
|
||||
];
|
||||
foreach ($stations as $station):
|
||||
$icon = isset($stationIcons[$station['station_type']]) ? $stationIcons[$station['station_type']] : 'fa-circle-o';
|
||||
$displayName = isset($stationNameMap[$station['station_type']]) ? $stationNameMap[$station['station_type']] : $station['station_name'];
|
||||
?>
|
||||
<li class="<?php echo (isset($activeStation) && $activeStation === $station['station_type']) ? 'active' : ''; ?>">
|
||||
<a href="<?php echo BASE_URL; ?>/Front/<?php echo $station['station_type']; ?>">
|
||||
<i class="fa <?php echo $icon; ?>"></i>
|
||||
<span><?php echo htmlspecialchars($displayName); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<section class="content-header">
|
||||
<h1><?php echo htmlspecialchars($title); ?><small> 前台工位</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="<?php echo BASE_URL; ?>/Front/index"><i class="fa fa-th"></i> 工位选择</a></li>
|
||||
<li class="active"><?php echo htmlspecialchars($title); ?></li>
|
||||
</ol>
|
||||
</section>
|
||||
<section class="content">
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
// 防御性检查:防止 footer 被重复 include
|
||||
if (!empty($GLOBALS['_station_footer_rendered'])) {
|
||||
error_log('[station_footer] WARNING: Already rendered, skipping duplicate include.');
|
||||
return;
|
||||
}
|
||||
$GLOBALS['_station_footer_rendered'] = true;
|
||||
?><div class="footer">
|
||||
©2026深圳市云创芯电子有限公司版权所有
|
||||
<br><span class="beian">备案号:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">粤ICP备16118477号-1</a></span>
|
||||
<br><span class="beian">公安网备:<a href="https://beian.mps.gov.cn/#/query/webSearch?code=44030002015390" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;gap:4px;"><img src="<?php echo BASE_URL; ?>/static/images/gongan_badge.png" width="16" height="17" alt="公安网备" loading="lazy" style="vertical-align:middle;" onerror="this.onerror=null;this.outerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 24 24"><path d="M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z" fill="#1a3a8f" stroke="#d4af37" stroke-width="1"/><polygon points="12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5" fill="#ffffff"/></svg>'">粤公网安备44030002015390号</a></span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ========== 实时时钟 ==========
|
||||
function updateClock() {
|
||||
var now = new Date();
|
||||
var str = now.getFullYear() + '-' +
|
||||
String(now.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(now.getDate()).padStart(2, '0') + ' ' +
|
||||
String(now.getHours()).padStart(2, '0') + ':' +
|
||||
String(now.getMinutes()).padStart(2, '0') + ':' +
|
||||
String(now.getSeconds()).padStart(2, '0');
|
||||
var el = document.getElementById('liveClock');
|
||||
if (el) el.textContent = str;
|
||||
}
|
||||
setInterval(updateClock, 1000);
|
||||
updateClock();
|
||||
|
||||
// ========== 工位网格列数调节(Front/index) ==========
|
||||
(function() {
|
||||
var $grid = $('#stationGrid');
|
||||
if (!$grid.length) return;
|
||||
var COL_KEY = 'station_grid_cols';
|
||||
|
||||
function applyColumns(cols) {
|
||||
$grid.attr('data-columns', cols);
|
||||
$('.column-adjuster .col-btn').removeClass('active');
|
||||
$('.column-adjuster .col-btn[data-cols="' + cols + '"]').addClass('active');
|
||||
try { localStorage.setItem(COL_KEY, cols); } catch(e) {}
|
||||
}
|
||||
|
||||
var savedCols = localStorage.getItem(COL_KEY) || 'auto';
|
||||
applyColumns(savedCols);
|
||||
|
||||
$('.column-adjuster .col-btn').click(function() {
|
||||
applyColumns($(this).data('cols'));
|
||||
});
|
||||
})();
|
||||
|
||||
// ========== 表格列选择器 ==========
|
||||
(function() {
|
||||
var STORAGE_PREFIX = 'table_cols_';
|
||||
|
||||
function initColSelector(pageKey, allCols) {
|
||||
var $dropdown = $('#colDropdown_' + pageKey);
|
||||
var $btn = $('#colSelectBtn_' + pageKey);
|
||||
if (!$dropdown.length || !$btn.length) return;
|
||||
|
||||
var storageKey = STORAGE_PREFIX + pageKey;
|
||||
var defaultVisible = {};
|
||||
allCols.forEach(function(c) { defaultVisible[c.key] = true; });
|
||||
|
||||
// 读取保存的偏好
|
||||
var saved = null;
|
||||
try { saved = JSON.parse(localStorage.getItem(storageKey)); } catch(e) {}
|
||||
|
||||
function getVisible() {
|
||||
if (saved && typeof saved === 'object') {
|
||||
var merged = {};
|
||||
allCols.forEach(function(c) {
|
||||
merged[c.key] = (saved[c.key] !== undefined) ? saved[c.key] : true;
|
||||
});
|
||||
return merged;
|
||||
}
|
||||
return $.extend({}, defaultVisible);
|
||||
}
|
||||
|
||||
function saveVisible(visible) {
|
||||
try { localStorage.setItem(storageKey, JSON.stringify(visible)); } catch(e) {}
|
||||
}
|
||||
|
||||
function applyVisible(visible) {
|
||||
// 更新表头
|
||||
$('table.table thead th').each(function() {
|
||||
var col = $(this).data('col');
|
||||
if (col && visible[col] === false) {
|
||||
$(this).addClass('col-hidden');
|
||||
} else {
|
||||
$(this).removeClass('col-hidden');
|
||||
}
|
||||
});
|
||||
// 更新表体
|
||||
$('table.table tbody td').each(function() {
|
||||
var col = $(this).data('col');
|
||||
if (col && visible[col] === false) {
|
||||
$(this).addClass('col-hidden');
|
||||
} else {
|
||||
$(this).removeClass('col-hidden');
|
||||
}
|
||||
});
|
||||
// 更新复选框状态
|
||||
$dropdown.find('.col-check-item').each(function() {
|
||||
var col = $(this).data('col');
|
||||
$(this).prop('checked', visible[col] !== false);
|
||||
});
|
||||
$dropdown.find('.col-check-all').prop('checked',
|
||||
allCols.every(function(c) { return visible[c.key] !== false; })
|
||||
);
|
||||
}
|
||||
|
||||
function refreshUI() {
|
||||
var visible = getVisible();
|
||||
applyVisible(visible);
|
||||
}
|
||||
|
||||
// 初始化
|
||||
refreshUI();
|
||||
|
||||
// 全选/取消全选
|
||||
$dropdown.find('.col-check-all').on('change', function() {
|
||||
var checked = $(this).prop('checked');
|
||||
var visible = getVisible();
|
||||
allCols.forEach(function(c) { visible[c.key] = checked; });
|
||||
saveVisible(visible);
|
||||
applyVisible(visible);
|
||||
});
|
||||
|
||||
// 单项切换
|
||||
$dropdown.find('.col-check-item').on('change', function() {
|
||||
var col = $(this).data('col');
|
||||
var checked = $(this).prop('checked');
|
||||
var visible = getVisible();
|
||||
visible[col] = checked;
|
||||
saveVisible(visible);
|
||||
applyVisible(visible);
|
||||
});
|
||||
|
||||
// 恢复默认
|
||||
$dropdown.find('.col-reset-btn').on('click', function() {
|
||||
var visible = $.extend({}, defaultVisible);
|
||||
saveVisible(visible);
|
||||
applyVisible(visible);
|
||||
});
|
||||
|
||||
// 按钮点击切换面板显示
|
||||
$btn.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
$dropdown.toggle();
|
||||
});
|
||||
|
||||
// 点击面板外部关闭
|
||||
$(document).on('click', function(e) {
|
||||
if (!$btn.is(e.target) && $btn.has(e.target).length === 0 &&
|
||||
!$dropdown.is(e.target) && $dropdown.has(e.target).length === 0) {
|
||||
$dropdown.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 处理队列中的列选择器初始化(延迟到 DOM 完全就绪)
|
||||
$(function() {
|
||||
if (window._colSelectorQueue && window._colSelectorQueue.length) {
|
||||
window._colSelectorQueue.forEach(function(item) {
|
||||
initColSelector(item.pageKey, item.cols);
|
||||
});
|
||||
window._colSelectorQueue = [];
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,764 @@
|
||||
<?php
|
||||
// 防御性检查:防止 header 被重复 include
|
||||
if (!empty($GLOBALS['_station_header_rendered'])) {
|
||||
error_log('[station_header] WARNING: Already rendered, skipping duplicate include.');
|
||||
return;
|
||||
}
|
||||
$GLOBALS['_station_header_rendered'] = true;
|
||||
?><!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title><?php echo htmlspecialchars($title); ?> - <?php echo htmlspecialchars($sysConfig['company_name'] ?? 'MES'); ?> 工位看板</title>
|
||||
<link rel="stylesheet" href="<?php echo BASE_URL; ?>/static/css/font-awesome.min.css">
|
||||
<style>
|
||||
:root {
|
||||
--bg: #0f1923;
|
||||
--card-bg: #1a2736;
|
||||
--text: #c8d6e5;
|
||||
--text-light: #8395a7;
|
||||
--primary: #0abde3;
|
||||
--success: #10ac84;
|
||||
--warning: #feca57;
|
||||
--danger: #ee5253;
|
||||
--border: #2d3a4a;
|
||||
}
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body {
|
||||
height: 100%;
|
||||
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
overflow-x: hidden;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ========== 顶部导航栏 ========== */
|
||||
.topbar {
|
||||
background: var(--card-bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 10px 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
.topbar .topbar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.topbar .logo {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.topbar .logo i { margin-right: 4px; }
|
||||
.topbar .logo-sep {
|
||||
color: var(--text-light);
|
||||
font-size: 13px;
|
||||
display: inline;
|
||||
}
|
||||
.topbar .user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.topbar .clock {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: var(--text);
|
||||
font-variant-numeric: tabular-nums;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.topbar .user-name {
|
||||
color: var(--primary);
|
||||
white-space: nowrap;
|
||||
font-size: 13px;
|
||||
}
|
||||
.topbar .btn-top {
|
||||
color: var(--text-light);
|
||||
text-decoration: none;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
transition: all 0.3s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.topbar .btn-top:hover {
|
||||
color: var(--primary);
|
||||
border-color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
.topbar .btn-top i { margin-right: 3px; }
|
||||
.topbar .btn-logout {
|
||||
color: var(--danger);
|
||||
border-color: rgba(238,82,83,0.3);
|
||||
}
|
||||
|
||||
/* ========== 返回按钮 ========== */
|
||||
.back-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--text-light);
|
||||
text-decoration: none;
|
||||
font-size: 13px;
|
||||
margin-bottom: 16px;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-link:hover { color: var(--primary); text-decoration: none; }
|
||||
|
||||
/* ========== 内容区 ========== */
|
||||
.content {
|
||||
padding: 16px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
flex: 1 0 auto;
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ========== 页面标题区 ========== */
|
||||
.page-title-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.page-title-bar h1 {
|
||||
font-size: 18px;
|
||||
color: var(--text);
|
||||
margin: 0;
|
||||
}
|
||||
.page-title-bar h1 i { color: var(--primary); margin-right: 6px; }
|
||||
|
||||
/* ========== 卡片容器 ========== */
|
||||
.card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card-header {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.card-header h3 {
|
||||
font-size: 15px;
|
||||
color: var(--text);
|
||||
margin: 0;
|
||||
}
|
||||
.card-header h3 i { color: var(--primary); margin-right: 6px; }
|
||||
.card-header .badge {
|
||||
display: inline-block;
|
||||
background: rgba(10, 189, 227, 0.15);
|
||||
color: var(--primary);
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.card-body {
|
||||
padding: 16px;
|
||||
}
|
||||
.card-body.no-padding { padding: 0; }
|
||||
|
||||
/* ========== 表单样式 ========== */
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
.form-group {
|
||||
flex: 1;
|
||||
min-width: 180px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.form-group label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: var(--text-light);
|
||||
margin-bottom: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.form-group label .required { color: var(--danger); margin-left: 2px; }
|
||||
.form-group label .hint { font-weight: normal; font-size: 10px; color: var(--text-light); }
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text);
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
outline: none;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(10, 189, 227, 0.05);
|
||||
box-shadow: 0 0 0 3px rgba(10, 189, 227, 0.1);
|
||||
}
|
||||
.form-control::placeholder { color: rgba(255,255,255,0.2); }
|
||||
select.form-control {
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%238395a7' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 10px center;
|
||||
padding-right: 30px;
|
||||
}
|
||||
select.form-control option { background: var(--card-bg); color: var(--text); }
|
||||
.form-control:disabled { opacity: 0.6; cursor: not-allowed; }
|
||||
.input-error, .input-error:focus {
|
||||
border-color: #d9534f !important;
|
||||
box-shadow: 0 0 0 3px rgba(217, 83, 79, 0.25) !important;
|
||||
animation: shake 0.4s ease-in-out;
|
||||
}
|
||||
.input-warning {
|
||||
border-color: #e67e22 !important;
|
||||
box-shadow: 0 0 0 2px rgba(230, 126, 34, 0.2) !important;
|
||||
}
|
||||
.input-valid {
|
||||
border-color: #27ae60 !important;
|
||||
box-shadow: 0 0 0 2px rgba(39, 174, 96, 0.2) !important;
|
||||
}
|
||||
@keyframes shake {
|
||||
0%, 100% { transform: translateX(0); }
|
||||
20% { transform: translateX(-6px); }
|
||||
40% { transform: translateX(6px); }
|
||||
60% { transform: translateX(-4px); }
|
||||
80% { transform: translateX(4px); }
|
||||
}
|
||||
.field-error-tip {
|
||||
animation: fadeInDown 0.25s ease-out;
|
||||
}
|
||||
@keyframes fadeInDown {
|
||||
from { opacity: 0; transform: translateY(-6px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
.form-actions {
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ========== 按钮样式 ========== */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.btn-primary { background: var(--primary); color: #fff; }
|
||||
.btn-primary:hover { background: #0cb0d6; transform: translateY(-1px); }
|
||||
.btn-success { background: var(--success); color: #fff; }
|
||||
.btn-success:hover { background: #0d9e78; transform: translateY(-1px); }
|
||||
.btn-warning { background: var(--warning); color: #1a2736; }
|
||||
.btn-warning:hover { background: #f5c24e; transform: translateY(-1px); }
|
||||
.btn-danger { background: var(--danger); color: #fff; }
|
||||
.btn-danger:hover { background: #e14849; transform: translateY(-1px); }
|
||||
.btn-info {
|
||||
background: rgba(10, 189, 227, 0.15);
|
||||
color: var(--primary);
|
||||
border: 1px solid rgba(10, 189, 227, 0.3);
|
||||
}
|
||||
.btn-info:hover { background: rgba(10, 189, 227, 0.25); }
|
||||
.btn-lg { padding: 10px 22px; font-size: 15px; }
|
||||
.btn-sm { padding: 5px 12px; font-size: 12px; }
|
||||
.btn-block { display: flex; width: 100%; justify-content: center; }
|
||||
|
||||
/* ========== 表格样式 ========== */
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 12px;
|
||||
min-width: 600px;
|
||||
}
|
||||
.table thead th {
|
||||
background: rgba(10, 189, 227, 0.1);
|
||||
color: var(--primary);
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
border-bottom: 2px solid var(--border);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.table tbody td {
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
font-size: 12px;
|
||||
}
|
||||
.table tbody tr:hover td { background: rgba(255,255,255,0.02); }
|
||||
.table code {
|
||||
background: rgba(10, 189, 227, 0.1);
|
||||
color: var(--primary);
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.table .label {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.table .label-success { background: rgba(16, 172, 132, 0.2); color: var(--success); }
|
||||
.table .label-danger { background: rgba(238, 82, 83, 0.2); color: var(--danger); }
|
||||
.table .label-warning { background: rgba(254, 202, 87, 0.2); color: var(--warning); }
|
||||
.table .label-info { background: rgba(10, 189, 227, 0.2); color: var(--primary); }
|
||||
.text-muted { color: var(--text-light); }
|
||||
|
||||
/* ========== 工位选择网格 (Front/index) ========== */
|
||||
.station-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* 默认自适应 */
|
||||
}
|
||||
.station-grid[data-columns="1"] { grid-template-columns: 1fr; }
|
||||
.station-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
|
||||
.station-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
|
||||
.station-grid[data-columns="auto"] { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
|
||||
.station-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 20px 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
text-decoration: none;
|
||||
color: var(--text);
|
||||
display: block;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.station-card:hover {
|
||||
border-color: var(--primary);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 20px rgba(10, 189, 227, 0.15);
|
||||
text-decoration: none;
|
||||
color: var(--text);
|
||||
}
|
||||
.station-card:active { transform: translateY(0); }
|
||||
.station-card .station-icon {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 10px;
|
||||
font-size: 24px;
|
||||
}
|
||||
.station-card .station-name {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.station-card .station-code {
|
||||
font-size: 10px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.station-card .station-status {
|
||||
margin-top: 8px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/* ========== 今日计数徽章 ========== */
|
||||
.today-count-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: linear-gradient(135deg, rgba(10,189,227,0.2), rgba(16,172,132,0.2));
|
||||
border: 1px solid rgba(10,189,227,0.3);
|
||||
padding: 5px 14px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.today-count-badge .count-num {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* ========== 提示信息 ========== */
|
||||
.alert {
|
||||
padding: 10px 14px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 14px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.alert-info {
|
||||
background: rgba(10, 189, 227, 0.1);
|
||||
border: 1px solid rgba(10, 189, 227, 0.25);
|
||||
color: var(--primary);
|
||||
}
|
||||
.alert-success {
|
||||
background: rgba(16, 172, 132, 0.1);
|
||||
border: 1px solid rgba(16, 172, 132, 0.25);
|
||||
color: var(--success);
|
||||
}
|
||||
.alert-danger {
|
||||
background: rgba(238, 82, 83, 0.1);
|
||||
border: 1px solid rgba(238, 82, 83, 0.25);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* ========== 筛选激活状态 ========== */
|
||||
.filter-active .card-header {
|
||||
background: rgba(10, 189, 227, 0.05);
|
||||
border-bottom: 2px solid var(--primary);
|
||||
}
|
||||
|
||||
/* ========== 空状态 ========== */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 32px 16px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.empty-state i { font-size: 40px; margin-bottom: 10px; opacity: 0.3; }
|
||||
.empty-state p { font-size: 13px; }
|
||||
|
||||
/* ========== 自适应表单网格 ========== */
|
||||
.station-fields-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
grid-template-columns: repeat(3, 1fr); /* 默认3列 */
|
||||
}
|
||||
.station-fields-grid[data-columns="1"] { grid-template-columns: 1fr; }
|
||||
.station-fields-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
|
||||
.station-fields-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
|
||||
.station-fields-grid[data-columns="4"] { grid-template-columns: repeat(4, 1fr); }
|
||||
.station-fields-grid[data-columns="auto"] {
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
}
|
||||
.station-field-item {
|
||||
min-width: 0; /* 防止 grid 溢出 */
|
||||
}
|
||||
.station-field-item label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: var(--text-light);
|
||||
margin-bottom: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.station-field-item label .required { color: var(--danger); margin-left: 2px; }
|
||||
.station-field-item label .hint { font-weight: normal; font-size: 10px; color: var(--text-light); }
|
||||
.station-field-item .form-control {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 扫描字段网格 */
|
||||
.station-scan-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
}
|
||||
.station-scan-item {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* ========== 列数调节器 ========== */
|
||||
.column-adjuster {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.column-adjuster .col-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: var(--text-light);
|
||||
cursor: pointer;
|
||||
font-size: 11px;
|
||||
transition: all 0.2s;
|
||||
white-space: nowrap;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.column-adjuster .col-btn:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
.column-adjuster .col-btn.active {
|
||||
background: rgba(10, 189, 227, 0.15);
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
.column-adjuster .col-btn i { font-size: 11px; }
|
||||
|
||||
/* ========== 表格列选择器下拉面板 ========== */
|
||||
.table-column-selector {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
.table-column-selector .col-btn-dropdown {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 4px 10px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: var(--text-light);
|
||||
cursor: pointer;
|
||||
font-size: 11px;
|
||||
transition: all 0.2s;
|
||||
white-space: nowrap;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.table-column-selector .col-btn-dropdown:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
.col-dropdown-panel {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 4px;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
min-width: 180px;
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
z-index: 200;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
|
||||
}
|
||||
.col-dropdown-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-size: 11px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.col-dropdown-header label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 11px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.col-reset-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-light);
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.col-reset-btn:hover {
|
||||
color: var(--warning);
|
||||
background: rgba(254,202,87,0.1);
|
||||
}
|
||||
.col-dropdown-list {
|
||||
padding: 4px 0;
|
||||
}
|
||||
.col-dropdown-list label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.col-dropdown-list label:hover {
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
.col-dropdown-list input[type="checkbox"] {
|
||||
accent-color: var(--primary);
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.col-dropdown-header input[type="checkbox"] {
|
||||
accent-color: var(--primary);
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* 被隐藏的表格列 */
|
||||
.table th.col-hidden,
|
||||
.table td.col-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ========== 底部 ========== */
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 12px 16px;
|
||||
color: var(--text-light);
|
||||
font-size: 11px;
|
||||
border-top: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* ========== 动画 ========== */
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
.refreshing { animation: pulse 0.6s ease-in-out; }
|
||||
|
||||
/* ========== 移动端响应式 ========== */
|
||||
@media (max-width: 768px) {
|
||||
.topbar {
|
||||
padding: 8px 12px;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.topbar .topbar-left { width: 100%; justify-content: space-between; }
|
||||
.topbar .logo { font-size: 14px; }
|
||||
.topbar .logo-sep { display: none; }
|
||||
.topbar .user-info {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.topbar .clock { font-size: 13px; }
|
||||
.topbar .btn-top { font-size: 11px; padding: 3px 8px; }
|
||||
|
||||
.content { padding: 10px; }
|
||||
|
||||
.page-title-bar { flex-direction: column; align-items: flex-start; }
|
||||
.page-title-bar h1 { font-size: 16px; }
|
||||
|
||||
.card-header { padding: 10px 12px; }
|
||||
.card-header h3 { font-size: 14px; }
|
||||
.card-body { padding: 12px; }
|
||||
|
||||
.form-group { min-width: 100%; flex: 1 1 100%; }
|
||||
.form-row { gap: 8px; }
|
||||
.form-actions { flex-direction: column; }
|
||||
.form-actions .btn { width: 100%; justify-content: center; }
|
||||
|
||||
.station-fields-grid { gap: 8px; }
|
||||
.station-fields-grid[data-columns="3"],
|
||||
.station-fields-grid[data-columns="4"] { grid-template-columns: repeat(2, 1fr); }
|
||||
.station-fields-grid[data-columns="auto"] { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
|
||||
.station-scan-grid { grid-template-columns: 1fr; }
|
||||
|
||||
.station-grid {
|
||||
gap: 8px;
|
||||
}
|
||||
.station-grid[data-columns="3"],
|
||||
.station-grid[data-columns="auto"] { grid-template-columns: repeat(2, 1fr); }
|
||||
.station-card { padding: 14px 10px; }
|
||||
.station-card .station-icon { width: 42px; height: 42px; font-size: 20px; }
|
||||
.station-card .station-name { font-size: 13px; }
|
||||
|
||||
.today-count-badge { font-size: 11px; }
|
||||
.today-count-badge .count-num { font-size: 16px; }
|
||||
|
||||
.table { font-size: 11px; }
|
||||
.table thead th { padding: 6px 8px; font-size: 11px; }
|
||||
.table tbody td { padding: 6px 8px; font-size: 11px; }
|
||||
|
||||
.btn { font-size: 13px; padding: 7px 14px; }
|
||||
.btn-lg { font-size: 14px; padding: 9px 18px; }
|
||||
|
||||
.alert { font-size: 12px; padding: 8px 12px; }
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
.station-grid { gap: 6px; }
|
||||
.station-grid[data-columns="2"],
|
||||
.station-grid[data-columns="3"],
|
||||
.station-grid[data-columns="auto"] { grid-template-columns: repeat(2, 1fr); }
|
||||
.station-card { padding: 12px 8px; }
|
||||
.station-card .station-icon { width: 36px; height: 36px; font-size: 18px; }
|
||||
.station-card .station-name { font-size: 12px; }
|
||||
|
||||
.topbar .user-info { flex-wrap: wrap; gap: 4px; }
|
||||
.topbar .btn-top { font-size: 10px; padding: 2px 6px; }
|
||||
.topbar .clock { font-size: 12px; }
|
||||
|
||||
.station-fields-grid[data-columns="2"],
|
||||
.station-fields-grid[data-columns="3"],
|
||||
.station-fields-grid[data-columns="4"] { grid-template-columns: 1fr; }
|
||||
.station-fields-grid[data-columns="auto"] { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
|
||||
}
|
||||
</style>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/jquery-3.7.1.min.js"></script>
|
||||
<?php // v3-P2 CSP:全局事件委托(替代内联 onclick 等),配合 nonce 实现无 unsafe-inline ?>
|
||||
<script src="<?php echo BASE_URL; ?>/static/js/csp_global.js" nonce="<?php echo csp_nonce(); ?>"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="topbar">
|
||||
<div class="topbar-left">
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="logo">
|
||||
<i class="fa fa-industry"></i>
|
||||
<?php echo htmlspecialchars($sysConfig['company_name'] ?? 'MES'); ?>
|
||||
</a>
|
||||
<span class="logo-sep">| 工位看板</span>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<span class="clock" id="liveClock"><?php echo date('Y-m-d H:i:s'); ?></span>
|
||||
<span class="user-name"><i class="fa fa-user"></i> <?php echo htmlspecialchars($user['emp_name']); ?></span>
|
||||
<a href="<?php echo BASE_URL; ?>/Dashboard/index" class="btn-top"><i class="fa fa-tachometer"></i> 看板</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Admin/index" class="btn-top"><i class="fa fa-cog"></i> 后台</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Front/index" class="btn-top"><i class="fa fa-th"></i> 工位</a>
|
||||
<a href="<?php echo BASE_URL; ?>/Login/logout" class="btn-top btn-logout confirm-link" data-confirm="确定退出?"><i class="fa fa-sign-out"></i> 退出</a>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user