致远OA V8.1数据字典速查:通讯录、代理、考勤、讨论区表结构全解析
简介致远OA V8.1 数据字典是面向致远OA二次开发、系统集成与数据库运维人员的基础参考文档用于快速查阅系统底层表结构与字段定义解决开发中字段含义不明、扩展字段用途不清等问题。资源包共1个PDF文件约2.2MB内容以表格形式系统整理各数据表信息涵盖字段名称、数据类型、是否强制及注释说明便于检索与对照。文档以ADDRESSBOOK通讯录表为例详细列出主键ID、人员ID、创建与修改时间以及文本、数字、日期、枚举、选人、选部门、选岗位等各类扩展字段的类型与用途并延伸至ADDRESSBOOK_MEMBER等关联表帮助读者理解联系人数据的组织方式。目前已有2606人学习下载适合需要梳理致远OA数据库架构、编写SQL或排查数据问题的开发者参考也可作为系统升级与维护时的结构对照依据。1. 致远OA V8.1 数据字典一份能让你少加三天班的表结构底稿接手一套已经跑了三五年的致远OA V8.1最怕的不是代码看不懂而是数据库里那几百张表像黑匣子一样横在面前。业务方说“通讯录里那个扩展字段怎么不显示”运维说“考勤统计对不上”你打开数据库一看ADDRESSBOOK 表里 EXT_ATTR_1 到 EXT_ATTR_70 排得整整齐齐可哪个字段对应哪个业务含义全靠猜。这份 V8.1 数据字典就是干这个用的——它把通讯录、代理、考勤、讨论区这几个核心模块的表结构、字段类型、是否必填、字段注释全部摊开让你不用再对着建表语句一行行反推。适合谁做致远二次开发的、接运维工单的、准备做数据迁移或报表对接的以及被“字段含义不明”坑过的后端。它不是官方手册的替代品而是一份能直接贴进 IDE 当注释用的速查底稿。2. 通讯录模块拆解ADDRESSBOOK 的 70 个扩展字段怎么读通讯录是致远里被改得最狠的模块之一因为每个单位的组织架构和人员信息维度都不一样。V8.1 把扩展能力全压在 ADDRESSBOOK 这张主表上70 个 EXT_ATTR 字段按类型分成了五组不先搞清楚分组逻辑查数据就是大海捞针。2.1 五组扩展字段的类型划分与业务映射先看字段命名规律。EXT_ATTR_1 到 EXT_ATTR_10 是 VARCHAR(1024)文本类型适合存备注、标签、自定义描述这类不定长内容。EXT_ATTR_11 到 EXT_ATTR_20 是 DECIMAL(19,4)数字类型精度到小数点后四位用来存金额、评分、工时都够用。EXT_ATTR_21 到 EXT_ATTR_30 是 DATETIME日期类型记录自定义的时间节点。EXT_ATTR_31 到 EXT_ATTR_40 是 VARCHAR(50)枚举类型存的是字典编码或状态值。EXT_ATTR_41 到 EXT_ATTR_70 全是 VARCHAR(50)但注释里明确写了选人、选部门、选岗位三类每类十个字段存的是对应组织模型实体的 ID。这个分组不是随便定的。文本和数字字段直接存值枚举字段存编码选人/选部门/选岗位字段存的是外键 ID。如果你在报表里直接查 EXT_ATTR_41 想拿到人名那肯定拿不到得 JOIN 组织模型表。常见做法是先把字段分组和业务含义的对应关系整理成一张映射表再写查询。-- 查看 ADDRESSBOOK 表结构确认扩展字段的实际类型 SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ADDRESSBOOK AND COLUMN_NAME LIKE EXT_ATTR% ORDER BY CAST(SUBSTRING(COLUMN_NAME, 10) AS UNSIGNED);这段 SQL 在 MySQL 环境下跑能一次性把 70 个扩展字段的类型、长度、是否可空、注释全拉出来。参数说明SUBSTRING(COLUMN_NAME, 10) 是从 EXT_ATTR_ 后面截取数字部分用来按字段序号排序不然默认按字母序排会乱。IS_NULLABLE 全是 FALSE 说明这些字段虽然业务上可空但建表时没设 NOT NULL插入数据时给 NULL 不会报错但查询时要注意 NULL 值的处理。2.2 主表与 ADDRESSBOOK_MEMBER 的关联查询写法ADDRESSBOOK 存的是通讯录条目的基础信息ADDRESSBOOK_MEMBER 存的是外部联系人的详细信息。两张表通过 MEMBER_ID 关联但注意 ADDRESSBOOK_MEMBER 的主键是 ID不是 MEMBER_ID。实际查询时ADDRESSBOOK 的 MEMBER_ID 指向 ADDRESSBOOK_MEMBER 的 ID。-- 查询通讯录条目及其外部联系人详情 SELECT a.ID AS addressbook_id, a.MEMBER_ID, m.NAME AS member_name, m.COMPANY_NAME, m.MOBILEPHONE, m.EMAIL, a.CREATE_DATE, a.UPDATE_DATE FROM ADDRESSBOOK a LEFT JOIN ADDRESSBOOK_MEMBER m ON a.MEMBER_ID m.ID WHERE a.TYPE 1 -- TYPE 字段区分通讯录类型 ORDER BY a.UPDATE_DATE DESC;逻辑说明用 LEFT JOIN 是因为 ADDRESSBOOK 里可能存的是内部人员MEMBER_ID 不一定对应外部联系人表。TYPE 字段在字典里只写了“I”实际业务中通常用数字或字符区分内部/外部具体值需要结合 ADDRESSBOOK_SET 表的配置来看。参数上ORDER BY a.UPDATE_DATE DESC 能快速定位最近修改的条目排查数据问题时很实用。注意ADDRESSBOOK_MEMBER 的 CREATOR_ID 和 CREATOR_NAME 都是 TRUE也就是必填。如果通过接口写入数据这两个字段必须传否则会报约束错误。2.3 ADDRESSBOOK_SET 与 ADDRESSBOOK_SET_SCOPE 的权限配置逻辑通讯录的查看范围、关键信息、导出打印权限全在 ADDRESSBOOK_SET 表里控制。VIEW_SCOPE 是 SMALLINTKEY_INFO 也是 SMALLINTKEY_INFO_TYPE 用 1、2、3 区分手机号职务级别、仅手机号、仅职务级别。EXTERNAL_SCOPE 控制编外人员权限1 是按工作范围显示2 是全部隐藏。ADDRESSBOOK_SET_SCOPE 是权限范围的具体存储表。ADDRESSBOOK_SET_TYPE 区分设置类型1 是查看范围2 是关键信息3 是导出与打印权限。USER_ID 和 USER_TYPE 组合起来指向组织模型里的实体。-- 查询某个单位的通讯录查看范围配置 SELECT s.ID AS set_id, s.VIEW_SCOPE, s.KEY_INFO, s.KEY_INFO_TYPE, sc.USER_ID, sc.USER_TYPE, sc.ADDRESSBOOK_SET_TYPE FROM ADDRESSBOOK_SET s JOIN ADDRESSBOOK_SET_SCOPE sc ON s.ID sc.ADDRESSBOOK_SET_ID WHERE s.ACCOUNT_ID ? -- 传入单位 ID AND sc.ADDRESSBOOK_SET_TYPE 1;参数说明ACCOUNT_ID 是单位 ID在致远里通常对应组织模型中的单位实体。USER_TYPE 存的是组织模型实体类型常见值有 ACCOUNT、DEPARTMENT、POST 等。如果查出来的范围不对先确认 ADDRESSBOOK_SET_SCOPE 里有没有对应记录再看 USER_TYPE 是否匹配。3. 代理与考勤模块AGENT 和 ATTENDANCE 系列表的落地用法代理和考勤是致远里业务逻辑最绕的两个模块表多、字段多、状态流转复杂。数据字典把这两块的表结构列得很细但光看字段注释不够得知道表之间怎么串。3.1 AGENT 表的状态字段与代理期限判断AGENT 表存代理设置核心字段是 AGENT_ID代理人、AGENT_TO_ID被代理人、START_DATE、END_DATE、CANCEL_DATE、CANCEL_FLAG。CANCEL_FLAG 是 SMALLINT0 表示未取消1 表示已取消。AGENT_TYPE 区分代理设置和离职交接1 是代理设置2 是离职交接。判断一个代理是否生效不能只看 CANCEL_FLAG还要看当前时间是否在 START_DATE 和 END_DATE 之间。-- 查询当前生效的代理关系 SELECT a.ID, a.AGENT_ID, a.AGENT_TO_ID, a.START_DATE, a.END_DATE, a.AGENT_TYPE, a.AGENT_OPTION FROM AGENT a WHERE a.CANCEL_FLAG 0 AND NOW() BETWEEN a.START_DATE AND a.END_DATE AND a.AGENT_TYPE 1;逻辑说明NOW() 是数据库当前时间BETWEEN 确保代理在有效期内。AGENT_OPTION 是 VARCHAR(50)存的是代理选项的编码具体含义需要结合业务配置。如果查不到生效代理先检查 CANCEL_FLAG 是否为 1再看日期范围是否覆盖当前时间。AGENT_DETAIL 表通过 AGENT_ID 关联 AGENTAPP 字段是 BIGINT 且必填表示代理的应用模块。AGENT_SCOPE 存发起人范围ENTITY_TYPE 指定实体类型如 ACCOUNT、DEPARTMENTENTITY_ID 是对应实体 ID。3.2 ATTENDANCE_DAY_STATISTICS 的统计字段与考勤日计算考勤日统计表 ATTENDANCE_DAY_STATISTICS 是考勤模块里查询频率最高的表之一。PUNCH_DATE 是考勤日WEEK_DAY 是工作日星期AM_START_TIME、AM_END_TIME、PM_START_TIME、PM_END_TIME 记录上午签到、上午签退、下午签到、下午签退时间。AM_START_STATE 到 PM_END_STATE 是签到签退结果。统计字段包括 NORMAL_DAYS出勤天数、AB_NORMAL_DAY异常天数、LATE_NUM迟到次数、LEAVE_EARLY_NUM早退次数、OUTSIDE_NUM外勤次数、MISSINGCLOCK_COUNT缺卡总数。PUNCH_CLASS 是应打卡次数1 表示一天一次2 表示一天两次。-- 查询某人员某月的考勤统计汇总 SELECT MEMBER_ID, PUNCH_DATE, WEEK_DAY, AM_START_TIME, AM_END_TIME, PM_START_TIME, PM_END_TIME, AM_START_STATE, AM_END_STATE, PM_START_STATE, PM_END_STATE, NORMAL_DAYS, LATE_NUM, LEAVE_EARLY_NUM, MISSINGCLOCK_COUNT FROM ATTENDANCE_DAY_STATISTICS WHERE MEMBER_ID ? AND PUNCH_DATE BETWEEN 2024-01-01 AND 2024-01-31 ORDER BY PUNCH_DATE;参数说明MEMBER_ID 是人员 IDPUNCH_DATE 是考勤日。AM_START_STATE 等状态字段是 SMALLINT具体值需要对照字典里的状态定义。如果统计结果和实际打卡记录对不上先检查 ATTENDANCE_HISTORY 表里的原始打卡记录再看统计表是否及时更新。3.3 ATTENDANCE_HISTORY 与 ATTENDANCE_INFO 的差异与选用ATTENDANCE_HISTORY 和 ATTENDANCE_INFO 两张表结构高度相似但用途不同。ATTENDANCE_HISTORY 的 SIGN 字段是 VARCHAR(500)ATTENDANCE_INFO 的 SIGN 是 VARCHAR(2000)。ATTENDANCE_INFO 多了 IS_WORK_DAY、MODIFY_NUM、DEVICE_INFO、PUNCH_TYPE、STATE、MAC_ADDRESS 等字段STATE 明确写了打卡状态3 是上班迟到4 是下班早退5 是正常上班6 是正常下班。ATTENDANCE_HISTORY 更像历史归档表ATTENDANCE_INFO 是当前打卡信息表。查询实时打卡状态用 ATTENDANCE_INFO查历史记录用 ATTENDANCE_HISTORY。-- 查询某人员某天的打卡记录及状态 SELECT OWNER_ID, SIGN_TIME, TYPE, SIGN, STATE, LONGITUDE, LATITUDE, DEVICE_INFO, MAC_ADDRESS FROM ATTENDANCE_INFO WHERE OWNER_ID ? AND PUNCH_DATE 2024-01-15 ORDER BY SIGN_TIME;逻辑说明TYPE 字段区分签到来源1 是签到2 是签退3 是外勤。STATE 字段直接给出打卡状态不用再根据时间差计算。MAC_ADDRESS 存的是 WIFI Mac 地址用于校验打卡位置。如果打卡记录缺失先确认 ATTENDANCE_INFO 里有没有数据再看 ATTENDANCE_HISTORY 里是否有归档记录。注意ATTENDANCE_INFO 的 SIGN 字段长度是 2000比 ATTENDANCE_HISTORY 的 500 大很多说明当前表存的地址信息更详细。迁移数据时要注意字段长度兼容。4. 讨论区与组织变更BBS 和 AI_ORG 系列表的排查要点讨论区和组织变更记录是致远里相对独立但又容易出问题的模块。BBS 系列表存讨论主题、回复、板块信息AI_ORG 系列表存组织变更记录。4.1 BBS_ARTICLE 的匿名与点赞字段处理BBS_ARTICLE 表里 ANONYMOUS_FLAG 是匿名标志0 是正常1 是匿名。ANONYMOUS_REPLY_FLAG 控制是否允许匿名回复0 是不允许1 是允许。PRAISE 字段是 TEXT存的是点赞人员 ID 集合PRAISE_SUM 是点赞总数。STATE 字段是 0 正常、1 删除。查询讨论主题时必须过滤 STATE 0否则会把已删除的主题也查出来。-- 查询某板块下的正常讨论主题 SELECT ID, ARTICLE_NAME, ISSUE_USER_ID, ISSUE_TIME, REPLY_NUMBER, PRAISE_SUM, ELITE_FLAG, TOP_SEQUENCE FROM BBS_ARTICLE WHERE V3X_BBS_BOARD_ID ? AND STATE 0 ORDER BY TOP_SEQUENCE DESC, ISSUE_TIME DESC;参数说明V3X_BBS_BOARD_ID 是板块 IDSTATE 0 过滤已删除主题。TOP_SEQUENCE 是置顶序号越大越靠前。ELITE_FLAG 是精华标志0 正常1 精华。如果讨论列表显示异常先检查 STATE 字段再看 TOP_SEQUENCE 和 TOP_NUMBER_GROUP、TOP_NUMBER_UNIT 的置顶逻辑。4.2 AI_ORG_CHANGE_RECORD 与 AI_ORG_MEMBER_CHANGE 的变更追踪AI_ORG_CHANGE_RECORD 存组织变更记录OLD_ID、OLD_VALUE、NEW_ID、NEW_VALUE 记录变更前后的值。ORG_TYPE 区分变更类别0 是部门1 是岗位2 是职务级别。AI_ORG_MEMBER_CHANGE 存人员变更记录OLD_ACCOUNT_ID、NEW_ACCOUNT_ID、OLD_DEPT_ID、NEW_DEPT_ID、OLD_POST_ID、NEW_POST_ID、OLD_LEVEL_ID、NEW_LEVEL_ID 记录人员单位、部门、岗位、职务级别的变更前后值。-- 查询某人员的组织变更历史 SELECT MEMBER_ID, OLD_ACCOUNT_ID, NEW_ACCOUNT_ID, OLD_DEPT_ID, NEW_DEPT_ID, OLD_POST_ID, NEW_POST_ID, OLD_LEVEL_ID, NEW_LEVEL_ID, CREATE_TIME FROM AI_ORG_MEMBER_CHANGE WHERE MEMBER_ID ? ORDER BY CREATE_TIME DESC;逻辑说明CREATE_TIME 是变更时间按倒序排列能快速看到最近的变更。如果人员组织信息异常先查这张表确认是否有未同步的变更记录。OLD_VALUE 和 NEW_VALUE 是 VARCHAR(500)存的是变更值的文本表示适合做审计日志。4.3 ATTENDANCE_TEAM 与 ATTENDANCE_AUTH_ENTITY 的权限校验ATTENDANCE_TEAM 存考勤组信息ATTENDANCE_AUTH_ENTITY 存考勤组的授权实体。ENTITY_TYPE 区分组织机构类型3 是人员1 是部门0 是单位。ATTENDANCE_TEAM_ID 关联考勤组。-- 查询某考勤组的授权实体 SELECT ae.ENTITY_ID, ae.ENTITY_TYPE, ae.ATTENDANCE_TEAM_ID, at.ATTENDANCE_TEAM_NAME FROM ATTENDANCE_AUTH_ENTITY ae JOIN ATTENDANCE_TEAM at ON ae.ATTENDANCE_TEAM_ID at.ID WHERE ae.ATTENDANCE_TEAM_ID ?;参数说明ENTITY_TYPE 是 3 时ENTITY_ID 对应人员 ID是 1 时对应部门 ID是 0 时对应单位 ID。如果考勤组人员显示不全先检查这张表里有没有对应的授权记录再看 ENTITY_TYPE 是否正确。5. 避坑与排查数据字典用错场景的五个血泪教训5.1 扩展字段类型对不上导致查询报错现象查 ADDRESSBOOK 的 EXT_ATTR_11 想拿数字结果返回 NULL 或报类型转换错误。原因EXT_ATTR_11 是 DECIMAL(19,4)但实际存的是文本数字或者字段根本没赋值。解决先用 SELECT EXT_ATTR_11 FROM ADDRESSBOOK WHERE EXT_ATTR_11 IS NOT NULL LIMIT 10 看实际存的值确认类型后再写查询。如果存的是文本用 CAST 转换。5.2 代理期限判断漏掉 CANCEL_FLAG现象查出来的代理关系明明已经取消了但业务上还在生效。原因只看了 START_DATE 和 END_DATE没过滤 CANCEL_FLAG 0。解决查询条件里必须同时带上 CANCEL_FLAG 0 和日期范围判断。CANCEL_DATE 是取消时间CANCEL_FLAG 是取消标记两个字段要一起看。5.3 考勤统计表和原始打卡记录不一致现象ATTENDANCE_DAY_STATISTICS 里显示正常出勤但 ATTENDANCE_HISTORY 里没有打卡记录。原因统计表是定时任务生成的可能还没跑完或者打卡记录被归档到了 ATTENDANCE_HISTORY 但统计表没更新。解决先查 ATTENDANCE_INFO 确认原始记录再看统计表的 CREATE_TIME 和 MODIFY_TIME判断是否是最新数据。如果是定时任务问题手动触发统计更新。5.4 BBS 讨论主题查询漏掉 STATE 过滤现象讨论区列表里出现了已删除的主题。原因查询时没加 STATE 0 条件。解决所有 BBS_ARTICLE 和 BBS_ARTICLE_REPLY 的查询都要带上 STATE 0。BBS_ARTICLE_REPLY 的 STATE 也是 0 正常、1 删除。如果列表还是不对检查 TOP_SEQUENCE 和 TOP_NUMBER_GROUP、TOP_NUMBER_UNIT 的置顶逻辑。5.5 组织变更记录查不到最新数据现象人员部门已经调整了但 AI_ORG_MEMBER_CHANGE 里没有对应记录。原因变更记录是异步写入的可能有延迟或者变更操作没触发记录写入。解决先查 AI_ORG_CHANGE_RECORD 看有没有部门变更记录再查 AI_ORG_MEMBER_CHANGE。如果都没有检查变更操作是否走了正确的接口。CREATE_TIME 是变更时间按时间倒序查最近记录。6. 把数据字典变成可查询的本地知识库数据字典的 PDF 或 Excel 看多了会烦我一般会把它导进本地数据库建一张字段元数据表然后用 SQL 直接查。这样比翻文档快得多而且能跟实际表结构做比对。-- 创建字段元数据表 CREATE TABLE IF NOT EXISTS oa_dict_meta ( id INT AUTO_INCREMENT PRIMARY KEY, table_name VARCHAR(100) NOT NULL, column_name VARCHAR(100) NOT NULL, data_type VARCHAR(50), is_nullable VARCHAR(10), column_comment VARCHAR(500), module VARCHAR(50), UNIQUE KEY uk_table_column (table_name, column_name) ); -- 插入示例数据实际使用时从字典文件批量导入 INSERT INTO oa_dict_meta (table_name, column_name, data_type, is_nullable, column_comment, module) VALUES (ADDRESSBOOK, ID, BIGINT, TRUE, 主键, 通讯录), (ADDRESSBOOK, MEMBER_ID, BIGINT, FALSE, 人员 id, 通讯录), (ADDRESSBOOK, EXT_ATTR_1, VARCHAR(1024), FALSE, 文本类型扩展字段 1, 通讯录), (AGENT, AGENT_ID, BIGINT, FALSE, 代理人 ID, 代理), (ATTENDANCE_DAY_STATISTICS, MEMBER_ID, BIGINT, FALSE, 人员 ID, 考勤);建好这张表后查字段含义就是一句 SQL 的事。-- 查询某个模块下所有字段 SELECT table_name, column_name, data_type, is_nullable, column_comment FROM oa_dict_meta WHERE module 通讯录 ORDER BY table_name, column_name;参数说明module 字段是我自己加的用来按业务模块分类。实际导入时可以从字典文件里解析出表名、字段名、类型、是否必填、注释批量 INSERT。这样查字段比翻文档快而且能跟 INFORMATION_SCHEMA 做比对发现实际表结构和字典不一致的地方。我一般还会加一个比对查询把字典里的字段和实际数据库的字段做 FULL OUTER JOIN找出字典里有但实际表没有的字段或者实际表有但字典没收录的字段。这个在版本升级后特别有用能快速发现表结构变更。-- 比对字典和实际表结构的差异MySQL 不支持 FULL OUTER JOIN用 UNION 模拟 SELECT COALESCE(d.table_name, c.TABLE_NAME) AS table_name, COALESCE(d.column_name, c.COLUMN_NAME) AS column_name, d.data_type AS dict_type, c.DATA_TYPE AS actual_type, CASE WHEN d.column_name IS NULL THEN 实际表有字典缺失 WHEN c.COLUMN_NAME IS NULL THEN 字典有实际表缺失 WHEN d.data_type ! c.DATA_TYPE THEN 类型不一致 ELSE 一致 END AS diff_status FROM oa_dict_meta d LEFT JOIN INFORMATION_SCHEMA.COLUMNS c ON d.table_name c.TABLE_NAME AND d.column_name c.COLUMN_NAME WHERE c.TABLE_SCHEMA your_database_name UNION SELECT c.TABLE_NAME, c.COLUMN_NAME, NULL, c.DATA_TYPE, 实际表有字典缺失 FROM INFORMATION_SCHEMA.COLUMNS c LEFT JOIN oa_dict_meta d ON c.TABLE_NAME d.table_name AND c.COLUMN_NAME d.column_name WHERE c.TABLE_SCHEMA your_database_name AND d.column_name IS NULL;这段 SQL 跑完差异一目了然。从那以后我每次拿到新版本的数据字典都强制走一遍导入、比对、标注差异的流程再开始写业务查询。希望帮到你。本文还有配套的精品资源点击获取