☰
致远OA V8.1数据字典深度拆解:通讯录、考勤与AI待办表结构解析
2026/10/27 11:34:06 网站建设 项目流程

简介:致远OA V8.1 数据字典面向致远OA二次开发、系统集成与数据库维护人员,用于快速查阅协同办公平台的表结构与字段定义,解决开发中字段含义不清、扩展字段用途不明等问题。资源以PDF形式整理,共1个文件,压缩包约2.2MB,便于随查随用。内容以ADDRESSBOOK、ADDRESSBOOK_MEMBER等通讯录相关表为切入点,逐字段列出名称、数据类型、是否必填及注释,涵盖主键ID、人员ID、创建与修改时间,以及文本、数字、日期、枚举、选人、选部门、选岗位等成组的扩展字段,并延伸说明数据字典在数据完整性、文档管理、系统维护与业务逻辑实现中的作用。已有2609人学习下载,适合需要理解数据库设计意图、保障数据一致性的开发者参考。

1. 拿到一份 OA 数据字典,先别急着建表

上周有个做企业集成的朋友甩过来一个压缩包,说“致远 OA V8.1 的数据字典,你帮我看看能不能直接拿来写同步脚本”。我打开一看,光通讯录模块就拆了五张表,考勤模块更夸张,从排班、班次、打卡记录到日统计一路铺开,字段里还夹着一堆EXT_ATTR_1到EXT_ATTR_70的扩展列。这种字典不是拿来“读”的,是拿来“对”的——对着业务场景反查字段含义,对着字段类型判断能不能直接落库。

这份 V8.1 数据字典覆盖通讯录、代理设置、AI 待办、考勤、讨论社区几大块,每张表都给了字段名、数据类型、是否强制、注释四列。对做 OA 二次开发、数据迁移、报表取数的人来说,它解决的是“字段到底叫什么、存的是什么、能不能为空”这三个最要命的问题。适合谁?适合手里有 OA 库但不敢乱动的人,适合要从 OA 抽数到数仓的人,也适合排查“为什么这条通讯录记录查不出来”的人。下面按我实际拆包的顺序讲,先讲怎么读,再讲怎么用,最后讲哪些地方我踩过坑。

2. 通讯录五张表:从 ADDRESSBOOK 到 ADDRESSBOOK_SET_SCOPE 的关联读法

通讯录这块是整份字典里结构最绕的,因为它把“人”“组”“设置”“范围”拆成了五张表。很多人第一反应是直接查ADDRESSBOOK,结果发现查出来的记录对不上前端显示,问题就出在没把设置表和范围表串起来。

2.1 ADDRESSBOOK 的 70 个扩展字段不是摆设

ADDRESSBOOK主表存的是通讯录条目本身,核心字段就四个:ID主键、MEMBER_ID关联人员、CREATE_DATE、UPDATE_DATE。真正占篇幅的是EXT_ATTR_1到EXT_ATTR_70,按类型分了五段:

字段区间类型用途
EXT_ATTR_1 ~ 10VARCHAR(1024)文本扩展
EXT_ATTR_11 ~ 20DECIMAL(19,4)数字扩展
EXT_ATTR_21 ~ 30DATETIME日期扩展
EXT_ATTR_31 ~ 40VARCHAR(50)枚举值
EXT_ATTR_41 ~ 50VARCHAR(50)选人(存人员 ID)
EXT_ATTR_51 ~ 60VARCHAR(50)选部门(存部门 ID)
EXT_ATTR_61 ~ 70VARCHAR(50)选岗位(存岗位 ID)

这里有个反直觉的点:选人、选部门、选岗位字段虽然叫VARCHAR(50),但存的是组织模型实体的 ID 字符串,不是名称。我见过有人直接拿EXT_ATTR_41去跟MEMBER_ID做等值关联,结果类型对上了、语义对不上——MEMBER_ID是通讯录条目归属人,EXT_ATTR_41是业务上选的某个人,两者不是一回事。要还原名称,得再回组织模型表按 ID 反查。

读这张表的顺序建议是:先SELECT ID, MEMBER_ID, TYPE FROM ADDRESSBOOK WHERE TYPE = ?确认条目类型,再按EXT_ATTR区间判断业务扩展落在哪一段。TYPE字段是VARCHAR(50),字典里没给枚举值,实际取值要靠SELECT DISTINCT TYPE自己摸,别假设它只有一两种。

