Welcome to HACMS

HACMS网页版是基于PHP+(MySQL/SQLite)开发的开源程序,采用CodeIgniter框架、Adminlte后台模板,以会员核心系统为中心,以自身需求为出发点,采用模块分离的方式快速建立站群,具有速度快、效率高、功能强大、操作体验佳等特点,支持文章页面生成HTML静态页面、URL Rewrite、支持多数据库、多表操作与管理,包括网页版进销存、文章、MD文档等等。

HACMS桌面版是以C#、Python为开发语言,选择PostgreSQL、MySQL、SQLite为数据库,还是以自身需求为出发点,现已形成以网页源码采集器、进销存系统、键盘鼠标自动化工具、软件多开助手、单表自定义设置管理、EPUB电子书阅读器等小工具。

SQLite表名

CREATE TABLE demo_test (
    tid      INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT (0),
    title    TEXT,
    notes    TEXT,
    dateline INTEGER
);

PHP操作SQLite

<?php
/**
 * demo_test 数据表管理程序 (SQLite 版本)
 * 功能:列表分页、新增、编辑、删除、查看详情(双击行)
 * 数据库表:demo_test (tid, title, notes, dateline)
 * 修复:新增时日期默认值显示异常的问题
 */

// ======================= 配置区域 =======================
define('TABLE_NAME', 'demo_test');
define('PAGE_SIZE', 10);
define('DB_FILE', 'data.db');
// =======================================================

try {
    $pdo = new PDO("sqlite:" . DB_FILE);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    die("数据库连接失败: " . $e->getMessage());
}

