生管理平臺(tái)從0到1:架構(gòu)設(shè)計(jì)與智能化預(yù)警落地實(shí)踐)
這一年我大部分精力都花在了一個(gè)學(xué)生管理平臺(tái)的項(xiàng)目上。起因很樸素某高校學(xué)工處的負(fù)責(zé)人找過來的時(shí)候自己也說不清手底下到底有多少?gòu)垖W(xué)生信息表。教務(wù)一套、宿管一套、資助一套Excel 在電腦里傳來傳去同一個(gè)學(xué)生的名字能出現(xiàn)好幾種寫法。他說得挺直白“我們就想讓校園管理更智能、更高效少讓我們加無意義的班?!边@句話我記了很久。這篇就圍繞這套平臺(tái)的從 0 到 1 過程把背景、架構(gòu)、功能落地、安全設(shè)計(jì)和踩過的坑完整寫出來給正打算做類似項(xiàng)目的人當(dāng)一份參考。1. 校園管理的真實(shí)痛點(diǎn)為什么傳統(tǒng)方式撐不住了1.1 信息孤島和 Excel 接力賽問題比想象中嚴(yán)重很多沒深入校園業(yè)務(wù)的人會(huì)把“學(xué)生管理”想得很簡(jiǎn)單不就是一張表存學(xué)生名單再加幾個(gè)查詢按鈕嗎真進(jìn)去做才知道數(shù)據(jù)分散程度能讓人崩潰。某高校內(nèi)部光學(xué)生相關(guān)的系統(tǒng)就有教務(wù)、宿管、學(xué)工、資助、心理中心、就業(yè)辦六七個(gè)每個(gè)系統(tǒng)各存各的數(shù)據(jù)連學(xué)號(hào)編碼規(guī)則都不完全一致。最典型的場(chǎng)景是每學(xué)年初的困難生認(rèn)定。資助口的老師要從十幾個(gè)學(xué)院收 Excel每個(gè)學(xué)院的列名還不一樣。有的叫“姓名”有的叫“學(xué)生姓名”有的干脆叫“名字”家庭經(jīng)濟(jì)情況有的填“困難”有的寫“一般困難”還有的寫“建檔立卡”。這么多表要靠人工合并、清洗、匹配一晚一晚地熬。我當(dāng)時(shí)拉著團(tuán)隊(duì)把各來源數(shù)據(jù)抽樣對(duì)比了一下光是“張三”這個(gè)人在不同系統(tǒng)里就有“張 三”“張三(2023級(jí))”“zhangsan”等多種形態(tài)。這還沒提那些用公式算完忘了粘貼成值、導(dǎo)致數(shù)據(jù)錯(cuò)的表格。信息孤島不是技術(shù)問題是治理問題。校園管理的智能化第一步不是上 AI而是先把數(shù)據(jù)這條線捋直。1.2 管理動(dòng)作靠人肉成本被嚴(yán)重低估數(shù)據(jù)亂帶來的直接后果就是日常管理動(dòng)作效率極低。輔導(dǎo)員的典型一天是這樣的早上查課看誰曠課手動(dòng)翻考勤表中午處理請(qǐng)假審批紙質(zhì)假條要在教學(xué)樓和宿舍樓之間跑好幾個(gè)簽字下午做心理健康排查挨個(gè)打電話問情況晚上還要去查寢拿著名單一間間宿舍核對(duì)。這些動(dòng)作單獨(dú)看都不難但乘上學(xué)生數(shù)量就是無底洞。一個(gè)輔導(dǎo)員帶兩百多個(gè)學(xué)生每周光“統(tǒng)計(jì)不在校名單”就要花半天。到了評(píng)獎(jiǎng)評(píng)優(yōu)季更夸張各種加分證明材料堆成山班長(zhǎng)統(tǒng)計(jì)、輔導(dǎo)員復(fù)核、學(xué)院終審一個(gè)環(huán)節(jié)出錯(cuò)后面全部推倒重來。人肉管理不只是累還會(huì)漏。誰連續(xù)幾天沒去上課、誰最近消費(fèi)異常下降、誰這學(xué)期已經(jīng)掛了兩科這些規(guī)律在人腦里很難被及時(shí)發(fā)現(xiàn)。等輔導(dǎo)員注意到的時(shí)候往往問題已經(jīng)發(fā)酵了很久。所以這個(gè)平臺(tái)的定位從一開始就不是“做一個(gè)花哨的電子花名冊(cè)”而是要把人從重復(fù)勞動(dòng)里解放出來讓系統(tǒng)替人盯著異常。1.3 這個(gè)平臺(tái)到底解決什么一條線、一個(gè)庫、一張網(wǎng)項(xiàng)目啟動(dòng)會(huì)上我們和學(xué)工處把需求收斂成了三句話統(tǒng)一數(shù)據(jù)源、自動(dòng)化流程、智能化預(yù)警。這就是后來整個(gè)平臺(tái)的三大支柱。統(tǒng)一數(shù)據(jù)源是把學(xué)生在校期間的全生命周期信息放進(jìn)一個(gè)核心庫從入學(xué)、選課、住宿、獎(jiǎng)懲、資助到畢業(yè)去向所有系統(tǒng)都圍繞它做數(shù)據(jù)交換。自動(dòng)化流程是把請(qǐng)假、查寢、評(píng)優(yōu)、困難認(rèn)定這些高頻場(chǎng)景搬上線用審批流替代跑腿簽字。智能化預(yù)警則是在數(shù)據(jù)基礎(chǔ)上做規(guī)則判斷和異常識(shí)別發(fā)現(xiàn)苗頭主動(dòng)通知老師而不是等老師來查。這三句話聽著簡(jiǎn)單落地時(shí)每一步都是硬骨頭。我們也算踩了不少坑下面的內(nèi)容我會(huì)按模塊展開把關(guān)鍵設(shè)計(jì)和背后的取舍講清楚。2. 平臺(tái)總體架構(gòu)與關(guān)鍵選型先把地基打扎實(shí)2.1 整體分層和模塊劃分平臺(tái)采用經(jīng)典的前后端分離架構(gòu)整體分為四層接入層、業(yè)務(wù)層、數(shù)據(jù)層和集成層。接入層負(fù)責(zé)統(tǒng)一的 API 網(wǎng)關(guān)和鑒權(quán)所有端的上行請(qǐng)求都走這里。業(yè)務(wù)層按領(lǐng)域拆模塊包括基礎(chǔ)信息、學(xué)籍、考勤、請(qǐng)假、評(píng)優(yōu)、資助、預(yù)警、消息通知八大模塊。數(shù)據(jù)層以 MySQL 為主庫Redis 做緩存和分布式鎖Elasticsearch 承擔(dān)全文檢索和大屏聚合查詢。集成層是對(duì)接第三方系統(tǒng)的通道包括教務(wù)系統(tǒng)、一卡通、宿管門禁、短信網(wǎng)關(guān)和企業(yè)微信。這樣分層的核心原因是為了讓“集成”這件事可控。學(xué)生管理平臺(tái)不可能推倒學(xué)校原有系統(tǒng)重建必須跟已有的教務(wù)、一卡通等系統(tǒng)共存。所以我們把所有外部對(duì)接都收斂到集成層統(tǒng)一用接口適配器模式哪怕某個(gè)老系統(tǒng)只提供 CSV 導(dǎo)出也能通過定時(shí)任務(wù)把數(shù)據(jù)落庫不讓外部差異污染核心業(yè)務(wù)代碼。2.2 技術(shù)棧選型為什么是這樣的組合技術(shù)選型上我們刻意沒有追新而是選了一套團(tuán)隊(duì)最熟、社區(qū)資料最多的組合。后端Java 17 Spring Boot 3.x MyBatis-Plus。前端Vue 3 TypeScript Element Plus。數(shù)據(jù)庫MySQL 8.0讀寫分離從庫負(fù)責(zé)報(bào)表查詢和大屏聚合。緩存與隊(duì)列Redis RabbitMQ。定時(shí)任務(wù)xxl-job。檢索Elasticsearch 8.x。有人會(huì)問為什么不用 PostgreSQL原因很現(xiàn)實(shí)某高校信息中心現(xiàn)有的運(yùn)維體系里MySQL 是所有人最熟的東西出了問題能快速響應(yīng)。在一個(gè)以“穩(wěn)定交付”為首要目標(biāo)的項(xiàng)目里團(tuán)隊(duì)熟悉度比技術(shù)先進(jìn)性重要得多。而選 MyBatis-Plus 是因?yàn)樗銐蜉p量既能有 ActiveRecord 式的便捷又能隨時(shí)寫原生 SQL 去處理復(fù)雜的多表統(tǒng)計(jì)。前端選 Vue 3 而不選 React除了團(tuán)隊(duì)技術(shù)棧一致還因?yàn)?Element Plus 的表格、表單、樹組件在管理后臺(tái)類項(xiàng)目里太好用了。這類系統(tǒng)核心是表單和列表組件庫的成熟度直接影響開發(fā)速度。我不建議在這種項(xiàng)目里搞前端微服務(wù)或者 SSR復(fù)雜度和收益不成正比。2.3 核心數(shù)據(jù)模型學(xué)生的“一張表”設(shè)計(jì)整個(gè)平臺(tái)的數(shù)據(jù)模型核心是一張stu_base_info學(xué)生基礎(chǔ)信息表幾乎其他所有表都通過stu_no與它關(guān)聯(lián)。CREATE TABLE stu_base_info ( id BIGINT PRIMARY KEY AUTO_INCREMENT, stu_no VARCHAR(20) NOT NULL UNIQUE COMMENT 學(xué)號(hào), name VARCHAR(50) NOT NULL COMMENT 姓名, gender TINYINT COMMENT 性別 1男 2女, id_card_no VARCHAR(18) COMMENT 身份證號(hào)(加密存儲(chǔ)), college_id BIGINT NOT NULL COMMENT 學(xué)院ID, major_id BIGINT NOT NULL COMMENT 專業(yè)ID, class_id BIGINT NOT NULL COMMENT 班級(jí)ID, enroll_year VARCHAR(4) COMMENT 入學(xué)年份, status TINYINT DEFAULT 1 COMMENT 1在讀 2休學(xué) 3退學(xué) 4畢業(yè), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_org (college_id, major_id, class_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT學(xué)生基礎(chǔ)信息表;這張表特別強(qiáng)調(diào)了兩件事。第一以學(xué)號(hào)作為唯一業(yè)務(wù)鍵而不是用姓名。原因就是前面說的姓名在全校范圍內(nèi)根本不可靠重名和格式問題太多。第二組織機(jī)構(gòu)字段直接冗余了學(xué)院、專業(yè)、班級(jí)三層 ID配合聯(lián)合索引后面做“按學(xué)院/專業(yè)/班級(jí)”維度的權(quán)限過濾和統(tǒng)計(jì)會(huì)快很多不用每次 join 組織表。有人可能會(huì)說規(guī)范化角度應(yīng)該只存class_id但在一個(gè)查詢占了七八成的管理系統(tǒng)里適度冗余比嚴(yán)格三范式更實(shí)用。這個(gè)取舍我們?cè)趬簻y(cè)里驗(yàn)證過加了冗余字段后“全院學(xué)生現(xiàn)狀”這類報(bào)表的查詢耗時(shí)從幾百毫秒降到了幾十毫秒。3. 智能化不是口頭功夫預(yù)警引擎與數(shù)據(jù)觸達(dá)的落地細(xì)節(jié)3.1 規(guī)則引擎設(shè)計(jì)讓業(yè)務(wù)老師自己配規(guī)則做預(yù)警功能之前我們問了一圈輔導(dǎo)員你最想被系統(tǒng)提醒什么答案集中在學(xué)業(yè)掛科、心理異常、經(jīng)濟(jì)困難、宿舍晚歸、連續(xù)曠課這幾類。但每個(gè)人的判斷標(biāo)準(zhǔn)不一樣有的老師覺得掛科兩門就該干預(yù)有的老師覺得掛一門就要介入。如果把這些標(biāo)準(zhǔn)寫死在代碼里需求變更一次就要發(fā)一次版業(yè)務(wù)老師也會(huì)產(chǎn)生依賴。所以我們?cè)O(shè)計(jì)了一個(gè)輕量規(guī)則引擎核心思路是指標(biāo) 閾值 邏輯關(guān)系 動(dòng)作。{ ruleCode: risk_absent_low, ruleName: 學(xué)業(yè)預(yù)警-掛科過多, metricRules: [ { metric: fail_courses, op: , value: 2, window: semester }, { metric: gpa, op: , value: 2.0, window: semester } ], logic: AND, action: { type: notify, channels: [wecom, sms], targets: [advisor, student] } }規(guī)則配置存在數(shù)據(jù)庫表里通過一個(gè)管理界面給學(xué)工處老師使用。他們可以自己定義“什么指標(biāo)、大于還是小于、閾值多少、多長(zhǎng)時(shí)間窗口、滿足條件后通知誰”不需要寫一行代碼。引擎層用策略模式實(shí)現(xiàn)每次學(xué)生數(shù)據(jù)變更或定時(shí)任務(wù)跑批時(shí)都會(huì)把相關(guān)指標(biāo)計(jì)算出來再和配置的規(guī)則比對(duì)。這個(gè)設(shè)計(jì)最讓我滿意的點(diǎn)是“可解釋”。它不像某些黑箱算法老師能看懂為什么這個(gè)學(xué)生被預(yù)警規(guī)則是透明的、可調(diào)整的。校園管理場(chǎng)景里老師要拿著預(yù)警結(jié)果去跟學(xué)生談話必須能講清楚依據(jù)否則再準(zhǔn)的模型也沒人敢用。3.2 基于統(tǒng)計(jì)特征的異常識(shí)別不止依賴固定閾值固定規(guī)則能覆蓋大部分顯性問題但有些異常是規(guī)則描述不清楚的。比如經(jīng)濟(jì)困難學(xué)生的認(rèn)定固定閾值很難定義什么叫“消費(fèi)異?!?。這時(shí)候我們引入了一些簡(jiǎn)單的統(tǒng)計(jì)特征。具體做法是從一卡通系統(tǒng)拉取學(xué)生每月的消費(fèi)記錄按窗口期計(jì)算該生過去 N 周的平均日消費(fèi)金額和標(biāo)準(zhǔn)差。如果當(dāng)前周的日均消費(fèi)低于歷史均值減兩倍標(biāo)準(zhǔn)差就標(biāo)記為“疑似消費(fèi)驟降”自動(dòng)觸發(fā)關(guān)注提醒。另一個(gè)例子是查寢統(tǒng)計(jì)某學(xué)生過去 30 天的晚歸次數(shù)超過該樓棟平均晚歸次數(shù)的 3 倍時(shí)標(biāo)記異常。這里必須強(qiáng)調(diào)的是我們刻意沒有堆深度學(xué)習(xí)模型。原因有兩個(gè)第一校園數(shù)據(jù)樣本量有限深度學(xué)習(xí)在這種場(chǎng)景容易過擬合第二異常識(shí)別的結(jié)果是要由人去處理的統(tǒng)計(jì)特征加閾值的方法更容易向一線老師解釋。做智能化不是越復(fù)雜越好而是在合適的約束下選最有效的方案。這套統(tǒng)計(jì)規(guī)則上線后確實(shí)幫資助口的老師發(fā)現(xiàn)了幾個(gè)之前沒注意到的案例這比模型 AUC 高多少個(gè)點(diǎn)更有意義。3.3 通知觸達(dá)的“最后一百米”怎么走通預(yù)警系統(tǒng)光有判斷還不夠還得把消息送到該看的人手里。我們做了三通道觸達(dá)企業(yè)微信、短信、站內(nèi)信。優(yōu)先級(jí)是企業(yè)微信最高因?yàn)樗赓M(fèi)、可雙向交互輔導(dǎo)員日常也習(xí)慣用它短信留作緊急兜底站內(nèi)信只做記錄展示。這里有個(gè)容易被忽略的點(diǎn)消息模板必須和業(yè)務(wù)場(chǎng)景強(qiáng)綁定。同樣是“預(yù)警通知”學(xué)業(yè)預(yù)警和晚歸預(yù)警的措辭、發(fā)送對(duì)象、抄送范圍完全不一樣。我們做了一個(gè)模板管理模塊每條模板都綁定規(guī)則編碼和優(yōu)先級(jí)文案由學(xué)工處審定避免系統(tǒng)直接把干巴巴的“學(xué)生張三觸發(fā)規(guī)則 001”發(fā)出去。還有個(gè)細(xì)節(jié)是免打擾邏輯。我們參考了運(yùn)營(yíng)平臺(tái)的做法加了全局頻控同一學(xué)生關(guān)聯(lián)的消息一小時(shí)最多 2 條同一事件只推一次晚上 22:30 到次日 7:00 不推短信避免家長(zhǎng)半夜被打擾。沒有這層控制預(yù)警系統(tǒng)很容易變成新的騷擾源。后面我會(huì)專門講這個(gè)坑。3.4 大屏不是面子工程從展示到?jīng)Q策的閉環(huán)學(xué)校領(lǐng)導(dǎo)對(duì)大屏數(shù)據(jù)可視化有執(zhí)念我們也理解。但做數(shù)據(jù)大屏最容易犯的錯(cuò)是只做漂亮的圖表沒有決策入口。我們的大屏支持三層下鉆第一層是全??傆[展示在校生總數(shù)、男女比例、當(dāng)前預(yù)警人數(shù)、今日請(qǐng)假人數(shù)等核心指標(biāo)第二層點(diǎn)某個(gè)學(xué)院看該學(xué)院的預(yù)警分布、晚歸趨勢(shì)、困難生占比第三層點(diǎn)某個(gè)具體預(yù)警直接跳轉(zhuǎn)到學(xué)生詳情頁和處置記錄頁。換句話說大屏不僅是看的也是“用”的。領(lǐng)導(dǎo)在屏幕上發(fā)現(xiàn)問題可以直接調(diào)度輔導(dǎo)員跟進(jìn)處置結(jié)果寫回系統(tǒng)形成閉環(huán)。技術(shù)上大屏數(shù)據(jù)走 Elasticsearch 預(yù)聚合用定時(shí)任務(wù)每 5 分鐘刷新一次避免頻繁查 MySQL 影響業(yè)務(wù)庫。首頁的聚合指標(biāo)單獨(dú)做了寬表冗余基本能做到秒開。4. 高頻校園場(chǎng)景的高效化怎么把流程壓縮成三步4.1 請(qǐng)假與銷假的在線閉環(huán)傳統(tǒng)的請(qǐng)假流程是學(xué)生手寫假條輔導(dǎo)員簽字再交到學(xué)院蓋章最后送到宿管備案。趕上輔導(dǎo)員不在辦公室來回拖一兩天很正常。我們把它搬上線流程壓縮成了三步學(xué)生提交申請(qǐng)、輔導(dǎo)員審批、系統(tǒng)自動(dòng)通知相關(guān)角色。這個(gè)流程看起來簡(jiǎn)單細(xì)節(jié)卻不少。比如請(qǐng)假類型分事假、病假、課程請(qǐng)假和離校請(qǐng)假不同類型對(duì)應(yīng)的審批鏈路不同。病假需要上傳醫(yī)院證明離校請(qǐng)假超過三天要加學(xué)院分管領(lǐng)導(dǎo)審批。我們把審批流做成了可配置的節(jié)點(diǎn)鏈每一步可以設(shè)置條件分支和審批人角色。比較得意的是銷假功能。傳統(tǒng)流程里學(xué)生假期結(jié)束回來經(jīng)常忘記到輔導(dǎo)員那銷假。系統(tǒng)做成這樣離校請(qǐng)假到期后自動(dòng)觸發(fā)銷假提醒學(xué)生回校后在小程序上點(diǎn)“確認(rèn)返校”系統(tǒng)記錄時(shí)間并通知宿管解除床位離校狀態(tài)。這樣一來輔導(dǎo)員不用整天盯著名單問“誰回來了沒”。4.2 評(píng)獎(jiǎng)評(píng)優(yōu)從人肉打分到規(guī)則自動(dòng)核算評(píng)獎(jiǎng)評(píng)優(yōu)是每年最讓輔導(dǎo)員頭疼的事沒有之一。一個(gè)獎(jiǎng)學(xué)金評(píng)審涉及成績(jī)排名、競(jìng)賽加分、志愿服務(wù)時(shí)長(zhǎng)、班級(jí)評(píng)議分四個(gè)維度每個(gè)學(xué)院的計(jì)算權(quán)重還不一樣。人工核算很容易漏加分項(xiàng)一旦公示出來被學(xué)生質(zhì)疑又要重新翻一遍材料。我們的做法是把評(píng)分模型做成可配置公式。每個(gè)評(píng)獎(jiǎng)項(xiàng)目設(shè)置若干維度、權(quán)重和加分上限系統(tǒng)自動(dòng)從成績(jī)系統(tǒng)拉取學(xué)分績(jī)點(diǎn)從志愿服務(wù)系統(tǒng)拉取時(shí)長(zhǎng)從競(jìng)賽系統(tǒng)拉取獲獎(jiǎng)記錄然后按公式自動(dòng)核算生成初評(píng)排名供輔導(dǎo)員復(fù)核。這里有一點(diǎn)要給同行提醒自動(dòng)化評(píng)分只能做“可量化”的部分不能替代人工評(píng)議。比如“思想政治表現(xiàn)”這類定性指標(biāo)系統(tǒng)只負(fù)責(zé)匯總材料和留痕最終評(píng)價(jià)仍然由評(píng)審小組在系統(tǒng)里填寫。自動(dòng)化和人的判斷各占一半這個(gè)項(xiàng)目才推得動(dòng)。上線第一個(gè)學(xué)期某學(xué)院的評(píng)獎(jiǎng)材料準(zhǔn)備時(shí)間從一周縮短到一天輔導(dǎo)員感嘆說“終于有時(shí)間干點(diǎn)真正該干的事”。4.3 查寢、晚歸、考勤的自動(dòng)化替代查寢是宿管工作的重頭戲。傳統(tǒng)方式晚上十點(diǎn)去敲宿舍門效率低還打擾學(xué)生。我們對(duì)接了宿管門禁系統(tǒng)每個(gè)宿舍門裝上掃碼/刷卡設(shè)備學(xué)生進(jìn)出自動(dòng)產(chǎn)生通行記錄。系統(tǒng)按時(shí)間窗口統(tǒng)計(jì)晚上 23:00 后沒有回寢記錄的學(xué)生自動(dòng)進(jìn)入“疑似晚歸名單”整晚無記錄且第二天一早也無出寢記錄的進(jìn)入“疑似夜不歸宿名單”。考勤也一樣。原來老師課前得挨個(gè)點(diǎn)名現(xiàn)在我們對(duì)接了教學(xué)樓的門禁閘機(jī)學(xué)生進(jìn)教學(xué)樓刷卡即視為到課。不過考勤這塊沒有完全自動(dòng)化裁決因?yàn)榭傆袑W(xué)生幫人代刷或者刷卡后溜走。所以系統(tǒng)生成的是“疑似缺勤名單”最終由任課教師人工確認(rèn)。這個(gè)“疑似確認(rèn)”的模式非常重要它既省了老師逐一點(diǎn)名的力氣又保留了人的判斷權(quán)推行阻力小很多。4.4 報(bào)表臺(tái)賬自動(dòng)生成把輔導(dǎo)員的時(shí)間還回去校園管理的日常工作有一大半是在填表、做臺(tái)賬、應(yīng)付檢查。困難生走訪記錄、心理談話記錄、宿舍檢查記錄每樣都要留痕。以前輔導(dǎo)員靠 Word 手打格式不統(tǒng)一檢查時(shí)還得自己重新整理。平臺(tái)內(nèi)置了一套臺(tái)賬引擎。輔導(dǎo)員在手機(jī)端處理完一筆業(yè)務(wù)比如一次心理談話、一次宿舍走訪系統(tǒng)會(huì)自動(dòng)生成結(jié)構(gòu)化記錄整合成可導(dǎo)出的臺(tái)賬文檔。需要給上級(jí)部門報(bào)送的數(shù)據(jù)選擇學(xué)院和日期范圍系統(tǒng)直接匯總成 Excel。數(shù)據(jù)來源都是日常業(yè)務(wù)過程中采的不需要二次錄入。這個(gè)功能上線后的口碑比預(yù)警系統(tǒng)還好。原因很實(shí)在它能直接減少加班。智能化很多時(shí)候不是炫技是把人從重復(fù)勞動(dòng)里解放出來這才是高效最樸素的定義。5. 權(quán)限、安全和隱私多角色場(chǎng)景下最容易出問題的地方5.1 角色權(quán)限模型誰看到什么數(shù)據(jù)必須像手術(shù)刀一樣精確學(xué)生管理平臺(tái)的角色非常復(fù)雜輔導(dǎo)員、班主任、學(xué)院副書記、學(xué)工處長(zhǎng)、宿管員、資助專員、心理老師每個(gè)人都只應(yīng)該看到自己職責(zé)范圍內(nèi)的數(shù)據(jù)。一開始我們只做了 RBAC 角色權(quán)限結(jié)果測(cè)試的時(shí)候發(fā)現(xiàn)一個(gè)大問題一個(gè)輔導(dǎo)員能搜到全校學(xué)生的信息。這個(gè)問題非常嚴(yán)重尤其涉及學(xué)生成績(jī)、家庭經(jīng)濟(jì)狀況、心理健康記錄這些敏感信息。我們后來在 RBAC 之上加了數(shù)據(jù)權(quán)限維度核心邏輯是“角色決定能看什么類型的數(shù)據(jù)數(shù)據(jù)范圍決定能看哪些行”。輔導(dǎo)員默認(rèn)只能看到自己所帶班級(jí)的學(xué)生學(xué)院領(lǐng)導(dǎo)能看到全院校級(jí)角色才能看全校宿管員只能看到住宿相關(guān)信息字段。實(shí)現(xiàn)上我們用 MyBatis-Plus 的攔截器在 SQL 解析階段自動(dòng)追加數(shù)據(jù)范圍條件。每個(gè)請(qǐng)求進(jìn)來時(shí)從上下文拿到當(dāng)前用戶的可視化范圍編碼拼進(jìn) SQL 的 WHERE 條件。這樣即使前端頁面漏傳了篩選條件后端也不會(huì)把數(shù)據(jù)泄露出去。這個(gè)設(shè)計(jì)我們?cè)谠u(píng)審時(shí)反復(fù)強(qiáng)調(diào)數(shù)據(jù)權(quán)限必須做在后端不能依賴前端隱藏。5.2 數(shù)據(jù)脫敏與審計(jì)日志學(xué)生數(shù)據(jù)里有大量個(gè)人敏感信息身份證號(hào)、手機(jī)號(hào)、家庭住址、貧困認(rèn)定材料。我們對(duì)這些字段做了分級(jí)處理接口返回時(shí)自動(dòng)脫敏身份證號(hào)只顯示前 6 位和后 4 位手機(jī)號(hào)顯示前 3 位和后 4 位。只有經(jīng)過二次授權(quán)的人比如資助專員在辦理業(yè)務(wù)時(shí)才能查看完整信息且查看行為會(huì)記錄審計(jì)日志。審計(jì)日志我們一開始沒打算做那么細(xì)后來出了個(gè)事才下定決心。有一次某學(xué)院副書記在系統(tǒng)里導(dǎo)出了全院的貧困生名單雖然他是學(xué)院有權(quán)限但導(dǎo)出動(dòng)作沒有留痕后來引發(fā)爭(zhēng)議找不到依據(jù)。所以現(xiàn)在系統(tǒng)規(guī)定任何涉及批量導(dǎo)出敏感數(shù)據(jù)的操作必須填寫導(dǎo)出事由并實(shí)時(shí)記錄操作人、時(shí)間、導(dǎo)出范圍。這個(gè)功能在高校審計(jì)和輿情應(yīng)對(duì)時(shí)特別有用。5.3 從設(shè)計(jì)之初就要考慮的合規(guī)底線關(guān)于安全合規(guī)我的建議是不要等項(xiàng)目上線了再補(bǔ)。我們這個(gè)平臺(tái)在設(shè)計(jì)階段就確定了幾個(gè)底線只采集業(yè)務(wù)必要的數(shù)據(jù)能做到離線導(dǎo)入就不開實(shí)時(shí)接口能脫敏就不存明文能數(shù)據(jù)保留在校內(nèi)就不上公有云。學(xué)生數(shù)據(jù)里有一部分比如心理測(cè)評(píng)結(jié)果和家庭經(jīng)濟(jì)信息屬于高度敏感范疇。我們對(duì)這類數(shù)據(jù)做了加密存儲(chǔ)AES-256 加密后落庫查詢時(shí)按需解密。傳輸鏈路全部走 HTTPS接口層面統(tǒng)一做參數(shù)校驗(yàn)和冪等處理防止重放攻擊。這里我想多說一句合規(guī)不是技術(shù)問題而是取舍問題。有些學(xué)校會(huì)要求平臺(tái) SaaS 化托管到校外但考慮到學(xué)生數(shù)據(jù)敏感性和后續(xù)可能的數(shù)據(jù)出境等問題我們最終堅(jiān)持校內(nèi)私有化部署。這個(gè)決策在推進(jìn)過程中會(huì)慢一些但從長(zhǎng)期看它避免了無數(shù)潛在的信任危機(jī)。做校園類系統(tǒng)安全底線要自己主動(dòng)抬高不要等出了問題再后悔。6. 上線半年踩過的坑比功能設(shè)計(jì)更值得記錄的事6.1 考勤數(shù)據(jù)的“臟”程度超乎想象平臺(tái)上線第一周學(xué)業(yè)預(yù)警模塊就鬧了個(gè)大笑話。我們直接對(duì)接了教務(wù)系統(tǒng)的成績(jī)表結(jié)果發(fā)現(xiàn)好多學(xué)生“掛科”記錄其實(shí)是補(bǔ)考通過的成績(jī)?cè)疾患案裼涗洓]有狀態(tài)清理。系統(tǒng)把已經(jīng)補(bǔ)考過了的學(xué)生又預(yù)警了一遍輔導(dǎo)員只能挨個(gè)跟學(xué)生解釋“系統(tǒng)出錯(cuò)了”。事后復(fù)盤問題出在我們對(duì)源頭數(shù)據(jù)缺少清洗規(guī)則。后來我們加了一層數(shù)據(jù)質(zhì)量校驗(yàn)成績(jī)同步時(shí)只取最終有效成績(jī)且通過“補(bǔ)考通過”“重修通過”等狀態(tài)字段過濾掉歷史不及格記錄。這個(gè)經(jīng)驗(yàn)對(duì)所有做數(shù)據(jù)集成的人都適用外部系統(tǒng)的數(shù)據(jù)不能信“原樣”必須把數(shù)據(jù)字典、狀態(tài)流轉(zhuǎn)、邏輯刪除規(guī)則徹底摸清楚再動(dòng)手做映射。6.2 預(yù)警閾值不是拍腦袋定的是拿歷史數(shù)據(jù)試出來的預(yù)警規(guī)則剛上線我們拍腦袋把“消費(fèi)驟降”的閾值定義成“低于歷史均值 20%”。結(jié)果系統(tǒng)一周吐出了 300 多條預(yù)警學(xué)工處的老師直接崩潰因?yàn)槊織l預(yù)警都要人工核實(shí)。后來我們拉了過去一年的消費(fèi)數(shù)據(jù)做離線回測(cè)發(fā)現(xiàn)正常學(xué)生的消費(fèi)波動(dòng)本身就很大兩倍標(biāo)準(zhǔn)差才是更合理的邊界。從那之后我們形成一個(gè)規(guī)矩任何預(yù)警規(guī)則上線前必須拿至少一年的歷史數(shù)據(jù)做回測(cè)調(diào)整閾值到“每周新增預(yù)警量不超過該角色處理能力的上限”。預(yù)警系統(tǒng)不是為了多報(bào)警而是為了精報(bào)警。如果老師打開手機(jī)看到一堆無效提醒下次就不會(huì)再看系統(tǒng)了這才是預(yù)警系統(tǒng)真正的失敗。6.3 消息推送會(huì)制造新的內(nèi)耗關(guān)于觸達(dá)頻率的取舍還有一次比較尷尬的事故是“晚安問候轟炸”。晚歸預(yù)警和查寢通知綁定了同一個(gè)消息隊(duì)列趕上周末大量學(xué)生外出晚歸宿管員和企業(yè)微信機(jī)器人被同一條消息刷屏。有的學(xué)生一晚收到 3 條提醒直接在平臺(tái)上投訴“這比查寢還煩人”。后來我們做了兩層優(yōu)化。第一層是事件去重同一個(gè)學(xué)生、同類預(yù)警、同一個(gè)自然日內(nèi)只推送一次。第二層是通道降噪低級(jí)別的預(yù)警只發(fā)站內(nèi)信和企業(yè)微信不發(fā)短信只有涉及安全類事件例如連續(xù)多日夜不歸宿才升級(jí)為短信通知。這里也建議其他項(xiàng)目組做觸達(dá)系統(tǒng)必須先定義“打擾上限”不然業(yè)務(wù)方只會(huì)不斷加需求最終把系統(tǒng)做成人人討厭的牛皮癬。6.4 大分頁和導(dǎo)出性能看起來簡(jiǎn)單實(shí)際上翻車輔導(dǎo)員最常用的一個(gè)操作是“按班級(jí)導(dǎo)出學(xué)生名單”聽起來很簡(jiǎn)單。但學(xué)生信息關(guān)聯(lián)了幾十張子表列表頁一次要返回上百個(gè)字段再加個(gè) deep offset 大分頁MySQL 直接被慢查詢拖崩。我們監(jiān)控中發(fā)現(xiàn)某個(gè)高頻接口的 99 分位響應(yīng)時(shí)間跑到了 8 秒頁面轉(zhuǎn)圈轉(zhuǎn)到用戶重新登錄。解決方式是三層優(yōu)化。第一列表接口輕量化默認(rèn)只返回 20 個(gè)核心字段詳情展開時(shí)再查明細(xì)。第二分頁改成游標(biāo)分頁用WHERE id ? ORDER BY id LIMIT ?替代LIMIT offset, size深分頁性能問題直接消失。第三導(dǎo)出接口全部改成異步任務(wù)用戶點(diǎn)導(dǎo)出后系統(tǒng)后臺(tái)生成 Excel 再推送給用戶下載而不是讓 HTTP 請(qǐng)求一直掛在那里。這套組合拳下來接口響應(yīng)時(shí)間降到了 500ms 以內(nèi)。6.5 一點(diǎn)個(gè)人感受與后續(xù)擴(kuò)展計(jì)劃做這個(gè)平臺(tái)最大的感受是項(xiàng)目成功的核心不是技術(shù)多新而是能不能真正融入校園管理的日常節(jié)奏。很多系統(tǒng)功能做得很全最后卻沒人用原因就是它給老師增加的負(fù)擔(dān)比省下的還多。我們這個(gè)平臺(tái)每一個(gè)功能上線前都會(huì)問同一個(gè)問題這個(gè)功能能讓一線輔導(dǎo)員少花多少時(shí)間答案不明確的功能寧可不做。后面我們計(jì)劃做兩件事。一是把畢業(yè)生去向跟蹤模塊完善起來從就業(yè)系統(tǒng)、校友系統(tǒng)自動(dòng)回填數(shù)據(jù)減少輔導(dǎo)員催就業(yè)的精力消耗。二是把現(xiàn)有的統(tǒng)計(jì)特征模型逐步升級(jí)成可解釋的序列模型比如根據(jù)前幾周的出勤、消費(fèi)、心理測(cè)評(píng)軌跡提前一個(gè)周期預(yù)判風(fēng)險(xiǎn)。不過升級(jí)之前先把數(shù)據(jù)質(zhì)量和用戶信任維護(hù)好這才是這類平臺(tái)最值錢的東西。如果你們也在做類似的校園系統(tǒng)記住一條少一點(diǎn)花架子多一點(diǎn)能省時(shí)間的真功能。