2.2 ADDRESSBOOK_SET 与 SCOPE 决定“谁能看到谁”

ADDRESSBOOK_SET是通讯录的显示设置表,关键字段是VIEW_SCOPE(查看范围)、KEY_INFO(关键信息)、EXPORT_PRINT(导出打印)、DISPLAY_COLUMN(显示列头)。ADDRESSBOOK_SET_SCOPE则是范围明细,通过ADDRESSBOOK_SET_ID关联回设置表,ADDRESSBOOK_SET_TYPE区分是查看范围(1)、关键信息(2)还是导出打印权限(3),USER_ID+USER_TYPE指向具体的组织模型实体。

实际取数的典型场景是“查某个人能看到哪些通讯录条目”,逻辑不是查ADDRESSBOOK加个WHERE,而是先定位这个人的设置记录,再展开范围。常见做法是:

-- 先拿到该人员生效的通讯录设置 SELECT s.ID, s.VIEW_SCOPE, s.DISPLAY_COLUMN FROM ADDRESSBOOK_SET s WHERE s.ACCOUNT_ID = :accountId; -- 再按设置 ID 展开查看范围 SELECT sc.USER_ID, sc.USER_TYPE FROM ADDRESSBOOK_SET_SCOPE sc WHERE sc.ADDRESSBOOK_SET_ID = :setId AND sc.ADDRESSBOOK_SET_TYPE = 1;

参数说明::accountId是单位 ID,:setId是上一步查出的设置主键。USER_TYPE是组织模型实体类型字符串,字典没给枚举,实际要和USER_ID一起解释,单看USER_ID会误判成人员。VIEW_SCOPE是SMALLINT,取值含义字典没展开,我一般先SELECT DISTINCT VIEW_SCOPE看库里实际分布再写分支,别硬编码。

ADDRESSBOOK_SET里还有M3_SET/M3_DISPLAY_COLUMN和ZX_SET/ZX_DISPLAY_COLUMN两组,分别对应移动端和致信端的独立显示字段配置。做多端同步时如果只读DISPLAY_COLUMN,移动端列头会对不上,这是血泪经验——两端配置是分开存的,M3_SET = 1时必须以M3_DISPLAY_COLUMN为准。

2.3 ADDRESSBOOK_TEAM 与 MEMBERS 的个人组逻辑

ADDRESSBOOK_TEAM存个人组/个人类别,TYPE字段区分系统组(0)、个人组(1)、私人通讯录(2)。ADDRESSBOOK_TEAM_MEMBERS是关联表,TEAM_ID对组、MEMBER_ID对成员。这里容易翻车的地方是CREATOR_NAME只有VARCHAR(20),而ADDRESSBOOK_MEMBER里的NAME是VARCHAR(255)——同一个人名在两个表里长度定义不一致,跨表比对名称时如果按 20 截断会丢字符。我一般统一用 ID 关联,名称只做展示不做匹配键。

ADDRESSBOOK_MEMBER是外部联系人表,字段比主表规整得多:NAME、COMPANY_NAME、COMPANY_DEPT、MOBILEPHONE、EMAIL都是常规VARCHAR,CREATOR_ID和CREATOR_NAME都是强制非空。注意MEMO是TEXT类型,导出时别用定长缓冲接。

3. 代理与 AI 待办:AGENT 系列和 AI_ 前缀表的落库要点

代理设置和 AI 待办是两块相对独立但都涉及“人-事-时间”三要素的模块。代理表管的是“谁替谁办事、什么时间段有效”,AI 表管的是“自动处理条件、催办次数、组织变更留痕”。这两块如果直接按字典建表,最容易忽略的是状态字段的默认值和取消标记的语义。

3.1 AGENT 表的代理期限与取消标记

AGENT表核心字段:AGENT_ID(代理人)、AGENT_TO_ID(被代理人)、START_DATE/END_DATE(代理期限)、CANCEL_DATE(取消时间)、CANCEL_FLAG(0 未取消 / 1 已取消)、AGENT_TYPE(1 代理设置 / 2 离职交接)、AGENT_OPERATION(0 被代理人自己 / 1 集团管理员 / 2 单位管理员)。

判断一条代理当前是否生效,不能只看CANCEL_FLAG = 0,还要卡时间窗:

