通达OA模块开发实战

0 阅读3分钟

一、引言

模块开发是通达OA二次开发的核心内容。本文将通过一个完整的实战案例,详细介绍如何创建一个功能完善的OA模块,包括目录结构、数据库设计、代码编写、菜单注册和权限分配等环节。

二、开发前准备

2.1 需求分析

假设我们需要开发一个"项目管理"模块,包含以下功能:

2.2 数据库设计

项目表(project)

字段名类型说明
project_idint项目ID(主键,自增)
project_namevarchar(100)项目名称
descriptiontext项目描述
start_datedate开始日期
end_datedate结束日期
statustinyint状态(0=进行中,1=已完成)
creator_uidint创建人ID
create_timedatetime创建时间
update_timedatetime更新时间

数据库关系图

三、模块开发步骤

3.1 步骤一:建立模块目录

MYOA\webroot\general 目录下创建模块目录:

New-Item -ItemType Directory -Path "MYOA\webroot\general\project"

目录结构规划

project/
├── index.php          # 项目列表页
├── add.php            # 添加项目页
├── edit.php           # 编辑项目页
├── detail.php         # 项目详情页
├── delete.php         # 删除项目接口
├── ajax.php           # AJAX接口
└── style.css          # 模块样式文件

3.2 步骤二:创建数据库表

使用phpMyAdmin或SQL语句创建表:

