到現(xiàn)代重構(gòu)的權(quán)限與流程設(shè)計(jì))
簡介這是面向企業(yè)CRM系統(tǒng)建設(shè)與產(chǎn)品設(shè)計(jì)人員的需求分析設(shè)計(jì)文檔圍繞客戶關(guān)系管理中的銷售自動(dòng)化、客戶信息整合與數(shù)據(jù)分析支持等目標(biāo)展開適合產(chǎn)品經(jīng)理、需求分析師和開發(fā)團(tuán)隊(duì)參考。文檔以1個(gè)doc文件呈現(xiàn)壓縮包大小1.66MB內(nèi)容涵蓋項(xiàng)目背景、用戶組織結(jié)構(gòu)、業(yè)務(wù)流程、功能需求及性能指標(biāo)并附有詳盡的用例描述、概念結(jié)構(gòu)圖、業(yè)務(wù)流程圖和界面原型預(yù)覽便于從需求到設(shè)計(jì)一體化理解。全文約60頁結(jié)構(gòu)按引言、任務(wù)概述、功能需求、性能需求等模塊劃分既可幫助團(tuán)隊(duì)統(tǒng)一術(shù)語與需求口徑也可作為后續(xù)系統(tǒng)設(shè)計(jì)與開發(fā)驗(yàn)收的基線。目前已有188人學(xué)習(xí)下載對正在規(guī)劃或?qū)嵤〤RM項(xiàng)目的人員具有直接借鑒價(jià)值。1. 這份CRM客戶關(guān)系管理需求文檔值得每個(gè)ToB開發(fā)者讀一遍剛接觸CRM客戶關(guān)系管理項(xiàng)目的開發(fā)者最容易把需求分析文檔當(dāng)成“一堆沒用的流程描述”。直到我接手一個(gè)老系統(tǒng)的二次開發(fā)領(lǐng)導(dǎo)丟來一份六十頁的需求規(guī)格說明書才意識(shí)到這些用例描述才是項(xiàng)目最值錢的部分——它定義了完整的三類角色、九大業(yè)務(wù)域、三十多個(gè)功能用例還有精確到按鈕級的界面交互規(guī)則。這套客戶關(guān)系管理系統(tǒng)文檔解決的是典型的中小型企業(yè)客戶管理問題銷售部門管客戶、就業(yè)部門盯合作企業(yè)、主管做審批、系統(tǒng)管理員控權(quán)限。適合正在做CRM相關(guān)項(xiàng)目、需要寫需求文檔、或者想看懂老項(xiàng)目設(shè)計(jì)邏輯的開發(fā)者和產(chǎn)品經(jīng)理。2. 需求文檔里的技術(shù)棧盤點(diǎn)J2EE SQL Server 2000時(shí)代的CRM該看什么2.1 從運(yùn)行環(huán)境反推技術(shù)選型WebSphere、SQL Server與JDK 1.5的組合這份文檔在任務(wù)概述部分給出了清晰的運(yùn)行環(huán)境約束這些信息對于拆解老項(xiàng)目至關(guān)重要。數(shù)據(jù)庫采用Microsoft SQL Server 2000應(yīng)用服務(wù)器是IBM WebSphere Application Server 6.1編譯程序是JDK 1.5操作系統(tǒng)是Windows XP SP2。這一套組合是2008年前后典型的J2EE企業(yè)級應(yīng)用標(biāo)準(zhǔn)配置也決定了代碼層面會(huì)遇到的兩個(gè)關(guān)鍵約束。第一個(gè)約束是JDK 1.5時(shí)代的語法限制。那時(shí)候還沒有Lambda表達(dá)式、Stream API和Optional寫循環(huán)基本靠for和Iterator集合操作靠的是Collections工具類。這意味著如果你打算把這段歷史資產(chǎn)翻新成Spring Boot項(xiàng)目幾乎所有業(yè)務(wù)層的代碼都要重寫而不是簡單調(diào)整依賴。第二個(gè)約束是WebSphere的部署特性。WebSphere 6.1對JSP編譯、類加載順序和數(shù)據(jù)源配置都有自己的一套玩法和今天嵌入式Tomcat的開發(fā)體驗(yàn)差別很大。文檔里提到的“單點(diǎn)登錄功能但不使用AD或其他LDAP系統(tǒng)”在當(dāng)年的技術(shù)背景下一般會(huì)采用Session共享加自定義用戶上下文的方式實(shí)現(xiàn)也就是登錄成功后把用戶信息塞進(jìn)Session再通過Filter攔截請求做身份校驗(yàn)。# 典型的老J2EE部署環(huán)境 JDK 1.5 IBM WebSphere Application Server 6.1 Microsoft SQL Server 2000 (SP4) Windows Server 2003 / Windows XP SP2這套組合決定了兩個(gè)事實(shí)第一系統(tǒng)內(nèi)部大量使用JSP/Servlet/JavaBean的分層方式頁面和業(yè)務(wù)邏輯耦合較重第二數(shù)據(jù)庫訪問走JDBC或早期ORM框架SQL語句直接寫在Java代碼里或配置文件里的情況很常見。2.2 系統(tǒng)目標(biāo)與角色劃分三類角色、三個(gè)業(yè)務(wù)域、一條審批鏈文檔在功能需求開頭明確說了系統(tǒng)由三類角色組成系統(tǒng)管理員、主管銷售部門/就業(yè)部門、業(yè)務(wù)員銷售部門/就業(yè)部門。這個(gè)三角色模型是理解整個(gè)CRM系統(tǒng)的鑰匙。業(yè)務(wù)員負(fù)責(zé)記錄客戶信息、通過和客戶交流記錄客戶表達(dá)的意愿和建議。主管通過業(yè)務(wù)員記錄的客戶信息和日程安排來把握客戶的整體意向動(dòng)態(tài)主管也可以直接和客戶溝通還可以通過郵件系統(tǒng)進(jìn)行雙方交流。系統(tǒng)管理員負(fù)責(zé)客戶分類、用戶信息管理與數(shù)據(jù)安全。從功能劃分來看系統(tǒng)包含九個(gè)模塊日程安排日常事務(wù)、日日程、周日程、月日程、客戶信息管理、指派員工與指派目標(biāo)主管才能操作、郵件系統(tǒng)寫郵件、收件箱、發(fā)件箱、廢件箱、查詢郵件、郵件帳號配置、刪除郵件、群發(fā)郵件、審批管理我的審批、我的申請、短信管理發(fā)送短信、查詢短信、刪除短信、組織結(jié)構(gòu)管理部門管理、員工管理、系統(tǒng)管理客戶分類管理、數(shù)據(jù)庫操作、設(shè)置用戶權(quán)限、組織管理添加修改刪除部門、添加修改刪除人員。-- 角色權(quán)限的核心邏輯數(shù)據(jù)歸屬?zèng)Q定可見范圍 -- 業(yè)務(wù)員只能操作自己的客戶、日程和郵件 -- 主管可以查看下屬業(yè)務(wù)員的數(shù)據(jù)并進(jìn)行審批 SELECT u.user_id, u.user_name, r.role_name, d.dept_name FROM sys_user u JOIN sys_user_role ur ON u.user_id ur.user_id JOIN sys_role r ON ur.role_id r.role_id LEFT JOIN sys_dept d ON u.dept_id d.dept_id WHERE u.user_id ? -- 當(dāng)前登錄用戶這段SQL是權(quán)限模型的核心思路用戶、角色、部門三張表關(guān)聯(lián)。業(yè)務(wù)層再根據(jù)角色類型做數(shù)據(jù)行級過濾。2.3 功能模塊全景十二個(gè)用例模塊的優(yōu)先級與歸屬文檔用表格列舉了三十二個(gè)用例并且標(biāo)注了優(yōu)先級。這里有一個(gè)值得注意的細(xì)節(jié)用例編號并不是統(tǒng)一連貫的——客戶信息管理是CRM201日程安排是CRM101郵件系統(tǒng)是CRM107審批管理是CRM114短信管理是CRM116組織結(jié)構(gòu)是CRM119系統(tǒng)管理是CRM301。這說明文檔在編寫過程中經(jīng)歷了多次功能增補(bǔ)編號體系并不嚴(yán)格。優(yōu)先級標(biāo)注也很有意思??蛻舴诸惞芾?、數(shù)據(jù)庫操作、設(shè)置用戶權(quán)限的優(yōu)先級都達(dá)到了四分以上客戶管理五分、日程安排五分說明文檔編制者認(rèn)為客戶和日程是最核心的業(yè)務(wù)。而郵件系統(tǒng)的用例分散在五到七的編號區(qū)間短信管理則相對邊緣。從這些優(yōu)先級數(shù)據(jù)中我一般會(huì)把模塊劃分為三個(gè)建設(shè)批次批次模塊理由P0必須客戶信息管理、日程安排客戶管理是系統(tǒng)存在的根本日程是銷售日常工作記錄P1重要審批管理、郵件系統(tǒng)、用戶權(quán)限審批支撐業(yè)務(wù)流轉(zhuǎn)郵件是內(nèi)外溝通管道權(quán)限是安全底線P2增強(qiáng)短信管理、組織管理、數(shù)據(jù)庫操作短信是補(bǔ)充通知手段數(shù)據(jù)庫備份還原屬于運(yùn)維功能這個(gè)劃分方式可以直接用于排期和資源分配。如果你在設(shè)計(jì)自己的CRM系統(tǒng)也可以借鑒這種按優(yōu)先級分層的方法把有限的開發(fā)資源先投入核心鏈路。3. 核心模塊拆解日程安排、審批流與郵件管理的用例鏈路3.1 日程安排的用例轉(zhuǎn)換從“點(diǎn)擊新增”到數(shù)據(jù)庫記錄文檔中CRM1.01“日程安排”用例是描述最詳盡的一個(gè)包含了日日程、周日程、月日程三種粒度?;臼录魇怯脩酎c(diǎn)擊日程安排頁面看到四個(gè)菜單——日常事務(wù)、日日程、周日程、月日程然后分別進(jìn)行新增、修改、刪除、查看操作。把這段需求轉(zhuǎn)成后端邏輯其實(shí)就是一張日程表加上增刪改查接口。關(guān)鍵在于“新增日程”對話框中有一個(gè)“關(guān)聯(lián)客戶”字段這個(gè)字段把日程和客戶信息綁定起來。// 日程表核心結(jié)構(gòu)根據(jù)需求推演 CREATE TABLE crm_schedule ( schedule_id INT PRIMARY KEY IDENTITY(1,1), -- 日程ID schedule_type TINYINT NOT NULL, -- 1日 2周 3月 subject NVARCHAR(200) NOT NULL, -- 主題 start_time DATETIME NOT NULL, -- 啟始時(shí)間 content NVARCHAR(2000), -- 內(nèi)容 customer_id INT, -- 關(guān)聯(lián)客戶ID owner_id INT NOT NULL, -- 歸屬人業(yè)務(wù)員ID dept_id INT NOT NULL, -- 歸屬部門 create_time DATETIME DEFAULT GETDATE(), update_time DATETIME DEFAULT GETDATE(), deleted_flag TINYINT DEFAULT 0 );這張表的設(shè)計(jì)思路是schedule_type區(qū)分日程粒度customer_id建立與客戶信息的關(guān)聯(lián)owner_id和dept_id配合實(shí)現(xiàn)數(shù)據(jù)隔離。業(yè)務(wù)規(guī)則中明確規(guī)定“銷售人員只能對自己的日程安排信息進(jìn)行查詢、添加、修改、刪除”所以每次查詢都要帶上owner_id條件。// 查詢?nèi)粘塘斜淼暮诵腟QL按歸屬人過濾 SELECT schedule_id, schedule_type, subject, start_time, content, customer_id FROM crm_schedule WHERE owner_id ? AND deleted_flag 0 AND schedule_type ? -- 日/周/月 ORDER BY start_time DESC;參數(shù)說明第一個(gè)問號是當(dāng)前登錄用戶的ID第二個(gè)問號是日程類型日、周、月。這看似簡單的設(shè)計(jì)恰恰解決了銷售管理中最常見的越權(quán)查看問題。3.2 審批流的狀態(tài)機(jī)我的申請與我的審批CRM1.04“我的申請”和CRM1.03“我的審批”構(gòu)成了一個(gè)完整的審批閉環(huán)。銷售人員發(fā)起申請主管進(jìn)行審批審批結(jié)果只有“同意”或“不同意”兩種。文檔中有一個(gè)特殊需求值得注意“審批通過后就不能對結(jié)果進(jìn)行刪除、修改只能有查看的功能”。這個(gè)需求說明審批流需要狀態(tài)機(jī)。申請從創(chuàng)建到結(jié)束會(huì)經(jīng)歷待審核、已同意、已拒絕、已撤回幾個(gè)狀態(tài)。其中只有待審核狀態(tài)的申請?jiān)试S修改和刪除已通過的申請鎖定。// 申請狀態(tài)枚舉 public enum ApplyStatus { PENDING(0, 待審核), APPROVED(1, 已同意), REJECTED(2, 已拒絕), CANCELED(3, 已撤回); private final int code; private final String desc; ApplyStatus(int code, String desc) { this.code code; this.desc desc; } }審批流實(shí)現(xiàn)的關(guān)鍵在于銷售人員添加申請時(shí)必須選擇一個(gè)審批人文檔明確要求申請內(nèi)容里必須有主題和內(nèi)容且兩項(xiàng)不能為空。審批人在“我的審批”頁面看到待審批列表點(diǎn)擊后查看細(xì)節(jié)并提交審批意見。審批結(jié)束后系統(tǒng)根據(jù)審批結(jié)果更新申請狀態(tài)同時(shí)可以觸發(fā)后續(xù)動(dòng)作比如通知申請者或者記錄日志。// 審批處理的核心邏輯偽代碼 public void approve(Long applyId, Long approverId, boolean approveResult) { // 1. 校驗(yàn)審批人身份 Apply apply applyMapper.selectById(applyId); if (!apply.getApproverId().equals(approverId)) { throw new BizException(只能審批指派給自己的申請); } // 2. 判斷狀態(tài)是否允許審批 if (apply.getStatus() ! ApplyStatus.PENDING.getCode()) { throw new BizException(該申請已處理不能重復(fù)審批); } // 3. 更新狀態(tài) apply.setStatus(approveResult ? ApplyStatus.APPROVED.getCode() : ApplyStatus.REJECTED.getCode()); apply.setApproveTime(new Date()); applyMapper.updateById(apply); }邏輯說明審批前必須校驗(yàn)身份和狀態(tài)雙條件這是防止越權(quán)審批和重復(fù)審批的基本保障。參數(shù)approveResult是布爾值true代表同意false代表不同意。3.3 郵件系統(tǒng)的四箱模型收件箱、發(fā)件箱、廢件箱與查詢郵件系統(tǒng)是這份文檔里用例最多的模塊覆蓋了寫郵件、收件箱、發(fā)件箱、廢件箱、查詢郵件、郵件帳號配置、刪除郵件、群發(fā)郵件八個(gè)功能。核心玩法是四箱模型收件箱存客戶來信發(fā)件箱存已發(fā)出的郵件廢件箱放刪除的郵件再加上一個(gè)查詢功能做全局搜索。四箱模型在數(shù)據(jù)表設(shè)計(jì)上有一個(gè)經(jīng)典做法不物理分區(qū)而是在郵件表上加狀態(tài)字段。-- 郵件系統(tǒng)的表結(jié)構(gòu)設(shè)計(jì)推演 CREATE TABLE crm_mail ( mail_id INT PRIMARY KEY IDENTITY(1,1), mail_to NVARCHAR(200) NOT NULL, -- 收件人地址 mail_from NVARCHAR(200) NOT NULL, -- 發(fā)件人地址 subject NVARCHAR(500), -- 主題 content NTEXT, -- 郵件正文 box_type TINYINT NOT NULL, -- 1收件箱 2發(fā)件箱 3廢件箱 owner_id INT NOT NULL, -- 郵件歸屬人 send_time DATETIME, read_flag TINYINT DEFAULT 0, -- 是否已讀 deleted_flag TINYINT DEFAULT 0, -- 是否邏輯刪除 permanent_flag TINYINT DEFAULT 0 -- 是否永久刪除 );參數(shù)說明box_type是核心字段決定了郵件顯示在哪個(gè)箱體。收件箱和發(fā)件箱刪除郵件時(shí)不會(huì)物理刪行而是把box_type改成3移到廢件箱廢件箱清空時(shí)才是物理刪除或標(biāo)記permanent_flag。這個(gè)設(shè)計(jì)的好處是誤刪可恢復(fù)符合文檔中“恢復(fù)郵件”“清空廢件箱”的用例要求。另外發(fā)件箱支持“再次發(fā)送”收件箱支持“導(dǎo)出Excel”“打印”這些功能在實(shí)現(xiàn)時(shí)都很直接——導(dǎo)出用POI生成Excel打印用瀏覽器的window.print()。4. 從文檔到落地權(quán)限邊界、數(shù)據(jù)模型與接口要求4.1 權(quán)限設(shè)計(jì)系統(tǒng)管理員、主管、業(yè)務(wù)員的數(shù)據(jù)隔離方案文檔反復(fù)強(qiáng)調(diào)三類角色的差異系統(tǒng)管理員負(fù)責(zé)客戶分類、用戶信息管理、數(shù)據(jù)安全主管能查看業(yè)務(wù)員記錄的客戶信息和日程安排能做審批能指派人員和目標(biāo)業(yè)務(wù)員只能管理自己的數(shù)據(jù)和日程。這個(gè)權(quán)限模型要落地需要解決兩個(gè)層面的問題。第一是功能權(quán)限什么人能進(jìn)入什么菜單、點(diǎn)什么按鈕。第二是數(shù)據(jù)權(quán)限業(yè)務(wù)員查客戶列表時(shí)只能看到自己名下或自己部門范圍內(nèi)的客戶。功能權(quán)限在J2EE時(shí)代常見做法是用Filter加上角色標(biāo)識(shí)進(jìn)行URL攔截。數(shù)據(jù)權(quán)限則在SQL層處理比如客戶信息管理模塊中“銷售部門只能對自己管理范圍內(nèi)的系統(tǒng)進(jìn)行管理”意味著客戶表必須有歸屬人字段和歸屬部門字段。// 數(shù)據(jù)權(quán)限過濾的三種策略從簡單到復(fù)雜 // 策略1僅限本人業(yè)務(wù)員 WHERE c.owner_id #{currentUserId} // 策略2本部門主管查看部門下屬業(yè)務(wù)員 WHERE c.dept_id IN ( SELECT dept_id FROM sys_dept WHERE parent_id #{currentUserDeptId} OR dept_id #{currentUserDeptId} ) // 策略3全部數(shù)據(jù)系統(tǒng)管理員 -- 不加過濾條件我一般會(huì)在MyBatis的攔截器里根據(jù)當(dāng)前用戶角色動(dòng)態(tài)拼接這些條件而不是在業(yè)務(wù)代碼里分散判斷。這樣做的原因是權(quán)限規(guī)則集中管理后續(xù)調(diào)整管控級別只需要改攔截器邏輯。4.2 數(shù)據(jù)模型設(shè)計(jì)從ER圖到業(yè)務(wù)表的推演文檔中提到了“數(shù)據(jù)概念結(jié)構(gòu)圖實(shí)體—關(guān)系圖”雖然正文沒有給出具體圖例但結(jié)合用例描述可以反推核心實(shí)體用戶、角色、部門、客戶、日程、郵件、申請審批、短信、客戶分類。這些實(shí)體之間的關(guān)系可以這樣理解一個(gè)部門有多個(gè)用戶一個(gè)用戶擁有多個(gè)客戶一個(gè)客戶有多個(gè)日程和郵件一個(gè)用戶發(fā)起多個(gè)申請、審批多個(gè)申請??蛻舴诸愂菢湫谓Y(jié)構(gòu)系統(tǒng)管理員可以添加修改刪除分類列表節(jié)點(diǎn)。-- 客戶信息表核心業(yè)務(wù)表 CREATE TABLE crm_customer ( customer_id INT PRIMARY KEY IDENTITY(1,1), customer_name NVARCHAR(200) NOT NULL, -- 客戶名稱 customer_type TINYINT, -- 客戶類型關(guān)聯(lián)客戶分類表 contact_name NVARCHAR(100), -- 聯(lián)系人 contact_phone NVARCHAR(50), -- 聯(lián)系電話 owner_id INT NOT NULL, -- 歸屬人業(yè)務(wù)員 dept_id INT NOT NULL, -- 歸屬部門 level TINYINT DEFAULT 1, -- 客戶級別 source NVARCHAR(100), -- 客戶來源 remark NVARCHAR(1000), -- 備注 create_time DATETIME DEFAULT GETDATE() );客戶信息管理是文檔強(qiáng)調(diào)的重點(diǎn)模塊“貫穿于整個(gè)項(xiàng)目”所以這張表的設(shè)計(jì)直接決定了后續(xù)所有關(guān)聯(lián)功能的數(shù)據(jù)基礎(chǔ)。4.3 非功能性需求安全性、界面要求與故障處理文檔的性能需求章節(jié)提到了數(shù)據(jù)精確度、時(shí)間特性、適應(yīng)性運(yùn)行需求部分涉及安全性、用戶界面、接口要求、故障處理。這類非功能性需求雖然不如用例生動(dòng)但在實(shí)施評審時(shí)是必選項(xiàng)。界面要求部分特別有意思文檔列出了二十多個(gè)界面的操作細(xì)節(jié)比如“添加發(fā)送短信”“查看已接收短信列表”“刪除已接收短信”“查看審批列表”“添加審批信息反饋”“查看我的申請列表”等等。界面層的需求文檔通常包含按鈕位置、表單字段、列表展示方式。安全性需求在文檔中沒有展開但結(jié)合“系統(tǒng)管理員對用戶權(quán)限進(jìn)行設(shè)置”這個(gè)用例可以推斷系統(tǒng)需要支持用戶密碼管理、會(huì)話超時(shí)、操作日志記錄。接口要求提到通過標(biāo)準(zhǔn)的WebService為其他軟件系統(tǒng)提供統(tǒng)一的權(quán)限管理服務(wù)這意味著系統(tǒng)不是一個(gè)孤立應(yīng)用而是未來CRM平臺(tái)的一個(gè)基礎(chǔ)服務(wù)。5. 避坑與排查老CRM需求文檔落地時(shí)的5個(gè)經(jīng)典翻車現(xiàn)場5.1 用例編號混亂導(dǎo)致需求追溯困難現(xiàn)象需求評審時(shí)開發(fā)按用例編號追蹤功能發(fā)現(xiàn)CRM119是部門管理、CRM301是客戶分類管理編號沒有任何連續(xù)性而且客戶信息管理同時(shí)出現(xiàn)CRM201和CRM1.01兩種寫法。原因文檔在多次迭代中由不同人補(bǔ)充需求編號體系沒有統(tǒng)一維護(hù)導(dǎo)致追蹤矩陣失效。解決落地前先建立需求追蹤矩陣RTM把所有用例重新編號與模塊、頁面、測試用例一一對應(yīng)。不要沿用文檔里的原始編號作為代碼注釋或接口命名依據(jù)。5.2 “能做成下拉列表的一定做成下拉列表”被過度解讀現(xiàn)象文檔里明確寫著“能做成下來列表的選項(xiàng)一定做成下拉列表。方便用戶”結(jié)果前端把所有文本框都改成了下拉框客戶名稱、郵件內(nèi)容這種自由文本也被做成下拉框數(shù)據(jù)錄入效率反而變低。原因需求描述過于口語化沒有明確哪些字段適合下拉、哪些字段適合自由輸入。解決整理一份枚舉字段清單。客戶分類、客戶類型、日程類型、優(yōu)先級、審批狀態(tài)這些有限取值的字段做下拉客戶名稱、日程主題、郵件正文這種無限取值的字段保留文本輸入。下拉框數(shù)據(jù)來源統(tǒng)一從數(shù)據(jù)字典表讀取。5.3 數(shù)據(jù)權(quán)限只在頁面隱藏沒在接口層管控現(xiàn)象銷售業(yè)務(wù)員通過修改URL參數(shù)訪問到了其他業(yè)務(wù)員的客戶詳情頁越權(quán)數(shù)據(jù)暴露。原因頁面按鈕根據(jù)角色做了顯示隱藏但后端接口沒有做數(shù)據(jù)行級過濾接口層是無條件信任前端傳參的。解決在Service層增加數(shù)據(jù)權(quán)限校驗(yàn)查詢客戶詳情時(shí)必須校驗(yàn)當(dāng)前用戶是否有權(quán)操作該客戶。原則是前端控制可見性后端控制數(shù)據(jù)邊界。5.4 郵件附件存儲(chǔ)方式?jīng)]提前規(guī)劃現(xiàn)象郵件支持導(dǎo)出、打印、再次發(fā)送但文檔沒有提及附件處理上線后用戶反饋發(fā)送含附件的郵件速度極慢服務(wù)器磁盤占用飆升。原因附件直接存在數(shù)據(jù)庫表里大文件讀寫頻繁導(dǎo)致性能瓶頸。解決附件走文件存儲(chǔ)路徑數(shù)據(jù)庫只存文件路徑等信息。經(jīng)驗(yàn)教訓(xùn)是這類隱含需求最好在需求評審階段主動(dòng)追問。5.5 邏輯刪除與物理刪除混用導(dǎo)致數(shù)據(jù)混亂現(xiàn)象廢件箱執(zhí)行“清空”操作后部分郵件還能在收件箱里出現(xiàn)恢復(fù)功能時(shí)數(shù)據(jù)錯(cuò)亂。原因有的模塊用deleted_flag做邏輯刪除有的模塊直接執(zhí)行DELETE語句物理刪除標(biāo)準(zhǔn)不統(tǒng)一。解決統(tǒng)一所有刪除操作走邏輯刪除永久刪除只允許在廢件箱階段執(zhí)行且需要二次確認(rèn)。數(shù)據(jù)表增加deleted_flag和permanent_flag雙字段代碼層用枚舉約束刪除行為。6. 二次開發(fā)改造把2009年的需求文檔翻譯成現(xiàn)代技術(shù)棧如果你拿到的就是這份類似的需求文檔要把它改造成可運(yùn)行的現(xiàn)代系統(tǒng)我的建議是先別急著寫代碼按照下面三個(gè)步驟走。先把六十頁文檔重新拆成用戶故事和驗(yàn)收標(biāo)準(zhǔn)。這個(gè)階段的工作量大約占整個(gè)改造周期的百分之三十。把每個(gè)用例轉(zhuǎn)換成“作為某角色我希望執(zhí)行某操作以便達(dá)到某目標(biāo)”然后給每個(gè)用戶故事標(biāo)注優(yōu)先級和依賴關(guān)系。日程安排、審批流、郵件系統(tǒng)這幾個(gè)用例必須保持原有業(yè)務(wù)語義因?yàn)殇N售流程一旦改得面目全非業(yè)務(wù)方是不會(huì)買賬的。技術(shù)棧遷移方面我一般會(huì)把原有的J2EE結(jié)構(gòu)翻譯成Spring Boot加MyBatis Plus的經(jīng)典組合。JDK 1.5的代碼全部重寫WebSphere的WebService接口改用RESTful方式暴露。數(shù)據(jù)庫方面保留客戶、日程、郵件、審批四張核心表的結(jié)構(gòu)設(shè)計(jì)SQL Server 2000的語法需要轉(zhuǎn)換到MySQL 8或PostgreSQL比如分頁方式要改、NTEXT類型要換成TEXT或JSONB。郵件模塊的改造值得單獨(dú)講一下。老系統(tǒng)的郵件收發(fā)是基于JavaMail直接對接郵件服務(wù)器的現(xiàn)在更推薦用Spring Boot的郵件自動(dòng)配置配合OAuth2協(xié)議對接企業(yè)郵箱。文檔中“廢件箱可恢復(fù)”的需求建議用軟刪除加回收站機(jī)制實(shí)現(xiàn)不要物理刪行。權(quán)限這塊我的經(jīng)驗(yàn)是直接換用Spring Security加Sa-Token這類成熟框架不建議自己寫Filter攔截器。文檔中“系統(tǒng)管理員可以在任何機(jī)構(gòu)下創(chuàng)建用戶機(jī)構(gòu)管理員可以在自己機(jī)構(gòu)下新建用戶”這個(gè)需求翻譯到現(xiàn)代框架里就是基于RBAC模型的用戶和機(jī)構(gòu)管理用數(shù)據(jù)權(quán)限注解加部門數(shù)據(jù)范圍控制就能搞定。從那以后我每次拿到老舊的需求文檔都會(huì)強(qiáng)制走一遍“拆用例、列名詞、畫邊界、定狀態(tài)”四個(gè)步驟再動(dòng)手寫代碼這樣既能保證需求不丟失又不會(huì)讓老文檔的過時(shí)設(shè)計(jì)拖累新技術(shù)方案。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取