SELECT ID, AGENT_ID, AGENT_TO_ID, START_DATE, END_DATE FROM AGENT WHERE CANCEL_FLAG = 0 AND (START_DATE IS NULL OR START_DATE <= NOW()) AND (END_DATE IS NULL OR END_DATE >= NOW());

参数说明:START_DATE/END_DATE允许为空,空值语义字典没写死,我按“空即不限”处理,但上线前一定拿实际数据验证——如果库里存在大量空END_DATE且业务上表示“已过期”,这个条件就会多捞。AGENT_OPTION是VARCHAR(50),字典没给枚举,别拿它做过滤主条件。

AGENT_DETAIL通过AGENT_ID关联,APP字段是BIGINT且强制非空,表示代理生效的应用;AGENT_SCOPE存发起人范围,ENTITY_TYPE是实体类型字符串(如ACCOUNT、DEPARTMENT),ENTITY_ID是实体 ID。做代理链路排查时,顺序是AGENT定人 →AGENT_DETAIL定应用 →AGENT_SCOPE定范围,三层缺一层都会出现“代理设置了但不生效”的玄学问题。

3.2 AI_DEAL_CONDITION 与 AI_REMIND_COUNT 的计数语义

AI_DEAL_CONDITION存自动处理条件,DEAL_TYPE是SMALLINT,字典给了明确枚举:0 回退、1 指定回退、2 撤销、3 终止、4 不同意、5 处理时长。SIGNLE_VIEW_PERIOD是BIGINT,默认 0,表示处理时长。注意字段名拼写是SIGNLE不是SINGLE,写 SQL 时按字典原样来,别自作主张改拼写,否则报字段不存在。

AI_REMIND_COUNT和AI_REMIND_RECORD是一对催办计数表。AI_REMIND_COUNT的AI_REMIND_ID关联AI_REMIND_RECORD.ID,AFFAIR_ID是被催办事项,COUNT是接收催办消息次数。AI_REMIND_RECORD里IS_SEND_MSG是SMALLINT(0 未发送 / 1 已发送),COUNT是查看次数。这两张表的COUNT语义不同:一个是“收到几次催办”,一个是“看了几次”,做催办报表时混用会导致数字翻倍。

AI_ORG_CHANGE_RECORD和AI_ORG_MEMBER_CHANGE是组织变更留痕表,前者记部门/岗位/职务级别的旧值新值(ORG_TYPE:0 部门、1 岗位、2 职务级别),后者记人员的单位、部门、岗位、级别变更。这两张表只增不改,做增量同步时按CREATE_TIME拉取即可,但要注意OLD_VALUE/NEW_VALUE是VARCHAR(500),长名称可能被截断,别拿它做精确回滚依据。

4. 考勤模块:ATTENDANCE_ 前缀表的排班与打卡数据链路

考勤是整份字典里表最多的一块,从ATTENDANCE_ARRANGE(排班)、ATTENDANCE_CLASS(班次)、ATTENDANCE_DAY(每日排班)到ATTENDANCE_INFO/ATTENDANCE_HISTORY(打卡记录)、ATTENDANCE_DAY_STATISTICS(日统计),一条链路七八张表。很多人取考勤数据直接查ATTENDANCE_INFO,结果统计口径对不上,因为真正的“应出勤”逻辑在排班和班次表里。

4.1 排班三件套:ARRANGE、CLASS、DAY 的层级关系

ATTENDANCE_ARRANGE是排班主表,ARRANGE_TYPE区分固定排班(0)和周期排班(1),ATTENDANCE_TEAM_ID关联考勤组。ATTENDANCE_CLASS是班次表,CLASS_TYPE区分一天一次(0)、一天两次(1)、一天三次(2),ATTENDANCE_ARRANGE_ID回挂排班。ATTENDANCE_DAY是每日展开表,WEEK_DAY是星期几,IS_WORK标记是否工作日(0 不是 / 1 是),同时挂ATTENDANCE_ARRANGE_ID和ATTENDANCE_CLASS_ID。

取“某人某天应该打几次卡”,正确路径是:人员 → 考勤组 → 排班 → 班次 →CLASS_TYPE换算打卡次数。ATTENDANCE_DAY_STATISTICS里的PUNCH_CLASS字段直接给了应打卡次数(1 一天一次 / 2 一天两次),但它是统计结果不是配置源,配置源还是ATTENDANCE_CLASS.CLASS_TYPE。我一般两边都查一遍做交叉验证,对不上就说明排班在统计之后被改过。