CREATE TABLE IF NOT EXISTS `project` (
    `project_id` int(11) NOT NULL AUTO_INCREMENT,
    `project_name` varchar(100) NOT NULL,
    `description` text,
    `start_date` date DEFAULT NULL,
    `end_date` date DEFAULT NULL,
    `status` tinyint(1) DEFAULT '0',
    `creator_uid` int(11) NOT NULL,
    `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
    `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`project_id`),
    KEY `creator_uid` (`creator_uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.3 步骤三:编写核心代码

3.3.1 项目列表页(index.php)

<?php
$HTML_PAGE_TITLE = _("项目管理");
include_once("inc/auth.inc.php");
include_once("inc/header.inc.php");

$td = new TD();

// 分页参数
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$page_size = 10;
$offset = ($page - 1) * $page_size;

// 查询项目列表
$sql = "SELECT p.*, u.name AS creator_name 
        FROM project p 
        LEFT JOIN user u ON p.creator_uid = u.uid 
        ORDER BY p.create_time DESC 
        LIMIT $offset, $page_size";
$result = $td->query($sql);

// 查询总数
$count_sql = "SELECT COUNT(*) AS total FROM project";
$count_result = $td->query($count_sql);
$count_row = $td->fetch_array($count_result);
$total = $count_row['total'];
$total_pages = ceil($total / $page_size);
?>

<div class="main-content">
    <h2><?php echo _("项目列表"); ?></h2>
    
    <a href="add.php" class="btn btn-primary">
        <?php echo _("添加项目"); ?>
    </a>
    
    <table class="table">
        <thead>
            <tr>
                <th><?php echo _("项目名称"); ?></th>
                <th><?php echo _("描述"); ?></th>
                <th><?php echo _("时间范围"); ?></th>
                <th><?php echo _("状态"); ?></th>
                <th><?php echo _("创建人"); ?></th>
                <th><?php echo _("操作"); ?></th>
            </tr>
        </thead>
        <tbody>
            <?php while ($row = $td->fetch_array($result)) { ?>
            <tr>
                <td><?php echo $row['project_name']; ?></td>
                <td><?php echo csubstr($row['description'], 0, 50); ?></td>
                <td><?php echo $row['start_date'] . ' ~ ' . $row['end_date']; ?></td>
                <td><?php echo $row['status'] ? _('已完成') : _('进行中'); ?></td>
                <td><?php echo $row['creator_name']; ?></td>
                <td>
                    <a href="detail.php?id=<?php echo $row['project_id']; ?>">
                        <?php echo _("查看"); ?>
                    </a>
                    <a href="edit.php?id=<?php echo $row['project_id']; ?>">
                        <?php echo _("编辑"); ?>
                    </a>
                    <a href="delete.php?id=<?php echo $row['project_id']; ?>" 
                       onclick="return confirm('<?php echo _('确定删除?'); ?>')">
                        <?php echo _("删除"); ?>
                    </a>
                </td>
            </tr>
            <?php } ?>
        </tbody>
    </table>
    
    <?php // 分页代码省略 ?>
</div>

<?php
include_once("inc/footer.inc.php");
?>

3.3.2 添加项目页(add.php)

<?php
$HTML_PAGE_TITLE = _("添加项目");
include_once("inc/auth.inc.php");
include_once("inc/header.inc.php");

if ($_POST) {
    $td = new TD();
    
    $project_name = $td->escape($_POST['project_name']);
    $description = $td->escape($_POST['description']);
    $start_date = $_POST['start_date'];
    $end_date = $_POST['end_date'];
    $creator_uid = $_SESSION['uid'];
    
    $sql = "INSERT INTO project (project_name, description, start_date, end_date, creator_uid) 
            VALUES ('$project_name', '$description', '$start_date', '$end_date', $creator_uid)";
    
    if ($td->query($sql)) {
        Message(_("添加成功"), "index.php");
        exit;
    } else {
        Message(_("添加失败"), "add.php");
        exit;
    }
}
?>

<div class="main-content">
    <h2><?php echo _("添加项目"); ?></h2>
    
    <form method="post" action="add.php">
        <div class="form-group">
            <label><?php echo _("项目名称"); ?>:</label>
            <input type="text" name="project_name" required class="form-control">
        </div>
        
        <div class="form-group">
            <label><?php echo _("项目描述"); ?>:</label>
            <textarea name="description" class="form-control"></textarea>
        </div>
        
        <div class="form-group">
            <label><?php echo _("开始日期"); ?>:</label>
            <input type="date" name="start_date" required class="form-control">
        </div>
        
        <div class="form-group">
            <label><?php echo _("结束日期"); ?>:</label>
            <input type="date" name="end_date" required class="form-control">
        </div>
        
        <button type="submit" class="btn btn-primary">
            <?php echo _("提交"); ?>
        </button>
        <a href="index.php" class="btn btn-default">
            <?php echo _("返回"); ?>
        </a>
    </form>
</div>

<?php
include_once("inc/footer.inc.php");
?>

3.3.3 删除项目(delete.php)

<?php
include_once("inc/auth.inc.php");

$td = new TD();
$project_id = isset($_GET['id']) ? intval($_GET['id']) : 0;

if ($project_id > 0) {
    $sql = "DELETE FROM project WHERE project_id = $project_id";
    if ($td->query($sql)) {
        Message(_("删除成功"), "index.php");
    } else {
        Message(_("删除失败"), "index.php");
    }
} else {
    Message(_("参数错误"), "index.php");
}
?>

3.4 步骤四:注册菜单

在通达OA系统管理中注册菜单:

Mermaid 渲染失败: Lexical error on line 9. Unrecognized text.
...al/project/index.php]    E -->|父菜单| E3[
-----------------------^

菜单注册信息

字段
菜单名称项目管理
菜单地址/general/project/index.php
父菜单工作台(或其他合适的父菜单)
菜单图标选择合适的图标
排序号根据需要设置

3.5 步骤五:分配权限

权限分配步骤

  1. 进入系统管理 → 角色管理
  2. 选择需要分配权限的角色
  3. 点击"编辑权限"
  4. 在权限列表中找到"项目管理"并勾选
  5. 保存权限设置

四、高级功能开发

4.1 附件上传功能

使用OA内置的文件上传函数:

<?php
include_once("inc/utility_file.php");

// 处理文件上传
if ($_FILES['attachment']['name']) {
    $attach = upload('attachment', 0, 0, 'project');
    if ($attach['error'] == 0) {
        $attach_id = $attach['id'];
        // 保存附件ID到数据库
    }
}
?>

4.2 人员选择组件

使用OA的人员选择组件:

<?php
include_once("inc/header.inc.php");
?>

<!-- 人员多选组件 -->
<input type="hidden" name="user_ids" id="user_ids">
<script type="text/javascript">
    // 调用人员选择组件
    selectUser('user_ids', 'multi');
</script>

4.3 AJAX交互

<?php
// ajax.php
include_once("inc/auth.inc.php");

$action = isset($_GET['action']) ? $_GET['action'] : '';

if ($action == 'search') {
    $keyword = $_GET['keyword'];
    $td = new TD();
    $keyword = $td->escape($keyword);
    
    $sql = "SELECT * FROM project WHERE project_name LIKE '%$keyword%'";
    $result = $td->query($sql);
    
    $data = array();
    while ($row = $td->fetch_array($result)) {
        $data[] = $row;
    }
    
    echo json_encode($data);
    exit;
}
?>

五、调试与测试

5.1 调试方法

调试工具

工具用途
php_errors.logPHP错误日志
浏览器开发者工具前端调试
phpMyAdmin数据库查询
var_dump()变量输出

5.2 测试用例

功能测试

测试项测试步骤预期结果
添加项目填写表单提交项目成功添加
编辑项目修改信息提交项目信息更新
删除项目点击删除确认项目成功删除
列表显示访问列表页显示所有项目
权限控制无权限用户访问提示无权限

六、模块部署与发布

6.1 部署流程

6.2 发布清单

项目说明
代码文件所有PHP文件
样式文件CSS文件
数据库脚本SQL文件
配置文件菜单配置
权限配置角色权限

七、最佳实践总结

7.1 代码规范

编码规范

规范项要求
变量命名驼峰式命名
文件命名小写字母,下划线分隔
数据库表小写字母,下划线分隔
SQL语句使用TD类的escape方法转义

7.2 安全注意事项

  1. 输入验证:对所有用户输入进行验证
  2. SQL注入:使用参数化查询或escape方法
  3. 文件上传:验证文件类型和大小
  4. 权限控制:使用auth.inc.php进行权限验证
  5. 敏感信息:不输出敏感信息到页面