-- ============================================================================ -- V10:数据字典(《03-接口设计》§13.3) -- -- 为什么内置字典**不进这张表** -- --------------------------------------------------------------------------- -- 契约 §13.3 把字典分成两类,而这个区分是刻意的: -- -- · **内置字典**(`builtin: true`):EDU_LEVEL / JOB_LEVEL / CERT_TYPE / -- RETARGET_SUBJECT / REJECT_REASON 五项。它们的选项**照抄官方表格**, -- 不许擅改(`BuiltinFields` 的类注释里写了这条)。所以它们定义在**代码里** —— -- 和权限码同样的思路:能改的放库里,不能改的放代码里,改它必须走一次发布。 -- 放进表里会带来一个具体风险:有人从界面上把"四级/中级工"改名成"中级", -- 导出的汇总表就与官方模板对不上了,而那时没有任何地方会报错。 -- -- · **可维护的字典**:客户填表时遇到的内置项不够用(例如多了个"技校"学历), -- 由管理员自己加。这类进 `sys_dict_item` —— 它们**允许**被改, -- 因为它们是客户自己的口径,不是官方的。 -- -- OCCUPATION(职业/工种)是第三种情况:它**来自 `sys_occupation_ref`** -- (国标职业库,有自己的层级与别名),既不进代码也不进这张表。 -- 三处来源的取舍都写在 `DictCatalog` 的注释里。 -- ============================================================================ -- 自定义字典项(含对内置字典的"追加") CREATE TABLE IF NOT EXISTS sys_dict_item ( id BIGSERIAL PRIMARY KEY, tenant_id BIGINT NOT NULL, -- 字典码,如 EDU_LEVEL / JOB_LEVEL / CERT_TYPE dict_code VARCHAR(64) NOT NULL, item_code VARCHAR(64) NOT NULL, item_name VARCHAR(128) NOT NULL, -- 层级(如职业-工种):指向同字典内另一个 item_code parent_item_code VARCHAR(64), sort_no INTEGER NOT NULL DEFAULT 0, -- 0 停用 / 1 启用 status SMALLINT NOT NULL DEFAULT 1, -- true = 这个项是对**内置字典**的追加(内置项本身仍在代码里) builtin_extend SMALLINT NOT NULL DEFAULT 0, create_by BIGINT, create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, update_by BIGINT, update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, deleted SMALLINT NOT NULL DEFAULT 0 ); COMMENT ON TABLE sys_dict_item IS '自定义字典项(内置字典的选项在代码里,见 DictCatalog;OCCUPATION 来自 sys_occupation_ref)'; COMMENT ON COLUMN sys_dict_item.dict_code IS '字典码:EDU_LEVEL/JOB_LEVEL/CERT_TYPE/RETARGET_SUBJECT/REJECT_REASON/OCCUPATION + 客户自定义'; COMMENT ON COLUMN sys_dict_item.item_code IS '项码。⚠️ **不许改**(改了会破坏历史数据里已经存下的值)'; COMMENT ON COLUMN sys_dict_item.parent_item_code IS '层级父项(如职业-工种);空表示顶层'; COMMENT ON COLUMN sys_dict_item.builtin_extend IS '1 = 对内置字典的追加项(内置项本身不出来在这里)'; -- 同一个字典里项码唯一(软删的不算)—— 手工建一条部分唯一索引: -- 普通 UNIQUE 会把软删的行也算进去,于是"删过再想加回来"会失败, -- 而用户看到的是"这个编码已存在",但他明明刚删掉它 CREATE UNIQUE INDEX IF NOT EXISTS uk_dict_item_code ON sys_dict_item (tenant_id, dict_code, item_code) WHERE deleted = 0; CREATE INDEX IF NOT EXISTS idx_dict_item_code ON sys_dict_item (tenant_id, dict_code, status, sort_no); -- 内置字典的"停用单项"(契约 §13.3:内置字典不可删,只可停用单项)。 -- ⚠️ 不复用 sys_dict_item.status:那张表是"客户自己加的项", -- 而这里是"官方项被客户停用了"。混在一起之后, -- "恢复默认"就没法做了(分不清哪些是官方项、哪些是客户加的)。 CREATE TABLE IF NOT EXISTS sys_dict_disabled ( id BIGSERIAL PRIMARY KEY, tenant_id BIGINT NOT NULL, dict_code VARCHAR(64) NOT NULL, item_code VARCHAR(64) NOT NULL, create_by BIGINT, create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE sys_dict_disabled IS '被停用的**内置**字典项(契约 §13.3:内置字典不可删、只可停用单项)'; CREATE UNIQUE INDEX IF NOT EXISTS uk_dict_disabled ON sys_dict_disabled (tenant_id, dict_code, item_code);