| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- """生成 13 类模板字段 ↔ DMS 模型字段 映射文档。
- 来源分三类:
- 1. DMS来源 —— DMS 模型中有对应字段(模型.字段)
- 2. 源Excel来源(DMS未建模型) —— 源 Excel 中确实存在,但 DMS 没有建模型,
- 需人工从源 Excel 填入模板(标注具体文件+列)
- 3. 新增融合(图谱关联字段) —— DMS 与源 Excel 均无,为图谱建模/关联额外添加
- """
- from __future__ import annotations
- import json
- import re
- import sys
- from pathlib import Path
- sys.stdout.reconfigure(encoding="utf-8")
- OUT = Path(r"E:\CODE\knowledge_agent\output\dms_models_fields.json")
- DOC = Path(r"E:\CODE\knowledge_agent\docs\DMS字段映射.md")
- def norm(s: str) -> str:
- return re.sub(r"[\s()()/*、,,::元万㎡条%]", "", s or "")
- TEMPLATES: dict[str, list[str]] = {
- "项目信息": ["项目编号", "项目名称", "项目简称", "上级项目编号", "续签前项目编号", "项目起止时间",
- "省份", "市(区)", "细分业态", "汇总业态", "委托方式", "计费方式", "合同面积",
- "合同金额", "年化合同额", "合同额具体信息", "服务期限", "合同状况", "首次服务日期",
- "年化合同收入", "客户满意度", "客户投诉", "甲方名称", "项目地址", "项目负责人",
- "项目负责人工号", "实际毛利率", "服务状态", "备注"],
- "项目月度财务": ["项目编号", "项目名称", "年月", "开票金额", "收款金额", "口径说明",
- "财务经办人工号", "财务经办人", "备注"],
- "投标记录": ["项目编号", "项目名称", "年份", "投标类型", "中标结果", "中标日期", "投标金额",
- "文档路径", "投标经办人工号", "投标经办人", "备注"],
- "人员信息": ["姓名", "工号", "组织名称", "岗位名称", "当前服务项目编号", "服务起始年月",
- "服务结束年月", "职级", "员工层级", "所属组织名称", "入职日期", "离职日期", "司龄",
- "性别", "出生日期", "政治面貌", "联系电话", "备注"],
- "考勤与人员财务": ["姓名", "工号", "项目编号", "项目名称", "年月", "1-31日", "上班天数",
- "平时加班小时", "国定加班小时", "餐费补助金额", "加班超时费金额",
- "国定加班费金额", "值班费金额", "税后工资", "备注"],
- "排班明细": ["姓名", "工号", "项目编号", "项目名称", "年月", "1-31日班次", "备注"],
- "岗位编制": ["项目编号", "项目名称", "岗位", "预算编制", "项目编制", "标准工时人数", "在岗人数", "备注"],
- "设备信息": ["项目编号", "项目名称", "设备编号", "设备类型", "名称", "规格型号参数", "制造厂商",
- "安装位置", "出厂日期", "启用日期", "入项目日期", "退项目日期", "出厂编号", "完好状况",
- "原值", "设备责任人工号", "设备责任人", "备注"],
- "采购与维保": ["记录类型", "项目编号", "项目名称", "供应商名称", "供应商编号", "类别",
- "名称/合同名称", "数量", "单位", "单价", "金额", "合同年限", "月份/日期",
- "当前状态", "经办人工号", "经办人", "备注"],
- "检查记录": ["项目编号", "项目名称", "检查类型", "检查日期", "检查得分", "问题描述",
- "整改情况", "整改完成日期", "检查人工号", "检查人", "备注"],
- "片区信息": ["片区编号", "片区名称", "片区负责人工号", "片区负责人", "备注"],
- "项目片区关系": ["项目编号", "项目名称", "片区编号", "片区名称", "备注"],
- "人员证书": ["工号", "姓名", "专业类别", "证书类别", "证书名称", "备注"],
- }
- NOTES: dict[str, str] = {
- "项目信息": "专用模型:sq_project(申勤项目数据) + shenqin_project_annual_stat(年化统计) + sq_project_period(项目期次) + sq_xq(续签表)",
- "人员信息": "专用模型:sq_employee(申勤员工)",
- "投标记录": "专用模型:shenqin_txb(投续标表) + shenqin_zbb(招标表) + sq_tender_intent/notice/result(招标意向/公告/结果)",
- "片区信息": "专用模型:xzbm(行政编码及片区)",
- "项目片区关系": "无专用关联表:可基于 sq_project.管理区域 / xzbm 行政编码 推导",
- "人员证书": "专用模型:sq_personnel_certificate(AMS枢元/人员证书)",
- "考勤与人员财务": "DMS 中未发现考勤专用模型(姓名/工号等为跨模型公共字段)",
- "排班明细": "DMS 中未发现排班专用模型",
- "项目月度财务": "DMS 无月度开票/收款明细(仅年化/合同金额)",
- "岗位编制": "DMS 无编制/在岗模型(sq_project 仅有定岗人数,为预算口径)",
- "设备信息": "DMS 中未发现设备台账模型",
- "检查记录": "DMS 中未发现品质/安全检查模型",
- "采购与维保": "DMS 中未发现采购/维保模型",
- }
- # 有专用 DMS 模型的模板(其余模板按"源Excel来源"处理)
- MODELED = {"项目信息", "人员信息", "投标记录", "片区信息", "人员证书"}
- # 字段的源 Excel 说明(DMS 未建模型时)
- DEFAULT_SOURCES: dict[str, str] = {
- "项目信息": "市场部项目管理表 + 业务大表(表1)",
- "项目月度财务": "财务部收费进程表(1-12月物业费/期内开票收款)",
- "投标记录": "业务大表表2 中标情况 + 档案目录(中标通知书等)",
- "人员信息": "人事部员工信息.xlsx(花名册)",
- "考勤与人员财务": "人事部考勤表(如 青浦-赵巷公园-员工岗位考勤表.xls)",
- "排班明细": "人事部排班文件(每日班次代码)",
- "岗位编制": "运营部 9-项目岗位编制汇总.xlsx",
- "设备信息": "运营部设备台账(青浦工业园区/徐汇环境监测中心)",
- "采购与维保": "采购部 耗材汇总/维保合同台账/固定资产台账",
- "检查记录": "运营部品质巡检及整改记录台账",
- "片区信息": "业务大表「管理区域」/ 8-项目信息汇总表",
- "项目片区关系": "业务大表「管理区域」推导(M:N)",
- "人员证书": "合景悠活职称及资格证书管理登记表",
- }
- # 源 Excel 字段级说明(DMS 未建模型时,标注到具体文件+列)
- SOURCE_EXCEL_NOTES: dict[tuple[str, str], str] = {
- ("考勤与人员财务", "工号"): "人事部考勤表「员工编码」列(13 份考勤 xls/xlsx)",
- ("考勤与人员财务", "年月"): "考勤表工作表名/表头(如 青浦-赵巷公园-员工岗位考勤表2026年1月-4月员工岗位考勤表.xls →「2026年×月」)",
- ("考勤与人员财务", "1-31日"): "考勤表 1~31 日列,班次标记(常/日/夜/日1 等)",
- ("考勤与人员财务", "上班天数"): "考勤表「上班天数」列",
- ("考勤与人员财务", "平时加班小时"): "考勤表「平时加班小时」列",
- ("考勤与人员财务", "国定加班小时"): "考勤表「国定加班小时」列",
- ("考勤与人员财务", "餐费补助金额"): "考勤表「餐费补助金额」列",
- ("考勤与人员财务", "加班超时费金额"): "考勤表「加班超时费金额」列",
- ("考勤与人员财务", "国定加班费金额"): "考勤表「国定加班费金额」列",
- ("考勤与人员财务", "值班费金额"): "考勤表「值班费金额」列",
- ("考勤与人员财务", "税后工资"): "考勤表末尾金额列(表头为「员工签字」,实际填月度税后工资,如 4896.25)",
- ("考勤与人员财务", "备注"): "考勤表「备注」列",
- ("排班明细", "工号"): "人事部排班 xlsx「工号(Employee ID)」列",
- ("排班明细", "年月"): "排班 xlsx 日期列(2026-01-01 … 2026-01-31),如 排班:青浦-赵巷公园、赵巷文体中心、赵巷镇政府、赵巷品牌公司系统排班(2026年1-4月).xlsx",
- ("排班明细", "1-31日班次"): "排班 xlsx 1~31 日「班次代码(Shift Code)」列(OFF/A003/SQ-104/M11-033 等)",
- ("岗位编制", "岗位"): "运营部 9-项目岗位编制汇总.xlsx",
- ("设备信息", "设备编号"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "设备类型"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "规格型号参数"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "制造厂商"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "安装位置"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "出厂日期"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "启用日期"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "出厂编号"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "完好状况"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("设备信息", "原值"): "运营部设备台账(如 青浦工业园区/徐汇环境监测中心)",
- ("检查记录", "检查类型"): "运营部品质巡检及整改记录台账",
- ("检查记录", "检查日期"): "运营部品质巡检及整改记录台账",
- ("检查记录", "检查得分"): "运营部品质巡检及整改记录台账",
- ("检查记录", "问题描述"): "运营部品质巡检及整改记录台账",
- ("检查记录", "整改情况"): "运营部品质巡检及整改记录台账",
- ("检查记录", "整改完成日期"): "运营部品质巡检及整改记录台账",
- ("项目月度财务", "年月"): "财务部收费进程表(1-12月物业费/期内开票收款)",
- ("项目月度财务", "开票金额"): "财务部收费进程表(1-12月物业费/期内开票收款)",
- ("项目月度财务", "收款金额"): "财务部收费进程表(1-12月物业费/期内开票收款)",
- ("项目信息", "客户满意度"): "运营部\\03 客户满意度及投诉记录\\客户满意度\\申勤物业服务满意度评价问卷报告(2025年度).docx → 满意度得分(聚合为项目属性)",
- ("项目信息", "客户投诉"): "运营部\\03 客户满意度及投诉记录\\客户投诉\\SHSQ-JGJL-02-0301客户投诉受理单.doc 等 → 投诉条数",
- }
- # 真正新增融合的字段(DMS 与源 Excel 均无,为图谱建模/关联添加)
- FUSION_FIELDS: dict[str, set[str]] = {
- "项目信息": {"项目负责人工号", "服务状态", "续签前项目编号"},
- "项目月度财务": {"项目名称", "口径说明", "财务经办人工号", "财务经办人"},
- "投标记录": {"项目名称", "投标类型", "投标经办人工号", "投标经办人", "中标日期", "文档路径"},
- "人员信息": {"当前服务项目编号", "服务起始年月", "服务结束年月", "离职日期"},
- "考勤与人员财务": {"项目名称"},
- "排班明细": {"项目名称", "备注"},
- "岗位编制": {"项目名称"},
- "设备信息": {"项目名称", "入项目日期", "退项目日期", "设备责任人工号", "设备责任人"},
- "采购与维保": {"记录类型", "项目名称", "供应商编号", "经办人工号", "经办人"},
- "检查记录": {"项目名称", "检查人工号", "检查人"},
- "片区信息": {"片区编号", "片区负责人工号", "片区负责人"},
- "项目片区关系": {"项目名称", "片区名称"},
- "人员证书": {"姓名", "备注"},
- }
- # 不参与 DMS 别名匹配的字段(避免被误匹配到跨模型公共字段,如 sq_employee.c_bz)
- EXCLUDE_DMS: set[tuple[str, str]] = {
- ("考勤与人员财务", "备注"),
- ("排班明细", "备注"),
- }
- # 语义映射覆盖:模板字段 -> (模型, DMS字段)
- OVERRIDES: dict[tuple[str, str], tuple[str, str]] = {
- ("人员信息", "工号"): ("sq_employee", "c_ygbm 员工编码"),
- ("人员信息", "姓名"): ("sq_employee", "c_xm 姓名"),
- ("人员信息", "岗位名称"): ("sq_employee", "c_gwmc 岗位名称"),
- ("人员信息", "员工层级"): ("sq_employee", "c_ygcj 员工层级"),
- ("人员信息", "职级"): ("sq_employee", "c_zj 职级"),
- ("人员信息", "所属组织名称"): ("sq_employee", "c_sszzmc 所属组织名称"),
- ("人员信息", "入职日期"): ("sq_employee", "c_rzrq 入职日期"),
- ("人员信息", "司龄"): ("sq_employee", "c_sl 司龄"),
- ("人员信息", "性别"): ("sq_employee", "c_xb 性别"),
- ("人员信息", "出生日期"): ("sq_employee", "c_csrq 出生日期"),
- ("人员信息", "政治面貌"): ("sq_employee", "c_zzmm 政治面貌"),
- ("人员信息", "联系电话"): ("sq_employee", "c_sjhm 手机号码"),
- ("人员信息", "当前服务项目编号"): ("sq_employee", "c_xmmc 项目名称(五级公司)"),
- ("项目信息", "项目编号"): ("sq_project", "c_jdbm 金蝶编码"),
- ("项目信息", "项目名称"): ("sq_project", "c_xmmc 项目名称"),
- ("项目信息", "上级项目编号"): ("sq_project", "c_father_code 父项目编码"),
- ("项目信息", "省份"): ("sq_project", "c_sfzxs 省份(直辖市)"),
- ("项目信息", "市(区)"): ("sq_project", "c_sq 市(区)"),
- ("项目信息", "管理区域"): ("sq_project", "c_glqynbkj 管理区域(内部口径)"),
- ("项目信息", "细分业态"): ("sq_project", "c_xfyt 细分业态"),
- ("项目信息", "汇总业态"): ("sq_project", "c_hzyt 汇总业态"),
- ("项目信息", "委托方式"): ("sq_project", "c_wtfs 委托方式"),
- ("项目信息", "计费方式"): ("sq_project", "c_jffs 计费方式"),
- ("项目信息", "合同面积"): ("sq_project", "c_htmj 合同面积(平方米)"),
- ("项目信息", "合同金额"): ("shenqin_project_annual_stat", "c_contract_amount 合同金额"),
- ("项目信息", "年化合同额"): ("shenqin_project_annual_stat", "c_annualized_amount 年化合同额"),
- ("项目信息", "合同额具体信息"): ("shenqin_project_annual_stat", "c_current_period_amount/预估/存量/新增"),
- ("项目信息", "服务期限"): ("shenqin_project_annual_stat", "c_service_period 服务期限"),
- ("项目信息", "合同状况"): ("shenqin_project_annual_stat", "c_contract_status_online/offline"),
- ("项目信息", "首次服务日期"): ("sq_project", "c_scfwrq 首次服务日期"),
- ("项目信息", "年化合同收入"): ("sq_project", "c_nhhtsr 年化合同收入"),
- ("项目信息", "甲方名称"): ("shenqin_project_annual_stat", "c_client_name 甲方名称"),
- ("项目信息", "项目地址"): ("shenqin_project_annual_stat", "c_project_address 项目地址"),
- ("项目信息", "项目负责人"): ("sq_project", "c_xmdzfzr 项目点状负责人"),
- ("项目信息", "实际毛利率"): ("sq_project", "c_xmdnsjmll 项目当年实际毛利率"),
- ("项目信息", "项目起止时间"): ("sq_project_period", "c_c_date_range_text 日期区间"),
- ("项目信息", "项目简称"): ("shenqin_project_annual_stat", "c_project_short_name 项目简称"),
- ("投标记录", "项目编号"): ("shenqin_txb", "c_jdbm 金蝶编码"),
- ("投标记录", "投标金额"): ("shenqin_txb", "tbbj 投标报价"),
- ("投标记录", "中标结果"): ("sq_tender_result", "c_winning_suppliers 中标供应商名称"),
- ("投标记录", "年份"): ("sq_tender_notice", "c_publish_time 发布时间"),
- ("片区信息", "片区编号"): ("xzbm", "c_part_code 片区编码"),
- ("片区信息", "片区名称"): ("xzbm", "c_part_name 片区名称"),
- ("人员证书", "工号"): ("sq_personnel_certificate", "c_c_person_id 人员ID"),
- ("人员证书", "证书类别"): ("sq_personnel_certificate", "c_c_cert_type 证书类型"),
- }
- def load_dms() -> dict[str, dict[str, str]]:
- data = json.loads(OUT.read_text(encoding="utf-8"))
- aliases: dict[str, str] = {}
- for model, info in data.items():
- for fname, alias in info.get("fields", []):
- key = norm(alias)
- if key:
- aliases.setdefault(key, f"{model}.{fname}({alias})")
- return aliases
- def main() -> None:
- aliases = load_dms()
- lines = ["# DMS 数据库字段映射(13 类模板)", "",
- "> 依据 DMS 模型元数据生成(模型:申勤物业数字化 / AMS枢元 相关)。"
- "来源分三类:① DMS来源 = 模型.字段(别名);② 源Excel来源(DMS未建模型)"
- "= 源 Excel 中确有、但 DMS 无对应模型,需人工从源 Excel 填入;"
- "③ 新增融合 = DMS 与源 Excel 均无,为图谱建模/关联额外添加。", ""]
- summary = []
- for tpl, fields in TEMPLATES.items():
- lines.append(f"## {tpl}")
- lines.append(f"**说明**:{NOTES.get(tpl, '')}")
- lines.append("| 模板字段 | 来源(DMS 模型.字段 / 源Excel文件+列) | 类型 |")
- lines.append("|---|---|---|")
- found = 0
- for f in fields:
- ov = OVERRIDES.get((tpl, f))
- src = ""
- note = ""
- if ov:
- src = f"{ov[0]}.{ov[1]}"
- found += 1
- else:
- if (tpl, f) not in EXCLUDE_DMS:
- for alias, desc in aliases.items():
- if norm(f) == alias or (len(norm(f)) >= 2 and norm(f) in alias):
- src = desc
- found += 1
- break
- if src:
- kind = "DMS来源"
- elif f in FUSION_FIELDS.get(tpl, set()):
- kind = "新增融合(图谱关联字段)"
- note = "DMS 与源 Excel 均无,图谱建模/关联用"
- else:
- kind = "源Excel来源(DMS未建模型)"
- note = SOURCE_EXCEL_NOTES.get((tpl, f)) or DEFAULT_SOURCES.get(tpl, "")
- if src:
- display = src
- elif kind.startswith("源Excel"):
- display = f"源Excel:{note}" if note else "—"
- else:
- display = note or "—"
- lines.append(f"| {f} | {display} | {kind} |")
- summary.append((tpl, len(fields), found))
- lines.append("")
- lines.insert(3, "## 覆盖概览")
- lines.insert(4, "| 模板 | 字段数 | 有DMS来源 |")
- lines.insert(5, "|---|---|---|")
- for t, n, f in summary:
- lines.insert(6, f"| {t} | {n} | {f} |")
- DOC.write_text("\n".join(lines), encoding="utf-8")
- import csv
- csv_path = Path(r"E:\CODE\knowledge_agent\output\dms_template_mapping.csv")
- with csv_path.open("w", newline="", encoding="utf-8-sig") as f:
- w = csv.writer(f)
- w.writerow(["模板", "模板字段", "DMS来源(模型.字段)", "类型", "说明"])
- for tpl, fields in TEMPLATES.items():
- for fld in fields:
- ov = OVERRIDES.get((tpl, fld))
- src = ""
- if ov:
- src = f"{ov[0]}.{ov[1]}"
- else:
- if (tpl, fld) not in EXCLUDE_DMS:
- for alias, desc in aliases.items():
- if norm(fld) == alias or (len(norm(fld)) >= 2 and norm(fld) in alias):
- src = desc
- break
- if src:
- kind = "DMS来源"
- note = NOTES.get(tpl, "")
- elif fld in FUSION_FIELDS.get(tpl, set()):
- kind = "新增融合"
- note = "图谱建模/关联字段"
- else:
- kind = "源Excel来源(DMS未建模型)"
- note = SOURCE_EXCEL_NOTES.get((tpl, fld)) or DEFAULT_SOURCES.get(tpl, "")
- w.writerow([tpl, fld, src, kind, note])
- print("覆盖概览:")
- for t, n, f in summary:
- print(f" {t}: {f}/{n}")
- print("文档输出:", DOC)
- print("CSV 输出:", csv_path)
- if __name__ == "__main__":
- main()
|