ATTENDANCE_FIX_TIME存固定班次的具体时间:WORK_TIME上班、END_TIME下班、EARLY_WORK_TIME最早签到、LAST_END_TIME最晚签退,还有ATTEND_REMIND/LEAVE_REMIND提醒开关。这些时间字段都是VARCHAR(50)不是TIME类型,比较时要先转格式,直接字符串比大小在跨天场景会翻车。

4.2 ATTENDANCE_INFO 与 HISTORY 的字段差异

ATTENDANCE_INFO和ATTENDANCE_HISTORY结构高度相似,但有几个关键差异必须注意:

字段ATTENDANCE_INFOATTENDANCE_HISTORY
SIGNVARCHAR(2000)VARCHAR(500)
NEAR_ADDRESSVARCHAR(300)VARCHAR(200)
IMG_INFO / RECORD_INFOJSON 格式附件表关联信息
STATE有(3 迟到 / 4 早退 / 5 正常上班 / 6 正常下班)无
MAC_ADDRESS有无
MODIFY_NUM有(签到修改次数)无

ATTENDANCE_INFO是当前有效打卡记录,ATTENDANCE_HISTORY是历史归档。做增量同步时如果只同步INFO,历史补录的数据会丢;只同步HISTORY,当天的实时打卡又拿不到。常见做法是两张表都按PUNCH_DATE拉,用ID去重。STATE字段只在INFO里有,HISTORY要靠TYPE(1 签到 / 2 签退 / 3 外勤)加时间比对反推状态,这是取数时最容易漏的一环。

ATTENDANCE_DAY_STATISTICS是日统计宽表,字段从AM_START_TIME到PM_END_STATE把上下午签到签退全铺开,还有LATE_NUM、LEAVE_EARLY_NUM、MISSINGCLOCK_COUNT等汇总列。这张表适合直接出报表,但不适合做明细追溯——它的粒度是“人+考勤日”,丢了单次打卡的经纬度和设备信息。要追“为什么这天算迟到”,还得回ATTENDANCE_INFO看SIGN_TIME和FIX_TIME的差值。

4.3 考勤组与权限:TEAM、AUTH_ENTITY、SETTING 的配合

ATTENDANCE_TEAM是考勤组主表,IS_NEW标记是否最新版本(0 不是 / 1 是),START_DATE/END_DATE是生效区间。同一考勤组可能有多条历史版本,取当前生效的要加IS_NEW = 1且卡时间窗。ATTENDANCE_AUTH_ENTITY是考勤组权限表,ENTITY_TYPE区分单位(0)、部门(1)、人员(3),ENTITY_ID是组织模型 ID。

ATTENDANCE_SETTING是打卡围栏设置,TYPE是过滤类型,FILTRATE_ENTITY是过滤实体,LONGITUDE/LATITUDE是围栏中心点,ATTEND_RANGE是范围,AVAILABLE是启用标记。RELATIVE_ID存第三方系统导入的围栏 ID,做多系统对接时靠它做映射。注意经纬度是VARCHAR(50)不是数值类型,算距离前要显式转换,直接拿字符串算会得到离谱结果。

5. 避坑清单:读这份字典时我踩过的五个坑

5.1 扩展字段类型对不上,插入报截断

现象:往ADDRESSBOOK.EXT_ATTR_11插一个带小数的金额,报Data truncation。原因:EXT_ATTR_11是DECIMAL(19,4),只保留四位小数,业务侧传了六位。解决:落库前统一按字段精度做ROUND,别指望数据库静默截断。文本扩展字段VARCHAR(1024)同理,超长直接报错不截断。

5.2 代理生效判断漏了 CANCEL_DATE

现象:CANCEL_FLAG = 0查出来一堆“生效中”的代理,但业务说早取消了。原因:取消动作可能只写了CANCEL_DATE没改CANCEL_FLAG,或者改标记和写时间不在同一事务。解决:判断条件同时卡CANCEL_FLAG = 0 AND CANCEL_DATE IS NULL,两个条件都满足才算未取消。

5.3 考勤统计和明细对不上

现象:ATTENDANCE_DAY_STATISTICS.LATE_NUM显示迟到 1 次,但ATTENDANCE_INFO里找不到对应记录。原因:统计表是定时任务跑的,明细可能被后续修改(MODIFY_NUM > 0)而统计没重算。解决:对账时以明细为准,统计表只做展示;发现不一致先看MODIFY_TIME和统计任务的执行时间先后。

