You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vtiger模块创建与更新咨询:模块不显示及字段添加问题

Vtiger模块开发:创建、更新及字段添加指南

一、解决"Module already present"但无模块文件的问题

这是因为脚本执行中途中断,数据库已写入模块元数据,但文件系统未生成对应文件夹和配置文件。解决步骤:

  • 登录Vtiger数据库,执行SQL清理残留记录:
    -- 先获取模块ID
    SELECT moduleid FROM vtiger_module WHERE name = 'namava';
    -- 替换下面的{MODULE_ID}为上面查询到的ID
    DELETE FROM vtiger_module WHERE moduleid = {MODULE_ID};
    DELETE FROM vtiger_blocks WHERE module = {MODULE_ID};
    DELETE FROM vtiger_fields WHERE module = {MODULE_ID};
    
  • 确认modules目录下无namava文件夹,若有则删除
  • 重新运行模块创建脚本

二、标准模块创建流程

你的原有脚本逻辑正确,以下是优化后的标准创建脚本(修正变量重复问题,规范字段命名):

include_once 'vtlib/Vtiger/Module.php';

$Vtiger_Utils_Log = true;
$MODULENAME = 'namava';

// 检查模块是否已存在(数据库+文件系统)
$moduleInstance = Vtiger_Module::getInstance($MODULENAME);
if ($moduleInstance || file_exists('modules/'.$MODULENAME)) {
    echo "Module already present - choose a different name or clean up existing records.";
    exit;
}

// 创建模块实例并设置基本信息
$moduleInstance = new Vtiger_Module();
$moduleInstance->name = $MODULENAME;
$moduleInstance->parent = 'Tools'; // 指定父菜单为Tools
$moduleInstance->save();

// 初始化模块数据表(自动创建vtiger_namava及关联CRM表记录)
$moduleInstance->initTables();

// 添加主信息块
$mainBlock = new Vtiger_Block();
$mainBlock->label = 'LBL_' . strtoupper($MODULENAME) . '_INFORMATION';
$moduleInstance->addBlock($mainBlock);

// 添加自定义信息块
$customBlock = new Vtiger_Block();
$customBlock->label = 'LBL_CUSTOM_INFORMATION';
$moduleInstance->addBlock($customBlock);

// 添加核心字段:Summary(设置为实体标识字段)
$summaryField = new Vtiger_Field();
$summaryField->name = 'summary';
$summaryField->label = 'Summary';
$summaryField->uitype = 2; // 单行文本框
$summaryField->column = $summaryField->name;
$summaryField->columntype = 'VARCHAR(255)';
$summaryField->typeofdata = 'V~M'; // 必填字符串
$mainBlock->addField($summaryField);
$moduleInstance->setEntityIdentifier($summaryField); // 列表页显示该字段内容

// 添加日期字段:Film On
$filmField = new Vtiger_Field();
$filmField->name = 'film_date';
$filmField->label = 'Film On';
$filmField->uitype = 5; // 日期选择器
$filmField->column = $filmField->name;
$filmField->columntype = 'DATE';
$filmField->typeofdata = 'D~O'; // 可选日期
$mainBlock->addField($filmField);

// 添加用户关联字段:Actor
$actorField = new Vtiger_Field();
$actorField->name = 'actor_id';
$actorField->label = 'Actor';
$actorField->uitype = 71; // 用户选择框
$actorField->column = $actorField->name;
$actorField->columntype = 'VARCHAR(255)';
$actorField->typeofdata = 'V~M'; // 必填
$mainBlock->addField($actorField);

// 添加描述字段(关联到crmentity表)
$descField = new Vtiger_Field();
$descField->name = 'description';
$descField->label = 'Description';
$descField->uitype = 19; // 多行文本框
$descField->column = 'description';
$descField->table = 'vtiger_crmentity';
$customBlock->addField($descField);