// 创建表
$pdo->exec("
CREATE TABLE IF NOT EXISTS " . TABLE_NAME . " (
    tid INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    notes TEXT NOT NULL,
    dateline INTEGER NOT NULL DEFAULT 0
)");

// 处理 AJAX 请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_X_REQUESTED_WITH']) 
    && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {

    $action = $_POST['action'] ?? '';
    $response = ['success' => false, 'message' => ''];

    switch ($action) {
        case 'add':
            $title = trim($_POST['title'] ?? '');
            $notes = trim($_POST['notes'] ?? '');
            $date = trim($_POST['date'] ?? '');
            if (empty($title) || empty($notes) || empty($date)) {
                $response['message'] = '所有字段都不能为空';
                break;
            }
            $timestamp = strtotime($date);
            if ($timestamp === false || $timestamp < 0) {
                $response['message'] = '日期格式无效,请使用 YYYY-MM-DD';
                break;
            }
            $stmt = $pdo->prepare("INSERT INTO " . TABLE_NAME . " (title, notes, dateline) VALUES (?, ?, ?)");
            if ($stmt->execute([$title, $notes, $timestamp])) {
                $response['success'] = true;
                $response['message'] = '添加成功';
            } else {
                $response['message'] = '添加失败';
            }
            break;

        case 'edit':
            $tid = intval($_POST['tid'] ?? 0);
            $title = trim($_POST['title'] ?? '');
            $notes = trim($_POST['notes'] ?? '');
            $date = trim($_POST['date'] ?? '');
            if ($tid <= 0 || empty($title) || empty($notes) || empty($date)) {
                $response['message'] = '参数错误或字段为空';
                break;
            }
            $timestamp = strtotime($date);
            if ($timestamp === false || $timestamp < 0) {
                $response['message'] = '日期格式无效';
                break;
            }
            $stmt = $pdo->prepare("UPDATE " . TABLE_NAME . " SET title=?, notes=?, dateline=? WHERE tid=?");
            if ($stmt->execute([$title, $notes, $timestamp, $tid])) {
                $response['success'] = true;
                $response['message'] = '更新成功';
            } else {
                $response['message'] = '更新失败';
            }
            break;

        case 'delete':
            $tid = intval($_POST['tid'] ?? 0);
            if ($tid <= 0) {
                $response['message'] = '无效的序号';
                break;
            }
            $stmt = $pdo->prepare("DELETE FROM " . TABLE_NAME . " WHERE tid=?");
            if ($stmt->execute([$tid])) {
                $response['success'] = true;
                $response['message'] = '删除成功';
            } else {
                $response['message'] = '删除失败';
            }
            break;

        case 'get_record':
            $tid = intval($_POST['tid'] ?? 0);
            if ($tid <= 0) {
                $response['message'] = '无效的序号';
                break;
            }
            $stmt = $pdo->prepare("SELECT tid, title, notes, dateline FROM " . TABLE_NAME . " WHERE tid=?");
            $stmt->execute([$tid]);
            $row = $stmt->fetch();
            if ($row) {
                $row['dateline_formatted'] = $row['dateline'] ? date('Y-m-d', $row['dateline']) : '';
                $response['success'] = true;
                $response['data'] = $row;
            } else {
                $response['message'] = '记录不存在';
            }
            break;

        default:
            $response['message'] = '未知操作';
    }

    header('Content-Type: application/json');
    echo json_encode($response);
    exit;
}

// 非 AJAX:显示页面
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$offset = ($page - 1) * PAGE_SIZE;

$total_stmt = $pdo->query("SELECT COUNT(*) as total FROM " . TABLE_NAME);
$total_records = $total_stmt->fetch()['total'];
$total_pages = ceil($total_records / PAGE_SIZE);

$stmt = $pdo->prepare("SELECT tid, title, notes, dateline FROM " . TABLE_NAME . " ORDER BY tid DESC LIMIT ? OFFSET ?");
$stmt->execute([PAGE_SIZE, $offset]);
$records = $stmt->fetchAll();
foreach ($records as &$row) {
    $row['dateline_show'] = $row['dateline'] ? date('Y-m-d', $row['dateline']) : '';
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo_Test 数据管理 (SQLite)</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        .clickable-row { cursor: pointer; }
        .clickable-row:hover { background-color: #f8f9fa; }
        .table-actions .btn { margin-right: 5px; }
        .pagination { justify-content: center; }
    </style>
</head>
<body>
<div class="container mt-4">
    <h2 class="mb-3"><i class="fas fa-database"></i> Demo_Test 数据管理 (SQLite)</h2>
    <div class="mb-3">
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#editModal" onclick="openAddModal()">
            <i class="fas fa-plus"></i> 新增
        </button>
    </div>
    <div class="table-responsive">
        <table class="table table-bordered table-hover">
            <thead class="table-dark">
                <tr><th>序号</th><th>标题</th><th>内容</th><th>日期</th><th>操作</th></tr>
            </thead>
            <tbody>
                <?php if (empty($records)): ?>
                    <tr><td colspan="5" class="text-center">暂无数据</td></tr>
                <?php else: ?>
                    <?php foreach ($records as $r): ?>
                    <tr class="clickable-row" data-tid="<?= $r['tid'] ?>">
                        <td><?= htmlspecialchars($r['tid']) ?></td>
                        <td><?= htmlspecialchars($r['title']) ?></td>
                        <td><?= htmlspecialchars(mb_substr($r['notes'], 0, 50)) . (mb_strlen($r['notes']) > 50 ? '...' : '') ?></td>
                        <td><?= htmlspecialchars($r['dateline_show']) ?></td>
                        <td class="table-actions">
                            <button class="btn btn-sm btn-info" onclick="viewRecord(<?= $r['tid'] ?>)"><i class="fas fa-eye"></i> 查看</button>
                            <button class="btn btn-sm btn-warning" onclick="editRecord(<?= $r['tid'] ?>)"><i class="fas fa-edit"></i> 编辑</button>
                            <button class="btn btn-sm btn-danger" onclick="deleteRecord(<?= $r['tid'] ?>)"><i class="fas fa-trash"></i> 删除</button>
                        </td>
                    </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
    </div>
    <?php if ($total_pages > 1): ?>
    <nav>
        <ul class="pagination">
            <li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>"><a class="page-link" href="?page=1">首页</a></li>
            <li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>"><a class="page-link" href="?page=<?= $page-1 ?>">上一页</a></li>
            <?php for ($i = max(1, $page-2); $i <= min($total_pages, $page+2); $i++): ?>
                <li class="page-item <?= $i == $page ? 'active' : '' ?>"><a class="page-link" href="?page=<?= $i ?>"><?= $i ?></a></li>
            <?php endfor; ?>
            <li class="page-item <?= $page >= $total_pages ? 'disabled' : '' ?>"><a class="page-link" href="?page=<?= $page+1 ?>">下一页</a></li>
            <li class="page-item <?= $page >= $total_pages ? 'disabled' : '' ?>"><a class="page-link" href="?page=<?= $total_pages ?>">末页</a></li>
        </ul>
    </nav>
    <?php endif; ?>
</div>

<!-- 新增/编辑模态框 -->
<div class="modal fade" id="editModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="editModalLabel">新增记录</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <form id="dataForm">
                    <input type="hidden" id="edit_tid" name="tid" value="0">
                    <div class="mb-3">
                        <label class="form-label">标题 <span class="text-danger">*</span></label>
                        <input type="text" class="form-control" id="title" required>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">内容 <span class="text-danger">*</span></label>
                        <textarea class="form-control" id="notes" rows="5" required></textarea>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">日期 <span class="text-danger">*</span></label>
                        <input type="date" class="form-control" id="date" required>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" id="saveBtn">保存</button>
            </div>
        </div>
    </div>
</div>

<!-- 查看详情模态框 -->
<div class="modal fade" id="viewModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header"><h5 class="modal-title">查看记录</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
            <div class="modal-body">
                <p><strong>序号:</strong> <span id="view_tid"></span></p>
                <p><strong>标题:</strong> <span id="view_title"></span></p>
                <p><strong>日期:</strong> <span id="view_date"></span></p>
                <p><strong>内容:</strong></p>
                <div id="view_notes" style="white-space: pre-wrap; border:1px solid #ddd; padding:8px; border-radius:5px;"></div>
            </div>
            <div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button></div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script>
let editModal = new bootstrap.Modal(document.getElementById('editModal'));
let viewModal = new bootstrap.Modal(document.getElementById('viewModal'));

function ajaxRequest(action, data, successCallback) {
    data.action = action;
    $.post(window.location.href, data, function(response) {
        if (response.success) {
            if (successCallback) successCallback(response);
            else { alert(response.message); location.reload(); }
        } else alert("操作失败:" + response.message);
    }, 'json').fail(() => alert("网络错误"));
}

function openAddModal() {
    document.getElementById('editModalLabel').innerText = '新增记录';
    document.getElementById('edit_tid').value = '0';
    document.getElementById('title').value = '';
    document.getElementById('notes').value = '';
    // 关键修复:确保日期默认值为当前日期的 YYYY-MM-DD 格式
    const today = new Date();
    const year = today.getFullYear();
    const month = String(today.getMonth() + 1).padStart(2, '0');
    const day = String(today.getDate()).padStart(2, '0');
    const defaultDate = `${year}-${month}-${day}`;
    document.getElementById('date').value = defaultDate;
    editModal.show();
}

function editRecord(tid) {
    ajaxRequest('get_record', {tid: tid}, function(resp) {
        let d = resp.data;
        document.getElementById('editModalLabel').innerText = '编辑记录';
        document.getElementById('edit_tid').value = d.tid;
        document.getElementById('title').value = d.title;
        document.getElementById('notes').value = d.notes;
        document.getElementById('date').value = d.dateline_formatted;
        editModal.show();
    });
}

function viewRecord(tid) {
    ajaxRequest('get_record', {tid: tid}, function(resp) {
        let d = resp.data;
        document.getElementById('view_tid').innerText = d.tid;
        document.getElementById('view_title').innerText = d.title;
        document.getElementById('view_date').innerText = d.dateline_formatted;
        document.getElementById('view_notes').innerText = d.notes;
        viewModal.show();
    });
}

function deleteRecord(tid) {
    if (confirm('确定删除吗?')) ajaxRequest('delete', {tid: tid}, () => { alert('删除成功'); location.reload(); });
}

document.getElementById('saveBtn').onclick = function() {
    let tid = document.getElementById('edit_tid').value;
    let title = document.getElementById('title').value.trim();
    let notes = document.getElementById('notes').value.trim();
    let date = document.getElementById('date').value;
    if (!title || !notes || !date) return alert('请完整填写所有字段');
    ajaxRequest(tid === '0' ? 'add' : 'edit', {tid, title, notes, date}, () => { alert('保存成功'); location.reload(); });
};

document.querySelectorAll('.clickable-row').forEach(row => {
    row.addEventListener('dblclick', function(e) {
        if (e.target.tagName === 'BUTTON') return;
        let tid = this.getAttribute('data-tid');
        if (tid) viewRecord(tid);
    });
});
</script>
</body>
</html>

帮助中心

HACMS进销存管理系统V1.0(桌面版)

HACMS进销存管理系统V1.0(桌面版)采用的是Python+MySQL开发,开发初衷仅为自己所用,主要包括采购管理、采购退货管理、销售管理、销售退货管理、库存预警、库存报表、报盈管理、报损管理、流水导出等功能 ...

使用手册

PHP

PHP is a popular general-purpose scripting language that is especially suited to web development. Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.

PHP 手册

CodeIgniter

CodeIgniter is a powerful PHP framework with a very small footprint, built for developers who need a simple and elegant toolkit to create full-featured web applications.

CodeIgniter4用户指南