5.4 讨论社区表名带 V3X_ 前缀,关联时写错

现象:按字典写BBS_ARTICLE_ISSUE_AREA.V3X_BBS_ARTICLE_ID关联BBS_ARTICLE.ID,报字段不存在。原因:字典里BBS_ARTICLE的主键注释写的是“主题 ID”,但关联字段名带V3X_前缀,实际列名要以DESC表结构为准,字典的字段名列和注释列偶尔错位。解决:建表或写关联前先SHOW COLUMNS FROM 表名核对一遍,别全信文档。

5.5 枚举字段没给全取值,硬编码分支翻车

现象:ADDRESSBOOK_SET.VIEW_SCOPE按字典猜了 1/2 两个值写CASE WHEN,上线后发现还有 0 和 3。原因:字典只给了类型SMALLINT,没给枚举说明。解决:所有SMALLINT状态字段上线前先跑SELECT 字段, COUNT(*) FROM 表 GROUP BY 字段摸清实际分布,再决定分支;摸不清的走ELSE兜底并打日志。

6. 把字典变成可查询的元数据:一张自建表管住 70 个扩展字段

字典是静态文档,真正干活时我需要的是“给个字段名就能查到它在哪张表、什么类型、能不能空”。我的习惯是把字典里每张表的四列抽出来,落成一张元数据表,后续写同步脚本、做字段映射、排查类型错误都查它,比翻文档快得多。

CREATE TABLE meta_column ( table_name VARCHAR(64) NOT NULL, column_name VARCHAR(64) NOT NULL, data_type VARCHAR(64) NOT NULL, is_required TINYINT NOT NULL DEFAULT 0, remark VARCHAR(255), PRIMARY KEY (table_name, column_name) ); -- 以 ADDRESSBOOK 扩展字段为例批量灌入 INSERT INTO meta_column (table_name, column_name, data_type, is_required, remark) VALUES ('ADDRESSBOOK', 'ID', 'BIGINT', 1, '主键'), ('ADDRESSBOOK', 'MEMBER_ID', 'BIGINT', 0, '人员 id'), ('ADDRESSBOOK', 'EXT_ATTR_1', 'VARCHAR(1024)', 0, '文本类型扩展字段 1'), ('ADDRESSBOOK', 'EXT_ATTR_11', 'DECIMAL(19,4)', 0, '数字类型扩展字段 1'), ('ADDRESSBOOK', 'EXT_ATTR_21', 'DATETIME', 0, '日期类型扩展字段 1'), ('ADDRESSBOOK', 'EXT_ATTR_31', 'VARCHAR(50)', 0, '枚举类型数据字段'), ('ADDRESSBOOK', 'EXT_ATTR_41', 'VARCHAR(50)', 0, '选人类型数据字段'), ('ADDRESSBOOK', 'EXT_ATTR_51', 'VARCHAR(50)', 0, '选部门类型数据字段'), ('ADDRESSBOOK', 'EXT_ATTR_61', 'VARCHAR(50)', 0, '选岗位类型数据字段');

灌完之后,几个高频查询就顺手了。查某张表所有必填字段:

SELECT column_name, data_type, remark FROM meta_column WHERE table_name = 'AGENT' AND is_required = 1;

查所有DECIMAL字段,防止金额精度踩坑:

SELECT table_name, column_name, data_type FROM meta_column WHERE data_type LIKE 'DECIMAL%';

参数说明:is_required用TINYINT存布尔,字典里的TRUE/FALSE直接映射 1/0;data_type原样保留字典写法(含长度),方便和information_schema比对。灌数据时我一般写个脚本按字典的表格结构解析,但EXT_ATTR这种规律字段可以按区间批量生成,省得手敲七十行。

这张表还有个进阶用法:拿它和information_schema.columns做全外连接,能直接查出“字典有但库里没有”或“库里有但字典没写”的字段。后者尤其重要——OA 升级后新增字段如果字典没同步,同步脚本会静默丢列。我一般每月跑一次比对,差异超过五个字段就停下来人工确认。

从那以后我每次拿到新版本字典,第一件事不是建表也不是写查询,而是先把四列灌进meta_column,再跑一遍和实际库结构的比对。这个习惯帮我拦下过两次升级后的字段漂移,也让我在写同步脚本时少翻了无数遍 PDF。希望这份拆解能帮到你,少走我走过的弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询