// 添加系统公共字段(关联crmentity表)
// 分配用户字段
$assignedField = new Vtiger_Field();
$assignedField->name = 'assigned_user_id';
$assignedField->label = 'Assigned To';
$assignedField->table = 'vtiger_crmentity';
$assignedField->column = 'smownerid';
$assignedField->uitype = 53; // 用户选择器
$assignedField->typeofdata = 'V~M';
$mainBlock->addField($assignedField);

// 创建时间字段(隐藏,自动填充)
$createdField = new Vtiger_Field();
$createdField->name = 'CreatedTime';
$createdField->label = 'Created Time';
$createdField->table = 'vtiger_crmentity';
$createdField->column = 'createdtime';
$createdField->uitype = 70; // 只读时间控件
$createdField->typeofdata = 'T~O';
$createdField->displaytype = 2; // 隐藏字段
$mainBlock->addField($createdField);

// 修改时间字段(隐藏,自动填充)
$modifiedField = new Vtiger_Field();
$modifiedField->name = 'ModifiedTime';
$modifiedField->label = 'Modified Time';
$modifiedField->table = 'vtiger_crmentity';
$modifiedField->column = 'modifiedtime';
$modifiedField->uitype = 70;
$modifiedField->typeofdata = 'T~O';
$modifiedField->displaytype = 2;
$mainBlock->addField($modifiedField);

// 添加默认过滤器
$defaultFilter = new Vtiger_Filter();
$defaultFilter->name = 'All';
$defaultFilter->isdefault = true;
$moduleInstance->addFilter($defaultFilter);
// 按顺序添加字段到过滤器
$defaultFilter->addField($summaryField)
              ->addField($filmField, 1)
              ->addField($actorField, 2)
              ->addField($assignedField, 3);

// 设置默认共享权限(私有模式)
$moduleInstance->setDefaultSharing();

echo "Module $MODULENAME created successfully!";

三、模块更新:添加新字段

模块创建完成后,不要重复运行全量创建脚本,单独编写更新脚本添加字段:

include_once 'vtlib/Vtiger/Module.php';

$Vtiger_Utils_Log = true;
$MODULENAME = 'namava';

// 获取已存在的模块实例
$moduleInstance = Vtiger_Module::getInstance($MODULENAME);
if (!$moduleInstance) {
    echo "Module $MODULENAME not found!";
    exit;
}

// 获取目标信息块(主信息块)
$mainBlock = Vtiger_Block::getInstance('LBL_NAMAVA_INFORMATION', $moduleInstance);
if (!$mainBlock) {
    echo "Main information block not found!";
    exit;
}

// 检查字段是否已存在
$ratingField = Vtiger_Field::getInstance('rating', $moduleInstance);
if ($ratingField) {
    echo "Field 'rating' already exists!";
    exit;
}

// 创建新字段:Rating
$ratingField = new Vtiger_Field();
$ratingField->name = 'rating';
$ratingField->label = 'Rating';
$ratingField->uitype = 1; // 单行文本框,或用uitype101表示评分组件
$ratingField->column = $ratingField->name;
$ratingField->columntype = 'INT(11)';
$ratingField->typeofdata = 'N~O'; // 可选数字
$mainBlock->addField($ratingField);

// 可选:将字段添加到默认过滤器
$defaultFilter = Vtiger_Filter::getInstance('All', $moduleInstance);
if ($defaultFilter) {
    $defaultFilter->addField($ratingField, 4); // 4为字段在过滤器中的排序位置
}

echo "Field 'rating' added successfully!";

四、console.php生成骨架后添加字段的方法

用php vtlib/tools/console.php生成的模块只有基础骨架,添加字段推荐用上述的更新脚本实现:

  1. 编写单独的字段添加脚本,通过vtlib API操作数据库
  2. 执行脚本后,清除Vtiger缓存(删除cache/目录下的缓存文件,或后台点击「清除缓存」)

常用字段Uitype参考

  • 2:单行文本框
  • 5:日期选择器
  • 19:多行文本框
  • 53:用户选择器
  • 71:用户/组选择器
  • 10:下拉列表

内容的提问来源于stack exchange,提问作者S k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 22:47:09