From 334bd8742ea915e487cc9ce7c666490a5c6b985b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cwuzhen=E2=80=9D?= Date: Mon, 24 Aug 2026 09:59:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E8=BA=AB=E4=BB=BD=E8=AE=A4=E8=AF=81=E7=94=A8=E6=88=B7=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AE=9A=E6=97=B6=E5=90=8C=E6=AD=A5=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将校园系统部门、教职工、学生数据同步到认证中间库6张标准表,支持 MySQL 本地测试与 Oracle 生产目标库配置。 Co-authored-by: Cursor --- .../3.在认证中间库建立表.sql | 313 ++++++++++++++++++ 用户信息同步统一身份认证/README.md | 68 ++++ 用户信息同步统一身份认证/create_tables.sh | 31 ++ 用户信息同步统一身份认证/data.conf | 41 +++ 用户信息同步统一身份认证/data.conf.prod | 38 +++ 用户信息同步统一身份认证/db_helper.py | 85 +++++ .../sync_oracle/merge_all.sql | 17 + .../sync_sql/sync_all_mysql.sql | 146 ++++++++ 用户信息同步统一身份认证/sync_user_to_sso.sh | 283 ++++++++++++++++ 用户信息同步统一身份认证/verify_sync.sh | 81 +++++ 用户信息同步统一身份认证/字段映射说明.md | 110 ++++++ 用户信息同步统一身份认证/建表脚本_mysql.sql | 179 ++++++++++ 12 files changed, 1392 insertions(+) create mode 100644 用户信息同步统一身份认证/3.在认证中间库建立表.sql create mode 100644 用户信息同步统一身份认证/README.md create mode 100755 用户信息同步统一身份认证/create_tables.sh create mode 100644 用户信息同步统一身份认证/data.conf create mode 100644 用户信息同步统一身份认证/data.conf.prod create mode 100755 用户信息同步统一身份认证/db_helper.py create mode 100644 用户信息同步统一身份认证/sync_oracle/merge_all.sql create mode 100644 用户信息同步统一身份认证/sync_sql/sync_all_mysql.sql create mode 100755 用户信息同步统一身份认证/sync_user_to_sso.sh create mode 100755 用户信息同步统一身份认证/verify_sync.sh create mode 100644 用户信息同步统一身份认证/字段映射说明.md create mode 100644 用户信息同步统一身份认证/建表脚本_mysql.sql diff --git a/用户信息同步统一身份认证/3.在认证中间库建立表.sql b/用户信息同步统一身份认证/3.在认证中间库建立表.sql new file mode 100644 index 00000000..412e79f8 --- /dev/null +++ b/用户信息同步统一身份认证/3.在认证中间库建立表.sql @@ -0,0 +1,313 @@ +-- Create table +create table GXXX_YXSDWJBSJZL +( + dwh VARCHAR2(10) not null, + dwmc VARCHAR2(60), + dwywmc VARCHAR2(180), + dwjc VARCHAR2(12), + dwywjc VARCHAR2(8), + dwjp VARCHAR2(6), + dwdz VARCHAR2(180), + lsdwh VARCHAR2(10), + dwlbm VARCHAR2(1), + dwbbm VARCHAR2(1), + dwyxbs VARCHAR2(1), + sxrq VARCHAR2(8), + sfst VARCHAR2(1), + jlny VARCHAR2(6), + dwfzrh VARCHAR2(20), + zhgxsj VARCHAR2(20) default to_char(sysdate,'yyyymmddhh24miss'), + scbz VARCHAR2(1), + dwjb VARCHAR2(8) +); + +-- Add comments to the table +comment on table GXXX_YXSDWJBSJZL is 'GXXX0301院系所单位基本数据子类'; +-- Add comments to the columns +comment on column GXXX_YXSDWJBSJZL.dwh is '单位号'; +comment on column GXXX_YXSDWJBSJZL.dwmc is '单位名称'; +comment on column GXXX_YXSDWJBSJZL.dwywmc is '单位英文名称'; +comment on column GXXX_YXSDWJBSJZL.dwjc is '单位简称'; +comment on column GXXX_YXSDWJBSJZL.dwywjc is '单位英文简称'; +comment on column GXXX_YXSDWJBSJZL.dwjp is '单位简拼'; +comment on column GXXX_YXSDWJBSJZL.dwdz is '单位地址'; +comment on column GXXX_YXSDWJBSJZL.lsdwh is '隶属单位号'; +comment on column GXXX_YXSDWJBSJZL.dwlbm is '单位类别码'; +comment on column GXXX_YXSDWJBSJZL.dwbbm is '单位办别码'; +comment on column GXXX_YXSDWJBSJZL.dwyxbs is '单位有效标识'; +comment on column GXXX_YXSDWJBSJZL.sxrq is '失效日期'; +comment on column GXXX_YXSDWJBSJZL.sfst is '是否实体'; +comment on column GXXX_YXSDWJBSJZL.jlny is '建立年月'; +comment on column GXXX_YXSDWJBSJZL.dwfzrh is '单位负责人号'; +comment on column GXXX_YXSDWJBSJZL.zhgxsj is '最后更新时间'; +comment on column GXXX_YXSDWJBSJZL.scbz is '删除标志:y/n'; +comment on column GXXX_YXSDWJBSJZL.dwjb is '单位级别'; +-- Create/Recreate primary, unique and foreign key constraints +alter table GXXX_YXSDWJBSJZL add primary key (DWH); +/ + +-- Create table +create table GXJG_JZGJCSJZLB +( + gh VARCHAR2(20) not null, + dwh VARCHAR2(10) not null, + xm VARCHAR2(36), + ywxm VARCHAR2(60), + xmpy VARCHAR2(60), + cym VARCHAR2(36), + xbm VARCHAR2(1), + csrq VARCHAR2(8), + csdm VARCHAR2(6), + jg VARCHAR2(20), + mzm VARCHAR2(2), + gjdqm VARCHAR2(3), + sfzjlxm VARCHAR2(1), + sfzjh VARCHAR2(20), + hyztm VARCHAR2(2), + gatqwm VARCHAR2(2), + zzmmm VARCHAR2(2), + jkzkm VARCHAR2(2), + xyzjm VARCHAR2(2), + xxm VARCHAR2(1), + zp BLOB, + sfzjyxq VARCHAR2(17), + xqh VARCHAR2(2), + zgxlm VARCHAR2(3), + whcdm VARCHAR2(3), + cjgzny VARCHAR2(6), + lxrq VARCHAR2(8), + qxrq VARCHAR2(8), + cjny VARCHAR2(6), + bzlbm VARCHAR2(2), + jzglbm VARCHAR2(3), + rkzkm VARCHAR2(2), + dabh VARCHAR2(20), + dawb CLOB, + dqztm VARCHAR2(2), + tc VARCHAR2(100), + xklbm VARCHAR2(6), + yjxkm VARCHAR2(4), + ejxkm VARCHAR2(6), + yjfx VARCHAR2(100), + zhgxsj VARCHAR2(20) default to_char(sysdate,'yyyymmddhh24miss'), + scbz VARCHAR2(1), + zhxw VARCHAR2(32), + zc VARCHAR2(32), + ygxs VARCHAR2(2) +); + +-- Add comments to the table +comment on table GXJG_JZGJCSJZLB is 'GXJG0101教职工基础数据子类表'; +-- Add comments to the columns +comment on column GXJG_JZGJCSJZLB.gh is '工号'; +comment on column GXJG_JZGJCSJZLB.dwh is '单位号'; +comment on column GXJG_JZGJCSJZLB.xm is '姓名'; +comment on column GXJG_JZGJCSJZLB.ywxm is '英文姓名'; +comment on column GXJG_JZGJCSJZLB.xmpy is '姓名拼音'; +comment on column GXJG_JZGJCSJZLB.cym is '曾用名'; +comment on column GXJG_JZGJCSJZLB.xbm is '性别码'; +comment on column GXJG_JZGJCSJZLB.csrq is '出生日期'; +comment on column GXJG_JZGJCSJZLB.csdm is '出生地码'; +comment on column GXJG_JZGJCSJZLB.jg is '籍贯'; +comment on column GXJG_JZGJCSJZLB.mzm is '民族码'; +comment on column GXJG_JZGJCSJZLB.gjdqm is '国籍/地区码'; +comment on column GXJG_JZGJCSJZLB.sfzjlxm is '身份证件类型码'; +comment on column GXJG_JZGJCSJZLB.sfzjh is '身份证件号'; +comment on column GXJG_JZGJCSJZLB.hyztm is '婚姻状况码'; +comment on column GXJG_JZGJCSJZLB.gatqwm is '港澳台侨外码'; +comment on column GXJG_JZGJCSJZLB.zzmmm is '政治面貌码'; +comment on column GXJG_JZGJCSJZLB.jkzkm is '健康状况码[DM_GB_B_JKZKEWSZDM]'; +comment on column GXJG_JZGJCSJZLB.xyzjm is '信仰宗教码'; +comment on column GXJG_JZGJCSJZLB.xxm is '血型码'; +comment on column GXJG_JZGJCSJZLB.zp is '照片'; +comment on column GXJG_JZGJCSJZLB.sfzjyxq is '身份证件有效期'; +comment on column GXJG_JZGJCSJZLB.xqh is '校区号'; +comment on column GXJG_JZGJCSJZLB.zgxlm is '最高学历码'; +comment on column GXJG_JZGJCSJZLB.whcdm is '文化程度码'; +comment on column GXJG_JZGJCSJZLB.cjgzny is '参加工作年月'; +comment on column GXJG_JZGJCSJZLB.lxrq is '来校日期'; +comment on column GXJG_JZGJCSJZLB.qxrq is '起薪日期'; +comment on column GXJG_JZGJCSJZLB.cjny is '从教年月'; +comment on column GXJG_JZGJCSJZLB.bzlbm is '编制类别码'; +comment on column GXJG_JZGJCSJZLB.jzglbm is '教职工类别码'; +comment on column GXJG_JZGJCSJZLB.rkzkm is '任课状况码'; +comment on column GXJG_JZGJCSJZLB.dabh is '档案编号'; +comment on column GXJG_JZGJCSJZLB.dawb is '档案文本'; +comment on column GXJG_JZGJCSJZLB.dqztm is '当前状态码'; +comment on column GXJG_JZGJCSJZLB.tc is '特长'; +comment on column GXJG_JZGJCSJZLB.xklbm is '学科类别码'; +comment on column GXJG_JZGJCSJZLB.yjxkm is '一级学科码'; +comment on column GXJG_JZGJCSJZLB.ejxkm is '二级学科码'; +comment on column GXJG_JZGJCSJZLB.yjfx is '研究方向'; +comment on column GXJG_JZGJCSJZLB.zhgxsj is '最后更新时间'; +comment on column GXJG_JZGJCSJZLB.scbz is '删除标志:y/n'; +comment on column GXJG_JZGJCSJZLB.zhxw is '最后学位'; +comment on column GXJG_JZGJCSJZLB.zc is '职称'; +comment on column GXJG_JZGJCSJZLB.ygxs is '用工形式'; +-- Create/Recreate primary, unique and foreign key constraints +alter table GXJG_JZGJCSJZLB add primary key (GH); +/ + +-- Create table +create table GXXS_XSJBSJZL +( + xh VARCHAR2(20) not null, + xm VARCHAR2(60), + ywxm VARCHAR2(60), + xmpy VARCHAR2(60), + cym VARCHAR2(60), + xbm VARCHAR2(1), + csrq VARCHAR2(10), + csdm VARCHAR2(200), + jg VARCHAR2(60), + mzm VARCHAR2(2), + gjdqm VARCHAR2(50), + sfzjlxm VARCHAR2(2), + sfzjh VARCHAR2(20), + hyzkm VARCHAR2(10), + gatqwm VARCHAR2(2), + zzmmm VARCHAR2(2), + jkzkm VARCHAR2(20), + xyzjm VARCHAR2(50), + xxm VARCHAR2(30), + sfzjyxq VARCHAR2(17), + sfdszn VARCHAR2(1), + zp BLOB, + zhgxsj VARCHAR2(20) default to_char(sysdate,'yyyymmddhh24miss'), + scbz VARCHAR2(1), + ksh VARCHAR2(20), + dwh VARCHAR2(20) not null, + szbh VARCHAR2(20), + sfzx VARCHAR2(10), + sfyby VARCHAR2(6) +); + +-- Add comments to the table +comment on table GXXS_XSJBSJZL is 'GXXS0101学生基本数据子类'; +-- Add comments to the columns +comment on column GXXS_XSJBSJZL.xh is '学号'; +comment on column GXXS_XSJBSJZL.xm is '姓名'; +comment on column GXXS_XSJBSJZL.ywxm is '英文姓名'; +comment on column GXXS_XSJBSJZL.xmpy is '姓名拼音'; +comment on column GXXS_XSJBSJZL.cym is '曾用名'; +comment on column GXXS_XSJBSJZL.xbm is '性别码'; +comment on column GXXS_XSJBSJZL.csrq is '出生日期'; +comment on column GXXS_XSJBSJZL.csdm is '出生地码'; +comment on column GXXS_XSJBSJZL.jg is '籍贯'; +comment on column GXXS_XSJBSJZL.mzm is '民族码'; +comment on column GXXS_XSJBSJZL.gjdqm is '国籍/地区码'; +comment on column GXXS_XSJBSJZL.sfzjlxm is '身份证件类型码'; +comment on column GXXS_XSJBSJZL.sfzjh is '身份证件号'; +comment on column GXXS_XSJBSJZL.hyzkm is '婚姻状况码'; +comment on column GXXS_XSJBSJZL.gatqwm is '港澳台侨外码'; +comment on column GXXS_XSJBSJZL.zzmmm is '政治面貌码'; +comment on column GXXS_XSJBSJZL.jkzkm is '健康状况码'; +comment on column GXXS_XSJBSJZL.xyzjm is '信仰宗教码'; +comment on column GXXS_XSJBSJZL.xxm is '血型码'; +comment on column GXXS_XSJBSJZL.sfzjyxq is '身份证件有效期'; +comment on column GXXS_XSJBSJZL.sfdszn is '是否独生子女'; +comment on column GXXS_XSJBSJZL.zp is '照片'; +comment on column GXXS_XSJBSJZL.zhgxsj is '最后更新时间'; +comment on column GXXS_XSJBSJZL.scbz is '删除标志:y/n'; +comment on column GXXS_XSJBSJZL.ksh is '考生号'; +comment on column GXXS_XSJBSJZL.dwh is 'null'; +comment on column GXXS_XSJBSJZL.szbh is '所在班号'; +comment on column GXXS_XSJBSJZL.sfzx is '是否在校'; +comment on column GXXS_XSJBSJZL.sfyby is '是否已毕业'; +-- Create/Recreate primary, unique and foreign key constraints +alter table GXXS_XSJBSJZL add primary key (XH); +/ + +-- Create table +create table GXXS_GRTXZL +( + yzbm VARCHAR2(6), + txdz VARCHAR2(180), + dh VARCHAR2(50), + yddh VARCHAR2(30), + czdh VARCHAR2(30), + dzxx VARCHAR2(40), + wldz VARCHAR2(60), + jstxh VARCHAR2(40), + xh VARCHAR2(20) not null, + zhgxsj VARCHAR2(20) default to_char(sysdate,'yyyymmddhh24miss'), + scbz VARCHAR2(1) +); + +-- Add comments to the table +comment on table GXXS_GRTXZL is 'GXXS0109学生个人通讯子类'; +-- Add comments to the columns +comment on column GXXS_GRTXZL.yzbm is '邮政编码'; +comment on column GXXS_GRTXZL.txdz is '通信地址'; +comment on column GXXS_GRTXZL.dh is '电话'; +comment on column GXXS_GRTXZL.yddh is '移动电话'; +comment on column GXXS_GRTXZL.czdh is '传真电话'; +comment on column GXXS_GRTXZL.dzxx is '电子信箱'; +comment on column GXXS_GRTXZL.wldz is '网络地址'; +comment on column GXXS_GRTXZL.jstxh is '即时通讯号'; +comment on column GXXS_GRTXZL.xh is '学号'; +comment on column GXXS_GRTXZL.zhgxsj is '最后更新时间'; +comment on column GXXS_GRTXZL.scbz is '删除标志:y/n'; +-- Create/Recreate primary, unique and foreign key constraints +alter table GXXS_GRTXZL add primary key (XH); +/ + +-- Create table +create table GXJG_GRTXFSZL +( + yzbm VARCHAR2(6), + txdz VARCHAR2(180), + dh VARCHAR2(30), + yddh VARCHAR2(30), + czdh VARCHAR2(30), + wldz VARCHAR2(60), + jstxh VARCHAR2(40), + gh VARCHAR2(20) not null, + dzxx VARCHAR2(40), + zhgxsj VARCHAR2(20) default to_char(sysdate,'yyyymmddhh24miss'), + scbz VARCHAR2(1), + id VARCHAR2(48) not null +); + +-- Add comments to the table +comment on table GXJG_GRTXFSZL is 'GXJG0102教职工个人通讯方式子类'; +-- Add comments to the columns +comment on column GXJG_GRTXFSZL.yzbm is '邮政编码'; +comment on column GXJG_GRTXFSZL.txdz is '通信地址'; +comment on column GXJG_GRTXFSZL.dh is '电话'; +comment on column GXJG_GRTXFSZL.yddh is '移动电话'; +comment on column GXJG_GRTXFSZL.czdh is '传真电话'; +comment on column GXJG_GRTXFSZL.wldz is '网络地址'; +comment on column GXJG_GRTXFSZL.jstxh is '即时通讯号'; +comment on column GXJG_GRTXFSZL.gh is '工号'; +comment on column GXJG_GRTXFSZL.dzxx is '电子信箱'; +comment on column GXJG_GRTXFSZL.zhgxsj is '最后更新时间'; +comment on column GXJG_GRTXFSZL.scbz is '删除标志:y/n'; +-- Create/Recreate primary, unique and foreign key constraints +alter table GXJG_GRTXFSZL add primary key (ID); +/ + +-- Create table +create table ZFTAL_XTGL_ERRLOG +( + YWXTMC VARCHAR2(100), + YWXTBM VARCHAR2(100), + YWXTCZ VARCHAR2(200), + SJCFQ VARCHAR2(100), + SJCCGC VARCHAR2(100), + CWZDXX VARCHAR2(1000), + CWSJ VARCHAR2(20) default to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') +); + +-- Add comments to the table +comment on table ZFTAL_XTGL_ERRLOG is '系统错误日志表'; +-- Add comments to the columns +comment on column ZFTAL_XTGL_ERRLOG.YWXTMC is '业务系统名称(例:认证系统)'; +comment on column ZFTAL_XTGL_ERRLOG.YWXTBM is '业务系统表名(例:ZFTAL_XTGL_YHB)'; +comment on column ZFTAL_XTGL_ERRLOG.YWXTCZ is '业务系统操作(例:修改学生用户联系电话,地址邮箱)'; +comment on column ZFTAL_XTGL_ERRLOG.SJCFQ is '操作涉及触发器(例:pro_gxxs_grtxzl)'; +comment on column ZFTAL_XTGL_ERRLOG.SJCCGC is '操作涉及存储过程(例:pro_gxxs_grtxzl)'; +comment on column ZFTAL_XTGL_ERRLOG.CWZDXX is '显示会导致报错的字段(例如: ZGH:200010)'; +comment on column ZFTAL_XTGL_ERRLOG.CWSJ is '错误时间'; +/ + diff --git a/用户信息同步统一身份认证/README.md b/用户信息同步统一身份认证/README.md new file mode 100644 index 00000000..97cbdd21 --- /dev/null +++ b/用户信息同步统一身份认证/README.md @@ -0,0 +1,68 @@ +# 统一身份认证用户数据同步 + +将校园管理系统用户/组织数据定时同步到认证中间库,供第三方统一身份认证平台拉取。 + +## 目录结构 + +``` +用户信息同步统一身份认证/ +├── 3.在认证中间库建立表.sql # 第三方原始 Oracle 建表脚本(勿修改) +├── 建表脚本_mysql.sql # MySQL 适配建表脚本(本地测试用) +├── data.conf # 研发环境配置 +├── data.conf.prod # 生产环境配置(Oracle 目标库) +├── create_tables.sh # 创建中间表 +├── sync_user_to_sso.sh # 主同步脚本 +├── verify_sync.sh # 同步结果校验 +├── sync_sql/sync_all_mysql.sql # MySQL 同步 SQL +├── sync_oracle/merge_all.sql # Oracle MERGE 模板(生产) +├── 字段映射说明.md +└── logs/ # 运行日志(自动创建) +``` + +## 快速开始(研发环境) + +```bash +cd 用户信息同步统一身份认证 + +# 1. 创建中间表(仅新增6张表,不修改已有表) +chmod +x *.sh +./create_tables.sh + +# 2. 执行一次全量同步 +./sync_user_to_sso.sh --full --once + +# 3. 校验同步结果 +./verify_sync.sh +``` + +## 定时运行 + +```bash +# 守护进程模式,默认每 3600 秒(1小时)同步一次 +./sync_user_to_sso.sh + +# 修改同步频率:编辑 data.conf 中 CYCLE_INTERVAL(秒) +``` + +## 生产部署 + +1. 复制 `data.conf.prod` 为 `data.conf` 或指定 `--config=data.conf.prod` +2. 填写源库(校园系统 MySQL)和目标库(认证中间库 Oracle)连接信息 +3. 目标库使用第三方提供的 `3.在认证中间库建立表.sql` 在 Oracle 中建表 +4. 确保服务器已安装 `sqlplus`(Oracle 客户端) +5. 使用 crontab 或 systemd 定时执行: + +```bash +# crontab 示例:每小时执行一次 +0 * * * * /path/to/用户信息同步统一身份认证/sync_user_to_sso.sh --once >> /path/to/logs/cron.log 2>&1 +``` + +## 配置说明 + +| 配置项 | 说明 | +|--------|------| +| SOURCE_DB_* | 源库(校园管理系统,只读) | +| TARGET_DB_* | 目标库(认证中间库,读写) | +| TARGET_DB_TYPE | `mysql`(测试)或 `oracle`(生产) | +| SYNC_MODE | `full` 全量 / `incremental` 增量 | +| CYCLE_INTERVAL | 循环间隔秒数,默认 3600 | diff --git a/用户信息同步统一身份认证/create_tables.sh b/用户信息同步统一身份认证/create_tables.sh new file mode 100755 index 00000000..cfb7483c --- /dev/null +++ b/用户信息同步统一身份认证/create_tables.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# =========================================== +# 创建统一身份认证中间库表(MySQL 测试环境) +# =========================================== + +set -euo pipefail +export LANG=C +export LC_ALL=C + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/data.conf" + +if [[ ! -f "$CONFIG_FILE" ]]; then + echo "错误:配置文件 $CONFIG_FILE 未找到" + exit 1 +fi + +source "$CONFIG_FILE" + +SQL_FILE="${SCRIPT_DIR}/建表脚本_mysql.sql" +if [[ ! -f "$SQL_FILE" ]]; then + echo "错误:建表脚本 $SQL_FILE 未找到" + exit 1 +fi + +echo "正在目标库创建中间表: ${TARGET_DB_USER}@${TARGET_DB_HOST}:${TARGET_DB_PORT}/${TARGET_DB_NAME}" +python3 "${SCRIPT_DIR}/db_helper.py" \ + --host "$TARGET_DB_HOST" --port "$TARGET_DB_PORT" \ + --user "$TARGET_DB_USER" --password "$TARGET_DB_PASS" --database "$TARGET_DB_NAME" \ + file "$SQL_FILE" +echo "建表完成" diff --git a/用户信息同步统一身份认证/data.conf b/用户信息同步统一身份认证/data.conf new file mode 100644 index 00000000..5e851085 --- /dev/null +++ b/用户信息同步统一身份认证/data.conf @@ -0,0 +1,41 @@ +# =========================================== +# 统一身份认证用户数据同步 - 研发环境配置 +# =========================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# ---------- 源库(校园管理系统,只读) ---------- +SOURCE_DB_TYPE="mysql" +SOURCE_DB_HOST="47.99.164.66" +SOURCE_DB_PORT="3306" +SOURCE_DB_NAME="hzdyjs_xg" +SOURCE_DB_USER="root" +SOURCE_DB_PASS="hn02le.34lkdLKD" + +# ---------- 目标库(认证中间库,读写) ---------- +# 研发环境:与源库同库,仅新增中间表 +TARGET_DB_TYPE="mysql" +TARGET_DB_HOST="47.99.164.66" +TARGET_DB_PORT="3306" +TARGET_DB_NAME="hzdyjs_xg" +TARGET_DB_USER="root" +TARGET_DB_PASS="hn02le.34lkdLKD" + +# ---------- 同步策略 ---------- +# 同步模式:full=全量,incremental=增量(按 update_time) +SYNC_MODE="full" +# 循环间隔(秒),默认 3600 = 1 小时 +CYCLE_INTERVAL=3600 +# 单次批量大小 +BATCH_SIZE=500 +# 失败重试 +MAX_RETRY=3 +RETRY_DELAY=5 + +# ---------- 日志与锁 ---------- +LOG_DIR="${SCRIPT_DIR}/logs" +LOCK_FILE="${SCRIPT_DIR}/sync_user_to_sso.lock" +STATE_FILE="${SCRIPT_DIR}/.sync_state" + +# ---------- 业务系统标识(写入错误日志) ---------- +YWXTMC="校园管理系统" diff --git a/用户信息同步统一身份认证/data.conf.prod b/用户信息同步统一身份认证/data.conf.prod new file mode 100644 index 00000000..9cab590e --- /dev/null +++ b/用户信息同步统一身份认证/data.conf.prod @@ -0,0 +1,38 @@ +# =========================================== +# 统一身份认证用户数据同步 - 生产环境配置 +# =========================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# ---------- 源库(校园管理系统,只读) ---------- +SOURCE_DB_TYPE="mysql" +SOURCE_DB_HOST="127.0.0.1" +SOURCE_DB_PORT="3306" +SOURCE_DB_NAME="hzdyjs_xg" +SOURCE_DB_USER="root" +SOURCE_DB_PASS="请填写生产源库密码" + +# ---------- 目标库(认证中间库 Oracle,读写) ---------- +TARGET_DB_TYPE="oracle" +TARGET_DB_HOST="请填写Oracle主机" +TARGET_DB_PORT="1521" +TARGET_DB_NAME="请填写Oracle服务名或SID" +TARGET_DB_USER="请填写Oracle用户名" +TARGET_DB_PASS="请填写Oracle密码" +# Oracle 连接串示例://host:1521/service_name +TARGET_ORACLE_CONNECT="${TARGET_DB_HOST}:${TARGET_DB_PORT}/${TARGET_DB_NAME}" + +# ---------- 同步策略 ---------- +SYNC_MODE="incremental" +CYCLE_INTERVAL=3600 +BATCH_SIZE=500 +MAX_RETRY=3 +RETRY_DELAY=5 + +# ---------- 日志与锁 ---------- +LOG_DIR="${SCRIPT_DIR}/logs" +LOCK_FILE="${SCRIPT_DIR}/sync_user_to_sso.lock" +STATE_FILE="${SCRIPT_DIR}/.sync_state" + +# ---------- 业务系统标识 ---------- +YWXTMC="校园管理系统" diff --git a/用户信息同步统一身份认证/db_helper.py b/用户信息同步统一身份认证/db_helper.py new file mode 100755 index 00000000..ee10cdd0 --- /dev/null +++ b/用户信息同步统一身份认证/db_helper.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""数据库操作辅助脚本,供 shell 同步脚本调用。""" + +import argparse +import sys +from pathlib import Path + +try: + import pymysql +except ImportError: + print("ERROR: 需要安装 pymysql: pip install pymysql", file=sys.stderr) + sys.exit(1) + + +def connect_mysql(host, port, user, password, database): + return pymysql.connect( + host=host, + port=int(port), + user=user, + password=password, + database=database, + charset="utf8mb4", + autocommit=True, + cursorclass=pymysql.cursors.Cursor, + ) + + +def exec_sql_file(conn, sql_file): + sql = Path(sql_file).read_text(encoding="utf-8") + statements = [s.strip() for s in sql.split(";") if s.strip()] + with conn.cursor() as cur: + for stmt in statements: + if stmt.upper().startswith("SET "): + cur.execute(stmt) + continue + cur.execute(stmt) + + +def exec_sql(conn, sql): + with conn.cursor() as cur: + cur.execute(sql) + if cur.description: + return cur.fetchall() + return None + + +def main(): + parser = argparse.ArgumentParser(description="MySQL 数据库辅助工具") + parser.add_argument("--host", required=True) + parser.add_argument("--port", default="3306") + parser.add_argument("--user", required=True) + parser.add_argument("--password", required=True) + parser.add_argument("--database", required=True) + sub = parser.add_subparsers(dest="action", required=True) + + p_file = sub.add_parser("file", help="执行 SQL 文件") + p_file.add_argument("sql_file") + + p_query = sub.add_parser("query", help="执行单条 SQL 并输出结果") + p_query.add_argument("sql") + + p_scalar = sub.add_parser("scalar", help="执行 SQL 并输出单个值") + p_scalar.add_argument("sql") + + args = parser.parse_args() + conn = connect_mysql(args.host, args.port, args.user, args.password, args.database) + try: + if args.action == "file": + exec_sql_file(conn, args.sql_file) + print("OK") + elif args.action == "query": + rows = exec_sql(conn, args.sql) + for row in rows or []: + print("\t".join("" if v is None else str(v) for v in row)) + elif args.action == "scalar": + rows = exec_sql(conn, args.sql) + if rows: + print(rows[0][0]) + finally: + conn.close() + + +if __name__ == "__main__": + main() diff --git a/用户信息同步统一身份认证/sync_oracle/merge_all.sql b/用户信息同步统一身份认证/sync_oracle/merge_all.sql new file mode 100644 index 00000000..c65131f2 --- /dev/null +++ b/用户信息同步统一身份认证/sync_oracle/merge_all.sql @@ -0,0 +1,17 @@ +-- ========================================== +-- Oracle 目标库 MERGE 同步脚本(生产环境) +-- 由 sync_user_to_sso.sh 通过 sqlplus 调用 +-- 注意:需根据实际导出文件格式调整 +-- ========================================== + +-- 示例:部门 MERGE(生产部署时需配合 sqlldr 或外部表导入) +-- 当前为占位模板,待 Oracle 环境连通后完善 + +WHENEVER SQLERROR EXIT SQL.SQLCODE +SET ECHO OFF +SET FEEDBACK ON +SET VERIFY OFF + +PROMPT Oracle MERGE sync placeholder - 请根据生产环境完善 + +EXIT; diff --git a/用户信息同步统一身份认证/sync_sql/sync_all_mysql.sql b/用户信息同步统一身份认证/sync_sql/sync_all_mysql.sql new file mode 100644 index 00000000..3e4768f6 --- /dev/null +++ b/用户信息同步统一身份认证/sync_sql/sync_all_mysql.sql @@ -0,0 +1,146 @@ +-- ========================================== +-- 统一身份认证中间库 - MySQL 目标库同步 SQL +-- 适用:SOURCE 与 TARGET 均为 MySQL(研发同库测试) +-- 使用方式:由 sync_user_to_sso.sh 调用,可传入增量时间条件 +-- ========================================== + +SET NAMES utf8mb4; + +-- 1. 院系所单位 GXXX_YXSDWJBSJZL <- sys_dept +INSERT INTO GXXX_YXSDWJBSJZL ( + dwh, dwmc, lsdwh, dwyxbs, zhgxsj, scbz +) +SELECT + RIGHT(CAST(d.dept_id AS CHAR), 10) AS dwh, + LEFT(IFNULL(d.dept_name, ''), 60) AS dwmc, + CASE + WHEN d.parent_id IS NULL OR d.parent_id = 0 THEN NULL + ELSE RIGHT(CAST(d.parent_id AS CHAR), 10) + END AS lsdwh, + CASE WHEN d.status = '0' AND d.del_flag = '0' THEN '1' ELSE '0' END AS dwyxbs, + DATE_FORMAT(IFNULL(d.update_time, d.create_time), '%Y%m%d%H%i%s') AS zhgxsj, + CASE WHEN d.del_flag = '1' THEN 'y' ELSE 'n' END AS scbz +FROM sys_dept d +WHERE 1=1 + /*INCREMENTAL_FILTER_DEPT*/ +ON DUPLICATE KEY UPDATE + dwmc = VALUES(dwmc), + lsdwh = VALUES(lsdwh), + dwyxbs = VALUES(dwyxbs), + zhgxsj = VALUES(zhgxsj), + scbz = VALUES(scbz); + +-- 2. 教职工基础 GXJG_JZGJCSJZLB <- sys_user (account_type=1) +INSERT INTO GXJG_JZGJCSJZLB ( + gh, dwh, xm, xbm, dqztm, zhgxsj, scbz +) +SELECT + LEFT(u.user_name, 20) AS gh, + RIGHT(CAST(IFNULL(u.dept_id, 0) AS CHAR), 10) AS dwh, + LEFT(IFNULL(u.nick_name, u.user_name), 36) AS xm, + CASE u.sex WHEN '0' THEN '1' WHEN '1' THEN '2' ELSE '0' END AS xbm, + CASE WHEN u.status = '0' THEN '11' ELSE '99' END AS dqztm, + DATE_FORMAT(IFNULL(u.update_time, u.create_time), '%Y%m%d%H%i%s') AS zhgxsj, + CASE WHEN u.del_flag = '1' THEN 'y' ELSE 'n' END AS scbz +FROM sys_user u +WHERE u.account_type = '1' + /*INCREMENTAL_FILTER_TEACHER*/ +ON DUPLICATE KEY UPDATE + dwh = VALUES(dwh), + xm = VALUES(xm), + xbm = VALUES(xbm), + dqztm = VALUES(dqztm), + zhgxsj = VALUES(zhgxsj), + scbz = VALUES(scbz); + +-- 3. 教职工通讯 GXJG_GRTXFSZL <- sys_user (account_type=1) +INSERT INTO GXJG_GRTXFSZL ( + id, gh, yddh, dzxx, zhgxsj, scbz +) +SELECT + LEFT(u.user_name, 48) AS id, + LEFT(u.user_name, 20) AS gh, + LEFT(NULLIF(u.phonenumber, ''), 30) AS yddh, + LEFT(NULLIF(u.email, ''), 40) AS dzxx, + DATE_FORMAT(IFNULL(u.update_time, u.create_time), '%Y%m%d%H%i%s') AS zhgxsj, + CASE WHEN u.del_flag = '1' THEN 'y' ELSE 'n' END AS scbz +FROM sys_user u +WHERE u.account_type = '1' + /*INCREMENTAL_FILTER_TEACHER*/ +ON DUPLICATE KEY UPDATE + gh = VALUES(gh), + yddh = VALUES(yddh), + dzxx = VALUES(dzxx), + zhgxsj = VALUES(zhgxsj), + scbz = VALUES(scbz); + +-- 4. 学生基础 GXXS_XSJBSJZL <- xg_student_msg +INSERT INTO GXXS_XSJBSJZL ( + xh, xm, ywxm, cym, xbm, csrq, jg, sfzjlxm, sfzjh, zzmmm, xxm, + sfdszn, zhgxsj, scbz, dwh, szbh, sfzx, sfyby +) +SELECT + LEFT(s.student_no, 20) AS xh, + LEFT(IFNULL(s.name, ''), 60) AS xm, + LEFT(IFNULL(s.name_english, ''), 60) AS ywxm, + LEFT(IFNULL(s.former_name, ''), 60) AS cym, + CASE s.gender WHEN '0' THEN '1' WHEN '1' THEN '2' ELSE '0' END AS xbm, + DATE_FORMAT(s.birth_date, '%Y%m%d') AS csrq, + LEFT(IFNULL(s.native_place, ''), 60) AS jg, + '1' AS sfzjlxm, + LEFT(IFNULL(s.id_card, ''), 20) AS sfzjh, + LEFT(IFNULL(s.political_status, ''), 2) AS zzmmm, + LEFT(IFNULL(s.blood_type, ''), 30) AS xxm, + CASE WHEN s.is_single_child = 1 THEN '1' ELSE '0' END AS sfdszn, + DATE_FORMAT(IFNULL(s.update_time, s.create_time), '%Y%m%d%H%i%s') AS zhgxsj, + CASE WHEN s.deleted = 1 THEN 'y' ELSE 'n' END AS scbz, + LEFT(IFNULL(s.college_id, '0'), 20) AS dwh, + LEFT(IFNULL(c.class_code, IFNULL(s.class_id, '')), 20) AS szbh, + CASE WHEN s.student_status IN ('1', '2', '3') THEN '1' ELSE '0' END AS sfzx, + CASE WHEN s.student_status = '5' THEN '1' ELSE '0' END AS sfyby +FROM xg_student_msg s +LEFT JOIN xg_class_msg c ON c.id = s.class_id AND c.deleted = 0 +WHERE 1=1 + /*INCREMENTAL_FILTER_STUDENT*/ +ON DUPLICATE KEY UPDATE + xm = VALUES(xm), + ywxm = VALUES(ywxm), + cym = VALUES(cym), + xbm = VALUES(xbm), + csrq = VALUES(csrq), + jg = VALUES(jg), + sfzjh = VALUES(sfzjh), + zzmmm = VALUES(zzmmm), + xxm = VALUES(xxm), + sfdszn = VALUES(sfdszn), + zhgxsj = VALUES(zhgxsj), + scbz = VALUES(scbz), + dwh = VALUES(dwh), + szbh = VALUES(szbh), + sfzx = VALUES(sfzx), + sfyby = VALUES(sfyby); + +-- 5. 学生通讯 GXXS_GRTXZL <- xg_student_msg +INSERT INTO GXXS_GRTXZL ( + xh, yzbm, txdz, yddh, dzxx, jstxh, zhgxsj, scbz +) +SELECT + LEFT(s.student_no, 20) AS xh, + LEFT(IFNULL(s.postal_code, ''), 6) AS yzbm, + LEFT(IFNULL(NULLIF(s.current_address, ''), s.home_address), 180) AS txdz, + LEFT(IFNULL(s.phone, ''), 30) AS yddh, + LEFT(IFNULL(s.email, ''), 40) AS dzxx, + LEFT(IFNULL(NULLIF(s.qq, ''), s.wechat), 40) AS jstxh, + DATE_FORMAT(IFNULL(s.update_time, s.create_time), '%Y%m%d%H%i%s') AS zhgxsj, + CASE WHEN s.deleted = 1 THEN 'y' ELSE 'n' END AS scbz +FROM xg_student_msg s +WHERE 1=1 + /*INCREMENTAL_FILTER_STUDENT*/ +ON DUPLICATE KEY UPDATE + yzbm = VALUES(yzbm), + txdz = VALUES(txdz), + yddh = VALUES(yddh), + dzxx = VALUES(dzxx), + jstxh = VALUES(jstxh), + zhgxsj = VALUES(zhgxsj), + scbz = VALUES(scbz); diff --git a/用户信息同步统一身份认证/sync_user_to_sso.sh b/用户信息同步统一身份认证/sync_user_to_sso.sh new file mode 100755 index 00000000..d15710c2 --- /dev/null +++ b/用户信息同步统一身份认证/sync_user_to_sso.sh @@ -0,0 +1,283 @@ +#!/bin/bash +# =========================================== +# 统一身份认证用户数据同步脚本 +# 参考:学生换班级 process_student_class_change_fixed.sh +# 功能:定时将校园系统用户/组织数据同步到认证中间库 +# 用法: +# ./sync_user_to_sso.sh # 守护进程,按 CYCLE_INTERVAL 循环 +# ./sync_user_to_sso.sh --once # 仅执行一次同步 +# ./sync_user_to_sso.sh --full # 强制全量同步(一次) +# =========================================== + +set -euo pipefail +export LANG=C +export LC_ALL=C + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/data.conf" +RUN_ONCE=false +FORCE_FULL=false + +for arg in "$@"; do + case "$arg" in + --once) RUN_ONCE=true ;; + --full) FORCE_FULL=true ;; + --config=*) CONFIG_FILE="${arg#*=}" ;; + esac +done + +if [[ ! -f "$CONFIG_FILE" ]]; then + echo "错误:配置文件 $CONFIG_FILE 未找到" + exit 1 +fi + +source "$CONFIG_FILE" + +mkdir -p "$LOG_DIR" +LOG_FILE="${LOG_DIR}/sync_user_to_sso_$(date +%Y%m%d_%H%M%S).log" + +log() { + local level="$1" + local message="$2" + local timestamp + timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE" +} + +error_exit() { + log "ERROR" "$1" + [[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE" + exit 1 +} + +acquire_lock() { + if [[ -f "$LOCK_FILE" ]]; then + local pid + pid=$(cat "$LOCK_FILE" 2>/dev/null || echo "") + if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then + error_exit "同步进程已在运行 (PID: $pid)" + fi + rm -f "$LOCK_FILE" + fi + echo $$ > "$LOCK_FILE" +} + +release_lock() { + [[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE" +} + +trap release_lock EXIT + +_db_helper() { + local host="$1" port="$2" user="$3" pass="$4" db="$5" action="$6" + shift 6 + python3 "${SCRIPT_DIR}/db_helper.py" \ + --host "$host" --port "$port" \ + --user "$user" --password "$pass" --database "$db" \ + "$action" "$@" +} + +source_mysql() { + local sql="$1" + _db_helper "$SOURCE_DB_HOST" "$SOURCE_DB_PORT" "$SOURCE_DB_USER" "$SOURCE_DB_PASS" "$SOURCE_DB_NAME" scalar "$sql" 2>&1 +} + +target_mysql() { + local sql="$1" + _db_helper "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" scalar "$sql" 2>&1 +} + +target_mysql_file() { + local file="$1" + _db_helper "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" file "$file" 2>&1 +} + +write_errlog() { + local table_name="$1" + local action="$2" + local err_msg="$3" + local escaped_msg + escaped_msg=$(echo "$err_msg" | sed "s/'/''/g" | head -c 900) + local sql="INSERT INTO ZFTAL_XTGL_ERRLOG (YWXTMC, YWXTBM, YWXTCZ, SJCCGC, CWZDXX, CWSJ) + VALUES ('${YWXTMC}', '${table_name}', '${action}', 'sync_user_to_sso.sh', '${escaped_msg}', DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'));" + if [[ "$TARGET_DB_TYPE" == "mysql" ]]; then + target_mysql "$sql" >/dev/null 2>&1 || true + fi +} + +get_last_sync_time() { + if [[ -f "$STATE_FILE" ]]; then + cat "$STATE_FILE" + else + echo "1970-01-01 00:00:00" + fi +} + +save_sync_time() { + date '+%Y-%m-%d %H:%M:%S' > "$STATE_FILE" +} + +build_incremental_filter() { + local alias="$1" + local last_sync="$2" + if [[ "$FORCE_FULL" == true ]] || [[ "$SYNC_MODE" == "full" ]]; then + echo "" + else + echo "AND (${alias}.update_time > '${last_sync}' OR ${alias}.create_time > '${last_sync}')" + fi +} + +prepare_mysql_sync_sql() { + local last_sync="$1" + local template="${SCRIPT_DIR}/sync_sql/sync_all_mysql.sql" + local output="/tmp/sso_sync_mysql_$$.sql" + + if [[ ! -f "$template" ]]; then + error_exit "同步 SQL 模板未找到: $template" + fi + + local dept_filter teacher_filter student_filter + dept_filter=$(build_incremental_filter "d" "$last_sync") + teacher_filter=$(build_incremental_filter "u" "$last_sync") + student_filter=$(build_incremental_filter "s" "$last_sync") + + sed \ + -e "s|/\*INCREMENTAL_FILTER_DEPT\*/|${dept_filter}|g" \ + -e "s|/\*INCREMENTAL_FILTER_TEACHER\*/|${teacher_filter}|g" \ + -e "s|/\*INCREMENTAL_FILTER_STUDENT\*/|${student_filter}|g" \ + "$template" > "$output" + echo "$output" +} + +sync_mysql_target() { + local last_sync + last_sync=$(get_last_sync_time) + log "INFO" "开始 MySQL 目标库同步,模式: $([[ "$FORCE_FULL" == true || "$SYNC_MODE" == "full" ]] && echo 全量 || echo 增量),上次同步: $last_sync" + + local sql_file + sql_file=$(prepare_mysql_sync_sql "$last_sync") + local result + if result=$(target_mysql_file "$sql_file" 2>&1); then + log "INFO" "MySQL 同步 SQL 执行成功" + rm -f "$sql_file" + save_sync_time + return 0 + else + log "ERROR" "MySQL 同步失败: $result" + write_errlog "ALL" "数据同步" "$result" + rm -f "$sql_file" + return 1 + fi +} + +sync_oracle_target() { + local last_sync + last_sync=$(get_last_sync_time) + log "INFO" "开始 Oracle 目标库同步,上次同步: $last_sync" + + if ! command -v sqlplus >/dev/null 2>&1; then + error_exit "未找到 sqlplus 命令,无法连接 Oracle 目标库" + fi + + local export_dir="/tmp/sso_sync_export_$$" + mkdir -p "$export_dir" + + # 导出部门 + source_mysql " + SELECT + RIGHT(CAST(d.dept_id AS CHAR), 10), + REPLACE(IFNULL(d.dept_name,''),'\t',' '), + CASE WHEN d.parent_id IS NULL OR d.parent_id=0 THEN '' ELSE RIGHT(CAST(d.parent_id AS CHAR),10) END, + CASE WHEN d.status='0' AND d.del_flag='0' THEN '1' ELSE '0' END, + DATE_FORMAT(IFNULL(d.update_time,d.create_time),'%Y%m%d%H%i%s'), + CASE WHEN d.del_flag='1' THEN 'y' ELSE 'n' END + FROM sys_dept d + " > "${export_dir}/dept.tsv" || true + + local oracle_script="${SCRIPT_DIR}/sync_oracle/merge_all.sql" + if [[ ! -f "$oracle_script" ]]; then + error_exit "Oracle MERGE 脚本未找到: $oracle_script" + fi + + local conn="${TARGET_DB_USER}/${TARGET_DB_PASS}@${TARGET_ORACLE_CONNECT:-${TARGET_DB_HOST}:${TARGET_DB_PORT}/${TARGET_DB_NAME}}" + if sqlplus -S "$conn" @"$oracle_script" "$export_dir" >> "$LOG_FILE" 2>&1; then + log "INFO" "Oracle 同步完成" + save_sync_time + rm -rf "$export_dir" + return 0 + else + log "ERROR" "Oracle 同步失败,详见日志" + write_errlog "ALL" "Oracle数据同步" "sqlplus执行失败" + rm -rf "$export_dir" + return 1 + fi +} + +run_sync_cycle() { + log "INFO" "========== 开始同步周期 ==========" + + # 测试源库连接 + if ! source_mysql "SELECT 1;" >/dev/null 2>&1; then + log "ERROR" "源库连接失败: ${SOURCE_DB_USER}@${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}" + return 1 + fi + + if [[ "$TARGET_DB_TYPE" == "mysql" ]]; then + if ! target_mysql "SELECT 1;" >/dev/null 2>&1; then + log "ERROR" "目标库连接失败: ${TARGET_DB_USER}@${TARGET_DB_HOST}:${TARGET_DB_PORT}/${TARGET_DB_NAME}" + return 1 + fi + sync_mysql_target + elif [[ "$TARGET_DB_TYPE" == "oracle" ]]; then + sync_oracle_target + else + log "ERROR" "不支持的目标库类型: $TARGET_DB_TYPE" + return 1 + fi + + log "INFO" "========== 同步周期结束 ==========" +} + +verify_counts() { + log "INFO" "---------- 数据校验 ----------" + if [[ "$TARGET_DB_TYPE" != "mysql" ]]; then + log "INFO" "Oracle 目标库校验请使用 verify_sync.sh" + return 0 + fi + + local tables=("GXXX_YXSDWJBSJZL" "GXJG_JZGJCSJZLB" "GXJG_GRTXFSZL" "GXXS_XSJBSJZL" "GXXS_GRTXZL") + for t in "${tables[@]}"; do + local cnt + cnt=$(target_mysql "SELECT COUNT(*) FROM ${t};" 2>/dev/null | tail -1) + log "INFO" "目标表 ${t}: ${cnt} 条" + done + + local src_dept src_teacher src_student + src_dept=$(source_mysql "SELECT COUNT(*) FROM sys_dept;" 2>/dev/null | tail -1) + src_teacher=$(source_mysql "SELECT COUNT(*) FROM sys_user WHERE account_type='1';" 2>/dev/null | tail -1) + src_student=$(source_mysql "SELECT COUNT(*) FROM xg_student_msg WHERE deleted=0;" 2>/dev/null | tail -1) + log "INFO" "源表 sys_dept: ${src_dept} 条" + log "INFO" "源表 sys_user(教职工): ${src_teacher} 条" + log "INFO" "源表 xg_student_msg(未删除): ${src_student} 条" +} + +main() { + acquire_lock + log "INFO" "统一身份认证用户数据同步启动" + log "INFO" "源库: ${SOURCE_DB_TYPE} ${SOURCE_DB_USER}@${SOURCE_DB_HOST}:${SOURCE_DB_PORT}/${SOURCE_DB_NAME}" + log "INFO" "目标库: ${TARGET_DB_TYPE} ${TARGET_DB_USER}@${TARGET_DB_HOST}:${TARGET_DB_PORT}/${TARGET_DB_NAME}" + log "INFO" "同步模式: ${SYNC_MODE},循环间隔: ${CYCLE_INTERVAL}秒" + + if [[ "$RUN_ONCE" == true ]]; then + run_sync_cycle && verify_counts + exit $? + fi + + while true; do + run_sync_cycle && verify_counts || log "WARN" "本轮同步失败,将在 ${CYCLE_INTERVAL} 秒后重试" + log "INFO" "等待 ${CYCLE_INTERVAL} 秒后开始下一轮..." + sleep "$CYCLE_INTERVAL" + done +} + +main "$@" diff --git a/用户信息同步统一身份认证/verify_sync.sh b/用户信息同步统一身份认证/verify_sync.sh new file mode 100755 index 00000000..d7bd3740 --- /dev/null +++ b/用户信息同步统一身份认证/verify_sync.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# =========================================== +# 统一身份认证同步结果校验脚本 +# =========================================== + +set -euo pipefail +export LANG=C +export LC_ALL=C + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_FILE="${SCRIPT_DIR}/data.conf" +[[ -f "$CONFIG_FILE" ]] || { echo "配置文件未找到"; exit 1; } +source "$CONFIG_FILE" + +mysql_q() { + python3 "${SCRIPT_DIR}/db_helper.py" \ + --host "$1" --port "$2" --user "$3" --password "$4" --database "$5" \ + scalar "$6" 2>/dev/null +} + +echo "========== 统一身份认证同步校验 ==========" +echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" +echo "" + +# 源库统计 +SRC_DEPT=$(mysql_q "$SOURCE_DB_HOST" "$SOURCE_DB_PORT" "$SOURCE_DB_USER" "$SOURCE_DB_PASS" "$SOURCE_DB_NAME" "SELECT COUNT(*) FROM sys_dept;") +SRC_TEACHER=$(mysql_q "$SOURCE_DB_HOST" "$SOURCE_DB_PORT" "$SOURCE_DB_USER" "$SOURCE_DB_PASS" "$SOURCE_DB_NAME" "SELECT COUNT(*) FROM sys_user WHERE account_type='1';") +SRC_STUDENT=$(mysql_q "$SOURCE_DB_HOST" "$SOURCE_DB_PORT" "$SOURCE_DB_USER" "$SOURCE_DB_PASS" "$SOURCE_DB_NAME" "SELECT COUNT(*) FROM xg_student_msg WHERE deleted=0;") + +echo "[源库] sys_dept: ${SRC_DEPT}" +echo "[源库] sys_user(教职工): ${SRC_TEACHER}" +echo "[源库] xg_student_msg(有效): ${SRC_STUDENT}" +echo "" + +if [[ "$TARGET_DB_TYPE" == "mysql" ]]; then + TGT_DEPT=$(mysql_q "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" "SELECT COUNT(*) FROM GXXX_YXSDWJBSJZL;") + TGT_TEACHER=$(mysql_q "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" "SELECT COUNT(*) FROM GXJG_JZGJCSJZLB;") + TGT_TEACHER_TX=$(mysql_q "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" "SELECT COUNT(*) FROM GXJG_GRTXFSZL;") + TGT_STUDENT=$(mysql_q "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" "SELECT COUNT(*) FROM GXXS_XSJBSJZL;") + TGT_STUDENT_TX=$(mysql_q "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" "SELECT COUNT(*) FROM GXXS_GRTXZL;") + TGT_ERR=$(mysql_q "$TARGET_DB_HOST" "$TARGET_DB_PORT" "$TARGET_DB_USER" "$TARGET_DB_PASS" "$TARGET_DB_NAME" "SELECT COUNT(*) FROM ZFTAL_XTGL_ERRLOG;") + + echo "[目标库] GXXX_YXSDWJBSJZL: ${TGT_DEPT}" + echo "[目标库] GXJG_JZGJCSJZLB: ${TGT_TEACHER}" + echo "[目标库] GXJG_GRTXFSZL: ${TGT_TEACHER_TX}" + echo "[目标库] GXXS_XSJBSJZL: ${TGT_STUDENT}" + echo "[目标库] GXXS_GRTXZL: ${TGT_STUDENT_TX}" + echo "[目标库] ZFTAL_XTGL_ERRLOG: ${TGT_ERR}" + echo "" + + # 抽样对比 + echo "---------- 抽样数据对比 ----------" + python3 "${SCRIPT_DIR}/db_helper.py" \ + --host "$TARGET_DB_HOST" --port "$TARGET_DB_PORT" \ + --user "$TARGET_DB_USER" --password "$TARGET_DB_PASS" --database "$TARGET_DB_NAME" \ + query "SELECT gh, xm, dwh, scbz FROM GXJG_JZGJCSJZLB LIMIT 3" 2>/dev/null + python3 "${SCRIPT_DIR}/db_helper.py" \ + --host "$TARGET_DB_HOST" --port "$TARGET_DB_PORT" \ + --user "$TARGET_DB_USER" --password "$TARGET_DB_PASS" --database "$TARGET_DB_NAME" \ + query "SELECT xh, xm, dwh, szbh, scbz FROM GXXS_XSJBSJZL LIMIT 3" 2>/dev/null + + echo "" + # 简单一致性检查 + PASS=true + [[ "$TGT_DEPT" -ge 1 ]] || { echo "WARN: 部门同步数量为0"; PASS=false; } + [[ "$TGT_TEACHER" -ge 1 ]] || { echo "WARN: 教职工同步数量为0"; PASS=false; } + [[ "$TGT_STUDENT" -ge 1 ]] || { echo "WARN: 学生同步数量为0"; PASS=false; } + [[ "$TGT_TEACHER" == "$TGT_TEACHER_TX" ]] || echo "WARN: 教职工基础表与通讯表数量不一致" + [[ "$TGT_STUDENT" == "$TGT_STUDENT_TX" ]] || echo "WARN: 学生基础表与通讯表数量不一致" + + if [[ "$PASS" == true ]]; then + echo "校验结果: 通过(基础数据已写入)" + exit 0 + else + echo "校验结果: 未通过" + exit 1 + fi +else + echo "目标库为 Oracle,请使用 sqlplus 手动校验目标表记录数" + exit 0 +fi diff --git a/用户信息同步统一身份认证/字段映射说明.md b/用户信息同步统一身份认证/字段映射说明.md new file mode 100644 index 00000000..b8deb6ff --- /dev/null +++ b/用户信息同步统一身份认证/字段映射说明.md @@ -0,0 +1,110 @@ +# 统一身份认证用户数据同步 - 字段映射说明 + +## 1. 概述 + +将校园管理系统(`hzdyjs_xg`)的组织与用户数据,定时同步到统一身份认证中间库 6 张标准表,供第三方平台拉取。 + +| 目标表 | 说明 | 数据源 | +|--------|------|--------| +| `GXXX_YXSDWJBSJZL` | 院系所单位 | `sys_dept` | +| `GXJG_JZGJCSJZLB` | 教职工基础 | `sys_user`(`account_type='1'`) | +| `GXJG_GRTXFSZL` | 教职工通讯 | `sys_user`(`account_type='1'`) | +| `GXXS_XSJBSJZL` | 学生基础 | `xg_student_msg` | +| `GXXS_GRTXZL` | 学生通讯 | `xg_student_msg` | +| `ZFTAL_XTGL_ERRLOG` | 同步错误日志 | 同步脚本写入 | + +**不同步字段**:`zp`(照片 BLOB)按约定不处理。 + +--- + +## 2. 单位表 GXXX_YXSDWJBSJZL + +| 目标字段 | 源字段 | 转换规则 | +|----------|--------|----------| +| dwh | sys_dept.dept_id | `RIGHT(CAST(dept_id AS CHAR), 10)`(雪花ID超长,取后10位) | +| dwmc | sys_dept.dept_name | 截断至60字符 | +| lsdwh | sys_dept.parent_id | parent_id=0 时 NULL,否则取后10位 | +| dwyxbs | status + del_flag | 正常且未删除='1',否则='0' | +| zhgxsj | update_time / create_time | `YYYYMMDDhhmmss` | +| scbz | del_flag | '0'→'n','1'→'y' | + +--- + +## 3. 教职工表 GXJG_JZGJCSJZLB + +| 目标字段 | 源字段 | 转换规则 | +|----------|--------|----------| +| gh | sys_user.user_name | 工号,截断至20字符 | +| dwh | sys_user.dept_id | 取后10位 | +| xm | sys_user.nick_name | 姓名 | +| xbm | sys_user.sex | 0男→'1',1女→'2',其他→'0' | +| dqztm | sys_user.status | 0正常→'11',停用→'99' | +| zhgxsj | update_time / create_time | `YYYYMMDDhhmmss` | +| scbz | del_flag | '0'→'n','1'→'y' | + +--- + +## 4. 教职工通讯表 GXJG_GRTXFSZL + +| 目标字段 | 源字段 | 转换规则 | +|----------|--------|----------| +| id | sys_user.user_name | 主键,用工号 | +| gh | sys_user.user_name | 工号 | +| yddh | sys_user.phonenumber | 手机号 | +| dzxx | sys_user.email | 邮箱 | +| zhgxsj | update_time / create_time | `YYYYMMDDhhmmss` | +| scbz | del_flag | '0'→'n','1'→'y' | + +--- + +## 5. 学生表 GXXS_XSJBSJZL + +| 目标字段 | 源字段 | 转换规则 | +|----------|--------|----------| +| xh | xg_student_msg.student_no | 学号 | +| xm | name | 姓名 | +| ywxm | name_english | 英文名 | +| cym | former_name | 曾用名 | +| xbm | gender | 0男→'1',1女→'2' | +| csrq | birth_date | `YYYYMMDD` | +| jg | native_place | 籍贯 | +| sfzjlxm | - | 固定 '1'(身份证) | +| sfzjh | id_card | 身份证号 | +| zzmmm | political_status | 政治面貌 | +| xxm | blood_type | 血型 | +| sfdszn | is_single_child | 1→'1',0→'0' | +| dwh | college_id | 学院ID | +| szbh | xg_class_msg.class_code | 关联班级表取班级代码 | +| sfzx | student_status | 1/2/3→'1'在校,其他→'0' | +| sfyby | student_status | 5毕业→'1',其他→'0' | +| zhgxsj | update_time / create_time | `YYYYMMDDhhmmss` | +| scbz | deleted | 0→'n',1→'y' | + +--- + +## 6. 学生通讯表 GXXS_GRTXZL + +| 目标字段 | 源字段 | 转换规则 | +|----------|--------|----------| +| xh | student_no | 学号 | +| yzbm | postal_code | 邮编 | +| txdz | current_address / home_address | 优先现住址 | +| yddh | phone | 手机 | +| dzxx | email | 邮箱 | +| jstxh | qq / wechat | 优先QQ | +| zhgxsj | update_time / create_time | `YYYYMMDDhhmmss` | +| scbz | deleted | 0→'n',1→'y' | + +--- + +## 7. 注意事项 + +1. **单位号 dwh 长度限制**:第三方表 `dwh` 仅 10 位,而 `sys_dept.dept_id` 为雪花ID(19位),当前取后10位;若对方有编码规范需另行映射。 +2. **增量同步**:基于源表 `update_time` / `create_time`,状态记录在 `.sync_state`。 +3. **全量同步**:设置 `SYNC_MODE=full` 或执行 `./sync_user_to_sso.sh --full --once`。 +4. **生产 Oracle**:修改 `data.conf.prod` 中 `TARGET_DB_TYPE=oracle` 及连接信息,使用 `sqlplus` 执行 MERGE(模板见 `sync_oracle/`)。 + +--- + +**版本**: v1.0.0 +**更新时间**: 2026-08-24 diff --git a/用户信息同步统一身份认证/建表脚本_mysql.sql b/用户信息同步统一身份认证/建表脚本_mysql.sql new file mode 100644 index 00000000..c8ea2468 --- /dev/null +++ b/用户信息同步统一身份认证/建表脚本_mysql.sql @@ -0,0 +1,179 @@ +-- ========================================== +-- 统一身份认证中间库建表脚本(MySQL 适配版) +-- 说明:由第三方 Oracle 建表语句转换,仅供本地 MySQL 测试使用 +-- 原始 Oracle 脚本:3.在认证中间库建立表.sql(请勿修改原文件) +-- ========================================== + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- GXXX_YXSDWJBSJZL 院系所单位基本数据子类 +-- ---------------------------- +DROP TABLE IF EXISTS `GXXX_YXSDWJBSJZL`; +CREATE TABLE `GXXX_YXSDWJBSJZL` ( + `dwh` VARCHAR(10) NOT NULL COMMENT '单位号', + `dwmc` VARCHAR(60) DEFAULT NULL COMMENT '单位名称', + `dwywmc` VARCHAR(180) DEFAULT NULL COMMENT '单位英文名称', + `dwjc` VARCHAR(12) DEFAULT NULL COMMENT '单位简称', + `dwywjc` VARCHAR(8) DEFAULT NULL COMMENT '单位英文简称', + `dwjp` VARCHAR(6) DEFAULT NULL COMMENT '单位简拼', + `dwdz` VARCHAR(180) DEFAULT NULL COMMENT '单位地址', + `lsdwh` VARCHAR(10) DEFAULT NULL COMMENT '隶属单位号', + `dwlbm` VARCHAR(1) DEFAULT NULL COMMENT '单位类别码', + `dwbbm` VARCHAR(1) DEFAULT NULL COMMENT '单位办别码', + `dwyxbs` VARCHAR(1) DEFAULT NULL COMMENT '单位有效标识', + `sxrq` VARCHAR(8) DEFAULT NULL COMMENT '失效日期', + `sfst` VARCHAR(1) DEFAULT NULL COMMENT '是否实体', + `jlny` VARCHAR(6) DEFAULT NULL COMMENT '建立年月', + `dwfzrh` VARCHAR(20) DEFAULT NULL COMMENT '单位负责人号', + `zhgxsj` VARCHAR(20) DEFAULT NULL COMMENT '最后更新时间', + `scbz` VARCHAR(1) DEFAULT NULL COMMENT '删除标志:y/n', + `dwjb` VARCHAR(8) DEFAULT NULL COMMENT '单位级别', + PRIMARY KEY (`dwh`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='GXXX0301院系所单位基本数据子类'; + +-- ---------------------------- +-- GXJG_JZGJCSJZLB 教职工基础数据子类表 +-- ---------------------------- +DROP TABLE IF EXISTS `GXJG_JZGJCSJZLB`; +CREATE TABLE `GXJG_JZGJCSJZLB` ( + `gh` VARCHAR(20) NOT NULL COMMENT '工号', + `dwh` VARCHAR(10) NOT NULL COMMENT '单位号', + `xm` VARCHAR(36) DEFAULT NULL COMMENT '姓名', + `ywxm` VARCHAR(60) DEFAULT NULL COMMENT '英文姓名', + `xmpy` VARCHAR(60) DEFAULT NULL COMMENT '姓名拼音', + `cym` VARCHAR(36) DEFAULT NULL COMMENT '曾用名', + `xbm` VARCHAR(1) DEFAULT NULL COMMENT '性别码', + `csrq` VARCHAR(8) DEFAULT NULL COMMENT '出生日期', + `csdm` VARCHAR(6) DEFAULT NULL COMMENT '出生地码', + `jg` VARCHAR(20) DEFAULT NULL COMMENT '籍贯', + `mzm` VARCHAR(2) DEFAULT NULL COMMENT '民族码', + `gjdqm` VARCHAR(3) DEFAULT NULL COMMENT '国籍/地区码', + `sfzjlxm` VARCHAR(1) DEFAULT NULL COMMENT '身份证件类型码', + `sfzjh` VARCHAR(20) DEFAULT NULL COMMENT '身份证件号', + `hyztm` VARCHAR(2) DEFAULT NULL COMMENT '婚姻状况码', + `gatqwm` VARCHAR(2) DEFAULT NULL COMMENT '港澳台侨外码', + `zzmmm` VARCHAR(2) DEFAULT NULL COMMENT '政治面貌码', + `jkzkm` VARCHAR(2) DEFAULT NULL COMMENT '健康状况码', + `xyzjm` VARCHAR(2) DEFAULT NULL COMMENT '信仰宗教码', + `xxm` VARCHAR(1) DEFAULT NULL COMMENT '血型码', + `zp` LONGBLOB DEFAULT NULL COMMENT '照片(不同步)', + `sfzjyxq` VARCHAR(17) DEFAULT NULL COMMENT '身份证件有效期', + `xqh` VARCHAR(2) DEFAULT NULL COMMENT '校区号', + `zgxlm` VARCHAR(3) DEFAULT NULL COMMENT '最高学历码', + `whcdm` VARCHAR(3) DEFAULT NULL COMMENT '文化程度码', + `cjgzny` VARCHAR(6) DEFAULT NULL COMMENT '参加工作年月', + `lxrq` VARCHAR(8) DEFAULT NULL COMMENT '来校日期', + `qxrq` VARCHAR(8) DEFAULT NULL COMMENT '起薪日期', + `cjny` VARCHAR(6) DEFAULT NULL COMMENT '从教年月', + `bzlbm` VARCHAR(2) DEFAULT NULL COMMENT '编制类别码', + `jzglbm` VARCHAR(3) DEFAULT NULL COMMENT '教职工类别码', + `rkzkm` VARCHAR(2) DEFAULT NULL COMMENT '任课状况码', + `dabh` VARCHAR(20) DEFAULT NULL COMMENT '档案编号', + `dawb` LONGTEXT DEFAULT NULL COMMENT '档案文本', + `dqztm` VARCHAR(2) DEFAULT NULL COMMENT '当前状态码', + `tc` VARCHAR(100) DEFAULT NULL COMMENT '特长', + `xklbm` VARCHAR(6) DEFAULT NULL COMMENT '学科类别码', + `yjxkm` VARCHAR(4) DEFAULT NULL COMMENT '一级学科码', + `ejxkm` VARCHAR(6) DEFAULT NULL COMMENT '二级学科码', + `yjfx` VARCHAR(100) DEFAULT NULL COMMENT '研究方向', + `zhgxsj` VARCHAR(20) DEFAULT NULL COMMENT '最后更新时间', + `scbz` VARCHAR(1) DEFAULT NULL COMMENT '删除标志:y/n', + `zhxw` VARCHAR(32) DEFAULT NULL COMMENT '最后学位', + `zc` VARCHAR(32) DEFAULT NULL COMMENT '职称', + `ygxs` VARCHAR(2) DEFAULT NULL COMMENT '用工形式', + PRIMARY KEY (`gh`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='GXJG0101教职工基础数据子类表'; + +-- ---------------------------- +-- GXXS_XSJBSJZL 学生基本数据子类 +-- ---------------------------- +DROP TABLE IF EXISTS `GXXS_XSJBSJZL`; +CREATE TABLE `GXXS_XSJBSJZL` ( + `xh` VARCHAR(20) NOT NULL COMMENT '学号', + `xm` VARCHAR(60) DEFAULT NULL COMMENT '姓名', + `ywxm` VARCHAR(60) DEFAULT NULL COMMENT '英文姓名', + `xmpy` VARCHAR(60) DEFAULT NULL COMMENT '姓名拼音', + `cym` VARCHAR(60) DEFAULT NULL COMMENT '曾用名', + `xbm` VARCHAR(1) DEFAULT NULL COMMENT '性别码', + `csrq` VARCHAR(10) DEFAULT NULL COMMENT '出生日期', + `csdm` VARCHAR(200) DEFAULT NULL COMMENT '出生地码', + `jg` VARCHAR(60) DEFAULT NULL COMMENT '籍贯', + `mzm` VARCHAR(2) DEFAULT NULL COMMENT '民族码', + `gjdqm` VARCHAR(50) DEFAULT NULL COMMENT '国籍/地区码', + `sfzjlxm` VARCHAR(2) DEFAULT NULL COMMENT '身份证件类型码', + `sfzjh` VARCHAR(20) DEFAULT NULL COMMENT '身份证件号', + `hyzkm` VARCHAR(10) DEFAULT NULL COMMENT '婚姻状况码', + `gatqwm` VARCHAR(2) DEFAULT NULL COMMENT '港澳台侨外码', + `zzmmm` VARCHAR(2) DEFAULT NULL COMMENT '政治面貌码', + `jkzkm` VARCHAR(20) DEFAULT NULL COMMENT '健康状况码', + `xyzjm` VARCHAR(50) DEFAULT NULL COMMENT '信仰宗教码', + `xxm` VARCHAR(30) DEFAULT NULL COMMENT '血型码', + `sfzjyxq` VARCHAR(17) DEFAULT NULL COMMENT '身份证件有效期', + `sfdszn` VARCHAR(1) DEFAULT NULL COMMENT '是否独生子女', + `zp` LONGBLOB DEFAULT NULL COMMENT '照片(不同步)', + `zhgxsj` VARCHAR(20) DEFAULT NULL COMMENT '最后更新时间', + `scbz` VARCHAR(1) DEFAULT NULL COMMENT '删除标志:y/n', + `ksh` VARCHAR(20) DEFAULT NULL COMMENT '考生号', + `dwh` VARCHAR(20) NOT NULL COMMENT '单位号(学院)', + `szbh` VARCHAR(20) DEFAULT NULL COMMENT '所在班号', + `sfzx` VARCHAR(10) DEFAULT NULL COMMENT '是否在校', + `sfyby` VARCHAR(6) DEFAULT NULL COMMENT '是否已毕业', + PRIMARY KEY (`xh`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='GXXS0101学生基本数据子类'; + +-- ---------------------------- +-- GXXS_GRTXZL 学生个人通讯子类 +-- ---------------------------- +DROP TABLE IF EXISTS `GXXS_GRTXZL`; +CREATE TABLE `GXXS_GRTXZL` ( + `yzbm` VARCHAR(6) DEFAULT NULL COMMENT '邮政编码', + `txdz` VARCHAR(180) DEFAULT NULL COMMENT '通信地址', + `dh` VARCHAR(50) DEFAULT NULL COMMENT '电话', + `yddh` VARCHAR(30) DEFAULT NULL COMMENT '移动电话', + `czdh` VARCHAR(30) DEFAULT NULL COMMENT '传真电话', + `dzxx` VARCHAR(40) DEFAULT NULL COMMENT '电子信箱', + `wldz` VARCHAR(60) DEFAULT NULL COMMENT '网络地址', + `jstxh` VARCHAR(40) DEFAULT NULL COMMENT '即时通讯号', + `xh` VARCHAR(20) NOT NULL COMMENT '学号', + `zhgxsj` VARCHAR(20) DEFAULT NULL COMMENT '最后更新时间', + `scbz` VARCHAR(1) DEFAULT NULL COMMENT '删除标志:y/n', + PRIMARY KEY (`xh`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='GXXS0109学生个人通讯子类'; + +-- ---------------------------- +-- GXJG_GRTXFSZL 教职工个人通讯方式子类 +-- ---------------------------- +DROP TABLE IF EXISTS `GXJG_GRTXFSZL`; +CREATE TABLE `GXJG_GRTXFSZL` ( + `yzbm` VARCHAR(6) DEFAULT NULL COMMENT '邮政编码', + `txdz` VARCHAR(180) DEFAULT NULL COMMENT '通信地址', + `dh` VARCHAR(30) DEFAULT NULL COMMENT '电话', + `yddh` VARCHAR(30) DEFAULT NULL COMMENT '移动电话', + `czdh` VARCHAR(30) DEFAULT NULL COMMENT '传真电话', + `wldz` VARCHAR(60) DEFAULT NULL COMMENT '网络地址', + `jstxh` VARCHAR(40) DEFAULT NULL COMMENT '即时通讯号', + `gh` VARCHAR(20) NOT NULL COMMENT '工号', + `dzxx` VARCHAR(40) DEFAULT NULL COMMENT '电子信箱', + `zhgxsj` VARCHAR(20) DEFAULT NULL COMMENT '最后更新时间', + `scbz` VARCHAR(1) DEFAULT NULL COMMENT '删除标志:y/n', + `id` VARCHAR(48) NOT NULL COMMENT '主键ID', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='GXJG0102教职工个人通讯方式子类'; + +-- ---------------------------- +-- ZFTAL_XTGL_ERRLOG 系统错误日志表 +-- ---------------------------- +DROP TABLE IF EXISTS `ZFTAL_XTGL_ERRLOG`; +CREATE TABLE `ZFTAL_XTGL_ERRLOG` ( + `YWXTMC` VARCHAR(100) DEFAULT NULL COMMENT '业务系统名称', + `YWXTBM` VARCHAR(100) DEFAULT NULL COMMENT '业务系统表名', + `YWXTCZ` VARCHAR(200) DEFAULT NULL COMMENT '业务系统操作', + `SJCFQ` VARCHAR(100) DEFAULT NULL COMMENT '操作涉及触发器', + `SJCCGC` VARCHAR(100) DEFAULT NULL COMMENT '操作涉及存储过程', + `CWZDXX` VARCHAR(1000) DEFAULT NULL COMMENT '报错字段信息', + `CWSJ` VARCHAR(20) DEFAULT NULL COMMENT '错误时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统错误日志表'; + +SET FOREIGN_KEY_CHECKS = 1;